diff --git a/.buildkite/package-lock.json b/.buildkite/package-lock.json new file mode 100644 index 0000000000000..cfbcb9ec1aae8 --- /dev/null +++ b/.buildkite/package-lock.json @@ -0,0 +1,915 @@ +{ + "name": "kibana-buildkite", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "kibana-buildkite", + "version": "1.0.0", + "dependencies": { + "kibana-buildkite-library": "git+https://git@github.com/elastic/kibana-buildkite-library#0f95579ace8100de9f1ad4cc16976b9ec6d5841e" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@octokit/auth-token": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", + "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", + "dependencies": { + "@octokit/types": "^6.0.3" + } + }, + "node_modules/@octokit/core": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz", + "integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==", + "dependencies": { + "@octokit/auth-token": "^2.4.4", + "@octokit/graphql": "^4.5.8", + "@octokit/request": "^5.6.3", + "@octokit/request-error": "^2.0.5", + "@octokit/types": "^6.0.3", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/endpoint": { + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", + "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", + "dependencies": { + "@octokit/types": "^6.0.3", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/graphql": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", + "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", + "dependencies": { + "@octokit/request": "^5.6.0", + "@octokit/types": "^6.0.3", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz", + "integrity": "sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz", + "integrity": "sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==", + "dependencies": { + "@octokit/types": "^6.34.0" + }, + "peerDependencies": { + "@octokit/core": ">=2" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz", + "integrity": "sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA==", + "dependencies": { + "@octokit/types": "^6.34.0", + "deprecation": "^2.3.1" + }, + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/request": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz", + "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", + "dependencies": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/request-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", + "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", + "dependencies": { + "@octokit/types": "^6.0.3", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "node_modules/@octokit/rest": { + "version": "18.12.0", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz", + "integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==", + "dependencies": { + "@octokit/core": "^3.5.1", + "@octokit/plugin-paginate-rest": "^2.16.8", + "@octokit/plugin-request-log": "^1.0.4", + "@octokit/plugin-rest-endpoint-methods": "^5.12.0" + } + }, + "node_modules/@octokit/types": { + "version": "6.34.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz", + "integrity": "sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==", + "dependencies": { + "@octokit/openapi-types": "^11.2.0" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, + "node_modules/before-after-hook": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", + "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==" + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", + "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/kibana-buildkite-library": { + "version": "1.0.0", + "resolved": "git+https://git@github.com/elastic/kibana-buildkite-library.git#0f95579ace8100de9f1ad4cc16976b9ec6d5841e", + "integrity": "sha512-Ayiyy3rAE/jOWcR65vxiv4zacMlpxuRZ+WKvly6magfClWTWIUTcW1aiOH2/PYWP3faiCbIDHOyxLeGGajk5dQ==", + "license": "MIT", + "dependencies": { + "@octokit/rest": "^18.10.0", + "axios": "^0.21.4", + "globby": "^11.1.0", + "js-yaml": "^4.1.0" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "node_modules/universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + } + }, + "dependencies": { + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@octokit/auth-token": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", + "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", + "requires": { + "@octokit/types": "^6.0.3" + } + }, + "@octokit/core": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz", + "integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==", + "requires": { + "@octokit/auth-token": "^2.4.4", + "@octokit/graphql": "^4.5.8", + "@octokit/request": "^5.6.3", + "@octokit/request-error": "^2.0.5", + "@octokit/types": "^6.0.3", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/endpoint": { + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", + "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", + "requires": { + "@octokit/types": "^6.0.3", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/graphql": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", + "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", + "requires": { + "@octokit/request": "^5.6.0", + "@octokit/types": "^6.0.3", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/openapi-types": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz", + "integrity": "sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==" + }, + "@octokit/plugin-paginate-rest": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz", + "integrity": "sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==", + "requires": { + "@octokit/types": "^6.34.0" + } + }, + "@octokit/plugin-request-log": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", + "requires": {} + }, + "@octokit/plugin-rest-endpoint-methods": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz", + "integrity": "sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA==", + "requires": { + "@octokit/types": "^6.34.0", + "deprecation": "^2.3.1" + } + }, + "@octokit/request": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz", + "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", + "requires": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/request-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", + "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", + "requires": { + "@octokit/types": "^6.0.3", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/rest": { + "version": "18.12.0", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz", + "integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==", + "requires": { + "@octokit/core": "^3.5.1", + "@octokit/plugin-paginate-rest": "^2.16.8", + "@octokit/plugin-request-log": "^1.0.4", + "@octokit/plugin-rest-endpoint-methods": "^5.12.0" + } + }, + "@octokit/types": { + "version": "6.34.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz", + "integrity": "sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==", + "requires": { + "@octokit/openapi-types": "^11.2.0" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" + }, + "axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "requires": { + "follow-redirects": "^1.14.0" + } + }, + "before-after-hook": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", + "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==" + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "requires": { + "path-type": "^4.0.0" + } + }, + "fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "requires": { + "reusify": "^1.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "follow-redirects": { + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", + "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "requires": { + "argparse": "^2.0.1" + } + }, + "kibana-buildkite-library": { + "version": "git+https://git@github.com/elastic/kibana-buildkite-library.git#0f95579ace8100de9f1ad4cc16976b9ec6d5841e", + "integrity": "sha512-Ayiyy3rAE/jOWcR65vxiv4zacMlpxuRZ+WKvly6magfClWTWIUTcW1aiOH2/PYWP3faiCbIDHOyxLeGGajk5dQ==", + "from": "kibana-buildkite-library@git+https://git@github.com/elastic/kibana-buildkite-library#0f95579ace8100de9f1ad4cc16976b9ec6d5841e", + "requires": { + "@octokit/rest": "^18.10.0", + "axios": "^0.21.4", + "globby": "^11.1.0", + "js-yaml": "^4.1.0" + } + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + } + } +} diff --git a/.buildkite/package.json b/.buildkite/package.json index 385c9f2429f79..551def1fa1800 100644 --- a/.buildkite/package.json +++ b/.buildkite/package.json @@ -3,6 +3,6 @@ "version": "1.0.0", "private": true, "dependencies": { - "kibana-buildkite-library": "elastic/kibana-buildkite-library" + "kibana-buildkite-library": "git+https://git@github.com/elastic/kibana-buildkite-library#0f95579ace8100de9f1ad4cc16976b9ec6d5841e" } } diff --git a/.buildkite/pipelines/es_snapshots/verify.yml b/.buildkite/pipelines/es_snapshots/verify.yml index 23ec38085c3d9..729d0d1b37b5f 100755 --- a/.buildkite/pipelines/es_snapshots/verify.yml +++ b/.buildkite/pipelines/es_snapshots/verify.yml @@ -42,7 +42,7 @@ steps: - command: .buildkite/scripts/steps/functional/oss_cigroup.sh label: 'OSS CI Group' - parallelism: 11 + parallelism: 12 agents: queue: ci-group-4d depends_on: build @@ -53,13 +53,12 @@ steps: - exit_status: '*' limit: 1 - - command: .buildkite/scripts/steps/test/jest_integration.sh - label: 'Jest Integration Tests' - parallelism: 3 + - command: .buildkite/scripts/steps/test/pick_jest_config_run_order.sh + label: 'Pick Jest Config Run Order' agents: - queue: n2-4 - timeout_in_minutes: 120 - key: jest-integration + queue: kibana-default + env: + FILTER_JEST_CONFIG_TYPE: integration retry: automatic: - exit_status: '*' diff --git a/.buildkite/pipelines/on_merge.yml b/.buildkite/pipelines/on_merge.yml index 8702493d9f4cf..1c89c4e90893b 100644 --- a/.buildkite/pipelines/on_merge.yml +++ b/.buildkite/pipelines/on_merge.yml @@ -66,7 +66,7 @@ steps: - command: .buildkite/scripts/steps/functional/oss_cigroup.sh label: 'OSS CI Group' - parallelism: 11 + parallelism: 12 agents: queue: n2-4-spot depends_on: build @@ -157,29 +157,14 @@ steps: - exit_status: '*' limit: 1 - - command: .buildkite/scripts/steps/test/jest.sh - label: 'Jest Tests' - parallelism: 8 + - command: .buildkite/scripts/steps/test/pick_jest_config_run_order.sh + label: 'Pick Jest Config Run Order' agents: - queue: n2-4-spot - timeout_in_minutes: 90 - key: jest - retry: - automatic: - - exit_status: '-1' - limit: 3 - - - command: .buildkite/scripts/steps/test/jest_integration.sh - label: 'Jest Integration Tests' - parallelism: 3 - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - key: jest-integration + queue: kibana-default retry: automatic: - - exit_status: '-1' - limit: 3 + - exit_status: '*' + limit: 1 - command: .buildkite/scripts/steps/test/api_integration.sh label: 'API Integration Tests' diff --git a/.buildkite/pipelines/pull_request/base.yml b/.buildkite/pipelines/pull_request/base.yml index 658d855d86cfd..4b4104f18c627 100644 --- a/.buildkite/pipelines/pull_request/base.yml +++ b/.buildkite/pipelines/pull_request/base.yml @@ -32,7 +32,7 @@ steps: - command: .buildkite/scripts/steps/functional/oss_cigroup.sh label: 'OSS CI Group' - parallelism: 11 + parallelism: 12 agents: queue: n2-4-spot depends_on: build @@ -123,29 +123,14 @@ steps: - exit_status: '*' limit: 1 - - command: .buildkite/scripts/steps/test/jest.sh - label: 'Jest Tests' - parallelism: 8 + - command: .buildkite/scripts/steps/test/pick_jest_config_run_order.sh + label: 'Pick Jest Config Run Order' agents: - queue: n2-4-spot - timeout_in_minutes: 90 - key: jest - retry: - automatic: - - exit_status: '-1' - limit: 3 - - - command: .buildkite/scripts/steps/test/jest_integration.sh - label: 'Jest Integration Tests' - parallelism: 3 - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - key: jest-integration + queue: kibana-default retry: automatic: - - exit_status: '-1' - limit: 3 + - exit_status: '*' + limit: 1 - command: .buildkite/scripts/steps/test/api_integration.sh label: 'API Integration Tests' diff --git a/.buildkite/pipelines/pull_request/response_ops.yml b/.buildkite/pipelines/pull_request/response_ops.yml index 846477170409b..87f6a60c85c5a 100644 --- a/.buildkite/pipelines/pull_request/response_ops.yml +++ b/.buildkite/pipelines/pull_request/response_ops.yml @@ -1,6 +1,6 @@ steps: - - command: .buildkite/scripts/steps/functional/response_ops_cases.sh - label: 'Cases Cypress Tests on Security Solution' + - command: .buildkite/scripts/steps/functional/response_ops.sh + label: 'Rules, Alerts and Exceptions ResponseOps Cypress Tests on Security Solution' agents: queue: ci-group-6 depends_on: build diff --git a/.buildkite/pipelines/pull_request/response_ops_cases.yml b/.buildkite/pipelines/pull_request/response_ops_cases.yml new file mode 100644 index 0000000000000..846477170409b --- /dev/null +++ b/.buildkite/pipelines/pull_request/response_ops_cases.yml @@ -0,0 +1,11 @@ +steps: + - command: .buildkite/scripts/steps/functional/response_ops_cases.sh + label: 'Cases Cypress Tests on Security Solution' + agents: + queue: ci-group-6 + depends_on: build + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: '*' + limit: 1 diff --git a/.buildkite/scripts/common/setup_bazel.sh b/.buildkite/scripts/common/setup_bazel.sh index 96cd04fa612fd..e3791dfa393c7 100755 --- a/.buildkite/scripts/common/setup_bazel.sh +++ b/.buildkite/scripts/common/setup_bazel.sh @@ -11,8 +11,29 @@ cat < $KIBANA_DIR/.bazelrc build --build_metadata=ROLE=CI EOF -if [[ "${BAZEL_CACHE_MODE:-none}" == read* ]]; then - echo "[bazel] enabling caching" +BAZEL_CACHE_MODE=${BAZEL_CACHE_MODE:-gcs} + +if [[ "$BAZEL_CACHE_MODE" == "gcs" ]]; then + echo "[bazel] enabling caching with GCS buckets" + + BAZEL_REGION="us-central1" + if [[ "$(curl -is metadata.google.internal || true)" ]]; then + # projects/1003139005402/zones/us-central1-a -> us-central1-a -> us-central1 + BAZEL_REGION=$(curl -sH Metadata-Flavor:Google http://metadata.google.internal/computeMetadata/v1/instance/zone | rev | cut -d'/' -f1 | cut -c3- | rev) + fi + + BAZEL_BUCKET="kibana-ci-bazel_$BAZEL_REGION" + + echo "[bazel] using GCS bucket: $BAZEL_BUCKET" + +cat <> $KIBANA_DIR/.bazelrc + build --remote_cache=https://storage.googleapis.com/$BAZEL_BUCKET + build --google_default_credentials +EOF +fi + +if [[ "$BAZEL_CACHE_MODE" == "buildbuddy" ]]; then + echo "[bazel] enabling caching with Buildbuddy" cat <> $KIBANA_DIR/.bazelrc build --bes_results_url=https://app.buildbuddy.io/invocation/ build --bes_backend=grpcs://remote.buildbuddy.io @@ -22,14 +43,7 @@ cat <> $KIBANA_DIR/.bazelrc EOF fi -if [[ "${BAZEL_CACHE_MODE:-none}" == "read" ]]; then - echo "[bazel] cache set to read-only" -cat <> $KIBANA_DIR/.bazelrc - build --noremote_upload_local_results -EOF -fi - -if [[ "${BAZEL_CACHE_MODE:-none}" != @(read|read-write|none|) ]]; then - echo "invalid value for BAZEL_CACHE_MODE received ($BAZEL_CACHE_MODE), expected one of [read,read-write,none]" +if [[ "$BAZEL_CACHE_MODE" != @(gcs|buildbuddy|none|) ]]; then + echo "invalid value for BAZEL_CACHE_MODE received ($BAZEL_CACHE_MODE), expected one of [gcs,buildbuddy,none]" exit 1 fi diff --git a/.buildkite/scripts/lifecycle/pre_command.sh b/.buildkite/scripts/lifecycle/pre_command.sh index e7a176a5c2666..8f3776db3ca6b 100755 --- a/.buildkite/scripts/lifecycle/pre_command.sh +++ b/.buildkite/scripts/lifecycle/pre_command.sh @@ -9,21 +9,7 @@ export BUILDKITE_TOKEN echo '--- Install buildkite dependencies' cd '.buildkite' - -# If this yarn install is terminated early, e.g. if the build is cancelled in buildkite, -# A node module could end up in a bad state that can cause all future builds to fail -# So, let's cache clean and try again to make sure that's not what caused the error -install_deps() { - yarn install --production --pure-lockfile - EXIT=$? - if [[ "$EXIT" != "0" ]]; then - yarn cache clean - fi - return $EXIT -} - -retry 5 15 install_deps - +retry 5 15 npm ci cd .. echo '--- Agent Debug/SSH Info' diff --git a/.buildkite/scripts/pipelines/pull_request/pipeline.js b/.buildkite/scripts/pipelines/pull_request/pipeline.js index fa167d9f324b4..35ea19c78cd93 100644 --- a/.buildkite/scripts/pipelines/pull_request/pipeline.js +++ b/.buildkite/scripts/pipelines/pull_request/pipeline.js @@ -20,6 +20,7 @@ const SKIPPABLE_PATHS = [ /^\.github\//, /\.md$/, /^\.backportrc\.json$/, + /^nav-kibana-dev\.docnav\.json$/, ]; const REQUIRED_PATHS = [ @@ -64,12 +65,12 @@ const uploadPipeline = (pipelineContent) => { if ( (await doAnyChangesMatch([ - /^x-pack\/plugins\/security_solution/, /^x-pack\/plugins\/lists/, + /^x-pack\/plugins\/security_solution/, /^x-pack\/plugins\/timelines/, - /^x-pack\/test\/security_solution_cypress/, /^x-pack\/plugins\/triggers_actions_ui\/public\/application\/sections\/action_connector_form/, /^x-pack\/plugins\/triggers_actions_ui\/public\/application\/context\/actions_connectors_context\.tsx/, + /^x-pack\/test\/security_solution_cypress/, ])) || process.env.GITHUB_PR_LABELS.includes('ci:all-cypress-suites') ) { @@ -77,12 +78,26 @@ const uploadPipeline = (pipelineContent) => { } if ( - (await doAnyChangesMatch([/^x-pack\/plugins\/cases/])) || + (await doAnyChangesMatch([ + /^src\/plugins\/data/, + /^x-pack\/plugins\/actions/, + /^x-pack\/plugins\/alerting/, + /^x-pack\/plugins\/event_log/, + /^x-pack\/plugins\/rule_registry/, + /^x-pack\/plugins\/task_manager/, + ])) || process.env.GITHUB_PR_LABELS.includes('ci:all-cypress-suites') ) { pipeline.push(getPipeline('.buildkite/pipelines/pull_request/response_ops.yml')); } + if ( + (await doAnyChangesMatch([/^x-pack\/plugins\/cases/])) || + process.env.GITHUB_PR_LABELS.includes('ci:all-cypress-suites') + ) { + pipeline.push(getPipeline('.buildkite/pipelines/pull_request/response_ops_cases.yml')); + } + if ( (await doAnyChangesMatch([/^x-pack\/plugins\/apm/])) || process.env.GITHUB_PR_LABELS.includes('ci:all-cypress-suites') diff --git a/.buildkite/scripts/steps/bazel_cache/bootstrap_mac.sh b/.buildkite/scripts/steps/bazel_cache/bootstrap_mac.sh index 1417137f0b6f0..62aabf496fd8a 100755 --- a/.buildkite/scripts/steps/bazel_cache/bootstrap_mac.sh +++ b/.buildkite/scripts/steps/bazel_cache/bootstrap_mac.sh @@ -2,7 +2,7 @@ set -euo pipefail -export BAZEL_CACHE_MODE=read-write +export BAZEL_CACHE_MODE=buildbuddy export DISABLE_BOOTSTRAP_VALIDATION=true # Since our Mac agents are currently static, diff --git a/.buildkite/scripts/steps/checks.sh b/.buildkite/scripts/steps/checks.sh index cae019150b626..42de0f2cf2393 100755 --- a/.buildkite/scripts/steps/checks.sh +++ b/.buildkite/scripts/steps/checks.sh @@ -8,6 +8,7 @@ export DISABLE_BOOTSTRAP_VALIDATION=false .buildkite/scripts/steps/checks/commit/commit.sh .buildkite/scripts/steps/checks/bazel_packages.sh .buildkite/scripts/steps/checks/telemetry.sh +.buildkite/scripts/steps/checks/validate_ci_groups.sh .buildkite/scripts/steps/checks/ts_projects.sh .buildkite/scripts/steps/checks/jest_configs.sh .buildkite/scripts/steps/checks/doc_api_changes.sh diff --git a/.buildkite/scripts/steps/checks/validate_ci_groups.sh b/.buildkite/scripts/steps/checks/validate_ci_groups.sh new file mode 100755 index 0000000000000..1216ff0a55e10 --- /dev/null +++ b/.buildkite/scripts/steps/checks/validate_ci_groups.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -euo pipefail + +source .buildkite/scripts/common/util.sh + +echo --- Ensure that all tests are in a CI Group +checks-reporter-with-killswitch "Ensure that all tests are in a CI Group" \ + node scripts/ensure_all_tests_in_ci_group diff --git a/.buildkite/scripts/steps/functional/response_ops.sh b/.buildkite/scripts/steps/functional/response_ops.sh new file mode 100755 index 0000000000000..d8484854ed29e --- /dev/null +++ b/.buildkite/scripts/steps/functional/response_ops.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +set -euo pipefail + +source .buildkite/scripts/steps/functional/common.sh + +export JOB=kibana-security-solution-chrome + +echo "--- Response Ops Cypress Tests on Security Solution" + +cd "$XPACK_DIR" + +checks-reporter-with-killswitch "Response Ops Cypress Tests on Security Solution" \ + node scripts/functional_tests \ + --debug --bail \ + --kibana-install-dir "$KIBANA_BUILD_LOCATION" \ + --config test/security_solution_cypress/response_ops_cli_config.ts diff --git a/.buildkite/scripts/steps/functional/synthetics.sh b/.buildkite/scripts/steps/functional/synthetics.sh index ecb2922f89c8d..b72e85c7b6a4c 100644 --- a/.buildkite/scripts/steps/functional/synthetics.sh +++ b/.buildkite/scripts/steps/functional/synthetics.sh @@ -14,4 +14,4 @@ echo "--- Uptime @elastic/synthetics Tests" cd "$XPACK_DIR" checks-reporter-with-killswitch "Uptime @elastic/synthetics Tests" \ - node plugins/uptime/scripts/e2e.js --kibana-install-dir "$KIBANA_BUILD_LOCATION" --grep "MonitorManagement-monitor*" \ No newline at end of file + node plugins/synthetics/scripts/e2e.js --kibana-install-dir "$KIBANA_BUILD_LOCATION" --grep "MonitorManagement-monitor*" diff --git a/.buildkite/scripts/steps/on_merge_ts_refs_api_docs.sh b/.buildkite/scripts/steps/on_merge_ts_refs_api_docs.sh index 6d08fbb2c6835..5659db50e1404 100755 --- a/.buildkite/scripts/steps/on_merge_ts_refs_api_docs.sh +++ b/.buildkite/scripts/steps/on_merge_ts_refs_api_docs.sh @@ -2,7 +2,7 @@ set -euo pipefail -export BAZEL_CACHE_MODE=read-write # Populate bazel remote cache for linux +export BAZEL_CACHE_MODE=buildbuddy # Populate Buildbuddy bazel remote cache for linux export BUILD_TS_REFS_CACHE_ENABLE=true export BUILD_TS_REFS_CACHE_CAPTURE=true export DISABLE_BOOTSTRAP_VALIDATION=true diff --git a/.buildkite/scripts/steps/storybooks/build_and_upload.js b/.buildkite/scripts/steps/storybooks/build_and_upload.js index 482640b8d9cc0..becb8f1bd871f 100644 --- a/.buildkite/scripts/steps/storybooks/build_and_upload.js +++ b/.buildkite/scripts/steps/storybooks/build_and_upload.js @@ -20,7 +20,7 @@ const STORYBOOKS = [ 'custom_integrations', 'dashboard_enhanced', 'dashboard', - 'data_enhanced', + 'data', 'embeddable', 'expression_error', 'expression_image', diff --git a/.buildkite/scripts/steps/test/jest_env.sh b/.buildkite/scripts/steps/test/jest_env.sh new file mode 100644 index 0000000000000..80e88bebba184 --- /dev/null +++ b/.buildkite/scripts/steps/test/jest_env.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +set -euo pipefail + +# keys used to associate test group data in ci-stats with Jest execution order +export TEST_GROUP_TYPE_UNIT="Jest Unit Tests" +export TEST_GROUP_TYPE_INTEGRATION="Jest Integration Tests" diff --git a/.buildkite/scripts/steps/test/jest_parallel.sh b/.buildkite/scripts/steps/test/jest_parallel.sh index 0530fe0f84161..86c685d82c7e7 100755 --- a/.buildkite/scripts/steps/test/jest_parallel.sh +++ b/.buildkite/scripts/steps/test/jest_parallel.sh @@ -2,29 +2,38 @@ set -uo pipefail -JOB=$BUILDKITE_PARALLEL_JOB -JOB_COUNT=$BUILDKITE_PARALLEL_JOB_COUNT +source .buildkite/scripts/steps/test/jest_env.sh -# a jest failure will result in the script returning an exit code of 10 +export JOB=$BUILDKITE_PARALLEL_JOB -i=0 +# a jest failure will result in the script returning an exit code of 10 exitCode=0 +if [[ "$1" == 'jest.config.js' ]]; then + # run unit tests in parallel + parallelism="-w2" + TEST_TYPE="unit" +else + # run integration tests in-band + parallelism="--runInBand" + TEST_TYPE="integration" +fi + +export TEST_TYPE +echo "--- downloading integration test run order" +buildkite-agent artifact download jest_run_order.json . +configs=$(jq -r 'getpath([env.TEST_TYPE]) | .groups[env.JOB | tonumber].names | .[]' jest_run_order.json) + while read -r config; do - if [ "$((i % JOB_COUNT))" -eq "$JOB" ]; then - echo "--- $ node scripts/jest --config $config" - node --max-old-space-size=14336 ./scripts/jest --config="$config" --runInBand --coverage=false --passWithNoTests - lastCode=$? - - if [ $lastCode -ne 0 ]; then - exitCode=10 - echo "Jest exited with code $lastCode" - echo "^^^ +++" - fi + echo "--- $ node scripts/jest --config $config" + NODE_OPTIONS="--max-old-space-size=14336" node ./scripts/jest --config="$config" "$parallelism" --coverage=false --passWithNoTests + lastCode=$? + + if [ $lastCode -ne 0 ]; then + exitCode=10 + echo "Jest exited with code $lastCode" + echo "^^^ +++" fi - - ((i=i+1)) -# uses heredoc to avoid the while loop being in a sub-shell thus unable to overwrite exitCode -done <<< "$(find src x-pack packages -name "$1" -not -path "*/__fixtures__/*" | sort)" +done <<< "$configs" exit $exitCode diff --git a/.buildkite/scripts/steps/test/pick_jest_config_run_order.js b/.buildkite/scripts/steps/test/pick_jest_config_run_order.js new file mode 100644 index 0000000000000..a5fa499419ab5 --- /dev/null +++ b/.buildkite/scripts/steps/test/pick_jest_config_run_order.js @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +const { CiStats } = require('kibana-buildkite-library'); + +(async () => { + try { + await CiStats.pickTestGroupRunOrder(); + } catch (ex) { + console.error('CI Stats Error', ex.message); + if (ex.response) { + console.error('HTTP Error Response Status', ex.response.status); + console.error('HTTP Error Response Body', ex.response.data); + } + process.exit(1); + } +})(); diff --git a/.buildkite/scripts/steps/test/pick_jest_config_run_order.sh b/.buildkite/scripts/steps/test/pick_jest_config_run_order.sh new file mode 100644 index 0000000000000..37d4e629c90b0 --- /dev/null +++ b/.buildkite/scripts/steps/test/pick_jest_config_run_order.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -euo pipefail + +source .buildkite/scripts/common/util.sh +source .buildkite/scripts/steps/test/jest_env.sh + +echo '--- Pick Jest Config Run Order' +node "$(dirname "${0}")/pick_jest_config_run_order.js" diff --git a/.buildkite/yarn.lock b/.buildkite/yarn.lock deleted file mode 100644 index c2d6928d30c5a..0000000000000 --- a/.buildkite/yarn.lock +++ /dev/null @@ -1,180 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@octokit/auth-token@^2.4.4": - "integrity" "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==" - "resolved" "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz" - "version" "2.5.0" - dependencies: - "@octokit/types" "^6.0.3" - -"@octokit/core@^3.5.1", "@octokit/core@>=2", "@octokit/core@>=3": - "integrity" "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==" - "resolved" "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz" - "version" "3.5.1" - dependencies: - "@octokit/auth-token" "^2.4.4" - "@octokit/graphql" "^4.5.8" - "@octokit/request" "^5.6.0" - "@octokit/request-error" "^2.0.5" - "@octokit/types" "^6.0.3" - "before-after-hook" "^2.2.0" - "universal-user-agent" "^6.0.0" - -"@octokit/endpoint@^6.0.1": - "integrity" "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==" - "resolved" "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz" - "version" "6.0.12" - dependencies: - "@octokit/types" "^6.0.3" - "is-plain-object" "^5.0.0" - "universal-user-agent" "^6.0.0" - -"@octokit/graphql@^4.5.8": - "integrity" "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==" - "resolved" "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz" - "version" "4.8.0" - dependencies: - "@octokit/request" "^5.6.0" - "@octokit/types" "^6.0.3" - "universal-user-agent" "^6.0.0" - -"@octokit/openapi-types@^11.2.0": - "integrity" "sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==" - "resolved" "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz" - "version" "11.2.0" - -"@octokit/plugin-paginate-rest@^2.16.8": - "integrity" "sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==" - "resolved" "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz" - "version" "2.17.0" - dependencies: - "@octokit/types" "^6.34.0" - -"@octokit/plugin-request-log@^1.0.4": - "integrity" "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==" - "resolved" "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz" - "version" "1.0.4" - -"@octokit/plugin-rest-endpoint-methods@^5.12.0": - "integrity" "sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA==" - "resolved" "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz" - "version" "5.13.0" - dependencies: - "@octokit/types" "^6.34.0" - "deprecation" "^2.3.1" - -"@octokit/request-error@^2.0.5", "@octokit/request-error@^2.1.0": - "integrity" "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==" - "resolved" "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz" - "version" "2.1.0" - dependencies: - "@octokit/types" "^6.0.3" - "deprecation" "^2.0.0" - "once" "^1.4.0" - -"@octokit/request@^5.6.0": - "integrity" "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==" - "resolved" "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz" - "version" "5.6.2" - dependencies: - "@octokit/endpoint" "^6.0.1" - "@octokit/request-error" "^2.1.0" - "@octokit/types" "^6.16.1" - "is-plain-object" "^5.0.0" - "node-fetch" "^2.6.1" - "universal-user-agent" "^6.0.0" - -"@octokit/rest@^18.10.0": - "integrity" "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==" - "resolved" "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz" - "version" "18.12.0" - dependencies: - "@octokit/core" "^3.5.1" - "@octokit/plugin-paginate-rest" "^2.16.8" - "@octokit/plugin-request-log" "^1.0.4" - "@octokit/plugin-rest-endpoint-methods" "^5.12.0" - -"@octokit/types@^6.0.3", "@octokit/types@^6.16.1", "@octokit/types@^6.34.0": - "integrity" "sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==" - "resolved" "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz" - "version" "6.34.0" - dependencies: - "@octokit/openapi-types" "^11.2.0" - -"axios@^0.21.4": - "integrity" "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==" - "resolved" "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz" - "version" "0.21.4" - dependencies: - "follow-redirects" "^1.14.0" - -"before-after-hook@^2.2.0": - "integrity" "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==" - "resolved" "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz" - "version" "2.2.2" - -"deprecation@^2.0.0", "deprecation@^2.3.1": - "integrity" "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" - "resolved" "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz" - "version" "2.3.1" - -"follow-redirects@^1.14.0": - "integrity" "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==" - "resolved" "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz" - "version" "1.14.5" - -"is-plain-object@^5.0.0": - "integrity" "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" - "resolved" "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz" - "version" "5.0.0" - -"kibana-buildkite-library@github:elastic/kibana-buildkite-library": - "resolved" "git+ssh://git@github.com/elastic/kibana-buildkite-library.git#ccf5b824c4294d1fdf3569d32218d3bdb0958121" - "version" "1.0.0" - dependencies: - "@octokit/rest" "^18.10.0" - "axios" "^0.21.4" - -"node-fetch@^2.6.1": - "integrity" "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==" - "resolved" "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz" - "version" "2.6.6" - dependencies: - "whatwg-url" "^5.0.0" - -"once@^1.4.0": - "integrity" "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=" - "resolved" "https://registry.npmjs.org/once/-/once-1.4.0.tgz" - "version" "1.4.0" - dependencies: - "wrappy" "1" - -"tr46@~0.0.3": - "integrity" "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" - "resolved" "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" - "version" "0.0.3" - -"universal-user-agent@^6.0.0": - "integrity" "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" - "resolved" "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz" - "version" "6.0.0" - -"webidl-conversions@^3.0.0": - "integrity" "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" - "resolved" "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" - "version" "3.0.1" - -"whatwg-url@^5.0.0": - "integrity" "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=" - "resolved" "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" - "version" "5.0.0" - dependencies: - "tr46" "~0.0.3" - "webidl-conversions" "^3.0.0" - -"wrappy@1": - "integrity" "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - "resolved" "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" - "version" "1.0.2" diff --git a/.ci/ci_groups.yml b/.ci/ci_groups.yml index c3786f299d4c0..508f118ce9dd7 100644 --- a/.ci/ci_groups.yml +++ b/.ci/ci_groups.yml @@ -10,6 +10,7 @@ root: - ciGroup9 - ciGroup10 - ciGroup11 + - ciGroup12 xpack: - ciGroup1 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 89cf1fdf38553..7f7c048717f02 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -79,7 +79,6 @@ /src/plugins/inspector/ @elastic/kibana-app-services /src/plugins/unified_search/ @elastic/kibana-app-services /x-pack/examples/ui_actions_enhanced_examples/ @elastic/kibana-app-services -/x-pack/plugins/data_enhanced/ @elastic/kibana-app-services /x-pack/plugins/embeddable_enhanced/ @elastic/kibana-app-services /x-pack/plugins/ui_actions_enhanced/ @elastic/kibana-app-services /x-pack/plugins/runtime_fields @elastic/kibana-app-services @@ -133,7 +132,7 @@ #CC# /x-pack/plugins/observability/ @elastic/apm-ui # Uptime -/x-pack/plugins/uptime @elastic/uptime +/x-pack/plugins/synthetics @elastic/uptime /x-pack/plugins/ux @elastic/uptime /x-pack/test/functional_with_es_ssl/apps/uptime @elastic/uptime /x-pack/test/functional/apps/uptime @elastic/uptime @@ -415,6 +414,7 @@ /x-pack/plugins/security_solution/cypress/integration/urls @elastic/security-threat-hunting-investigations /x-pack/plugins/security_solution/public/common/components/alerts_viewer @elastic/security-threat-hunting-investigations +/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_action @elastic/security-threat-hunting-investigations /x-pack/plugins/security_solution/public/common/components/event_details @elastic/security-threat-hunting-investigations /x-pack/plugins/security_solution/public/common/components/events_viewer @elastic/security-threat-hunting-investigations /x-pack/plugins/security_solution/public/common/components/markdown_editor @elastic/security-threat-hunting-investigations diff --git a/.gitignore b/.gitignore index 7c20367dfe6de..fac261b2a97ea 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,7 @@ selenium *.swo *.out package-lock.json +!/.buildkite/package-lock.json .yo-rc.json .vscode *.sublime-* diff --git a/api_docs/actions.devdocs.json b/api_docs/actions.devdocs.json index 227bba7d93599..b5fd8147b8a2e 100644 --- a/api_docs/actions.devdocs.json +++ b/api_docs/actions.devdocs.json @@ -1,12 +1,209 @@ { "id": "actions", "client": { - "classes": [], + "classes": [ + { + "parentPluginId": "actions", + "id": "def-public.Plugin", + "type": "Class", + "tags": [], + "label": "Plugin", + "description": [], + "signature": [ + { + "pluginId": "actions", + "scope": "public", + "docId": "kibActionsPluginApi", + "section": "def-public.Plugin", + "text": "Plugin" + }, + " implements ", + { + "pluginId": "core", + "scope": "public", + "docId": "kibCorePluginApi", + "section": "def-public.Plugin", + "text": "Plugin" + }, + "<", + { + "pluginId": "actions", + "scope": "public", + "docId": "kibActionsPluginApi", + "section": "def-public.ActionsPublicPluginSetup", + "text": "ActionsPublicPluginSetup" + }, + ", void, object, object>" + ], + "path": "x-pack/plugins/actions/public/plugin.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "actions", + "id": "def-public.Plugin.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "x-pack/plugins/actions/public/plugin.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "actions", + "id": "def-public.Plugin.Unnamed.$1", + "type": "Object", + "tags": [], + "label": "ctx", + "description": [], + "signature": [ + { + "pluginId": "core", + "scope": "public", + "docId": "kibCorePluginApi", + "section": "def-public.PluginInitializerContext", + "text": "PluginInitializerContext" + }, + "<", + "Config", + ">" + ], + "path": "x-pack/plugins/actions/public/plugin.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "actions", + "id": "def-public.Plugin.setup", + "type": "Function", + "tags": [], + "label": "setup", + "description": [], + "signature": [ + "() => ", + { + "pluginId": "actions", + "scope": "public", + "docId": "kibActionsPluginApi", + "section": "def-public.ActionsPublicPluginSetup", + "text": "ActionsPublicPluginSetup" + } + ], + "path": "x-pack/plugins/actions/public/plugin.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "actions", + "id": "def-public.Plugin.start", + "type": "Function", + "tags": [], + "label": "start", + "description": [], + "signature": [ + "() => void" + ], + "path": "x-pack/plugins/actions/public/plugin.ts", + "deprecated": false, + "children": [], + "returnComment": [] + } + ], + "initialIsOpen": false + } + ], "functions": [], "interfaces": [], "enums": [], "misc": [], - "objects": [] + "objects": [], + "setup": { + "parentPluginId": "actions", + "id": "def-public.ActionsPublicPluginSetup", + "type": "Interface", + "tags": [], + "label": "ActionsPublicPluginSetup", + "description": [], + "path": "x-pack/plugins/actions/public/plugin.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "actions", + "id": "def-public.ActionsPublicPluginSetup.validateEmailAddresses", + "type": "Function", + "tags": [], + "label": "validateEmailAddresses", + "description": [], + "signature": [ + "(emails: string[], options?: ", + { + "pluginId": "actions", + "scope": "common", + "docId": "kibActionsPluginApi", + "section": "def-common.ValidateEmailAddressesOptions", + "text": "ValidateEmailAddressesOptions" + }, + " | undefined) => ", + { + "pluginId": "actions", + "scope": "common", + "docId": "kibActionsPluginApi", + "section": "def-common.ValidatedEmail", + "text": "ValidatedEmail" + }, + "[]" + ], + "path": "x-pack/plugins/actions/public/plugin.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "actions", + "id": "def-public.ActionsPublicPluginSetup.validateEmailAddresses.$1", + "type": "Array", + "tags": [], + "label": "emails", + "description": [], + "signature": [ + "string[]" + ], + "path": "x-pack/plugins/actions/public/plugin.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "actions", + "id": "def-public.ActionsPublicPluginSetup.validateEmailAddresses.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + { + "pluginId": "actions", + "scope": "common", + "docId": "kibActionsPluginApi", + "section": "def-common.ValidateEmailAddressesOptions", + "text": "ValidateEmailAddressesOptions" + }, + " | undefined" + ], + "path": "x-pack/plugins/actions/public/plugin.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + } + ], + "lifecycle": "setup", + "initialIsOpen": true + } }, "server": { "classes": [], @@ -181,6 +378,16 @@ "description": [], "path": "x-pack/plugins/actions/server/types.ts", "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-server.ActionResult.isDeprecated", + "type": "boolean", + "tags": [], + "label": "isDeprecated", + "description": [], + "path": "x-pack/plugins/actions/server/types.ts", + "deprecated": false } ], "initialIsOpen": false @@ -738,7 +945,7 @@ "label": "ActionParamsType", "description": [], "signature": [ - "{ readonly source?: string | undefined; readonly summary?: string | undefined; readonly group?: string | undefined; readonly timestamp?: string | undefined; readonly eventAction?: \"resolve\" | \"trigger\" | \"acknowledge\" | undefined; readonly dedupKey?: string | undefined; readonly severity?: \"error\" | \"info\" | \"warning\" | \"critical\" | undefined; readonly component?: string | undefined; readonly class?: string | undefined; }" + "{ readonly source?: string | undefined; readonly summary?: string | undefined; readonly group?: string | undefined; readonly timestamp?: string | undefined; readonly eventAction?: \"resolve\" | \"trigger\" | \"acknowledge\" | undefined; readonly dedupKey?: string | undefined; readonly severity?: \"error\" | \"warning\" | \"info\" | \"critical\" | undefined; readonly component?: string | undefined; readonly class?: string | undefined; }" ], "path": "x-pack/plugins/actions/server/builtin_action_types/pagerduty.ts", "deprecated": false, @@ -1586,6 +1793,85 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "actions", + "id": "def-common.hasMustacheTemplate", + "type": "Function", + "tags": [], + "label": "hasMustacheTemplate", + "description": [ + "does the string contain `{{.*}}`?" + ], + "signature": [ + "(string: string) => boolean" + ], + "path": "x-pack/plugins/actions/common/mustache_template.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "actions", + "id": "def-common.hasMustacheTemplate.$1", + "type": "string", + "tags": [], + "label": "string", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/plugins/actions/common/mustache_template.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "actions", + "id": "def-common.invalidEmailsAsMessage", + "type": "Function", + "tags": [], + "label": "invalidEmailsAsMessage", + "description": [], + "signature": [ + "(validatedEmails: ", + { + "pluginId": "actions", + "scope": "common", + "docId": "kibActionsPluginApi", + "section": "def-common.ValidatedEmail", + "text": "ValidatedEmail" + }, + "[]) => string | undefined" + ], + "path": "x-pack/plugins/actions/common/validate_email_addresses.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "actions", + "id": "def-common.invalidEmailsAsMessage.$1", + "type": "Array", + "tags": [], + "label": "validatedEmails", + "description": [], + "signature": [ + { + "pluginId": "actions", + "scope": "common", + "docId": "kibActionsPluginApi", + "section": "def-common.ValidatedEmail", + "text": "ValidatedEmail" + }, + "[]" + ], + "path": "x-pack/plugins/actions/common/validate_email_addresses.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "actions", "id": "def-common.isActionTypeExecutorResult", @@ -1616,70 +1902,249 @@ ], "returnComment": [], "initialIsOpen": false - } - ], - "interfaces": [ + }, { "parentPluginId": "actions", - "id": "def-common.ActionResult", - "type": "Interface", + "id": "def-common.validateEmailAddresses", + "type": "Function", "tags": [], - "label": "ActionResult", + "label": "validateEmailAddresses", "description": [], - "path": "x-pack/plugins/actions/common/types.ts", - "deprecated": false, - "children": [ + "signature": [ + "(allowedDomains: string[] | null, addresses: string[], options: ", { - "parentPluginId": "actions", - "id": "def-common.ActionResult.id", - "type": "string", - "tags": [], - "label": "id", - "description": [], - "path": "x-pack/plugins/actions/common/types.ts", - "deprecated": false + "pluginId": "actions", + "scope": "common", + "docId": "kibActionsPluginApi", + "section": "def-common.ValidateEmailAddressesOptions", + "text": "ValidateEmailAddressesOptions" }, + ") => ", { - "parentPluginId": "actions", - "id": "def-common.ActionResult.actionTypeId", - "type": "string", - "tags": [], - "label": "actionTypeId", - "description": [], - "path": "x-pack/plugins/actions/common/types.ts", - "deprecated": false + "pluginId": "actions", + "scope": "common", + "docId": "kibActionsPluginApi", + "section": "def-common.ValidatedEmail", + "text": "ValidatedEmail" }, + "[]" + ], + "path": "x-pack/plugins/actions/common/validate_email_addresses.ts", + "deprecated": false, + "children": [ { "parentPluginId": "actions", - "id": "def-common.ActionResult.name", - "type": "string", + "id": "def-common.validateEmailAddresses.$1", + "type": "CompoundType", "tags": [], - "label": "name", + "label": "allowedDomains", "description": [], - "path": "x-pack/plugins/actions/common/types.ts", - "deprecated": false + "signature": [ + "string[] | null" + ], + "path": "x-pack/plugins/actions/common/validate_email_addresses.ts", + "deprecated": false, + "isRequired": false }, { "parentPluginId": "actions", - "id": "def-common.ActionResult.config", - "type": "Object", + "id": "def-common.validateEmailAddresses.$2", + "type": "Array", "tags": [], - "label": "config", + "label": "addresses", "description": [], "signature": [ - "{ [x: string]: any; }" + "string[]" ], - "path": "x-pack/plugins/actions/common/types.ts", - "deprecated": false + "path": "x-pack/plugins/actions/common/validate_email_addresses.ts", + "deprecated": false, + "isRequired": true }, { "parentPluginId": "actions", - "id": "def-common.ActionResult.isPreconfigured", - "type": "boolean", + "id": "def-common.validateEmailAddresses.$3", + "type": "Object", "tags": [], - "label": "isPreconfigured", + "label": "options", "description": [], - "path": "x-pack/plugins/actions/common/types.ts", + "signature": [ + { + "pluginId": "actions", + "scope": "common", + "docId": "kibActionsPluginApi", + "section": "def-common.ValidateEmailAddressesOptions", + "text": "ValidateEmailAddressesOptions" + } + ], + "path": "x-pack/plugins/actions/common/validate_email_addresses.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "actions", + "id": "def-common.validateEmailAddressesAsAlwaysValid", + "type": "Function", + "tags": [], + "label": "validateEmailAddressesAsAlwaysValid", + "description": [], + "signature": [ + "(addresses: string[]) => ", + { + "pluginId": "actions", + "scope": "common", + "docId": "kibActionsPluginApi", + "section": "def-common.ValidatedEmail", + "text": "ValidatedEmail" + }, + "[]" + ], + "path": "x-pack/plugins/actions/common/validate_email_addresses.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "actions", + "id": "def-common.validateEmailAddressesAsAlwaysValid.$1", + "type": "Array", + "tags": [], + "label": "addresses", + "description": [], + "signature": [ + "string[]" + ], + "path": "x-pack/plugins/actions/common/validate_email_addresses.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "actions", + "id": "def-common.withoutMustacheTemplate", + "type": "Function", + "tags": [], + "label": "withoutMustacheTemplate", + "description": [ + "filter strings that do not contain `{{.*}}`" + ], + "signature": [ + "(strings: string[]) => string[]" + ], + "path": "x-pack/plugins/actions/common/mustache_template.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "actions", + "id": "def-common.withoutMustacheTemplate.$1", + "type": "Array", + "tags": [], + "label": "strings", + "description": [], + "signature": [ + "string[]" + ], + "path": "x-pack/plugins/actions/common/mustache_template.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [ + { + "parentPluginId": "actions", + "id": "def-common.ActionResult", + "type": "Interface", + "tags": [], + "label": "ActionResult", + "description": [], + "path": "x-pack/plugins/actions/common/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "actions", + "id": "def-common.ActionResult.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "path": "x-pack/plugins/actions/common/types.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.ActionResult.actionTypeId", + "type": "string", + "tags": [], + "label": "actionTypeId", + "description": [], + "path": "x-pack/plugins/actions/common/types.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.ActionResult.name", + "type": "string", + "tags": [], + "label": "name", + "description": [], + "path": "x-pack/plugins/actions/common/types.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.ActionResult.config", + "type": "Object", + "tags": [], + "label": "config", + "description": [], + "signature": [ + "{ [x: string]: any; }" + ], + "path": "x-pack/plugins/actions/common/types.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.ActionResult.isPreconfigured", + "type": "boolean", + "tags": [], + "label": "isPreconfigured", + "description": [], + "path": "x-pack/plugins/actions/common/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "actions", + "id": "def-common.ActionsPublicConfigType", + "type": "Interface", + "tags": [], + "label": "ActionsPublicConfigType", + "description": [], + "path": "x-pack/plugins/actions/common/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "actions", + "id": "def-common.ActionsPublicConfigType.allowedEmailDomains", + "type": "Array", + "tags": [], + "label": "allowedEmailDomains", + "description": [], + "signature": [ + "string[]" + ], + "path": "x-pack/plugins/actions/common/types.ts", "deprecated": false } ], @@ -1858,6 +2323,165 @@ } ], "initialIsOpen": false + }, + { + "parentPluginId": "actions", + "id": "def-common.SNProductsConfigValue", + "type": "Interface", + "tags": [], + "label": "SNProductsConfigValue", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "actions", + "id": "def-common.SNProductsConfigValue.table", + "type": "string", + "tags": [], + "label": "table", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.SNProductsConfigValue.appScope", + "type": "string", + "tags": [], + "label": "appScope", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.SNProductsConfigValue.useImportAPI", + "type": "boolean", + "tags": [], + "label": "useImportAPI", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.SNProductsConfigValue.importSetTable", + "type": "string", + "tags": [], + "label": "importSetTable", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.SNProductsConfigValue.commentFieldKey", + "type": "string", + "tags": [], + "label": "commentFieldKey", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.SNProductsConfigValue.appId", + "type": "string", + "tags": [], + "label": "appId", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "actions", + "id": "def-common.ValidatedEmail", + "type": "Interface", + "tags": [], + "label": "ValidatedEmail", + "description": [], + "path": "x-pack/plugins/actions/common/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "actions", + "id": "def-common.ValidatedEmail.address", + "type": "string", + "tags": [], + "label": "address", + "description": [], + "path": "x-pack/plugins/actions/common/types.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.ValidatedEmail.valid", + "type": "boolean", + "tags": [], + "label": "valid", + "description": [], + "path": "x-pack/plugins/actions/common/types.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.ValidatedEmail.reason", + "type": "CompoundType", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + { + "pluginId": "actions", + "scope": "common", + "docId": "kibActionsPluginApi", + "section": "def-common.InvalidEmailReason", + "text": "InvalidEmailReason" + }, + " | undefined" + ], + "path": "x-pack/plugins/actions/common/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "actions", + "id": "def-common.ValidateEmailAddressesOptions", + "type": "Interface", + "tags": [], + "label": "ValidateEmailAddressesOptions", + "description": [ + "Options that can be used when validating email addresses" + ], + "path": "x-pack/plugins/actions/common/validate_email_addresses.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "actions", + "id": "def-common.ValidateEmailAddressesOptions.treatMustacheTemplatesAsValid", + "type": "CompoundType", + "tags": [], + "label": "treatMustacheTemplatesAsValid", + "description": [ + "treat any address which contains a mustache template as valid" + ], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/actions/common/validate_email_addresses.ts", + "deprecated": false + } + ], + "initialIsOpen": false } ], "enums": [ @@ -1871,6 +2495,17 @@ "path": "x-pack/plugins/actions/common/index.ts", "deprecated": false, "initialIsOpen": false + }, + { + "parentPluginId": "actions", + "id": "def-common.InvalidEmailReason", + "type": "Enum", + "tags": [], + "label": "InvalidEmailReason", + "description": [], + "path": "x-pack/plugins/actions/common/types.ts", + "deprecated": false, + "initialIsOpen": false } ], "misc": [ @@ -1969,6 +2604,34 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "actions", + "id": "def-common.DEFAULT_ALERTS_GROUPING_KEY", + "type": "string", + "tags": [], + "label": "DEFAULT_ALERTS_GROUPING_KEY", + "description": [], + "signature": [ + "\"{{rule.id}}:{{alert.id}}\"" + ], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "actions", + "id": "def-common.FIELD_PREFIX", + "type": "string", + "tags": [], + "label": "FIELD_PREFIX", + "description": [], + "signature": [ + "\"u_\"" + ], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "actions", "id": "def-common.INTERNAL_BASE_ACTION_API_PATH", @@ -2066,8 +2729,343 @@ } ], "initialIsOpen": false + }, + { + "parentPluginId": "actions", + "id": "def-common.ServiceNowITOMActionTypeId", + "type": "string", + "tags": [], + "label": "ServiceNowITOMActionTypeId", + "description": [], + "signature": [ + "\".servicenow-itom\"" + ], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "actions", + "id": "def-common.ServiceNowITSMActionTypeId", + "type": "string", + "tags": [], + "label": "ServiceNowITSMActionTypeId", + "description": [], + "signature": [ + "\".servicenow\"" + ], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "actions", + "id": "def-common.serviceNowITSMTable", + "type": "string", + "tags": [], + "label": "serviceNowITSMTable", + "description": [], + "signature": [ + "\"incident\"" + ], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "actions", + "id": "def-common.ServiceNowSIRActionTypeId", + "type": "string", + "tags": [], + "label": "ServiceNowSIRActionTypeId", + "description": [], + "signature": [ + "\".servicenow-sir\"" + ], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "actions", + "id": "def-common.serviceNowSIRTable", + "type": "string", + "tags": [], + "label": "serviceNowSIRTable", + "description": [], + "signature": [ + "\"sn_si_incident\"" + ], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "actions", + "id": "def-common.SNProductsConfig", + "type": "Type", + "tags": [], + "label": "SNProductsConfig", + "description": [], + "signature": [ + "{ [x: string]: ", + { + "pluginId": "actions", + "scope": "common", + "docId": "kibActionsPluginApi", + "section": "def-common.SNProductsConfigValue", + "text": "SNProductsConfigValue" + }, + "; }" + ], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false, + "initialIsOpen": false } ], - "objects": [] + "objects": [ + { + "parentPluginId": "actions", + "id": "def-common.MustacheInEmailRegExp", + "type": "Object", + "tags": [], + "label": "MustacheInEmailRegExp", + "description": [], + "signature": [ + "RegExp" + ], + "path": "x-pack/plugins/actions/common/mustache_template.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "actions", + "id": "def-common.snExternalServiceConfig", + "type": "Object", + "tags": [], + "label": "snExternalServiceConfig", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "actions", + "id": "def-common.snExternalServiceConfig..servicenow", + "type": "Object", + "tags": [], + "label": "'.servicenow'", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "actions", + "id": "def-common.snExternalServiceConfig..servicenow.importSetTable", + "type": "string", + "tags": [], + "label": "importSetTable", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.snExternalServiceConfig..servicenow.appScope", + "type": "string", + "tags": [], + "label": "appScope", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.snExternalServiceConfig..servicenow.table", + "type": "string", + "tags": [], + "label": "table", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.snExternalServiceConfig..servicenow.useImportAPI", + "type": "boolean", + "tags": [], + "label": "useImportAPI", + "description": [], + "signature": [ + "true" + ], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.snExternalServiceConfig..servicenow.commentFieldKey", + "type": "string", + "tags": [], + "label": "commentFieldKey", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.snExternalServiceConfig..servicenow.appId", + "type": "string", + "tags": [], + "label": "appId", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "actions", + "id": "def-common.snExternalServiceConfig..servicenowsir", + "type": "Object", + "tags": [], + "label": "'.servicenow-sir'", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "actions", + "id": "def-common.snExternalServiceConfig..servicenowsir.importSetTable", + "type": "string", + "tags": [], + "label": "importSetTable", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.snExternalServiceConfig..servicenowsir.appScope", + "type": "string", + "tags": [], + "label": "appScope", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.snExternalServiceConfig..servicenowsir.table", + "type": "string", + "tags": [], + "label": "table", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.snExternalServiceConfig..servicenowsir.useImportAPI", + "type": "boolean", + "tags": [], + "label": "useImportAPI", + "description": [], + "signature": [ + "true" + ], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.snExternalServiceConfig..servicenowsir.commentFieldKey", + "type": "string", + "tags": [], + "label": "commentFieldKey", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.snExternalServiceConfig..servicenowsir.appId", + "type": "string", + "tags": [], + "label": "appId", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "actions", + "id": "def-common.snExternalServiceConfig..servicenowitom", + "type": "Object", + "tags": [], + "label": "'.servicenow-itom'", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "actions", + "id": "def-common.snExternalServiceConfig..servicenowitom.importSetTable", + "type": "string", + "tags": [], + "label": "importSetTable", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.snExternalServiceConfig..servicenowitom.appScope", + "type": "string", + "tags": [], + "label": "appScope", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.snExternalServiceConfig..servicenowitom.table", + "type": "string", + "tags": [], + "label": "table", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.snExternalServiceConfig..servicenowitom.useImportAPI", + "type": "boolean", + "tags": [], + "label": "useImportAPI", + "description": [], + "signature": [ + "false" + ], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + }, + { + "parentPluginId": "actions", + "id": "def-common.snExternalServiceConfig..servicenowitom.commentFieldKey", + "type": "string", + "tags": [], + "label": "commentFieldKey", + "description": [], + "path": "x-pack/plugins/actions/common/servicenow_config.ts", + "deprecated": false + } + ] + } + ], + "initialIsOpen": false + } + ] } } \ No newline at end of file diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index 72bb9168e149d..267f24e44374c 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github summary: API docs for the actions plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,15 @@ Contact [Response Ops](https://github.com/orgs/elastic/teams/response-ops) for q | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 127 | 0 | 127 | 10 | +| 195 | 0 | 191 | 11 | + +## Client + +### Setup + + +### Classes + ## Server @@ -39,6 +47,9 @@ Contact [Response Ops](https://github.com/orgs/elastic/teams/response-ops) for q ## Common +### Objects + + ### Functions diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx index ae965957eacb7..4403e9604c11a 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github summary: API docs for the advancedSettings plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/alerting.devdocs.json b/api_docs/alerting.devdocs.json index dcaed350c4882..a7c437fda9dbf 100644 --- a/api_docs/alerting.devdocs.json +++ b/api_docs/alerting.devdocs.json @@ -2456,20 +2456,6 @@ ], "path": "x-pack/plugins/alerting/server/types.ts", "deprecated": false - }, - { - "parentPluginId": "alerting", - "id": "def-server.RuleType.config", - "type": "Object", - "tags": [], - "label": "config", - "description": [], - "signature": [ - "RuleTypeConfig", - " | undefined" - ], - "path": "x-pack/plugins/alerting/server/types.ts", - "deprecated": false } ], "initialIsOpen": false @@ -3889,10 +3875,10 @@ }, { "parentPluginId": "alerting", - "id": "def-common.IExecutionLog.num_scheduled_actions", + "id": "def-common.IExecutionLog.num_generated_actions", "type": "number", "tags": [], - "label": "num_scheduled_actions", + "label": "num_generated_actions", "description": [], "path": "x-pack/plugins/alerting/common/execution_log_types.ts", "deprecated": false @@ -4547,72 +4533,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "alerting", - "id": "def-common.RuleExecutionRunResult", - "type": "Interface", - "tags": [], - "label": "RuleExecutionRunResult", - "description": [], - "path": "x-pack/plugins/alerting/common/rule_task_instance.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "alerting", - "id": "def-common.RuleExecutionRunResult.state", - "type": "CompoundType", - "tags": [], - "label": "state", - "description": [], - "signature": [ - "{ alertTypeState?: { [x: string]: unknown; } | undefined; alertInstances?: { [x: string]: { state?: { [x: string]: unknown; } | undefined; meta?: { lastScheduledActions?: ({ subgroup?: string | undefined; } & { group: string; date: Date; }) | undefined; } | undefined; }; } | undefined; previousStartedAt?: Date | null | undefined; } & { metrics: { numSearches?: number | undefined; totalSearchDurationMs?: number | undefined; esSearchDurationMs?: number | undefined; }; alertExecutionStore: { numberOfTriggeredActions?: number | undefined; numberOfScheduledActions?: number | undefined; triggeredActionsStatus?: string | undefined; }; }" - ], - "path": "x-pack/plugins/alerting/common/rule_task_instance.ts", - "deprecated": false - }, - { - "parentPluginId": "alerting", - "id": "def-common.RuleExecutionRunResult.monitoring", - "type": "Object", - "tags": [], - "label": "monitoring", - "description": [], - "signature": [ - { - "pluginId": "alerting", - "scope": "common", - "docId": "kibAlertingPluginApi", - "section": "def-common.RuleMonitoring", - "text": "RuleMonitoring" - }, - " | undefined" - ], - "path": "x-pack/plugins/alerting/common/rule_task_instance.ts", - "deprecated": false - }, - { - "parentPluginId": "alerting", - "id": "def-common.RuleExecutionRunResult.schedule", - "type": "Object", - "tags": [], - "label": "schedule", - "description": [], - "signature": [ - { - "pluginId": "alerting", - "scope": "common", - "docId": "kibAlertingPluginApi", - "section": "def-common.IntervalSchedule", - "text": "IntervalSchedule" - }, - " | undefined" - ], - "path": "x-pack/plugins/alerting/common/rule_task_instance.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "alerting", "id": "def-common.RuleExecutionStatus", @@ -4631,46 +4551,7 @@ "label": "status", "description": [], "signature": [ - "\"error\" | \"unknown\" | \"warning\" | \"pending\" | \"ok\" | \"active\"" - ], - "path": "x-pack/plugins/alerting/common/rule.ts", - "deprecated": false - }, - { - "parentPluginId": "alerting", - "id": "def-common.RuleExecutionStatus.numberOfTriggeredActions", - "type": "number", - "tags": [], - "label": "numberOfTriggeredActions", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "x-pack/plugins/alerting/common/rule.ts", - "deprecated": false - }, - { - "parentPluginId": "alerting", - "id": "def-common.RuleExecutionStatus.numberOfScheduledActions", - "type": "number", - "tags": [], - "label": "numberOfScheduledActions", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "x-pack/plugins/alerting/common/rule.ts", - "deprecated": false - }, - { - "parentPluginId": "alerting", - "id": "def-common.RuleExecutionStatus.metrics", - "type": "Object", - "tags": [], - "label": "metrics", - "description": [], - "signature": [ - "{ numSearches?: number | undefined; totalSearchDurationMs?: number | undefined; esSearchDurationMs?: number | undefined; } | undefined" + "\"error\" | \"warning\" | \"unknown\" | \"pending\" | \"ok\" | \"active\"" ], "path": "x-pack/plugins/alerting/common/rule.ts", "deprecated": false @@ -5103,6 +4984,17 @@ } ], "enums": [ + { + "parentPluginId": "alerting", + "id": "def-common.ActionsCompletion", + "type": "Enum", + "tags": [], + "label": "ActionsCompletion", + "description": [], + "path": "x-pack/plugins/alerting/common/rule_task_instance.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "alerting", "id": "def-common.HealthStatus", @@ -5263,7 +5155,7 @@ "label": "ExecutionLogSortFields", "description": [], "signature": [ - "\"timestamp\" | \"execution_duration\" | \"total_search_duration\" | \"es_search_duration\" | \"schedule_delay\" | \"num_triggered_actions\" | \"num_scheduled_actions\"" + "\"timestamp\" | \"execution_duration\" | \"total_search_duration\" | \"es_search_duration\" | \"schedule_delay\" | \"num_triggered_actions\" | \"num_generated_actions\"" ], "path": "x-pack/plugins/alerting/common/execution_log_types.ts", "deprecated": false, @@ -5463,34 +5355,6 @@ "deprecated": false, "initialIsOpen": false }, - { - "parentPluginId": "alerting", - "id": "def-common.RuleExecutionMetrics", - "type": "Type", - "tags": [], - "label": "RuleExecutionMetrics", - "description": [], - "signature": [ - "{ numSearches?: number | undefined; totalSearchDurationMs?: number | undefined; esSearchDurationMs?: number | undefined; }" - ], - "path": "x-pack/plugins/alerting/common/rule_task_instance.ts", - "deprecated": false, - "initialIsOpen": false - }, - { - "parentPluginId": "alerting", - "id": "def-common.RuleExecutionState", - "type": "Type", - "tags": [], - "label": "RuleExecutionState", - "description": [], - "signature": [ - "{ alertTypeState?: { [x: string]: unknown; } | undefined; alertInstances?: { [x: string]: { state?: { [x: string]: unknown; } | undefined; meta?: { lastScheduledActions?: ({ subgroup?: string | undefined; } & { group: string; date: Date; }) | undefined; } | undefined; }; } | undefined; previousStartedAt?: Date | null | undefined; } & { metrics: { numSearches?: number | undefined; totalSearchDurationMs?: number | undefined; esSearchDurationMs?: number | undefined; }; alertExecutionStore: { numberOfTriggeredActions?: number | undefined; numberOfScheduledActions?: number | undefined; triggeredActionsStatus?: string | undefined; }; }" - ], - "path": "x-pack/plugins/alerting/common/rule_task_instance.ts", - "deprecated": false, - "initialIsOpen": false - }, { "parentPluginId": "alerting", "id": "def-common.RuleExecutionStatuses", @@ -5499,7 +5363,7 @@ "label": "RuleExecutionStatuses", "description": [], "signature": [ - "\"error\" | \"unknown\" | \"warning\" | \"pending\" | \"ok\" | \"active\"" + "\"error\" | \"warning\" | \"unknown\" | \"pending\" | \"ok\" | \"active\"" ], "path": "x-pack/plugins/alerting/common/rule.ts", "deprecated": false, @@ -5750,7 +5614,7 @@ "label": "executionLogSortableColumns", "description": [], "signature": [ - "readonly [\"timestamp\", \"execution_duration\", \"total_search_duration\", \"es_search_duration\", \"schedule_delay\", \"num_triggered_actions\", \"num_scheduled_actions\"]" + "readonly [\"timestamp\", \"execution_duration\", \"total_search_duration\", \"es_search_duration\", \"schedule_delay\", \"num_triggered_actions\", \"num_generated_actions\"]" ], "path": "x-pack/plugins/alerting/common/execution_log_types.ts", "deprecated": false, diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index 8ed04bc845f1a..cc9c60a87987e 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github summary: API docs for the alerting plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Response Ops](https://github.com/orgs/elastic/teams/response-ops) for q | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 334 | 0 | 325 | 20 | +| 325 | 0 | 316 | 19 | ## Client diff --git a/api_docs/apm.devdocs.json b/api_docs/apm.devdocs.json index bd88217f34fc3..302f8c93bdea9 100644 --- a/api_docs/apm.devdocs.json +++ b/api_docs/apm.devdocs.json @@ -345,12 +345,43 @@ { "parentPluginId": "apm", "id": "def-server.APMRouteHandlerResources.context", - "type": "Object", + "type": "CompoundType", "tags": [], "label": "context", "description": [], "signature": [ - "ApmPluginRequestHandlerContext" + { + "pluginId": "core", + "scope": "server", + "docId": "kibCorePluginApi", + "section": "def-server.RequestHandlerContext", + "text": "RequestHandlerContext" + }, + " & { licensing: Promise<", + { + "pluginId": "licensing", + "scope": "server", + "docId": "kibLicensingPluginApi", + "section": "def-server.LicensingApiRequestHandlerContext", + "text": "LicensingApiRequestHandlerContext" + }, + ">; alerting: Promise<", + { + "pluginId": "alerting", + "scope": "server", + "docId": "kibAlertingPluginApi", + "section": "def-server.AlertingApiRequestHandlerContext", + "text": "AlertingApiRequestHandlerContext" + }, + ">; rac: Promise<", + { + "pluginId": "ruleRegistry", + "scope": "server", + "docId": "kibRuleRegistryPluginApi", + "section": "def-server.RacApiRequestHandlerContext", + "text": "RacApiRequestHandlerContext" + }, + ">; }" ], "path": "x-pack/plugins/apm/server/routes/typings.ts", "deprecated": false @@ -491,7 +522,7 @@ "section": "def-server.RequestHandlerContext", "text": "RequestHandlerContext" }, - " & { licensing: ", + " & { licensing: Promise<", { "pluginId": "licensing", "scope": "server", @@ -499,7 +530,7 @@ "section": "def-server.LicensingApiRequestHandlerContext", "text": "LicensingApiRequestHandlerContext" }, - "; }, request: ", + ">; }, request: ", { "pluginId": "core", "scope": "server", @@ -2979,7 +3010,11 @@ "Type", "; end: ", "Type", - "; }>]>; }>, ", + "; }>, ", + "TypeC", + "<{ probability: ", + "Type", + "; }>]>; }>, ", { "pluginId": "apm", "scope": "server", @@ -4010,6 +4045,8 @@ "<{ query: ", "IntersectionC", "<[", + "IntersectionC", + "<[", "TypeC", "<{ environment: ", "UnionC", @@ -4039,6 +4076,10 @@ "StringC", "; }>, ", "TypeC", + "<{ probability: ", + "Type", + "; }>]>, ", + "TypeC", "<{ serviceNames: ", "Type", "; }>]>; }>, ", @@ -4085,7 +4126,11 @@ "PartialC", "<{ serviceGroup: ", "StringC", - "; }>]>; }>, ", + "; }>, ", + "TypeC", + "<{ probability: ", + "Type", + "; }>]>; }>, ", { "pluginId": "apm", "scope": "server", @@ -5219,12 +5264,43 @@ { "parentPluginId": "apm", "id": "def-server.APMPluginSetup.createApmEventClient.$1.context", - "type": "Object", + "type": "CompoundType", "tags": [], "label": "context", "description": [], "signature": [ - "ApmPluginRequestHandlerContext" + { + "pluginId": "core", + "scope": "server", + "docId": "kibCorePluginApi", + "section": "def-server.RequestHandlerContext", + "text": "RequestHandlerContext" + }, + " & { licensing: Promise<", + { + "pluginId": "licensing", + "scope": "server", + "docId": "kibLicensingPluginApi", + "section": "def-server.LicensingApiRequestHandlerContext", + "text": "LicensingApiRequestHandlerContext" + }, + ">; alerting: Promise<", + { + "pluginId": "alerting", + "scope": "server", + "docId": "kibAlertingPluginApi", + "section": "def-server.AlertingApiRequestHandlerContext", + "text": "AlertingApiRequestHandlerContext" + }, + ">; rac: Promise<", + { + "pluginId": "ruleRegistry", + "scope": "server", + "docId": "kibRuleRegistryPluginApi", + "section": "def-server.RacApiRequestHandlerContext", + "text": "RacApiRequestHandlerContext" + }, + ">; }" ], "path": "x-pack/plugins/apm/server/types.ts", "deprecated": false diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index 2337384644551..9dd3c0c89fdf4 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github summary: API docs for the apm plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/banners.devdocs.json b/api_docs/banners.devdocs.json index eae41491a43d2..d370967767d93 100644 --- a/api_docs/banners.devdocs.json +++ b/api_docs/banners.devdocs.json @@ -38,7 +38,7 @@ "label": "placement", "description": [], "signature": [ - "\"top\" | \"disabled\"" + "\"disabled\" | \"top\"" ], "path": "x-pack/plugins/banners/common/types.ts", "deprecated": false @@ -129,7 +129,7 @@ "label": "BannerPlacement", "description": [], "signature": [ - "\"top\" | \"disabled\"" + "\"disabled\" | \"top\"" ], "path": "x-pack/plugins/banners/common/types.ts", "deprecated": false, diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index 732a3f841f0c3..e22924610e9ae 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github summary: API docs for the banners plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'banners'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/bfetch.mdx b/api_docs/bfetch.mdx index c19e0fecea759..2b2f9e84817e5 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github summary: API docs for the bfetch plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'bfetch'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/canvas.mdx b/api_docs/canvas.mdx index 623e6529ac3f4..cc1fdd45c597c 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github summary: API docs for the canvas plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'canvas'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/cases.devdocs.json b/api_docs/cases.devdocs.json index 76d0d7ae642cc..a78b058751b23 100644 --- a/api_docs/cases.devdocs.json +++ b/api_docs/cases.devdocs.json @@ -1348,7 +1348,9 @@ "type": "string", "tags": [], "label": "SECURITY_SOLUTION_OWNER", - "description": [], + "description": [ + "\nOwner" + ], "signature": [ "\"securitySolution\"" ], diff --git a/api_docs/cases.mdx b/api_docs/cases.mdx index 9ec7594d975cd..3b1c2a5e78c50 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github summary: API docs for the cases plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cases'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [ResponseOps](https://github.com/orgs/elastic/teams/response-ops) for qu | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 71 | 0 | 58 | 19 | +| 71 | 0 | 57 | 19 | ## Client diff --git a/api_docs/charts.devdocs.json b/api_docs/charts.devdocs.json index d65c1a3de92dc..584443f5b46dc 100644 --- a/api_docs/charts.devdocs.json +++ b/api_docs/charts.devdocs.json @@ -9,29 +9,68 @@ "type": "Function", "tags": [], "label": "ColorPicker", - "description": [], + "description": [ + "\nA `ColorPicker` component that is wrapped by the `withSuspense` HOC. This component can\nbe used directly by consumers and will load the `ColorPickerLazy` component lazily with\na predefined fallback and error boundary." + ], "signature": [ - "({ onChange, color: selectedColor, label, useLegacyColors, colorIsOverwritten, onKeyDown, maxDepth, layerIndex, }: ColorPickerProps) => JSX.Element" + "React.ForwardRefExoticComponent<", + "ColorPickerProps", + " & React.RefAttributes<{}>>" ], - "path": "src/plugins/charts/public/static/components/color_picker.tsx", + "path": "src/plugins/charts/public/static/components/index.ts", "deprecated": false, + "returnComment": [], "children": [ { "parentPluginId": "charts", "id": "def-public.ColorPicker.$1", - "type": "Object", + "type": "Uncategorized", "tags": [], - "label": "{\n onChange,\n color: selectedColor,\n label,\n useLegacyColors = true,\n colorIsOverwritten = true,\n onKeyDown,\n maxDepth,\n layerIndex,\n}", + "label": "props", "description": [], "signature": [ - "ColorPickerProps" + "P" ], - "path": "src/plugins/charts/public/static/components/color_picker.tsx", - "deprecated": false, - "isRequired": true + "path": "node_modules/@types/react/index.d.ts", + "deprecated": false } ], + "initialIsOpen": false + }, + { + "parentPluginId": "charts", + "id": "def-public.ColorPickerLazy", + "type": "Function", + "tags": [], + "label": "ColorPickerLazy", + "description": [ + "\nThe Lazily-loaded `ColorPicker` component. Consumers should use `React.Suspense` or\nthe withSuspense` HOC to load this component." + ], + "signature": [ + "React.ExoticComponent<", + "ColorPickerProps", + "> & { readonly _result: ({ onChange, color: selectedColor, label, useLegacyColors, colorIsOverwritten, onKeyDown, maxDepth, layerIndex, }: ", + "ColorPickerProps", + ") => JSX.Element; }" + ], + "path": "src/plugins/charts/public/static/components/index.ts", + "deprecated": false, "returnComment": [], + "children": [ + { + "parentPluginId": "charts", + "id": "def-public.ColorPickerLazy.$1", + "type": "Uncategorized", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "P" + ], + "path": "node_modules/@types/react/index.d.ts", + "deprecated": false + } + ], "initialIsOpen": false }, { @@ -108,9 +147,9 @@ "label": "EmptyPlaceholder", "description": [], "signature": [ - "({ icon, iconColor, message, dataTestSubj, className, }: { icon: ", - "IconType", - "; iconColor?: string | undefined; message?: JSX.Element | undefined; dataTestSubj?: string | undefined; className?: string | undefined; }) => JSX.Element" + "({ icon, iconColor, message, dataTestSubj, className, }: ", + "EmptyPlaceholderProps", + ") => JSX.Element" ], "path": "src/plugins/charts/public/static/components/empty_placeholder.tsx", "deprecated": false, @@ -122,75 +161,12 @@ "tags": [], "label": "{\n icon,\n iconColor = 'subdued',\n message = ,\n dataTestSubj = 'emptyPlaceholder',\n className,\n}", "description": [], + "signature": [ + "EmptyPlaceholderProps" + ], "path": "src/plugins/charts/public/static/components/empty_placeholder.tsx", "deprecated": false, - "children": [ - { - "parentPluginId": "charts", - "id": "def-public.EmptyPlaceholder.$1.icon", - "type": "CompoundType", - "tags": [], - "label": "icon", - "description": [], - "signature": [ - "string | React.ComponentType<{}>" - ], - "path": "src/plugins/charts/public/static/components/empty_placeholder.tsx", - "deprecated": false - }, - { - "parentPluginId": "charts", - "id": "def-public.EmptyPlaceholder.$1.iconColor", - "type": "string", - "tags": [], - "label": "iconColor", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/charts/public/static/components/empty_placeholder.tsx", - "deprecated": false - }, - { - "parentPluginId": "charts", - "id": "def-public.EmptyPlaceholder.$1.message", - "type": "Object", - "tags": [], - "label": "message", - "description": [], - "signature": [ - "JSX.Element | undefined" - ], - "path": "src/plugins/charts/public/static/components/empty_placeholder.tsx", - "deprecated": false - }, - { - "parentPluginId": "charts", - "id": "def-public.EmptyPlaceholder.$1.dataTestSubj", - "type": "string", - "tags": [], - "label": "dataTestSubj", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/charts/public/static/components/empty_placeholder.tsx", - "deprecated": false - }, - { - "parentPluginId": "charts", - "id": "def-public.EmptyPlaceholder.$1.className", - "type": "string", - "tags": [], - "label": "className", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/charts/public/static/components/empty_placeholder.tsx", - "deprecated": false - } - ] + "isRequired": true } ], "returnComment": [], @@ -628,11 +604,15 @@ "type": "Function", "tags": [], "label": "LegendToggle", - "description": [], + "description": [ + "\nA `LegendToggle` component that is wrapped by the `withSuspense` HOC. This component can\nbe used directly by consumers and will load the `LegendToggleLazy` component lazily with\na predefined fallback and error boundary." + ], "signature": [ - "React.NamedExoticComponent & { readonly type: ({ onClick, showLegend, legendPosition }: LegendToggleProps) => JSX.Element; }" + "React.ForwardRefExoticComponent<", + "LegendToggleProps", + " & React.RefAttributes<{}>>" ], - "path": "src/plugins/charts/public/static/components/legend_toggle.tsx", + "path": "src/plugins/charts/public/static/components/index.ts", "deprecated": false, "returnComment": [], "children": [ @@ -652,6 +632,42 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "charts", + "id": "def-public.LegendToggleLazy", + "type": "Function", + "tags": [], + "label": "LegendToggleLazy", + "description": [ + "\nThe Lazily-loaded `LegendToggle` component. Consumers should use `React.Suspense` or\nthe withSuspense` HOC to load this component." + ], + "signature": [ + "React.ExoticComponent<", + "LegendToggleProps", + "> & { readonly _result: React.MemoExoticComponent<({ onClick, showLegend, legendPosition }: ", + "LegendToggleProps", + ") => JSX.Element>; }" + ], + "path": "src/plugins/charts/public/static/components/index.ts", + "deprecated": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "charts", + "id": "def-public.LegendToggleLazy.$1", + "type": "Uncategorized", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "P" + ], + "path": "node_modules/@types/react/index.d.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "charts", "id": "def-public.lightenColor", @@ -866,6 +882,26 @@ ], "returnComment": [], "initialIsOpen": false + }, + { + "parentPluginId": "charts", + "id": "def-public.useCommonChartStyles", + "type": "Function", + "tags": [], + "label": "useCommonChartStyles", + "description": [], + "signature": [ + "() => { chartIcon: { subdued: ", + "SerializedStyles", + "; accent: ", + "SerializedStyles", + "; }; }" + ], + "path": "src/plugins/charts/public/static/components/common_chart_styles.ts", + "deprecated": false, + "children": [], + "returnComment": [], + "initialIsOpen": false } ], "interfaces": [ @@ -916,81 +952,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "charts", - "id": "def-public.ChartColorConfiguration", - "type": "Interface", - "tags": [], - "label": "ChartColorConfiguration", - "description": [ - "\nInformation about the structure of a chart to determine the color of a series within it." - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "charts", - "id": "def-public.ChartColorConfiguration.totalSeries", - "type": "number", - "tags": [], - "label": "totalSeries", - "description": [ - "\nOverall number of series in the current chart" - ], - "signature": [ - "number | undefined" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false - }, - { - "parentPluginId": "charts", - "id": "def-public.ChartColorConfiguration.maxDepth", - "type": "number", - "tags": [], - "label": "maxDepth", - "description": [ - "\nMax nesting depth of the series tree" - ], - "signature": [ - "number | undefined" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false - }, - { - "parentPluginId": "charts", - "id": "def-public.ChartColorConfiguration.behindText", - "type": "CompoundType", - "tags": [], - "label": "behindText", - "description": [ - "\nFlag whether the color will be used behind text. The palette can use this information to\nadjust colors for better a11y. Might be ignored depending on the palette." - ], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false - }, - { - "parentPluginId": "charts", - "id": "def-public.ChartColorConfiguration.syncColors", - "type": "CompoundType", - "tags": [], - "label": "syncColors", - "description": [ - "\nFlag whether a color assignment to a given key should be remembered and re-used the next time the key shows up.\nThis setting might be ignored based on the palette." - ], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "charts", "id": "def-public.ClickTriggerEvent", @@ -1162,7 +1123,7 @@ "tags": [], "label": "CustomPaletteArguments", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false, "children": [ { @@ -1175,7 +1136,7 @@ "signature": [ "string[] | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -1185,7 +1146,7 @@ "tags": [], "label": "gradient", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -1198,7 +1159,7 @@ "signature": [ "boolean | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -1211,7 +1172,7 @@ "signature": [ "number[] | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -1224,7 +1185,7 @@ "signature": [ "\"number\" | \"percent\" | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -1237,7 +1198,7 @@ "signature": [ "number | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -1250,7 +1211,7 @@ "signature": [ "number | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -1261,16 +1222,10 @@ "label": "continuity", "description": [], "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteContinuity", - "text": "PaletteContinuity" - }, + "PaletteContinuity", " | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false } ], @@ -1283,7 +1238,7 @@ "tags": [], "label": "CustomPaletteState", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false, "children": [ { @@ -1296,7 +1251,7 @@ "signature": [ "string[]" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -1306,7 +1261,7 @@ "tags": [], "label": "gradient", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -1319,7 +1274,7 @@ "signature": [ "number[]" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -1332,7 +1287,7 @@ "signature": [ "\"number\" | \"percent\"" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -1342,7 +1297,7 @@ "tags": [], "label": "rangeMin", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -1352,7 +1307,7 @@ "tags": [], "label": "rangeMax", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -1363,16 +1318,10 @@ "label": "continuity", "description": [], "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteContinuity", - "text": "PaletteContinuity" - }, + "PaletteContinuity", " | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false } ], @@ -1471,576 +1420,54 @@ }, { "parentPluginId": "charts", - "id": "def-public.PaletteDefinition", + "id": "def-public.RawColorSchema", "type": "Interface", "tags": [], - "label": "PaletteDefinition", - "description": [ - "\nDefinition of a global palette.\n\nA palette controls the appearance of Lens charts on an editor level.\nThe palette wont get reset when switching charts.\n\nA palette can hold internal state (e.g. for customizations) and also includes\nan editor component to edit the internal state." - ], - "signature": [ - { - "pluginId": "charts", - "scope": "public", - "docId": "kibChartsPluginApi", - "section": "def-public.PaletteDefinition", - "text": "PaletteDefinition" - }, - "" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", + "label": "RawColorSchema", + "description": [], + "path": "src/plugins/charts/common/static/color_maps/color_maps.ts", "deprecated": false, "children": [ { "parentPluginId": "charts", - "id": "def-public.PaletteDefinition.id", - "type": "string", + "id": "def-public.RawColorSchema.id", + "type": "Enum", "tags": [], "label": "id", - "description": [ - "\nUnique id of the palette (this will be persisted along with the visualization state)" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false - }, - { - "parentPluginId": "charts", - "id": "def-public.PaletteDefinition.title", - "type": "string", - "tags": [], - "label": "title", - "description": [ - "\nUser facing title (should be i18n-ized)" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false - }, - { - "parentPluginId": "charts", - "id": "def-public.PaletteDefinition.internal", - "type": "CompoundType", - "tags": [], - "label": "internal", - "description": [ - "\nFlag indicating whether users should be able to pick this palette manually." - ], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false - }, - { - "parentPluginId": "charts", - "id": "def-public.PaletteDefinition.toExpression", - "type": "Function", - "tags": [], - "label": "toExpression", - "description": [ - "\nSerialize the internal state of the palette into an expression function.\nThis function should be used to pass the palette to the expression function applying color and other styles" - ], + "description": [], "signature": [ - "(state?: T | undefined) => ", { - "pluginId": "expressions", + "pluginId": "charts", "scope": "common", - "docId": "kibExpressionsPluginApi", - "section": "def-common.ExpressionAstExpression", - "text": "ExpressionAstExpression" - } - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "charts", - "id": "def-public.PaletteDefinition.toExpression.$1", - "type": "Uncategorized", - "tags": [], - "label": "state", - "description": [ - "The internal state of the palette" - ], - "signature": [ - "T | undefined" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "charts", - "id": "def-public.PaletteDefinition.getCategoricalColor", - "type": "Function", - "tags": [], - "label": "getCategoricalColor", - "description": [ - "\nColor a series according to the internal rules of the palette." - ], - "signature": [ - "(series: ", - { - "pluginId": "charts", - "scope": "public", - "docId": "kibChartsPluginApi", - "section": "def-public.SeriesLayer", - "text": "SeriesLayer" - }, - "[], chartConfiguration?: ", - { - "pluginId": "charts", - "scope": "public", - "docId": "kibChartsPluginApi", - "section": "def-public.ChartColorConfiguration", - "text": "ChartColorConfiguration" - }, - " | undefined, state?: T | undefined) => string | null" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "charts", - "id": "def-public.PaletteDefinition.getCategoricalColor.$1", - "type": "Array", - "tags": [], - "label": "series", - "description": [ - "The current series along with its ancestors." - ], - "signature": [ - { - "pluginId": "charts", - "scope": "public", - "docId": "kibChartsPluginApi", - "section": "def-public.SeriesLayer", - "text": "SeriesLayer" - }, - "[]" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "charts", - "id": "def-public.PaletteDefinition.getCategoricalColor.$2", - "type": "Object", - "tags": [], - "label": "chartConfiguration", - "description": [], - "signature": [ - { - "pluginId": "charts", - "scope": "public", - "docId": "kibChartsPluginApi", - "section": "def-public.ChartColorConfiguration", - "text": "ChartColorConfiguration" - }, - " | undefined" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false, - "isRequired": false - }, - { - "parentPluginId": "charts", - "id": "def-public.PaletteDefinition.getCategoricalColor.$3", - "type": "Uncategorized", - "tags": [], - "label": "state", - "description": [ - "The internal state of the palette" - ], - "signature": [ - "T | undefined" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "charts", - "id": "def-public.PaletteDefinition.getCategoricalColors", - "type": "Function", - "tags": [], - "label": "getCategoricalColors", - "description": [ - "\nGet a spectrum of colors of the current palette.\nThis can be used if the chart wants to control color assignment locally." - ], - "signature": [ - "(size: number, state?: T | undefined) => string[]" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "charts", - "id": "def-public.PaletteDefinition.getCategoricalColors.$1", - "type": "number", - "tags": [], - "label": "size", - "description": [], - "signature": [ - "number" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "charts", - "id": "def-public.PaletteDefinition.getCategoricalColors.$2", - "type": "Uncategorized", - "tags": [], - "label": "state", - "description": [], - "signature": [ - "T | undefined" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "charts", - "id": "def-public.PaletteDefinition.canDynamicColoring", - "type": "CompoundType", - "tags": [], - "label": "canDynamicColoring", - "description": [ - "\nDefine whether a palette supports dynamic coloring (i.e. gradient colors mapped to number values)" - ], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false - }, - { - "parentPluginId": "charts", - "id": "def-public.PaletteDefinition.getColorForValue", - "type": "Function", - "tags": [], - "label": "getColorForValue", - "description": [ - "\nGet the assigned color for the given value based on its data domain and state settings.\nThis can be used for dynamic coloring based on uniform color distribution or custom stops." - ], - "signature": [ - "((value: number | undefined, state: T, { min, max }: { min: number; max: number; }) => string | undefined) | undefined" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "charts", - "id": "def-public.PaletteDefinition.getColorForValue.$1", - "type": "number", - "tags": [], - "label": "value", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false, - "isRequired": false - }, - { - "parentPluginId": "charts", - "id": "def-public.PaletteDefinition.getColorForValue.$2", - "type": "Uncategorized", - "tags": [], - "label": "state", - "description": [], - "signature": [ - "T" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "charts", - "id": "def-public.PaletteDefinition.getColorForValue.$3", - "type": "Object", - "tags": [], - "label": "{ min, max }", - "description": [], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "charts", - "id": "def-public.PaletteDefinition.getColorForValue.$3.min", - "type": "number", - "tags": [], - "label": "min", - "description": [], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false - }, - { - "parentPluginId": "charts", - "id": "def-public.PaletteDefinition.getColorForValue.$3.max", - "type": "number", - "tags": [], - "label": "max", - "description": [], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false - } - ] - } - ], - "returnComment": [] - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "charts", - "id": "def-public.PaletteOutput", - "type": "Interface", - "tags": [], - "label": "PaletteOutput", - "description": [], - "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, - "" - ], - "path": "src/plugins/charts/common/palette.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "charts", - "id": "def-public.PaletteOutput.type", - "type": "CompoundType", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "\"palette\" | \"system_palette\"" - ], - "path": "src/plugins/charts/common/palette.ts", - "deprecated": false - }, - { - "parentPluginId": "charts", - "id": "def-public.PaletteOutput.name", - "type": "string", - "tags": [], - "label": "name", - "description": [], - "path": "src/plugins/charts/common/palette.ts", - "deprecated": false - }, - { - "parentPluginId": "charts", - "id": "def-public.PaletteOutput.params", - "type": "Uncategorized", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "T | undefined" - ], - "path": "src/plugins/charts/common/palette.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "charts", - "id": "def-public.PaletteRegistry", - "type": "Interface", - "tags": [], - "label": "PaletteRegistry", - "description": [], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "charts", - "id": "def-public.PaletteRegistry.get", - "type": "Function", - "tags": [], - "label": "get", - "description": [], - "signature": [ - "(name: string) => ", - { - "pluginId": "charts", - "scope": "public", - "docId": "kibChartsPluginApi", - "section": "def-public.PaletteDefinition", - "text": "PaletteDefinition" - }, - "" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "charts", - "id": "def-public.PaletteRegistry.get.$1", - "type": "string", - "tags": [], - "label": "name", - "description": [], - "signature": [ - "string" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "charts", - "id": "def-public.PaletteRegistry.getAll", - "type": "Function", - "tags": [], - "label": "getAll", - "description": [], - "signature": [ - "() => ", - { - "pluginId": "charts", - "scope": "public", "docId": "kibChartsPluginApi", - "section": "def-public.PaletteDefinition", - "text": "PaletteDefinition" - }, - "[]" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false, - "children": [], - "returnComment": [] - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "charts", - "id": "def-public.RawColorSchema", - "type": "Interface", - "tags": [], - "label": "RawColorSchema", - "description": [], - "path": "src/plugins/charts/common/static/color_maps/color_maps.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "charts", - "id": "def-public.RawColorSchema.id", - "type": "Enum", - "tags": [], - "label": "id", - "description": [], - "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.ColorSchemas", - "text": "ColorSchemas" - } - ], - "path": "src/plugins/charts/common/static/color_maps/color_maps.ts", - "deprecated": false - }, - { - "parentPluginId": "charts", - "id": "def-public.RawColorSchema.label", - "type": "string", - "tags": [], - "label": "label", - "description": [], - "path": "src/plugins/charts/common/static/color_maps/color_maps.ts", - "deprecated": false - }, - { - "parentPluginId": "charts", - "id": "def-public.RawColorSchema.value", - "type": "Array", - "tags": [], - "label": "value", - "description": [], - "signature": [ - "[number, number[]][]" - ], - "path": "src/plugins/charts/common/static/color_maps/color_maps.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "charts", - "id": "def-public.SeriesLayer", - "type": "Interface", - "tags": [], - "label": "SeriesLayer", - "description": [ - "\nInformation about a series in a chart used to determine its color.\nSeries layers can be nested, this means each series layer can have an ancestor." - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "charts", - "id": "def-public.SeriesLayer.name", - "type": "string", - "tags": [], - "label": "name", - "description": [ - "\nName of the series (can be used for lookup-based coloring)" + "section": "def-common.ColorSchemas", + "text": "ColorSchemas" + } ], - "path": "src/plugins/charts/public/services/palettes/types.ts", + "path": "src/plugins/charts/common/static/color_maps/color_maps.ts", "deprecated": false }, { "parentPluginId": "charts", - "id": "def-public.SeriesLayer.rankAtDepth", - "type": "number", + "id": "def-public.RawColorSchema.label", + "type": "string", "tags": [], - "label": "rankAtDepth", - "description": [ - "\nRank of the series compared to siblings with the same ancestor" - ], - "path": "src/plugins/charts/public/services/palettes/types.ts", + "label": "label", + "description": [], + "path": "src/plugins/charts/common/static/color_maps/color_maps.ts", "deprecated": false }, { "parentPluginId": "charts", - "id": "def-public.SeriesLayer.totalSeriesAtDepth", - "type": "number", + "id": "def-public.RawColorSchema.value", + "type": "Array", "tags": [], - "label": "totalSeriesAtDepth", - "description": [ - "\nTotal number of series with the same ancestor" + "label": "value", + "description": [], + "signature": [ + "[number, number[]][]" ], - "path": "src/plugins/charts/public/services/palettes/types.ts", + "path": "src/plugins/charts/common/static/color_maps/color_maps.ts", "deprecated": false } ], @@ -2116,7 +1543,7 @@ "tags": [], "label": "SystemPaletteArguments", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/system_palette.ts", "deprecated": false, "children": [ { @@ -2126,7 +1553,7 @@ "tags": [], "label": "name", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/system_palette.ts", "deprecated": false } ], @@ -2858,13 +2285,7 @@ "description": [], "signature": [ "{ getPalettes: () => Promise<", - { - "pluginId": "charts", - "scope": "public", - "docId": "kibChartsPluginApi", - "section": "def-public.PaletteRegistry", - "text": "PaletteRegistry" - }, + "PaletteRegistry", ">; }" ], "path": "src/plugins/charts/public/plugin.ts", @@ -2910,7 +2331,7 @@ "tags": [], "label": "CustomPaletteArguments", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false, "children": [ { @@ -2923,7 +2344,7 @@ "signature": [ "string[] | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -2933,7 +2354,7 @@ "tags": [], "label": "gradient", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -2946,7 +2367,7 @@ "signature": [ "boolean | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -2959,7 +2380,7 @@ "signature": [ "number[] | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -2972,7 +2393,7 @@ "signature": [ "\"number\" | \"percent\" | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -2985,7 +2406,7 @@ "signature": [ "number | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -2998,7 +2419,7 @@ "signature": [ "number | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -3009,16 +2430,10 @@ "label": "continuity", "description": [], "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteContinuity", - "text": "PaletteContinuity" - }, + "PaletteContinuity", " | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false } ], @@ -3031,7 +2446,7 @@ "tags": [], "label": "CustomPaletteState", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false, "children": [ { @@ -3044,7 +2459,7 @@ "signature": [ "string[]" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -3054,7 +2469,7 @@ "tags": [], "label": "gradient", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -3067,7 +2482,7 @@ "signature": [ "number[]" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -3080,7 +2495,7 @@ "signature": [ "\"number\" | \"percent\"" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -3090,7 +2505,7 @@ "tags": [], "label": "rangeMin", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -3100,7 +2515,7 @@ "tags": [], "label": "rangeMax", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -3111,75 +2526,10 @@ "label": "continuity", "description": [], "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteContinuity", - "text": "PaletteContinuity" - }, + "PaletteContinuity", " | undefined" ], - "path": "src/plugins/charts/common/palette.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "charts", - "id": "def-server.PaletteOutput", - "type": "Interface", - "tags": [], - "label": "PaletteOutput", - "description": [], - "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, - "" - ], - "path": "src/plugins/charts/common/palette.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "charts", - "id": "def-server.PaletteOutput.type", - "type": "CompoundType", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "\"palette\" | \"system_palette\"" - ], - "path": "src/plugins/charts/common/palette.ts", - "deprecated": false - }, - { - "parentPluginId": "charts", - "id": "def-server.PaletteOutput.name", - "type": "string", - "tags": [], - "label": "name", - "description": [], - "path": "src/plugins/charts/common/palette.ts", - "deprecated": false - }, - { - "parentPluginId": "charts", - "id": "def-server.PaletteOutput.params", - "type": "Uncategorized", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "T | undefined" - ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false } ], @@ -3192,7 +2542,7 @@ "tags": [], "label": "SystemPaletteArguments", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/system_palette.ts", "deprecated": false, "children": [ { @@ -3202,7 +2552,7 @@ "tags": [], "label": "name", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/system_palette.ts", "deprecated": false } ], @@ -3231,98 +2581,6 @@ "common": { "classes": [], "functions": [ - { - "parentPluginId": "charts", - "id": "def-common.checkIsMaxContinuity", - "type": "Function", - "tags": [], - "label": "checkIsMaxContinuity", - "description": [], - "signature": [ - "(continuity: ", - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteContinuity", - "text": "PaletteContinuity" - }, - " | undefined) => boolean" - ], - "path": "src/plugins/charts/common/static/palette/index.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "charts", - "id": "def-common.checkIsMaxContinuity.$1", - "type": "CompoundType", - "tags": [], - "label": "continuity", - "description": [], - "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteContinuity", - "text": "PaletteContinuity" - }, - " | undefined" - ], - "path": "src/plugins/charts/common/static/palette/index.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "charts", - "id": "def-common.checkIsMinContinuity", - "type": "Function", - "tags": [], - "label": "checkIsMinContinuity", - "description": [], - "signature": [ - "(continuity: ", - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteContinuity", - "text": "PaletteContinuity" - }, - " | undefined) => boolean" - ], - "path": "src/plugins/charts/common/static/palette/index.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "charts", - "id": "def-common.checkIsMinContinuity.$1", - "type": "CompoundType", - "tags": [], - "label": "continuity", - "description": [], - "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteContinuity", - "text": "PaletteContinuity" - }, - " | undefined" - ], - "path": "src/plugins/charts/common/static/palette/index.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [], - "initialIsOpen": false - }, { "parentPluginId": "charts", "id": "def-common.getHeatmapColors", @@ -3377,58 +2635,9 @@ "description": [], "signature": [ "() => ", - { - "pluginId": "expressions", - "scope": "common", - "docId": "kibExpressionsPluginApi", - "section": "def-common.ExpressionFunctionDefinition", - "text": "ExpressionFunctionDefinition" - }, - "<\"palette\", null, ", - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.CustomPaletteArguments", - "text": "CustomPaletteArguments" - }, - ", ", - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, - "<", - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.CustomPaletteState", - "text": "CustomPaletteState" - }, - ">, ", - { - "pluginId": "expressions", - "scope": "common", - "docId": "kibExpressionsPluginApi", - "section": "def-common.ExecutionContext", - "text": "ExecutionContext" - }, - "<", - { - "pluginId": "inspector", - "scope": "common", - "docId": "kibInspectorPluginApi", - "section": "def-common.Adapters", - "text": "Adapters" - }, - ", ", - "SerializableRecord", - ">>" + "PaletteExpressionFunctionDefinition" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/palette.ts", "deprecated": false, "children": [], "returnComment": [], @@ -3459,13 +2668,7 @@ "text": "SystemPaletteArguments" }, ", ", - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, + "PaletteOutput", "<{ [key: string]: unknown; }>, ", { "pluginId": "expressions", @@ -3486,7 +2689,7 @@ "SerializableRecord", ">>" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/system_palette.ts", "deprecated": false, "children": [], "returnComment": [], @@ -3618,7 +2821,7 @@ "tags": [], "label": "CustomPaletteArguments", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false, "children": [ { @@ -3631,7 +2834,7 @@ "signature": [ "string[] | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -3641,7 +2844,7 @@ "tags": [], "label": "gradient", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -3654,7 +2857,7 @@ "signature": [ "boolean | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -3667,7 +2870,7 @@ "signature": [ "number[] | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -3680,7 +2883,7 @@ "signature": [ "\"number\" | \"percent\" | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -3693,7 +2896,7 @@ "signature": [ "number | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -3706,7 +2909,7 @@ "signature": [ "number | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -3717,16 +2920,10 @@ "label": "continuity", "description": [], "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteContinuity", - "text": "PaletteContinuity" - }, + "PaletteContinuity", " | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false } ], @@ -3739,7 +2936,7 @@ "tags": [], "label": "CustomPaletteState", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false, "children": [ { @@ -3752,7 +2949,7 @@ "signature": [ "string[]" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -3762,7 +2959,7 @@ "tags": [], "label": "gradient", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -3775,7 +2972,7 @@ "signature": [ "number[]" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -3788,7 +2985,7 @@ "signature": [ "\"number\" | \"percent\"" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -3798,7 +2995,7 @@ "tags": [], "label": "rangeMin", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -3808,7 +3005,7 @@ "tags": [], "label": "rangeMax", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false }, { @@ -3819,16 +3016,10 @@ "label": "continuity", "description": [], "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteContinuity", - "text": "PaletteContinuity" - }, + "PaletteContinuity", " | undefined" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/types.ts", "deprecated": false } ], @@ -3925,65 +3116,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "charts", - "id": "def-common.PaletteOutput", - "type": "Interface", - "tags": [], - "label": "PaletteOutput", - "description": [], - "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, - "" - ], - "path": "src/plugins/charts/common/palette.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "charts", - "id": "def-common.PaletteOutput.type", - "type": "CompoundType", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "\"palette\" | \"system_palette\"" - ], - "path": "src/plugins/charts/common/palette.ts", - "deprecated": false - }, - { - "parentPluginId": "charts", - "id": "def-common.PaletteOutput.name", - "type": "string", - "tags": [], - "label": "name", - "description": [], - "path": "src/plugins/charts/common/palette.ts", - "deprecated": false - }, - { - "parentPluginId": "charts", - "id": "def-common.PaletteOutput.params", - "type": "Uncategorized", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "T | undefined" - ], - "path": "src/plugins/charts/common/palette.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "charts", "id": "def-common.RawColorSchema", @@ -4109,7 +3241,7 @@ "tags": [], "label": "SystemPaletteArguments", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/system_palette.ts", "deprecated": false, "children": [ { @@ -4119,7 +3251,7 @@ "tags": [], "label": "name", "description": [], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/expressions/palette/system_palette.ts", "deprecated": false } ], @@ -4210,7 +3342,7 @@ "signature": [ "string[]" ], - "path": "src/plugins/charts/common/palette.ts", + "path": "src/plugins/charts/common/constants.ts", "deprecated": false, "initialIsOpen": false }, @@ -4242,20 +3374,6 @@ "deprecated": false, "initialIsOpen": false }, - { - "parentPluginId": "charts", - "id": "def-common.PaletteContinuity", - "type": "Type", - "tags": [], - "label": "PaletteContinuity", - "description": [], - "signature": [ - "\"above\" | \"below\" | \"none\" | \"all\"" - ], - "path": "src/plugins/charts/common/types.ts", - "deprecated": false, - "initialIsOpen": false - }, { "parentPluginId": "charts", "id": "def-common.paletteIds", diff --git a/api_docs/charts.mdx b/api_docs/charts.mdx index dc22287d352d0..0fe3642f18398 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github summary: API docs for the charts plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 322 | 2 | 289 | 4 | +| 272 | 2 | 253 | 9 | ## Client diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx index 378879307a9d0..ccf2076033b67 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github summary: API docs for the cloud plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index d9a6b1d20909c..d487aab1a4754 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github summary: API docs for the cloudSecurityPosture plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudSecurityPosture'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/console.mdx b/api_docs/console.mdx index 343ada2ae4109..4d91e53febaf7 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github summary: API docs for the console plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/controls.devdocs.json b/api_docs/controls.devdocs.json index 7cd89434ad64f..fe22caa955878 100644 --- a/api_docs/controls.devdocs.json +++ b/api_docs/controls.devdocs.json @@ -3154,31 +3154,11 @@ "text": "OptionsListEmbeddableInput" }, " extends ", - "ControlInput" + "DataControlInput" ], "path": "src/plugins/controls/common/control_types/options_list/types.ts", "deprecated": false, "children": [ - { - "parentPluginId": "controls", - "id": "def-public.OptionsListEmbeddableInput.fieldName", - "type": "string", - "tags": [], - "label": "fieldName", - "description": [], - "path": "src/plugins/controls/common/control_types/options_list/types.ts", - "deprecated": false - }, - { - "parentPluginId": "controls", - "id": "def-public.OptionsListEmbeddableInput.dataViewId", - "type": "string", - "tags": [], - "label": "dataViewId", - "description": [], - "path": "src/plugins/controls/common/control_types/options_list/types.ts", - "deprecated": false - }, { "parentPluginId": "controls", "id": "def-public.OptionsListEmbeddableInput.selectedOptions", @@ -3302,31 +3282,11 @@ "text": "RangeSliderEmbeddableInput" }, " extends ", - "ControlInput" + "DataControlInput" ], "path": "src/plugins/controls/common/control_types/range_slider/types.ts", "deprecated": false, "children": [ - { - "parentPluginId": "controls", - "id": "def-public.RangeSliderEmbeddableInput.fieldName", - "type": "string", - "tags": [], - "label": "fieldName", - "description": [], - "path": "src/plugins/controls/common/control_types/range_slider/types.ts", - "deprecated": false - }, - { - "parentPluginId": "controls", - "id": "def-public.RangeSliderEmbeddableInput.dataViewId", - "type": "string", - "tags": [], - "label": "dataViewId", - "description": [], - "path": "src/plugins/controls/common/control_types/range_slider/types.ts", - "deprecated": false - }, { "parentPluginId": "controls", "id": "def-public.RangeSliderEmbeddableInput.value", @@ -3600,7 +3560,46 @@ }, "server": { "classes": [], - "functions": [], + "functions": [ + { + "parentPluginId": "controls", + "id": "def-server.initializeControlGroupTelemetry", + "type": "Function", + "tags": [], + "label": "initializeControlGroupTelemetry", + "description": [], + "signature": [ + "(statsSoFar: Record) => ", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.ControlGroupTelemetry", + "text": "ControlGroupTelemetry" + } + ], + "path": "src/plugins/controls/server/control_group/control_group_telemetry.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "controls", + "id": "def-server.initializeControlGroupTelemetry.$1", + "type": "Object", + "tags": [], + "label": "statsSoFar", + "description": [], + "signature": [ + "Record" + ], + "path": "src/plugins/controls/server/control_group/control_group_telemetry.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], "interfaces": [], "enums": [], "misc": [], @@ -3609,6 +3608,60 @@ "common": { "classes": [], "functions": [ + { + "parentPluginId": "controls", + "id": "def-common.controlGroupInputToRawControlGroupAttributes", + "type": "Function", + "tags": [], + "label": "controlGroupInputToRawControlGroupAttributes", + "description": [], + "signature": [ + "(controlGroupInput: Omit<", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.ControlGroupInput", + "text": "ControlGroupInput" + }, + ", \"id\">) => ", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.RawControlGroupAttributes", + "text": "RawControlGroupAttributes" + } + ], + "path": "src/plugins/controls/common/control_group/control_group_persistence.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "controls", + "id": "def-common.controlGroupInputToRawControlGroupAttributes.$1", + "type": "Object", + "tags": [], + "label": "controlGroupInput", + "description": [], + "signature": [ + "Omit<", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.ControlGroupInput", + "text": "ControlGroupInput" + }, + ", \"id\">" + ], + "path": "src/plugins/controls/common/control_group/control_group_persistence.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "controls", "id": "def-common.getDefaultControlGroupInput", @@ -3627,11 +3680,228 @@ }, ", \"id\">" ], - "path": "src/plugins/controls/common/control_group/control_group_constants.ts", + "path": "src/plugins/controls/common/control_group/control_group_persistence.ts", "deprecated": false, "children": [], "returnComment": [], "initialIsOpen": false + }, + { + "parentPluginId": "controls", + "id": "def-common.persistableControlGroupInputIsEqual", + "type": "Function", + "tags": [], + "label": "persistableControlGroupInputIsEqual", + "description": [], + "signature": [ + "(a: ", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.PersistableControlGroupInput", + "text": "PersistableControlGroupInput" + }, + " | undefined, b: ", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.PersistableControlGroupInput", + "text": "PersistableControlGroupInput" + }, + " | undefined) => boolean" + ], + "path": "src/plugins/controls/common/control_group/control_group_persistence.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "controls", + "id": "def-common.persistableControlGroupInputIsEqual.$1", + "type": "Object", + "tags": [], + "label": "a", + "description": [], + "signature": [ + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.PersistableControlGroupInput", + "text": "PersistableControlGroupInput" + }, + " | undefined" + ], + "path": "src/plugins/controls/common/control_group/control_group_persistence.ts", + "deprecated": false, + "isRequired": false + }, + { + "parentPluginId": "controls", + "id": "def-common.persistableControlGroupInputIsEqual.$2", + "type": "Object", + "tags": [], + "label": "b", + "description": [], + "signature": [ + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.PersistableControlGroupInput", + "text": "PersistableControlGroupInput" + }, + " | undefined" + ], + "path": "src/plugins/controls/common/control_group/control_group_persistence.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "controls", + "id": "def-common.rawControlGroupAttributesToControlGroupInput", + "type": "Function", + "tags": [], + "label": "rawControlGroupAttributesToControlGroupInput", + "description": [], + "signature": [ + "(rawControlGroupAttributes: ", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.RawControlGroupAttributes", + "text": "RawControlGroupAttributes" + }, + ") => Omit<", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.ControlGroupInput", + "text": "ControlGroupInput" + }, + ", \"id\"> | undefined" + ], + "path": "src/plugins/controls/common/control_group/control_group_persistence.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "controls", + "id": "def-common.rawControlGroupAttributesToControlGroupInput.$1", + "type": "CompoundType", + "tags": [], + "label": "rawControlGroupAttributes", + "description": [], + "signature": [ + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.RawControlGroupAttributes", + "text": "RawControlGroupAttributes" + } + ], + "path": "src/plugins/controls/common/control_group/control_group_persistence.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "controls", + "id": "def-common.rawControlGroupAttributesToSerializable", + "type": "Function", + "tags": [], + "label": "rawControlGroupAttributesToSerializable", + "description": [], + "signature": [ + "(rawControlGroupAttributes: Omit<", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.RawControlGroupAttributes", + "text": "RawControlGroupAttributes" + }, + ", \"id\">) => ", + "SerializableRecord" + ], + "path": "src/plugins/controls/common/control_group/control_group_persistence.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "controls", + "id": "def-common.rawControlGroupAttributesToSerializable.$1", + "type": "Object", + "tags": [], + "label": "rawControlGroupAttributes", + "description": [], + "signature": [ + "Omit<", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.RawControlGroupAttributes", + "text": "RawControlGroupAttributes" + }, + ", \"id\">" + ], + "path": "src/plugins/controls/common/control_group/control_group_persistence.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "controls", + "id": "def-common.serializableToRawControlGroupAttributes", + "type": "Function", + "tags": [], + "label": "serializableToRawControlGroupAttributes", + "description": [], + "signature": [ + "(serializable: ", + "SerializableRecord", + ") => Omit<", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.RawControlGroupAttributes", + "text": "RawControlGroupAttributes" + }, + ", \"id\" | \"type\">" + ], + "path": "src/plugins/controls/common/control_group/control_group_persistence.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "controls", + "id": "def-common.serializableToRawControlGroupAttributes.$1", + "type": "Object", + "tags": [], + "label": "serializable", + "description": [], + "signature": [ + "SerializableRecord" + ], + "path": "src/plugins/controls/common/control_group/control_group_persistence.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false } ], "interfaces": [ @@ -3732,6 +4002,81 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "controls", + "id": "def-common.ControlGroupTelemetry", + "type": "Interface", + "tags": [], + "label": "ControlGroupTelemetry", + "description": [], + "path": "src/plugins/controls/common/control_group/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "controls", + "id": "def-common.ControlGroupTelemetry.total", + "type": "number", + "tags": [], + "label": "total", + "description": [], + "path": "src/plugins/controls/common/control_group/types.ts", + "deprecated": false + }, + { + "parentPluginId": "controls", + "id": "def-common.ControlGroupTelemetry.chaining_system", + "type": "Object", + "tags": [], + "label": "chaining_system", + "description": [], + "signature": [ + "{ [key: string]: number; }" + ], + "path": "src/plugins/controls/common/control_group/types.ts", + "deprecated": false + }, + { + "parentPluginId": "controls", + "id": "def-common.ControlGroupTelemetry.label_position", + "type": "Object", + "tags": [], + "label": "label_position", + "description": [], + "signature": [ + "{ [key: string]: number; }" + ], + "path": "src/plugins/controls/common/control_group/types.ts", + "deprecated": false + }, + { + "parentPluginId": "controls", + "id": "def-common.ControlGroupTelemetry.ignore_settings", + "type": "Object", + "tags": [], + "label": "ignore_settings", + "description": [], + "signature": [ + "{ [key: string]: number; }" + ], + "path": "src/plugins/controls/common/control_group/types.ts", + "deprecated": false + }, + { + "parentPluginId": "controls", + "id": "def-common.ControlGroupTelemetry.by_type", + "type": "Object", + "tags": [], + "label": "by_type", + "description": [], + "signature": [ + "{ [key: string]: { total: number; details: { [key: string]: number; }; }; }" + ], + "path": "src/plugins/controls/common/control_group/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "controls", "id": "def-common.ControlPanelState", @@ -3838,31 +4183,11 @@ "text": "OptionsListEmbeddableInput" }, " extends ", - "ControlInput" + "DataControlInput" ], "path": "src/plugins/controls/common/control_types/options_list/types.ts", "deprecated": false, "children": [ - { - "parentPluginId": "controls", - "id": "def-common.OptionsListEmbeddableInput.fieldName", - "type": "string", - "tags": [], - "label": "fieldName", - "description": [], - "path": "src/plugins/controls/common/control_types/options_list/types.ts", - "deprecated": false - }, - { - "parentPluginId": "controls", - "id": "def-common.OptionsListEmbeddableInput.dataViewId", - "type": "string", - "tags": [], - "label": "dataViewId", - "description": [], - "path": "src/plugins/controls/common/control_types/options_list/types.ts", - "deprecated": false - }, { "parentPluginId": "controls", "id": "def-common.OptionsListEmbeddableInput.selectedOptions", @@ -3921,31 +4246,11 @@ "text": "RangeSliderEmbeddableInput" }, " extends ", - "ControlInput" + "DataControlInput" ], "path": "src/plugins/controls/common/control_types/range_slider/types.ts", "deprecated": false, "children": [ - { - "parentPluginId": "controls", - "id": "def-common.RangeSliderEmbeddableInput.fieldName", - "type": "string", - "tags": [], - "label": "fieldName", - "description": [], - "path": "src/plugins/controls/common/control_types/range_slider/types.ts", - "deprecated": false - }, - { - "parentPluginId": "controls", - "id": "def-common.RangeSliderEmbeddableInput.dataViewId", - "type": "string", - "tags": [], - "label": "dataViewId", - "description": [], - "path": "src/plugins/controls/common/control_types/range_slider/types.ts", - "deprecated": false - }, { "parentPluginId": "controls", "id": "def-common.RangeSliderEmbeddableInput.value", @@ -3993,6 +4298,34 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "controls", + "id": "def-common.DEFAULT_CONTROL_STYLE", + "type": "CompoundType", + "tags": [], + "label": "DEFAULT_CONTROL_STYLE", + "description": [], + "signature": [ + "\"twoLine\" | \"oneLine\"" + ], + "path": "src/plugins/controls/common/control_group/control_group_constants.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "controls", + "id": "def-common.DEFAULT_CONTROL_WIDTH", + "type": "CompoundType", + "tags": [], + "label": "DEFAULT_CONTROL_WIDTH", + "description": [], + "signature": [ + "\"auto\" | \"small\" | \"medium\" | \"large\"" + ], + "path": "src/plugins/controls/common/control_group/control_group_constants.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "controls", "id": "def-common.OPTIONS_LIST_CONTROL", @@ -4007,6 +4340,34 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "controls", + "id": "def-common.PersistableControlGroupInput", + "type": "Type", + "tags": [], + "label": "PersistableControlGroupInput", + "description": [], + "signature": [ + "{ controlStyle: ", + "ControlStyle", + "; ignoreParentSettings?: ", + "ParentIgnoreSettings", + " | undefined; chainingSystem: ", + "ControlGroupChainingSystem", + "; panels: ", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.ControlsPanels", + "text": "ControlsPanels" + }, + "; }" + ], + "path": "src/plugins/controls/common/control_group/types.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "controls", "id": "def-common.RANGE_SLIDER_CONTROL", @@ -4021,6 +4382,28 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "controls", + "id": "def-common.RawControlGroupAttributes", + "type": "Type", + "tags": [], + "label": "RawControlGroupAttributes", + "description": [], + "signature": [ + "Omit<", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.PersistableControlGroupInput", + "text": "PersistableControlGroupInput" + }, + ", \"ignoreParentSettings\" | \"panels\"> & { ignoreParentSettingsJSON: string; panelsJSON: string; }" + ], + "path": "src/plugins/controls/common/control_group/types.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "controls", "id": "def-common.TIME_SLIDER_CONTROL", diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index 7a59f3a0a5120..870bc6876f2c6 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github summary: API docs for the controls plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-prese | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 188 | 0 | 182 | 4 | +| 203 | 0 | 197 | 6 | ## Client @@ -34,6 +34,11 @@ Contact [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-prese ### Consts, variables and types +## Server + +### Functions + + ## Common ### Functions diff --git a/api_docs/core.devdocs.json b/api_docs/core.devdocs.json index 7568da42bdc95..ae6443972aefb 100644 --- a/api_docs/core.devdocs.json +++ b/api_docs/core.devdocs.json @@ -651,7 +651,7 @@ "description": [ "\r\nAnalytics client's public APIs" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -666,7 +666,7 @@ "signature": [ ">(eventType: string, eventData: EventTypeData) => void" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -681,7 +681,7 @@ "signature": [ "string" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": true }, @@ -697,7 +697,7 @@ "signature": [ "EventTypeData" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": true } @@ -718,7 +718,7 @@ "EventTypeOpts", ") => void" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -732,7 +732,7 @@ "EventTypeOpts", "" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": true } @@ -757,7 +757,7 @@ "RegisterShipperOpts", " | undefined) => void" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -773,7 +773,7 @@ "ShipperClassConstructor", "" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": true }, @@ -789,7 +789,7 @@ "signature": [ "ShipperConfig" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": true }, @@ -806,7 +806,7 @@ "RegisterShipperOpts", " | undefined" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": false } @@ -827,7 +827,7 @@ "OptInConfig", ") => void" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -842,7 +842,7 @@ "signature": [ "OptInConfig" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": true } @@ -863,7 +863,7 @@ "ContextProviderOpts", ") => void" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -879,7 +879,7 @@ "ContextProviderOpts", "" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": true } @@ -898,7 +898,7 @@ "signature": [ "(contextProviderName: string) => void" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -913,7 +913,7 @@ "signature": [ "string" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": true } @@ -935,7 +935,7 @@ "TelemetryCounter", ">" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false } ], @@ -1113,7 +1113,7 @@ "ContextProviderOpts", "" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -1125,7 +1125,7 @@ "description": [ "\r\nThe name of the provider." ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -1141,7 +1141,7 @@ "Observable", "" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -1158,7 +1158,7 @@ "SchemaValue", "; }" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false } ], @@ -2075,7 +2075,7 @@ "signature": [ "Event" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -2087,7 +2087,7 @@ "description": [ "\r\nThe time the event was generated in ISO format." ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -2099,7 +2099,7 @@ "description": [ "\r\nThe event type." ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -2114,7 +2114,7 @@ "signature": [ "{ [x: string]: unknown; }" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -2129,7 +2129,7 @@ "signature": [ "EventContext" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false } ], @@ -2141,10 +2141,102 @@ "type": "Interface", "tags": [], "label": "EventContext", - "description": [], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "description": [ + "\r\nDefinition of the context that can be appended to the events through the {@link IAnalyticsClient.registerContextProvider}." + ], + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ + { + "parentPluginId": "core", + "id": "def-public.EventContext.userId", + "type": "string", + "tags": [], + "label": "userId", + "description": [ + "\r\nThe unique user ID." + ], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", + "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-public.EventContext.cloudId", + "type": "string", + "tags": [], + "label": "cloudId", + "description": [ + "\r\nThe Cloud ID." + ], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", + "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-public.EventContext.version", + "type": "string", + "tags": [], + "label": "version", + "description": [ + "\r\nThe product's version." + ], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", + "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-public.EventContext.pageName", + "type": "string", + "tags": [], + "label": "pageName", + "description": [ + "\r\nThe name of the current page." + ], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", + "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-public.EventContext.applicationId", + "type": "string", + "tags": [], + "label": "applicationId", + "description": [ + "\r\nThe current application ID." + ], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", + "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-public.EventContext.entityId", + "type": "string", + "tags": [], + "label": "entityId", + "description": [ + "\r\nThe current entity ID (dashboard ID, visualization ID, etc.)." + ], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", + "deprecated": false + }, { "parentPluginId": "core", "id": "def-public.EventContext.Unnamed", @@ -2155,7 +2247,7 @@ "signature": [ "[key: string]: unknown" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false } ], @@ -2174,7 +2266,7 @@ "EventTypeOpts", "" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -2186,7 +2278,7 @@ "description": [ "\r\nThe event type's unique name." ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -2203,7 +2295,7 @@ "SchemaValue", "; }" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false } ], @@ -2619,7 +2711,7 @@ "description": [ "\r\nBasic structure of a Shipper" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -2636,7 +2728,7 @@ "Event", "[]) => void" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -2652,7 +2744,7 @@ "Event", "[]" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": true } @@ -2671,7 +2763,7 @@ "signature": [ "(isOptedIn: boolean) => void" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -2686,7 +2778,7 @@ "signature": [ "boolean" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": true } @@ -2707,7 +2799,7 @@ "EventContext", ") => void) | undefined" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -2720,7 +2812,7 @@ "signature": [ "EventContext" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": true } @@ -2742,7 +2834,7 @@ "TelemetryCounter", "> | undefined" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false } ], @@ -3479,7 +3571,7 @@ "description": [ "\r\n" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -3494,7 +3586,7 @@ "signature": [ "OptInConfigPerType" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -3511,7 +3603,7 @@ "OptInConfigPerType", " | undefined> | undefined" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false } ], @@ -5391,6 +5483,21 @@ "path": "src/core/server/saved_objects/service/lib/collect_multi_namespace_references.ts", "deprecated": false }, + { + "parentPluginId": "core", + "id": "def-public.SavedObjectReferenceWithContext.originId", + "type": "string", + "tags": [], + "label": "originId", + "description": [ + "The origin ID of the referenced object (if it has one)" + ], + "signature": [ + "string | undefined" + ], + "path": "src/core/server/saved_objects/service/lib/collect_multi_namespace_references.ts", + "deprecated": false + }, { "parentPluginId": "core", "id": "def-public.SavedObjectReferenceWithContext.spaces", @@ -5450,6 +5557,21 @@ ], "path": "src/core/server/saved_objects/service/lib/collect_multi_namespace_references.ts", "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-public.SavedObjectReferenceWithContext.spacesWithMatchingOrigins", + "type": "Array", + "tags": [], + "label": "spacesWithMatchingOrigins", + "description": [ + "The space(s) that objects matching this origin exist in (including this one)" + ], + "signature": [ + "string[] | undefined" + ], + "path": "src/core/server/saved_objects/service/lib/collect_multi_namespace_references.ts", + "deprecated": false } ], "initialIsOpen": false @@ -6793,7 +6915,7 @@ "ShipperClassConstructor", "" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -6805,7 +6927,7 @@ "description": [ "\r\nThe shipper's unique name" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -6820,7 +6942,7 @@ "signature": [ "any" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false } ], @@ -6835,7 +6957,7 @@ "description": [ "\r\nShape of the events emitted by the telemetryCounter$ observable" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -6850,7 +6972,7 @@ "signature": [ "TelemetryCounterType" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -6862,7 +6984,7 @@ "description": [ "\r\nWho emitted the event? It can be \"client\" or the name of the shipper." ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -6874,7 +6996,7 @@ "description": [ "\r\nThe event type the success/failure/drop event refers to." ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -6886,7 +7008,7 @@ "description": [ "\r\nCode to provide additional information about the success or failure. Examples are 200/400/504/ValidationError/UnknownError" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -6898,7 +7020,7 @@ "description": [ "\r\nThe number of events that this counter refers to." ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false } ], @@ -7340,7 +7462,7 @@ "description": [ "\r\nTypes of the Telemetry Counter: It allows to differentiate what happened to the events" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "initialIsOpen": false } @@ -7412,7 +7534,7 @@ "signature": [ "string" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "initialIsOpen": false }, @@ -7903,7 +8025,7 @@ "signature": [ "Pick<", "Toast", - ", \"children\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"className\" | \"security\" | \"defaultValue\" | \"hidden\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\"> & { title?: string | ", + ", \"children\" | \"color\" | \"className\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"hidden\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\"> & { title?: string | ", { "pluginId": "core", "scope": "public", @@ -7960,7 +8082,7 @@ "signature": [ "Pick<", "Toast", - ", \"children\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"className\" | \"security\" | \"defaultValue\" | \"hidden\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\"> & { title?: string | ", + ", \"children\" | \"color\" | \"className\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"hidden\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\"> & { title?: string | ", { "pluginId": "core", "scope": "public", @@ -8750,7 +8872,7 @@ "label": "rawConfig", "description": [], "signature": [ - "Readonly<{ username?: string | undefined; password?: string | undefined; serviceAccountToken?: string | undefined; } & { ssl: Readonly<{ key?: string | undefined; certificateAuthorities?: string | string[] | undefined; certificate?: string | undefined; keyPassphrase?: string | undefined; } & { verificationMode: \"none\" | \"full\" | \"certificate\"; keystore: Readonly<{ path?: string | undefined; password?: string | undefined; } & {}>; truststore: Readonly<{ path?: string | undefined; password?: string | undefined; } & {}>; alwaysPresentCertificate: boolean; }>; healthCheck: Readonly<{} & { delay: moment.Duration; }>; hosts: string | string[]; sniffOnStart: boolean; sniffInterval: false | moment.Duration; sniffOnConnectionFault: boolean; maxSockets: number; compression: boolean; requestHeadersWhitelist: string | string[]; customHeaders: Record; shardTimeout: moment.Duration; requestTimeout: moment.Duration; pingTimeout: moment.Duration; logQueries: boolean; apiVersion: string; ignoreVersionMismatch: boolean; skipStartupConnectionCheck: boolean; }>" + "Readonly<{ username?: string | undefined; password?: string | undefined; serviceAccountToken?: string | undefined; } & { ssl: Readonly<{ key?: string | undefined; certificateAuthorities?: string | string[] | undefined; certificate?: string | undefined; keyPassphrase?: string | undefined; } & { verificationMode: \"none\" | \"full\" | \"certificate\"; keystore: Readonly<{ path?: string | undefined; password?: string | undefined; } & {}>; truststore: Readonly<{ path?: string | undefined; password?: string | undefined; } & {}>; alwaysPresentCertificate: boolean; }>; healthCheck: Readonly<{} & { delay: moment.Duration; }>; customHeaders: Record; hosts: string | string[]; sniffOnStart: boolean; sniffInterval: false | moment.Duration; sniffOnConnectionFault: boolean; maxSockets: number; compression: boolean; requestHeadersWhitelist: string | string[]; shardTimeout: moment.Duration; requestTimeout: moment.Duration; pingTimeout: moment.Duration; logQueries: boolean; apiVersion: string; ignoreVersionMismatch: boolean; skipStartupConnectionCheck: boolean; }>" ], "path": "src/core/server/elasticsearch/elasticsearch_config.ts", "deprecated": false, @@ -8918,7 +9040,7 @@ "description": [ "\r\nAnalytics client's public APIs" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -8933,7 +9055,7 @@ "signature": [ ">(eventType: string, eventData: EventTypeData) => void" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -8948,7 +9070,7 @@ "signature": [ "string" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": true }, @@ -8964,7 +9086,7 @@ "signature": [ "EventTypeData" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": true } @@ -8985,7 +9107,7 @@ "EventTypeOpts", ") => void" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -8999,7 +9121,7 @@ "EventTypeOpts", "" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": true } @@ -9024,7 +9146,7 @@ "RegisterShipperOpts", " | undefined) => void" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -9040,7 +9162,7 @@ "ShipperClassConstructor", "" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": true }, @@ -9056,7 +9178,7 @@ "signature": [ "ShipperConfig" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": true }, @@ -9073,7 +9195,7 @@ "RegisterShipperOpts", " | undefined" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": false } @@ -9094,7 +9216,7 @@ "OptInConfig", ") => void" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -9109,7 +9231,7 @@ "signature": [ "OptInConfig" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": true } @@ -9130,7 +9252,7 @@ "ContextProviderOpts", ") => void" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -9146,7 +9268,7 @@ "ContextProviderOpts", "" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": true } @@ -9165,7 +9287,7 @@ "signature": [ "(contextProviderName: string) => void" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -9180,7 +9302,7 @@ "signature": [ "string" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": true } @@ -9202,7 +9324,7 @@ "TelemetryCounter", ">" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false } ], @@ -10300,7 +10422,7 @@ "ContextProviderOpts", "" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -10312,7 +10434,7 @@ "description": [ "\r\nThe name of the provider." ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -10328,7 +10450,7 @@ "Observable", "" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -10345,7 +10467,7 @@ "SchemaValue", "; }" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false } ], @@ -10483,6 +10605,161 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "core", + "id": "def-server.CoreRequestHandlerContext", + "type": "Interface", + "tags": [], + "label": "CoreRequestHandlerContext", + "description": [ + "\nThe `core` context provided to route handler.\n\nProvides the following clients and services:\n - {@link SavedObjectsClient | savedObjects.client} - Saved Objects client\n which uses the credentials of the incoming request\n - {@link ISavedObjectTypeRegistry | savedObjects.typeRegistry} - Type registry containing\n all the registered types.\n - {@link IScopedClusterClient | elasticsearch.client} - Elasticsearch\n data client which uses the credentials of the incoming request\n - {@link IUiSettingsClient | uiSettings.client} - uiSettings client\n which uses the credentials of the incoming request" + ], + "path": "src/core/server/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.CoreRequestHandlerContext.savedObjects", + "type": "Object", + "tags": [], + "label": "savedObjects", + "description": [], + "signature": [ + "{ client: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsClientContract", + "text": "SavedObjectsClientContract" + }, + "; typeRegistry: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.ISavedObjectTypeRegistry", + "text": "ISavedObjectTypeRegistry" + }, + "; getClient: (options?: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsClientProviderOptions", + "text": "SavedObjectsClientProviderOptions" + }, + " | undefined) => ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsClientContract", + "text": "SavedObjectsClientContract" + }, + "; getExporter: (client: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsClientContract", + "text": "SavedObjectsClientContract" + }, + ") => ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.ISavedObjectsExporter", + "text": "ISavedObjectsExporter" + }, + "; getImporter: (client: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.SavedObjectsClientContract", + "text": "SavedObjectsClientContract" + }, + ") => ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreSavedObjectsPluginApi", + "section": "def-server.ISavedObjectsImporter", + "text": "ISavedObjectsImporter" + }, + "; }" + ], + "path": "src/core/server/index.ts", + "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-server.CoreRequestHandlerContext.elasticsearch", + "type": "Object", + "tags": [], + "label": "elasticsearch", + "description": [], + "signature": [ + "{ client: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCorePluginApi", + "section": "def-server.IScopedClusterClient", + "text": "IScopedClusterClient" + }, + "; }" + ], + "path": "src/core/server/index.ts", + "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-server.CoreRequestHandlerContext.uiSettings", + "type": "Object", + "tags": [], + "label": "uiSettings", + "description": [], + "signature": [ + "{ client: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCorePluginApi", + "section": "def-server.IUiSettingsClient", + "text": "IUiSettingsClient" + }, + "; }" + ], + "path": "src/core/server/index.ts", + "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-server.CoreRequestHandlerContext.deprecations", + "type": "Object", + "tags": [], + "label": "deprecations", + "description": [], + "signature": [ + "{ client: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCorePluginApi", + "section": "def-server.DeprecationsClient", + "text": "DeprecationsClient" + }, + "; }" + ], + "path": "src/core/server/index.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "core", "id": "def-server.CoreSetup", @@ -11470,6 +11747,21 @@ ], "path": "src/core/server/plugins/types.ts", "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-server.DiscoveredPlugin.enabledOnAnonymousPages", + "type": "CompoundType", + "tags": [], + "label": "enabledOnAnonymousPages", + "description": [ + "\nSpecifies whether this plugin - and its required dependencies - will be enabled for anonymous pages (login page, status page when\nconfigured, etc.) Default is false." + ], + "signature": [ + "boolean | undefined" + ], + "path": "src/core/server/plugins/types.ts", + "deprecated": false } ], "initialIsOpen": false @@ -12002,7 +12294,7 @@ "signature": [ "Event" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -12014,7 +12306,7 @@ "description": [ "\r\nThe time the event was generated in ISO format." ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -12026,7 +12318,7 @@ "description": [ "\r\nThe event type." ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -12041,7 +12333,7 @@ "signature": [ "{ [x: string]: unknown; }" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -12056,7 +12348,7 @@ "signature": [ "EventContext" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false } ], @@ -12068,10 +12360,102 @@ "type": "Interface", "tags": [], "label": "EventContext", - "description": [], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "description": [ + "\r\nDefinition of the context that can be appended to the events through the {@link IAnalyticsClient.registerContextProvider}." + ], + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ + { + "parentPluginId": "core", + "id": "def-server.EventContext.userId", + "type": "string", + "tags": [], + "label": "userId", + "description": [ + "\r\nThe unique user ID." + ], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", + "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-server.EventContext.cloudId", + "type": "string", + "tags": [], + "label": "cloudId", + "description": [ + "\r\nThe Cloud ID." + ], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", + "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-server.EventContext.version", + "type": "string", + "tags": [], + "label": "version", + "description": [ + "\r\nThe product's version." + ], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", + "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-server.EventContext.pageName", + "type": "string", + "tags": [], + "label": "pageName", + "description": [ + "\r\nThe name of the current page." + ], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", + "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-server.EventContext.applicationId", + "type": "string", + "tags": [], + "label": "applicationId", + "description": [ + "\r\nThe current application ID." + ], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", + "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-server.EventContext.entityId", + "type": "string", + "tags": [], + "label": "entityId", + "description": [ + "\r\nThe current entity ID (dashboard ID, visualization ID, etc.)." + ], + "signature": [ + "string | undefined" + ], + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", + "deprecated": false + }, { "parentPluginId": "core", "id": "def-server.EventContext.Unnamed", @@ -12082,7 +12466,7 @@ "signature": [ "[key: string]: unknown" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false } ], @@ -12101,7 +12485,7 @@ "EventTypeOpts", "" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -12113,7 +12497,7 @@ "description": [ "\r\nThe event type's unique name." ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -12130,7 +12514,7 @@ "SchemaValue", "; }" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false } ], @@ -12236,7 +12620,7 @@ "Headers used for authentication against Elasticsearch" ], "signature": [ - "{ from?: string | string[] | undefined; date?: string | string[] | undefined; range?: string | string[] | undefined; warning?: string | string[] | undefined; location?: string | string[] | undefined; origin?: string | string[] | undefined; allow?: string | string[] | undefined; accept?: string | string[] | undefined; host?: string | string[] | undefined; \"accept-language\"?: string | string[] | undefined; \"accept-patch\"?: string | string[] | undefined; \"accept-ranges\"?: string | string[] | undefined; \"access-control-allow-credentials\"?: string | string[] | undefined; \"access-control-allow-headers\"?: string | string[] | undefined; \"access-control-allow-methods\"?: string | string[] | undefined; \"access-control-allow-origin\"?: string | string[] | undefined; \"access-control-expose-headers\"?: string | string[] | undefined; \"access-control-max-age\"?: string | string[] | undefined; \"access-control-request-headers\"?: string | string[] | undefined; \"access-control-request-method\"?: string | string[] | undefined; age?: string | string[] | undefined; \"alt-svc\"?: string | string[] | undefined; authorization?: string | string[] | undefined; \"cache-control\"?: string | string[] | undefined; connection?: string | string[] | undefined; \"content-disposition\"?: string | string[] | undefined; \"content-encoding\"?: string | string[] | undefined; \"content-language\"?: string | string[] | undefined; \"content-length\"?: string | string[] | undefined; \"content-location\"?: string | string[] | undefined; \"content-range\"?: string | string[] | undefined; \"content-type\"?: string | string[] | undefined; cookie?: string | string[] | undefined; etag?: string | string[] | undefined; expect?: string | string[] | undefined; expires?: string | string[] | undefined; forwarded?: string | string[] | undefined; \"if-match\"?: string | string[] | undefined; \"if-modified-since\"?: string | string[] | undefined; \"if-none-match\"?: string | string[] | undefined; \"if-unmodified-since\"?: string | string[] | undefined; \"last-modified\"?: string | string[] | undefined; pragma?: string | string[] | undefined; \"proxy-authenticate\"?: string | string[] | undefined; \"proxy-authorization\"?: string | string[] | undefined; \"public-key-pins\"?: string | string[] | undefined; referer?: string | string[] | undefined; \"retry-after\"?: string | string[] | undefined; \"sec-websocket-accept\"?: string | string[] | undefined; \"sec-websocket-extensions\"?: string | string[] | undefined; \"sec-websocket-key\"?: string | string[] | undefined; \"sec-websocket-protocol\"?: string | string[] | undefined; \"sec-websocket-version\"?: string | string[] | undefined; \"set-cookie\"?: string | string[] | undefined; \"strict-transport-security\"?: string | string[] | undefined; tk?: string | string[] | undefined; trailer?: string | string[] | undefined; \"transfer-encoding\"?: string | string[] | undefined; upgrade?: string | string[] | undefined; \"user-agent\"?: string | string[] | undefined; vary?: string | string[] | undefined; via?: string | string[] | undefined; \"www-authenticate\"?: string | string[] | undefined; } & { [header: string]: string | string[] | undefined; }" + "{ warning?: string | string[] | undefined; from?: string | string[] | undefined; date?: string | string[] | undefined; range?: string | string[] | undefined; location?: string | string[] | undefined; origin?: string | string[] | undefined; allow?: string | string[] | undefined; accept?: string | string[] | undefined; host?: string | string[] | undefined; \"accept-language\"?: string | string[] | undefined; \"accept-patch\"?: string | string[] | undefined; \"accept-ranges\"?: string | string[] | undefined; \"access-control-allow-credentials\"?: string | string[] | undefined; \"access-control-allow-headers\"?: string | string[] | undefined; \"access-control-allow-methods\"?: string | string[] | undefined; \"access-control-allow-origin\"?: string | string[] | undefined; \"access-control-expose-headers\"?: string | string[] | undefined; \"access-control-max-age\"?: string | string[] | undefined; \"access-control-request-headers\"?: string | string[] | undefined; \"access-control-request-method\"?: string | string[] | undefined; age?: string | string[] | undefined; \"alt-svc\"?: string | string[] | undefined; authorization?: string | string[] | undefined; \"cache-control\"?: string | string[] | undefined; connection?: string | string[] | undefined; \"content-disposition\"?: string | string[] | undefined; \"content-encoding\"?: string | string[] | undefined; \"content-language\"?: string | string[] | undefined; \"content-length\"?: string | string[] | undefined; \"content-location\"?: string | string[] | undefined; \"content-range\"?: string | string[] | undefined; \"content-type\"?: string | string[] | undefined; cookie?: string | string[] | undefined; etag?: string | string[] | undefined; expect?: string | string[] | undefined; expires?: string | string[] | undefined; forwarded?: string | string[] | undefined; \"if-match\"?: string | string[] | undefined; \"if-modified-since\"?: string | string[] | undefined; \"if-none-match\"?: string | string[] | undefined; \"if-unmodified-since\"?: string | string[] | undefined; \"last-modified\"?: string | string[] | undefined; pragma?: string | string[] | undefined; \"proxy-authenticate\"?: string | string[] | undefined; \"proxy-authorization\"?: string | string[] | undefined; \"public-key-pins\"?: string | string[] | undefined; referer?: string | string[] | undefined; \"retry-after\"?: string | string[] | undefined; \"sec-websocket-accept\"?: string | string[] | undefined; \"sec-websocket-extensions\"?: string | string[] | undefined; \"sec-websocket-key\"?: string | string[] | undefined; \"sec-websocket-protocol\"?: string | string[] | undefined; \"sec-websocket-version\"?: string | string[] | undefined; \"set-cookie\"?: string | string[] | undefined; \"strict-transport-security\"?: string | string[] | undefined; tk?: string | string[] | undefined; trailer?: string | string[] | undefined; \"transfer-encoding\"?: string | string[] | undefined; upgrade?: string | string[] | undefined; \"user-agent\"?: string | string[] | undefined; vary?: string | string[] | undefined; via?: string | string[] | undefined; \"www-authenticate\"?: string | string[] | undefined; } & { [header: string]: string | string[] | undefined; }" ], "path": "src/core/server/elasticsearch/types.ts", "deprecated": false @@ -14725,6 +15109,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -14915,6 +15303,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -15151,6 +15543,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -15582,12 +15978,12 @@ "children": [ { "parentPluginId": "core", - "id": "def-server.IRenderOptions.includeUserSettings", + "id": "def-server.IRenderOptions.isAnonymousPage", "type": "CompoundType", "tags": [], - "label": "includeUserSettings", + "label": "isAnonymousPage", "description": [ - "\nSet whether to output user settings in the page metadata.\n`true` by default." + "\nSet whether the page is anonymous, which determines what plugins are enabled and whether to output user settings in the page metadata.\n`false` by default." ], "signature": [ "boolean | undefined" @@ -18028,7 +18424,7 @@ "description": [ "\r\nBasic structure of a Shipper" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -18045,7 +18441,7 @@ "Event", "[]) => void" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -18061,7 +18457,7 @@ "Event", "[]" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": true } @@ -18080,7 +18476,7 @@ "signature": [ "(isOptedIn: boolean) => void" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -18095,7 +18491,7 @@ "signature": [ "boolean" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": true } @@ -18116,7 +18512,7 @@ "EventContext", ") => void) | undefined" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -18129,7 +18525,7 @@ "signature": [ "EventContext" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "isRequired": true } @@ -18151,7 +18547,7 @@ "TelemetryCounter", "> | undefined" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false } ], @@ -18884,7 +19280,7 @@ "label": "loggers", "description": [], "signature": [ - "Readonly<{} & { name: string; level: \"all\" | \"error\" | \"info\" | \"off\" | \"debug\" | \"trace\" | \"warn\" | \"fatal\"; appenders: string[]; }>[] | undefined" + "Readonly<{} & { name: string; level: \"error\" | \"all\" | \"info\" | \"off\" | \"debug\" | \"trace\" | \"warn\" | \"fatal\"; appenders: string[]; }>[] | undefined" ], "path": "src/core/server/logging/logging_config.ts", "deprecated": false @@ -19593,7 +19989,7 @@ "description": [ "\r\n" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -19608,7 +20004,7 @@ "signature": [ "OptInConfigPerType" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -19625,7 +20021,7 @@ "OptInConfigPerType", " | undefined> | undefined" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false } ], @@ -20266,6 +20662,21 @@ ], "path": "src/core/server/plugins/types.ts", "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-server.PluginManifest.enabledOnAnonymousPages", + "type": "CompoundType", + "tags": [], + "label": "enabledOnAnonymousPages", + "description": [ + "\nSpecifies whether this plugin - and its required dependencies - will be enabled for anonymous pages (login page, status page when\nconfigured, etc.) Default is false." + ], + "signature": [ + "boolean | undefined" + ], + "path": "src/core/server/plugins/types.ts", + "deprecated": false } ], "initialIsOpen": false @@ -21781,7 +22192,24 @@ "tags": [], "label": "RequestHandlerContext", "description": [ - "\nPlugin specific context passed to a route handler.\n\nProvides the following clients and services:\n - {@link SavedObjectsClient | savedObjects.client} - Saved Objects client\n which uses the credentials of the incoming request\n - {@link ISavedObjectTypeRegistry | savedObjects.typeRegistry} - Type registry containing\n all the registered types.\n - {@link IScopedClusterClient | elasticsearch.client} - Elasticsearch\n data client which uses the credentials of the incoming request\n - {@link IUiSettingsClient | uiSettings.client} - uiSettings client\n which uses the credentials of the incoming request\n" + "\nBase context passed to a route handler.\n" + ], + "signature": [ + { + "pluginId": "core", + "scope": "server", + "docId": "kibCorePluginApi", + "section": "def-server.RequestHandlerContext", + "text": "RequestHandlerContext" + }, + " extends ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCorePluginApi", + "section": "def-server.RequestHandlerContextBase", + "text": "RequestHandlerContextBase" + } ], "path": "src/core/server/index.ts", "deprecated": false, @@ -21794,95 +22222,15 @@ "label": "core", "description": [], "signature": [ - "{ savedObjects: { client: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsClientContract", - "text": "SavedObjectsClientContract" - }, - "; typeRegistry: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.ISavedObjectTypeRegistry", - "text": "ISavedObjectTypeRegistry" - }, - "; getClient: (options?: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsClientProviderOptions", - "text": "SavedObjectsClientProviderOptions" - }, - " | undefined) => ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsClientContract", - "text": "SavedObjectsClientContract" - }, - "; getExporter: (client: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsClientContract", - "text": "SavedObjectsClientContract" - }, - ") => ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.ISavedObjectsExporter", - "text": "ISavedObjectsExporter" - }, - "; getImporter: (client: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsClientContract", - "text": "SavedObjectsClientContract" - }, - ") => ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.ISavedObjectsImporter", - "text": "ISavedObjectsImporter" - }, - "; }; elasticsearch: { client: ", + "Promise<", { "pluginId": "core", "scope": "server", "docId": "kibCorePluginApi", - "section": "def-server.IScopedClusterClient", - "text": "IScopedClusterClient" - }, - "; }; uiSettings: { client: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCorePluginApi", - "section": "def-server.IUiSettingsClient", - "text": "IUiSettingsClient" - }, - "; }; deprecations: { client: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCorePluginApi", - "section": "def-server.DeprecationsClient", - "text": "DeprecationsClient" + "section": "def-server.CoreRequestHandlerContext", + "text": "CoreRequestHandlerContext" }, - "; }; }" + ">" ], "path": "src/core/server/index.ts", "deprecated": false @@ -21890,6 +22238,53 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "core", + "id": "def-server.RequestHandlerContextBase", + "type": "Interface", + "tags": [], + "label": "RequestHandlerContextBase", + "description": [], + "path": "src/core/server/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.RequestHandlerContextBase.resolve", + "type": "Function", + "tags": [], + "label": "resolve", + "description": [ + "\nAwait all the specified context parts and return them.\n" + ], + "signature": [ + ">(parts: T[]) => Promise<", + "AwaitedProperties", + ">>" + ], + "path": "src/core/server/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.RequestHandlerContextBase.resolve.$1", + "type": "Array", + "tags": [], + "label": "parts", + "description": [], + "signature": [ + "T[]" + ], + "path": "src/core/server/index.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + }, { "parentPluginId": "core", "id": "def-server.ResolveCapabilitiesOptions", @@ -22530,7 +22925,7 @@ "ShipperClassConstructor", "" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -22542,7 +22937,7 @@ "description": [ "\r\nThe shipper's unique name" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -22557,7 +22952,7 @@ "signature": [ "any" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false } ], @@ -22751,7 +23146,7 @@ "description": [ "\r\nShape of the events emitted by the telemetryCounter$ observable" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "children": [ { @@ -22766,7 +23161,7 @@ "signature": [ "TelemetryCounterType" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -22778,7 +23173,7 @@ "description": [ "\r\nWho emitted the event? It can be \"client\" or the name of the shipper." ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -22790,7 +23185,7 @@ "description": [ "\r\nThe event type the success/failure/drop event refers to." ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -22802,7 +23197,7 @@ "description": [ "\r\nCode to provide additional information about the success or failure. Examples are 200/400/504/ValidationError/UnknownError" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false }, { @@ -22814,7 +23209,7 @@ "description": [ "\r\nThe number of events that this counter refers to." ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false } ], @@ -23486,7 +23881,7 @@ "description": [ "\r\nTypes of the Telemetry Counter: It allows to differentiate what happened to the events" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "initialIsOpen": false } @@ -23851,6 +24246,27 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "core", + "id": "def-server.CustomRequestHandlerContext", + "type": "Type", + "tags": [], + "label": "CustomRequestHandlerContext", + "description": [], + "signature": [ + { + "pluginId": "core", + "scope": "server", + "docId": "kibCorePluginApi", + "section": "def-server.RequestHandlerContext", + "text": "RequestHandlerContext" + }, + " & { [Key in keyof T]: T[Key] extends Promise ? T[Key] : Promise; }" + ], + "path": "src/core/server/index.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "core", "id": "def-server.DeprecationsDetails", @@ -23951,7 +24367,7 @@ "label": "EcsEventOutcome", "description": [], "signature": [ - "\"unknown\" | \"success\" | \"failure\"" + "\"success\" | \"unknown\" | \"failure\"" ], "path": "node_modules/@types/kbn__logging/index.d.ts", "deprecated": false, @@ -23965,7 +24381,7 @@ "label": "EcsEventType", "description": [], "signature": [ - "\"start\" | \"user\" | \"error\" | \"info\" | \"group\" | \"end\" | \"protocol\" | \"connection\" | \"access\" | \"admin\" | \"allowed\" | \"change\" | \"creation\" | \"deletion\" | \"denied\" | \"installation\"" + "\"start\" | \"error\" | \"user\" | \"info\" | \"group\" | \"end\" | \"admin\" | \"protocol\" | \"connection\" | \"access\" | \"allowed\" | \"change\" | \"creation\" | \"deletion\" | \"denied\" | \"installation\"" ], "path": "node_modules/@types/kbn__logging/index.d.ts", "deprecated": false, @@ -25193,7 +25609,7 @@ "section": "def-server.ElasticsearchConfig", "text": "ElasticsearchConfig" }, - ", \"username\" | \"hosts\" | \"password\" | \"sniffOnStart\" | \"sniffInterval\" | \"sniffOnConnectionFault\" | \"maxSockets\" | \"compression\" | \"serviceAccountToken\" | \"requestHeadersWhitelist\" | \"customHeaders\"> & { pingTimeout?: number | moment.Duration | undefined; requestTimeout?: number | moment.Duration | undefined; ssl?: Partial; truststore: Readonly<{ path?: string | undefined; password?: string | undefined; } & {}>; alwaysPresentCertificate: boolean; }>, \"key\" | \"verificationMode\" | \"certificate\" | \"keyPassphrase\" | \"alwaysPresentCertificate\"> & { certificateAuthorities?: string[] | undefined; }> | undefined; keepAlive?: boolean | undefined; caFingerprint?: string | undefined; }" + ", \"username\" | \"customHeaders\" | \"hosts\" | \"password\" | \"sniffOnStart\" | \"sniffInterval\" | \"sniffOnConnectionFault\" | \"maxSockets\" | \"compression\" | \"serviceAccountToken\" | \"requestHeadersWhitelist\"> & { pingTimeout?: number | moment.Duration | undefined; requestTimeout?: number | moment.Duration | undefined; ssl?: Partial; truststore: Readonly<{ path?: string | undefined; password?: string | undefined; } & {}>; alwaysPresentCertificate: boolean; }>, \"key\" | \"verificationMode\" | \"certificate\" | \"keyPassphrase\" | \"alwaysPresentCertificate\"> & { certificateAuthorities?: string[] | undefined; }> | undefined; keepAlive?: boolean | undefined; caFingerprint?: string | undefined; }" ], "path": "src/core/server/elasticsearch/client/client_config.ts", "deprecated": false, @@ -25211,7 +25627,7 @@ "signature": [ "string" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "initialIsOpen": false }, @@ -25488,6 +25904,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -25795,6 +26215,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -25851,7 +26275,9 @@ }, ") => ", "KibanaResponse", - "; }) => Context[ContextName] | Promise" + "; }) => ", + "MaybePromise", + ">" ], "path": "src/core/server/context/container/context.ts", "deprecated": false, @@ -26018,6 +26444,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -26106,7 +26536,7 @@ "label": "LoggerConfigType", "description": [], "signature": [ - "{ readonly name: string; readonly level: \"all\" | \"error\" | \"info\" | \"off\" | \"debug\" | \"trace\" | \"warn\" | \"fatal\"; readonly appenders: string[]; }" + "{ readonly name: string; readonly level: \"error\" | \"all\" | \"info\" | \"off\" | \"debug\" | \"trace\" | \"warn\" | \"fatal\"; readonly appenders: string[]; }" ], "path": "src/core/server/logging/logging_config.ts", "deprecated": false, diff --git a/api_docs/core.mdx b/api_docs/core.mdx index 0290b6009ea42..765f93b5bb6f9 100644 --- a/api_docs/core.mdx +++ b/api_docs/core.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/core title: "core" image: https://source.unsplash.com/400x175/?github summary: API docs for the core plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2497 | 15 | 971 | 33 | +| 2524 | 15 | 977 | 33 | ## Client diff --git a/api_docs/core_application.devdocs.json b/api_docs/core_application.devdocs.json index cc3cb0a2d1dd2..1f59b41949a3a 100644 --- a/api_docs/core_application.devdocs.json +++ b/api_docs/core_application.devdocs.json @@ -510,7 +510,7 @@ "tags": [], "label": "id", "description": [ - "\nThe unique identifier of the application" + "\nThe unique identifier of the application.\n\nCan only be composed of alphanumeric characters, `-`, `:` and `_`" ], "path": "src/core/public/application/types.ts", "deprecated": false @@ -1210,7 +1210,9 @@ "type": "Object", "tags": [], "label": "options", - "description": [], + "description": [ + "- navigation options" + ], "signature": [ { "pluginId": "core", diff --git a/api_docs/core_application.mdx b/api_docs/core_application.mdx index ad976a37aa5db..680c5de7566c6 100644 --- a/api_docs/core_application.mdx +++ b/api_docs/core_application.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/core-application title: "core.application" image: https://source.unsplash.com/400x175/?github summary: API docs for the core.application plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core.application'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2497 | 15 | 971 | 33 | +| 2524 | 15 | 977 | 33 | ## Client diff --git a/api_docs/core_chrome.mdx b/api_docs/core_chrome.mdx index 09e098a7bf1ba..43eda7a95eaf8 100644 --- a/api_docs/core_chrome.mdx +++ b/api_docs/core_chrome.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/core-chrome title: "core.chrome" image: https://source.unsplash.com/400x175/?github summary: API docs for the core.chrome plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core.chrome'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2497 | 15 | 971 | 33 | +| 2524 | 15 | 977 | 33 | ## Client diff --git a/api_docs/core_http.devdocs.json b/api_docs/core_http.devdocs.json index 1f99d8f6e9bc1..ea42549b15bf9 100644 --- a/api_docs/core_http.devdocs.json +++ b/api_docs/core_http.devdocs.json @@ -2345,7 +2345,7 @@ "\nReadonly copy of incoming request headers." ], "signature": [ - "{ from?: string | string[] | undefined; date?: string | string[] | undefined; range?: string | string[] | undefined; warning?: string | string[] | undefined; location?: string | string[] | undefined; origin?: string | string[] | undefined; allow?: string | string[] | undefined; accept?: string | string[] | undefined; host?: string | string[] | undefined; \"accept-language\"?: string | string[] | undefined; \"accept-patch\"?: string | string[] | undefined; \"accept-ranges\"?: string | string[] | undefined; \"access-control-allow-credentials\"?: string | string[] | undefined; \"access-control-allow-headers\"?: string | string[] | undefined; \"access-control-allow-methods\"?: string | string[] | undefined; \"access-control-allow-origin\"?: string | string[] | undefined; \"access-control-expose-headers\"?: string | string[] | undefined; \"access-control-max-age\"?: string | string[] | undefined; \"access-control-request-headers\"?: string | string[] | undefined; \"access-control-request-method\"?: string | string[] | undefined; age?: string | string[] | undefined; \"alt-svc\"?: string | string[] | undefined; authorization?: string | string[] | undefined; \"cache-control\"?: string | string[] | undefined; connection?: string | string[] | undefined; \"content-disposition\"?: string | string[] | undefined; \"content-encoding\"?: string | string[] | undefined; \"content-language\"?: string | string[] | undefined; \"content-length\"?: string | string[] | undefined; \"content-location\"?: string | string[] | undefined; \"content-range\"?: string | string[] | undefined; \"content-type\"?: string | string[] | undefined; cookie?: string | string[] | undefined; etag?: string | string[] | undefined; expect?: string | string[] | undefined; expires?: string | string[] | undefined; forwarded?: string | string[] | undefined; \"if-match\"?: string | string[] | undefined; \"if-modified-since\"?: string | string[] | undefined; \"if-none-match\"?: string | string[] | undefined; \"if-unmodified-since\"?: string | string[] | undefined; \"last-modified\"?: string | string[] | undefined; pragma?: string | string[] | undefined; \"proxy-authenticate\"?: string | string[] | undefined; \"proxy-authorization\"?: string | string[] | undefined; \"public-key-pins\"?: string | string[] | undefined; referer?: string | string[] | undefined; \"retry-after\"?: string | string[] | undefined; \"sec-websocket-accept\"?: string | string[] | undefined; \"sec-websocket-extensions\"?: string | string[] | undefined; \"sec-websocket-key\"?: string | string[] | undefined; \"sec-websocket-protocol\"?: string | string[] | undefined; \"sec-websocket-version\"?: string | string[] | undefined; \"set-cookie\"?: string | string[] | undefined; \"strict-transport-security\"?: string | string[] | undefined; tk?: string | string[] | undefined; trailer?: string | string[] | undefined; \"transfer-encoding\"?: string | string[] | undefined; upgrade?: string | string[] | undefined; \"user-agent\"?: string | string[] | undefined; vary?: string | string[] | undefined; via?: string | string[] | undefined; \"www-authenticate\"?: string | string[] | undefined; } & { [header: string]: string | string[] | undefined; }" + "{ warning?: string | string[] | undefined; from?: string | string[] | undefined; date?: string | string[] | undefined; range?: string | string[] | undefined; location?: string | string[] | undefined; origin?: string | string[] | undefined; allow?: string | string[] | undefined; accept?: string | string[] | undefined; host?: string | string[] | undefined; \"accept-language\"?: string | string[] | undefined; \"accept-patch\"?: string | string[] | undefined; \"accept-ranges\"?: string | string[] | undefined; \"access-control-allow-credentials\"?: string | string[] | undefined; \"access-control-allow-headers\"?: string | string[] | undefined; \"access-control-allow-methods\"?: string | string[] | undefined; \"access-control-allow-origin\"?: string | string[] | undefined; \"access-control-expose-headers\"?: string | string[] | undefined; \"access-control-max-age\"?: string | string[] | undefined; \"access-control-request-headers\"?: string | string[] | undefined; \"access-control-request-method\"?: string | string[] | undefined; age?: string | string[] | undefined; \"alt-svc\"?: string | string[] | undefined; authorization?: string | string[] | undefined; \"cache-control\"?: string | string[] | undefined; connection?: string | string[] | undefined; \"content-disposition\"?: string | string[] | undefined; \"content-encoding\"?: string | string[] | undefined; \"content-language\"?: string | string[] | undefined; \"content-length\"?: string | string[] | undefined; \"content-location\"?: string | string[] | undefined; \"content-range\"?: string | string[] | undefined; \"content-type\"?: string | string[] | undefined; cookie?: string | string[] | undefined; etag?: string | string[] | undefined; expect?: string | string[] | undefined; expires?: string | string[] | undefined; forwarded?: string | string[] | undefined; \"if-match\"?: string | string[] | undefined; \"if-modified-since\"?: string | string[] | undefined; \"if-none-match\"?: string | string[] | undefined; \"if-unmodified-since\"?: string | string[] | undefined; \"last-modified\"?: string | string[] | undefined; pragma?: string | string[] | undefined; \"proxy-authenticate\"?: string | string[] | undefined; \"proxy-authorization\"?: string | string[] | undefined; \"public-key-pins\"?: string | string[] | undefined; referer?: string | string[] | undefined; \"retry-after\"?: string | string[] | undefined; \"sec-websocket-accept\"?: string | string[] | undefined; \"sec-websocket-extensions\"?: string | string[] | undefined; \"sec-websocket-key\"?: string | string[] | undefined; \"sec-websocket-protocol\"?: string | string[] | undefined; \"sec-websocket-version\"?: string | string[] | undefined; \"set-cookie\"?: string | string[] | undefined; \"strict-transport-security\"?: string | string[] | undefined; tk?: string | string[] | undefined; trailer?: string | string[] | undefined; \"transfer-encoding\"?: string | string[] | undefined; upgrade?: string | string[] | undefined; \"user-agent\"?: string | string[] | undefined; vary?: string | string[] | undefined; via?: string | string[] | undefined; \"www-authenticate\"?: string | string[] | undefined; } & { [header: string]: string | string[] | undefined; }" ], "path": "src/core/server/http/router/request.ts", "deprecated": false @@ -3946,7 +3946,7 @@ "section": "def-server.RequestHandlerContext", "text": "RequestHandlerContext" }, - ", ContextName extends keyof Context>(contextName: ContextName, provider: ", + ", ContextName extends Exclude>(contextName: ContextName, provider: ", { "pluginId": "core", "scope": "server", @@ -4613,6 +4613,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -4841,6 +4845,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -5121,6 +5129,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -5349,6 +5361,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -5629,6 +5645,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -5857,6 +5877,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -6137,6 +6161,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -6365,6 +6393,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -6645,6 +6677,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -6873,6 +6909,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -7161,6 +7201,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -7343,6 +7387,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -8950,6 +8998,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -9152,6 +9204,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -9397,7 +9453,7 @@ "\nHttp request headers to read." ], "signature": [ - "{ from?: string | string[] | undefined; date?: string | string[] | undefined; range?: string | string[] | undefined; warning?: string | string[] | undefined; location?: string | string[] | undefined; origin?: string | string[] | undefined; allow?: string | string[] | undefined; accept?: string | string[] | undefined; host?: string | string[] | undefined; \"accept-language\"?: string | string[] | undefined; \"accept-patch\"?: string | string[] | undefined; \"accept-ranges\"?: string | string[] | undefined; \"access-control-allow-credentials\"?: string | string[] | undefined; \"access-control-allow-headers\"?: string | string[] | undefined; \"access-control-allow-methods\"?: string | string[] | undefined; \"access-control-allow-origin\"?: string | string[] | undefined; \"access-control-expose-headers\"?: string | string[] | undefined; \"access-control-max-age\"?: string | string[] | undefined; \"access-control-request-headers\"?: string | string[] | undefined; \"access-control-request-method\"?: string | string[] | undefined; age?: string | string[] | undefined; \"alt-svc\"?: string | string[] | undefined; authorization?: string | string[] | undefined; \"cache-control\"?: string | string[] | undefined; connection?: string | string[] | undefined; \"content-disposition\"?: string | string[] | undefined; \"content-encoding\"?: string | string[] | undefined; \"content-language\"?: string | string[] | undefined; \"content-length\"?: string | string[] | undefined; \"content-location\"?: string | string[] | undefined; \"content-range\"?: string | string[] | undefined; \"content-type\"?: string | string[] | undefined; cookie?: string | string[] | undefined; etag?: string | string[] | undefined; expect?: string | string[] | undefined; expires?: string | string[] | undefined; forwarded?: string | string[] | undefined; \"if-match\"?: string | string[] | undefined; \"if-modified-since\"?: string | string[] | undefined; \"if-none-match\"?: string | string[] | undefined; \"if-unmodified-since\"?: string | string[] | undefined; \"last-modified\"?: string | string[] | undefined; pragma?: string | string[] | undefined; \"proxy-authenticate\"?: string | string[] | undefined; \"proxy-authorization\"?: string | string[] | undefined; \"public-key-pins\"?: string | string[] | undefined; referer?: string | string[] | undefined; \"retry-after\"?: string | string[] | undefined; \"sec-websocket-accept\"?: string | string[] | undefined; \"sec-websocket-extensions\"?: string | string[] | undefined; \"sec-websocket-key\"?: string | string[] | undefined; \"sec-websocket-protocol\"?: string | string[] | undefined; \"sec-websocket-version\"?: string | string[] | undefined; \"set-cookie\"?: string | string[] | undefined; \"strict-transport-security\"?: string | string[] | undefined; tk?: string | string[] | undefined; trailer?: string | string[] | undefined; \"transfer-encoding\"?: string | string[] | undefined; upgrade?: string | string[] | undefined; \"user-agent\"?: string | string[] | undefined; vary?: string | string[] | undefined; via?: string | string[] | undefined; \"www-authenticate\"?: string | string[] | undefined; } & { [header: string]: string | string[] | undefined; }" + "{ warning?: string | string[] | undefined; from?: string | string[] | undefined; date?: string | string[] | undefined; range?: string | string[] | undefined; location?: string | string[] | undefined; origin?: string | string[] | undefined; allow?: string | string[] | undefined; accept?: string | string[] | undefined; host?: string | string[] | undefined; \"accept-language\"?: string | string[] | undefined; \"accept-patch\"?: string | string[] | undefined; \"accept-ranges\"?: string | string[] | undefined; \"access-control-allow-credentials\"?: string | string[] | undefined; \"access-control-allow-headers\"?: string | string[] | undefined; \"access-control-allow-methods\"?: string | string[] | undefined; \"access-control-allow-origin\"?: string | string[] | undefined; \"access-control-expose-headers\"?: string | string[] | undefined; \"access-control-max-age\"?: string | string[] | undefined; \"access-control-request-headers\"?: string | string[] | undefined; \"access-control-request-method\"?: string | string[] | undefined; age?: string | string[] | undefined; \"alt-svc\"?: string | string[] | undefined; authorization?: string | string[] | undefined; \"cache-control\"?: string | string[] | undefined; connection?: string | string[] | undefined; \"content-disposition\"?: string | string[] | undefined; \"content-encoding\"?: string | string[] | undefined; \"content-language\"?: string | string[] | undefined; \"content-length\"?: string | string[] | undefined; \"content-location\"?: string | string[] | undefined; \"content-range\"?: string | string[] | undefined; \"content-type\"?: string | string[] | undefined; cookie?: string | string[] | undefined; etag?: string | string[] | undefined; expect?: string | string[] | undefined; expires?: string | string[] | undefined; forwarded?: string | string[] | undefined; \"if-match\"?: string | string[] | undefined; \"if-modified-since\"?: string | string[] | undefined; \"if-none-match\"?: string | string[] | undefined; \"if-unmodified-since\"?: string | string[] | undefined; \"last-modified\"?: string | string[] | undefined; pragma?: string | string[] | undefined; \"proxy-authenticate\"?: string | string[] | undefined; \"proxy-authorization\"?: string | string[] | undefined; \"public-key-pins\"?: string | string[] | undefined; referer?: string | string[] | undefined; \"retry-after\"?: string | string[] | undefined; \"sec-websocket-accept\"?: string | string[] | undefined; \"sec-websocket-extensions\"?: string | string[] | undefined; \"sec-websocket-key\"?: string | string[] | undefined; \"sec-websocket-protocol\"?: string | string[] | undefined; \"sec-websocket-version\"?: string | string[] | undefined; \"set-cookie\"?: string | string[] | undefined; \"strict-transport-security\"?: string | string[] | undefined; tk?: string | string[] | undefined; trailer?: string | string[] | undefined; \"transfer-encoding\"?: string | string[] | undefined; upgrade?: string | string[] | undefined; \"user-agent\"?: string | string[] | undefined; vary?: string | string[] | undefined; via?: string | string[] | undefined; \"www-authenticate\"?: string | string[] | undefined; } & { [header: string]: string | string[] | undefined; }" ], "path": "src/core/server/http/router/headers.ts", "deprecated": false, @@ -9670,6 +9726,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -9742,7 +9802,7 @@ "\nSet of well-known HTTP headers." ], "signature": [ - "\"from\" | \"date\" | \"range\" | \"warning\" | \"location\" | \"origin\" | \"allow\" | \"accept\" | \"host\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"etag\" | \"expect\" | \"expires\" | \"forwarded\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"www-authenticate\"" + "\"warning\" | \"from\" | \"date\" | \"range\" | \"location\" | \"origin\" | \"allow\" | \"accept\" | \"host\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"etag\" | \"expect\" | \"expires\" | \"forwarded\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"www-authenticate\"" ], "path": "src/core/server/http/router/headers.ts", "deprecated": false, @@ -9864,6 +9924,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -10016,6 +10080,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -10190,6 +10258,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -10363,6 +10435,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -10537,6 +10613,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -10811,6 +10891,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -10985,6 +11069,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -11318,6 +11406,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -11374,7 +11466,9 @@ }, ") => ", "KibanaResponse", - "; }) => Context[ContextName] | Promise" + "; }) => ", + "MaybePromise", + ">" ], "path": "src/core/server/http/types.ts", "deprecated": false, @@ -11535,6 +11629,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -11759,6 +11857,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -11941,6 +12043,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -12158,7 +12264,7 @@ "\nHttp response headers to set." ], "signature": [ - "Record<\"from\" | \"date\" | \"range\" | \"warning\" | \"location\" | \"origin\" | \"allow\" | \"accept\" | \"host\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"etag\" | \"expect\" | \"expires\" | \"forwarded\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"www-authenticate\", string | string[]> | Record" + "Record<\"warning\" | \"from\" | \"date\" | \"range\" | \"location\" | \"origin\" | \"allow\" | \"accept\" | \"host\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"etag\" | \"expect\" | \"expires\" | \"forwarded\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"www-authenticate\", string | string[]> | Record" ], "path": "src/core/server/http/router/headers.ts", "deprecated": false, @@ -12362,6 +12468,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -12586,6 +12696,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", diff --git a/api_docs/core_http.mdx b/api_docs/core_http.mdx index 394a7c613118c..954a5b1421f89 100644 --- a/api_docs/core_http.mdx +++ b/api_docs/core_http.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/core-http title: "core.http" image: https://source.unsplash.com/400x175/?github summary: API docs for the core.http plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core.http'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2497 | 15 | 971 | 33 | +| 2524 | 15 | 977 | 33 | ## Client diff --git a/api_docs/core_saved_objects.devdocs.json b/api_docs/core_saved_objects.devdocs.json index 08b910c7268f8..ba6118416a1e1 100644 --- a/api_docs/core_saved_objects.devdocs.json +++ b/api_docs/core_saved_objects.devdocs.json @@ -9895,6 +9895,21 @@ "path": "src/core/server/saved_objects/service/lib/collect_multi_namespace_references.ts", "deprecated": false }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectReferenceWithContext.originId", + "type": "string", + "tags": [], + "label": "originId", + "description": [ + "The origin ID of the referenced object (if it has one)" + ], + "signature": [ + "string | undefined" + ], + "path": "src/core/server/saved_objects/service/lib/collect_multi_namespace_references.ts", + "deprecated": false + }, { "parentPluginId": "core", "id": "def-server.SavedObjectReferenceWithContext.spaces", @@ -9954,6 +9969,21 @@ ], "path": "src/core/server/saved_objects/service/lib/collect_multi_namespace_references.ts", "deprecated": false + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectReferenceWithContext.spacesWithMatchingOrigins", + "type": "Array", + "tags": [], + "label": "spacesWithMatchingOrigins", + "description": [ + "The space(s) that objects matching this origin exist in (including this one)" + ], + "signature": [ + "string[] | undefined" + ], + "path": "src/core/server/saved_objects/service/lib/collect_multi_namespace_references.ts", + "deprecated": false } ], "initialIsOpen": false diff --git a/api_docs/core_saved_objects.mdx b/api_docs/core_saved_objects.mdx index 43c89a9e03e2f..3d2ddcc47ed8a 100644 --- a/api_docs/core_saved_objects.mdx +++ b/api_docs/core_saved_objects.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/core-savedObjects title: "core.savedObjects" image: https://source.unsplash.com/400x175/?github summary: API docs for the core.savedObjects plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core.savedObjects'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2497 | 15 | 971 | 33 | +| 2524 | 15 | 977 | 33 | ## Client diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index d100081f7b272..3d1c022b25501 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github summary: API docs for the customIntegrations plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'customIntegrations'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/dashboard.devdocs.json b/api_docs/dashboard.devdocs.json index a7a90e41d4b05..840d4d1eee1e8 100644 --- a/api_docs/dashboard.devdocs.json +++ b/api_docs/dashboard.devdocs.json @@ -1219,7 +1219,13 @@ "label": "controlGroupInput", "description": [], "signature": [ - "DashboardContainerControlGroupInput", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.PersistableControlGroupInput", + "text": "PersistableControlGroupInput" + }, " | undefined" ], "path": "src/plugins/dashboard/public/types.ts", @@ -1952,7 +1958,13 @@ "description": [], "signature": [ "Omit<", - "RawControlGroupAttributes", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.RawControlGroupAttributes", + "text": "RawControlGroupAttributes" + }, ", \"id\"> | undefined" ], "path": "src/plugins/dashboard/public/saved_dashboards/saved_dashboard.ts", @@ -2079,7 +2091,7 @@ "section": "def-common.RawSavedDashboardPanel730ToLatest", "text": "RawSavedDashboardPanel730ToLatest" }, - ", \"type\" | \"title\" | \"panelIndex\" | \"gridData\" | \"version\" | \"embeddableConfig\" | \"panelRefName\"> & { readonly id?: string | undefined; readonly type: string; }" + ", \"title\" | \"type\" | \"panelIndex\" | \"gridData\" | \"version\" | \"embeddableConfig\" | \"panelRefName\"> & { readonly id?: string | undefined; readonly type: string; }" ], "path": "src/plugins/dashboard/common/types.ts", "deprecated": false, @@ -2431,78 +2443,6 @@ "common": { "classes": [], "functions": [ - { - "parentPluginId": "dashboard", - "id": "def-common.controlGroupInputToRawAttributes", - "type": "Function", - "tags": [], - "label": "controlGroupInputToRawAttributes", - "description": [], - "signature": [ - "(controlGroupInput: Omit<", - { - "pluginId": "controls", - "scope": "common", - "docId": "kibControlsPluginApi", - "section": "def-common.ControlGroupInput", - "text": "ControlGroupInput" - }, - ", \"id\">) => ", - "RawControlGroupAttributes" - ], - "path": "src/plugins/dashboard/common/embeddable/dashboard_control_group.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "dashboard", - "id": "def-common.controlGroupInputToRawAttributes.$1", - "type": "Object", - "tags": [], - "label": "controlGroupInput", - "description": [], - "signature": [ - "Omit<", - { - "pluginId": "controls", - "scope": "common", - "docId": "kibControlsPluginApi", - "section": "def-common.ControlGroupInput", - "text": "ControlGroupInput" - }, - ", \"id\">" - ], - "path": "src/plugins/dashboard/common/embeddable/dashboard_control_group.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "dashboard", - "id": "def-common.getDefaultDashboardControlGroupInput", - "type": "Function", - "tags": [], - "label": "getDefaultDashboardControlGroupInput", - "description": [], - "signature": [ - "() => Omit<", - { - "pluginId": "controls", - "scope": "common", - "docId": "kibControlsPluginApi", - "section": "def-common.ControlGroupInput", - "text": "ControlGroupInput" - }, - ", \"id\">" - ], - "path": "src/plugins/dashboard/common/embeddable/dashboard_control_group.ts", - "deprecated": false, - "returnComment": [], - "children": [], - "initialIsOpen": false - }, { "parentPluginId": "dashboard", "id": "def-common.migratePanelsTo730", @@ -2677,118 +2617,6 @@ ], "returnComment": [], "initialIsOpen": false - }, - { - "parentPluginId": "dashboard", - "id": "def-common.rawAttributesToControlGroupInput", - "type": "Function", - "tags": [], - "label": "rawAttributesToControlGroupInput", - "description": [], - "signature": [ - "(rawControlGroupAttributes: ", - "RawControlGroupAttributes", - ") => Omit<", - { - "pluginId": "controls", - "scope": "common", - "docId": "kibControlsPluginApi", - "section": "def-common.ControlGroupInput", - "text": "ControlGroupInput" - }, - ", \"id\"> | undefined" - ], - "path": "src/plugins/dashboard/common/embeddable/dashboard_control_group.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "dashboard", - "id": "def-common.rawAttributesToControlGroupInput.$1", - "type": "CompoundType", - "tags": [], - "label": "rawControlGroupAttributes", - "description": [], - "signature": [ - "RawControlGroupAttributes" - ], - "path": "src/plugins/dashboard/common/embeddable/dashboard_control_group.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "dashboard", - "id": "def-common.rawAttributesToSerializable", - "type": "Function", - "tags": [], - "label": "rawAttributesToSerializable", - "description": [], - "signature": [ - "(rawControlGroupAttributes: Omit<", - "RawControlGroupAttributes", - ", \"id\">) => ", - "SerializableRecord" - ], - "path": "src/plugins/dashboard/common/embeddable/dashboard_control_group.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "dashboard", - "id": "def-common.rawAttributesToSerializable.$1", - "type": "Object", - "tags": [], - "label": "rawControlGroupAttributes", - "description": [], - "signature": [ - "Omit<", - "RawControlGroupAttributes", - ", \"id\">" - ], - "path": "src/plugins/dashboard/common/embeddable/dashboard_control_group.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "dashboard", - "id": "def-common.serializableToRawAttributes", - "type": "Function", - "tags": [], - "label": "serializableToRawAttributes", - "description": [], - "signature": [ - "(serializable: ", - "SerializableRecord", - ") => Omit<", - "RawControlGroupAttributes", - ", \"type\" | \"id\">" - ], - "path": "src/plugins/dashboard/common/embeddable/dashboard_control_group.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "dashboard", - "id": "def-common.serializableToRawAttributes.$1", - "type": "Object", - "tags": [], - "label": "serializable", - "description": [], - "signature": [ - "SerializableRecord" - ], - "path": "src/plugins/dashboard/common/embeddable/dashboard_control_group.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false } ], "interfaces": [ @@ -2850,7 +2678,13 @@ "label": "controlGroupInput", "description": [], "signature": [ - "DashboardContainerControlGroupInput", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.PersistableControlGroupInput", + "text": "PersistableControlGroupInput" + }, " | undefined" ], "path": "src/plugins/dashboard/common/types.ts", @@ -2944,7 +2778,7 @@ "signature": [ "Pick<", "RawSavedDashboardPanel610", - ", \"columns\" | \"title\" | \"sort\" | \"panelIndex\" | \"gridData\" | \"version\"> & { readonly id: string; readonly type: string; }" + ", \"title\" | \"columns\" | \"sort\" | \"panelIndex\" | \"gridData\" | \"version\"> & { readonly id: string; readonly type: string; }" ], "path": "src/plugins/dashboard/common/types.ts", "deprecated": false, @@ -2960,7 +2794,7 @@ "signature": [ "Pick<", "RawSavedDashboardPanel620", - ", \"columns\" | \"title\" | \"sort\" | \"panelIndex\" | \"gridData\" | \"version\" | \"embeddableConfig\"> & { readonly id: string; readonly type: string; }" + ", \"title\" | \"columns\" | \"sort\" | \"panelIndex\" | \"gridData\" | \"version\" | \"embeddableConfig\"> & { readonly id: string; readonly type: string; }" ], "path": "src/plugins/dashboard/common/types.ts", "deprecated": false, @@ -2976,7 +2810,7 @@ "signature": [ "Pick<", "RawSavedDashboardPanel620", - ", \"columns\" | \"title\" | \"sort\" | \"panelIndex\" | \"gridData\" | \"version\" | \"embeddableConfig\"> & { readonly id: string; readonly type: string; }" + ", \"title\" | \"columns\" | \"sort\" | \"panelIndex\" | \"gridData\" | \"version\" | \"embeddableConfig\"> & { readonly id: string; readonly type: string; }" ], "path": "src/plugins/dashboard/common/types.ts", "deprecated": false, @@ -3014,7 +2848,7 @@ "section": "def-common.RawSavedDashboardPanel730ToLatest", "text": "RawSavedDashboardPanel730ToLatest" }, - ", \"type\" | \"title\" | \"panelIndex\" | \"gridData\" | \"version\" | \"embeddableConfig\" | \"panelRefName\"> & { readonly id?: string | undefined; readonly type: string; }" + ", \"title\" | \"type\" | \"panelIndex\" | \"gridData\" | \"version\" | \"embeddableConfig\" | \"panelRefName\"> & { readonly id?: string | undefined; readonly type: string; }" ], "path": "src/plugins/dashboard/common/types.ts", "deprecated": false, @@ -3030,7 +2864,7 @@ "signature": [ "Pick<", "RawSavedDashboardPanelTo60", - ", \"columns\" | \"title\" | \"sort\" | \"size_x\" | \"size_y\" | \"row\" | \"col\" | \"panelIndex\"> & { readonly id: string; readonly type: string; }" + ", \"title\" | \"columns\" | \"sort\" | \"size_x\" | \"size_y\" | \"row\" | \"col\" | \"panelIndex\"> & { readonly id: string; readonly type: string; }" ], "path": "src/plugins/dashboard/common/types.ts", "deprecated": false, diff --git a/api_docs/dashboard.mdx b/api_docs/dashboard.mdx index d0f5a00bab677..b7d6084864327 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github summary: API docs for the dashboard plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboard'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-prese | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 151 | 0 | 149 | 14 | +| 142 | 0 | 140 | 12 | ## Client diff --git a/api_docs/dashboard_enhanced.mdx b/api_docs/dashboard_enhanced.mdx index 532dc65f407b6..458cdf96fef07 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github summary: API docs for the dashboardEnhanced plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/data.devdocs.json b/api_docs/data.devdocs.json index 75239e090a139..62c04ae8d5d64 100644 --- a/api_docs/data.devdocs.json +++ b/api_docs/data.devdocs.json @@ -2395,7 +2395,7 @@ "section": "def-public.PluginInitializerContext", "text": "PluginInitializerContext" }, - "; }>; }>; autocomplete: Readonly<{} & { querySuggestions: Readonly<{} & { enabled: boolean; }>; valueSuggestions: Readonly<{} & { timeout: moment.Duration; enabled: boolean; tiers: string[]; terminateAfter: moment.Duration; }>; }>; }>>" + "; }>; }>; }>>" ], "path": "src/plugins/data/public/plugin.ts", "deprecated": false, @@ -2731,26 +2731,6 @@ "plugin": "dataViewEditor", "path": "src/plugins/data_view_editor/public/open_editor.tsx" }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/hooks/update_kuery_string.ts" - }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/hooks/update_kuery_string.ts" - }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx" - }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx" - }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx" - }, { "plugin": "maps", "path": "x-pack/plugins/maps/public/classes/tooltips/es_tooltip_property.test.ts" @@ -3265,6 +3245,96 @@ "children": [], "initialIsOpen": false }, + { + "parentPluginId": "data", + "id": "def-public.NowProvider", + "type": "Class", + "tags": [], + "label": "NowProvider", + "description": [ + "\nUsed to synchronize time between parallel searches with relative time range that rely on `now`." + ], + "path": "src/plugins/data/public/now_provider/now_provider.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-public.NowProvider.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "src/plugins/data/public/now_provider/now_provider.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "data", + "id": "def-public.NowProvider.get", + "type": "Function", + "tags": [], + "label": "get", + "description": [], + "signature": [ + "() => Date" + ], + "path": "src/plugins/data/public/now_provider/now_provider.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "data", + "id": "def-public.NowProvider.set", + "type": "Function", + "tags": [], + "label": "set", + "description": [], + "signature": [ + "(now: Date) => void" + ], + "path": "src/plugins/data/public/now_provider/now_provider.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-public.NowProvider.set.$1", + "type": "Object", + "tags": [], + "label": "now", + "description": [], + "signature": [ + "Date" + ], + "path": "src/plugins/data/public/now_provider/now_provider.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "data", + "id": "def-public.NowProvider.reset", + "type": "Function", + "tags": [], + "label": "reset", + "description": [], + "signature": [ + "() => void" + ], + "path": "src/plugins/data/public/now_provider/now_provider.ts", + "deprecated": false, + "children": [], + "returnComment": [] + } + ], + "initialIsOpen": false + }, { "parentPluginId": "data", "id": "def-public.OptionedParamType", @@ -7626,6 +7696,50 @@ "plugin": "dataViews", "path": "src/plugins/data_views/common/data_views/data_view.ts" }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts" + }, { "plugin": "unifiedSearch", "path": "src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts" @@ -7660,31 +7774,27 @@ }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" + "path": "src/plugins/unified_search/server/autocomplete/terms_enum.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" + "path": "src/plugins/unified_search/server/autocomplete/terms_enum.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" + "path": "src/plugins/unified_search/server/autocomplete/terms_agg.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/server/utils.ts" + "path": "src/plugins/unified_search/server/autocomplete/terms_agg.ts" }, { - "plugin": "dataViews", - "path": "src/plugins/data_views/server/utils.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/server/autocomplete/terms_agg.ts" }, { - "plugin": "dataViews", - "path": "src/plugins/data_views/server/utils.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/server/autocomplete/terms_agg.ts" }, { "plugin": "unifiedSearch", @@ -7711,24 +7821,28 @@ "path": "src/plugins/unified_search/public/filter_bar/filter_editor/value_input_type.tsx" }, { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/utils.test.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" }, { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/utils.test.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" }, { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/fields/fields.mocks.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" }, { "plugin": "dataViews", - "path": "src/plugins/data_views/common/fields/fields.mocks.ts" + "path": "src/plugins/data_views/common/utils.test.ts" }, { "plugin": "dataViews", - "path": "src/plugins/data_views/common/fields/fields.mocks.ts" + "path": "src/plugins/data_views/common/utils.test.ts" } ], "children": [ @@ -8028,155 +8142,31 @@ }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/query_string_input.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/query_string_input.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/query_string_input.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/query_string_input.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/query_string_input.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/components/kuery_bar/with_kuery_autocompletion.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/components/kuery_bar/with_kuery_autocompletion.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/components/kuery_bar/index.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/components/kuery_bar/index.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/lib/kuery.ts" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/lib/kuery.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/phrase_suggestor.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/phrase_suggestor.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_item.tsx" + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_item.tsx" + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_bar.tsx" + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_bar.tsx" + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/search_bar/search_bar.tsx" + "path": "src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/search_bar/search_bar.tsx" + "path": "src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/apply_filters/apply_filter_popover_content.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/apply_filters/apply_filter_popover_content.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/apply_filters/apply_filters_popover.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/apply_filters/apply_filters_popover.tsx" - }, - { - "plugin": "stackAlerts", - "path": "x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx" - }, - { - "plugin": "stackAlerts", - "path": "x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx" + "path": "src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts" } ], "children": [ @@ -9581,7 +9571,7 @@ "label": "AggConfigOptions", "description": [], "signature": [ - "{ type: ", + "{ id?: string | undefined; type: ", { "pluginId": "data", "scope": "common", @@ -9589,7 +9579,7 @@ "section": "def-common.IAggType", "text": "IAggType" }, - "; id?: string | undefined; enabled?: boolean | undefined; params?: {} | ", + "; enabled?: boolean | undefined; params?: {} | ", "SerializableRecord", " | undefined; schema?: string | undefined; }" ], @@ -10727,14 +10717,6 @@ "plugin": "dataViews", "path": "src/plugins/data_views/public/index.ts" }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/fetch_index_patterns.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/fetch_index_patterns.ts" - }, { "plugin": "unifiedSearch", "path": "src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx" @@ -11119,12 +11101,60 @@ "removeBy": "8.1", "references": [ { - "plugin": "dataEnhanced", - "path": "x-pack/plugins/data_enhanced/server/search/session/types.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts" }, { - "plugin": "dataEnhanced", - "path": "x-pack/plugins/data_enhanced/server/search/session/types.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.test.ts" + }, + { + "plugin": "dataEnhanced", + "path": "x-pack/plugins/data_enhanced/server/search/session/types.ts" + }, + { + "plugin": "dataEnhanced", + "path": "x-pack/plugins/data_enhanced/server/search/session/types.ts" }, { "plugin": "dataEnhanced", @@ -11182,6 +11212,20 @@ "references": [], "initialIsOpen": false }, + { + "parentPluginId": "data", + "id": "def-public.NowProviderInternalContract", + "type": "Type", + "tags": [], + "label": "NowProviderInternalContract", + "description": [], + "signature": [ + "{ get: () => Date; set: (now: Date) => void; reset: () => void; }" + ], + "path": "src/plugins/data/public/now_provider/now_provider.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "data", "id": "def-public.ParsedInterval", @@ -12237,8 +12281,8 @@ "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.IIndexPattern", - "text": "IIndexPattern" + "section": "def-common.DataView", + "text": "DataView" }, "[]) => string" ], @@ -12275,8 +12319,8 @@ "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.IIndexPattern", - "text": "IIndexPattern" + "section": "def-common.DataView", + "text": "DataView" }, "[]" ], @@ -12560,9 +12604,9 @@ "Observable", "; getTimeUpdate$: () => ", "Observable", - "; getRefreshIntervalUpdate$: () => ", + "; getRefreshIntervalUpdate$: () => ", "Observable", - "; getAutoRefreshFetch$: () => ", + "; getAutoRefreshFetch$: () => ", "Observable", "<", { @@ -12574,7 +12618,7 @@ }, ">; getFetch$: () => ", "Observable", - "; getTime: () => ", + "; getTime: () => ", { "pluginId": "data", "scope": "common", @@ -14725,27 +14769,6 @@ "path": "src/plugins/data/public/types.ts", "deprecated": false, "children": [ - { - "parentPluginId": "data", - "id": "def-public.DataPublicPluginSetup.autocomplete", - "type": "Object", - "tags": [], - "label": "autocomplete", - "description": [], - "signature": [ - "{ getQuerySuggestions: ", - { - "pluginId": "data", - "scope": "public", - "docId": "kibDataAutocompletePluginApi", - "section": "def-public.QuerySuggestionGetFn", - "text": "QuerySuggestionGetFn" - }, - "; getAutocompleteSettings: () => { terminateAfter: number; timeout: number; }; }" - ], - "path": "src/plugins/data/public/types.ts", - "deprecated": false - }, { "parentPluginId": "data", "id": "def-public.DataPublicPluginSetup.search", @@ -14782,7 +14805,13 @@ "text": "FilterManager" }, "; timefilter: ", - "TimefilterSetup", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.TimefilterSetup", + "text": "TimefilterSetup" + }, "; queryString: ", { "pluginId": "data", @@ -14851,31 +14880,6 @@ "path": "src/plugins/data/public/types.ts", "deprecated": false }, - { - "parentPluginId": "data", - "id": "def-public.DataPublicPluginStart.autocomplete", - "type": "Object", - "tags": [], - "label": "autocomplete", - "description": [ - "\nautocomplete service\n{@link AutocompleteStart}" - ], - "signature": [ - "{ getQuerySuggestions: ", - { - "pluginId": "data", - "scope": "public", - "docId": "kibDataAutocompletePluginApi", - "section": "def-public.QuerySuggestionGetFn", - "text": "QuerySuggestionGetFn" - }, - "; hasQuerySuggestions: (language: string) => boolean; getValueSuggestions: ", - "ValueSuggestionsGetFn", - "; }" - ], - "path": "src/plugins/data/public/types.ts", - "deprecated": false - }, { "parentPluginId": "data", "id": "def-public.DataPublicPluginStart.dataViews", @@ -14949,14 +14953,6 @@ "plugin": "graph", "path": "x-pack/plugins/graph/public/plugin.ts" }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts" @@ -14981,10 +14977,6 @@ "plugin": "stackAlerts", "path": "x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/index.tsx" }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx" - }, { "plugin": "inputControlVis", "path": "src/plugins/input_control_vis/public/control/list_control_factory.ts" @@ -15232,7 +15224,13 @@ "text": "QueryState" }, "; }>; timefilter: ", - "TimefilterSetup", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.TimefilterSetup", + "text": "TimefilterSetup" + }, "; getEsQuery: (indexPattern: ", { "pluginId": "dataViews", @@ -15352,7 +15350,7 @@ "section": "def-server.PluginInitializerContext", "text": "PluginInitializerContext" }, - "; }>; }>; autocomplete: Readonly<{} & { querySuggestions: Readonly<{} & { enabled: boolean; }>; valueSuggestions: Readonly<{} & { timeout: moment.Duration; enabled: boolean; tiers: string[]; terminateAfter: moment.Duration; }>; }>; }>>" + "; }>; }>; }>>" ], "path": "src/plugins/data/server/plugin.ts", "deprecated": false, @@ -15389,7 +15387,7 @@ }, ">, { bfetch, expressions, usageCollection, fieldFormats }: ", "DataPluginSetupDependencies", - ") => { autocomplete: { getAutocompleteSettings: () => { terminateAfter: number; timeout: number; }; }; __enhance: (enhancements: DataEnhancements) => void; search: ", + ") => { __enhance: (enhancements: DataEnhancements) => void; search: ", "ISearchSetup", "; query: { filterManager: { extract: (filters: ", "Filter", @@ -17157,26 +17155,6 @@ "plugin": "dataViewEditor", "path": "src/plugins/data_view_editor/public/open_editor.tsx" }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/hooks/update_kuery_string.ts" - }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/hooks/update_kuery_string.ts" - }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx" - }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx" - }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx" - }, { "plugin": "maps", "path": "x-pack/plugins/maps/public/classes/tooltips/es_tooltip_property.test.ts" @@ -18113,6 +18091,44 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "data", + "id": "def-server.getRequestAbortedSignal", + "type": "Function", + "tags": [], + "label": "getRequestAbortedSignal", + "description": [ + "\nA simple utility function that returns an `AbortSignal` corresponding to an `AbortController`\nwhich aborts when the given request is aborted." + ], + "signature": [ + "(aborted$: ", + "Observable", + ") => AbortSignal" + ], + "path": "src/plugins/data/server/lib/get_request_aborted_signal.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-server.getRequestAbortedSignal.$1", + "type": "Object", + "tags": [], + "label": "aborted$", + "description": [ + "The observable of abort events (usually `request.events.aborted$`)" + ], + "signature": [ + "Observable", + "" + ], + "path": "src/plugins/data/server/lib/get_request_aborted_signal.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "data", "id": "def-server.getTime", @@ -18463,552 +18479,103 @@ }, { "parentPluginId": "data", - "id": "def-server.IFieldType", + "id": "def-server.ISearchOptions", "type": "Interface", - "tags": [ - "deprecated" - ], - "label": "IFieldType", + "tags": [], + "label": "ISearchOptions", "description": [], - "signature": [ - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.IFieldType", - "text": "IFieldType" - }, - " extends ", - "DataViewFieldBase" - ], - "path": "src/plugins/data_views/common/fields/types.ts", - "deprecated": true, - "removeBy": "8.2", - "references": [ + "path": "src/plugins/data/common/search/types.ts", + "deprecated": false, + "children": [ { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/fields/utils.ts" + "parentPluginId": "data", + "id": "def-server.ISearchOptions.abortSignal", + "type": "Object", + "tags": [], + "label": "abortSignal", + "description": [ + "\nAn `AbortSignal` that allows the caller of `search` to abort a search request." + ], + "signature": [ + "AbortSignal | undefined" + ], + "path": "src/plugins/data/common/search/types.ts", + "deprecated": false }, { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/fields/utils.ts" + "parentPluginId": "data", + "id": "def-server.ISearchOptions.strategy", + "type": "string", + "tags": [], + "label": "strategy", + "description": [ + "\nUse this option to force using a specific server side search strategy. Leave empty to use the default strategy." + ], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data/common/search/types.ts", + "deprecated": false }, { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/fields/data_view_field.ts" + "parentPluginId": "data", + "id": "def-server.ISearchOptions.legacyHitsTotal", + "type": "CompoundType", + "tags": [], + "label": "legacyHitsTotal", + "description": [ + "\nRequest the legacy format for the total number of hits. If sending `rest_total_hits_as_int` to\nsomething other than `true`, this should be set to `false`." + ], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/data/common/search/types.ts", + "deprecated": false }, { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/fields/data_view_field.ts" + "parentPluginId": "data", + "id": "def-server.ISearchOptions.sessionId", + "type": "string", + "tags": [], + "label": "sessionId", + "description": [ + "\nA session ID, grouping multiple search requests into a single session." + ], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data/common/search/types.ts", + "deprecated": false }, { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/fields/field_list.ts" + "parentPluginId": "data", + "id": "def-server.ISearchOptions.isStored", + "type": "CompoundType", + "tags": [], + "label": "isStored", + "description": [ + "\nWhether the session is already saved (i.e. sent to background)" + ], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/data/common/search/types.ts", + "deprecated": false }, { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/fields/field_list.ts" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/fields/field_list.ts" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/fields/field_list.ts" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/types.ts" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/types.ts" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/types.ts" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/types.ts" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/index.ts" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/data_views/data_view.ts" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/data_views/data_view.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/phrase_suggestor.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/phrase_suggestor.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/range_value_input.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/range_value_input.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/server/utils.ts" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/server/utils.ts" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/server/utils.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_operators.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_operators.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_operators.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_operators.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/value_input_type.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/value_input_type.tsx" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/utils.test.ts" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/utils.test.ts" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/fields/fields.mocks.ts" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/fields/fields.mocks.ts" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/fields/fields.mocks.ts" - } - ], - "children": [ - { - "parentPluginId": "data", - "id": "def-server.IFieldType.count", - "type": "number", - "tags": [], - "label": "count", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "src/plugins/data_views/common/fields/types.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-server.IFieldType.esTypes", - "type": "Array", - "tags": [], - "label": "esTypes", - "description": [], - "signature": [ - "string[] | undefined" - ], - "path": "src/plugins/data_views/common/fields/types.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-server.IFieldType.aggregatable", - "type": "CompoundType", - "tags": [], - "label": "aggregatable", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/data_views/common/fields/types.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-server.IFieldType.filterable", - "type": "CompoundType", - "tags": [], - "label": "filterable", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/data_views/common/fields/types.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-server.IFieldType.searchable", - "type": "CompoundType", - "tags": [], - "label": "searchable", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/data_views/common/fields/types.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-server.IFieldType.sortable", - "type": "CompoundType", - "tags": [], - "label": "sortable", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/data_views/common/fields/types.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-server.IFieldType.visualizable", - "type": "CompoundType", - "tags": [], - "label": "visualizable", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/data_views/common/fields/types.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-server.IFieldType.readFromDocValues", - "type": "CompoundType", - "tags": [], - "label": "readFromDocValues", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/data_views/common/fields/types.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-server.IFieldType.displayName", - "type": "string", - "tags": [], - "label": "displayName", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/data_views/common/fields/types.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-server.IFieldType.customLabel", - "type": "string", - "tags": [], - "label": "customLabel", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/data_views/common/fields/types.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-server.IFieldType.format", - "type": "Any", - "tags": [], - "label": "format", - "description": [], - "signature": [ - "any" - ], - "path": "src/plugins/data_views/common/fields/types.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-server.IFieldType.toSpec", - "type": "Function", - "tags": [], - "label": "toSpec", - "description": [], - "signature": [ - "((options?: { getFormatterForField?: ((field: ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.IFieldType", - "text": "IFieldType" - }, - " | ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.FieldSpec", - "text": "FieldSpec" - }, - " | ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewField", - "text": "DataViewField" - }, - ") => ", - { - "pluginId": "fieldFormats", - "scope": "common", - "docId": "kibFieldFormatsPluginApi", - "section": "def-common.FieldFormat", - "text": "FieldFormat" - }, - ") | undefined; } | undefined) => ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.FieldSpec", - "text": "FieldSpec" - }, - ") | undefined" - ], - "path": "src/plugins/data_views/common/fields/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "data", - "id": "def-server.IFieldType.toSpec.$1", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "path": "src/plugins/data_views/common/fields/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "data", - "id": "def-server.IFieldType.toSpec.$1.getFormatterForField", - "type": "Function", - "tags": [], - "label": "getFormatterForField", - "description": [], - "signature": [ - "((field: ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.IFieldType", - "text": "IFieldType" - }, - " | ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.FieldSpec", - "text": "FieldSpec" - }, - " | ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewField", - "text": "DataViewField" - }, - ") => ", - { - "pluginId": "fieldFormats", - "scope": "common", - "docId": "kibFieldFormatsPluginApi", - "section": "def-common.FieldFormat", - "text": "FieldFormat" - }, - ") | undefined" - ], - "path": "src/plugins/data_views/common/fields/types.ts", - "deprecated": false - } - ] - } - ], - "returnComment": [] - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-server.ISearchOptions", - "type": "Interface", - "tags": [], - "label": "ISearchOptions", - "description": [], - "path": "src/plugins/data/common/search/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "data", - "id": "def-server.ISearchOptions.abortSignal", - "type": "Object", - "tags": [], - "label": "abortSignal", - "description": [ - "\nAn `AbortSignal` that allows the caller of `search` to abort a search request." - ], - "signature": [ - "AbortSignal | undefined" - ], - "path": "src/plugins/data/common/search/types.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-server.ISearchOptions.strategy", - "type": "string", - "tags": [], - "label": "strategy", - "description": [ - "\nUse this option to force using a specific server side search strategy. Leave empty to use the default strategy." - ], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/data/common/search/types.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-server.ISearchOptions.legacyHitsTotal", - "type": "CompoundType", - "tags": [], - "label": "legacyHitsTotal", - "description": [ - "\nRequest the legacy format for the total number of hits. If sending `rest_total_hits_as_int` to\nsomething other than `true`, this should be set to `false`." - ], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/data/common/search/types.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-server.ISearchOptions.sessionId", - "type": "string", - "tags": [], - "label": "sessionId", - "description": [ - "\nA session ID, grouping multiple search requests into a single session." - ], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/data/common/search/types.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-server.ISearchOptions.isStored", - "type": "CompoundType", - "tags": [], - "label": "isStored", - "description": [ - "\nWhether the session is already saved (i.e. sent to background)" - ], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/data/common/search/types.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-server.ISearchOptions.isRestore", - "type": "CompoundType", - "tags": [], - "label": "isRestore", - "description": [ - "\nWhether the session is restored (i.e. search requests should re-use the stored search IDs,\nrather than starting from scratch)" - ], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/data/common/search/types.ts", - "deprecated": false + "parentPluginId": "data", + "id": "def-server.ISearchOptions.isRestore", + "type": "CompoundType", + "tags": [], + "label": "isRestore", + "description": [ + "\nWhether the session is restored (i.e. search requests should re-use the stored search IDs,\nrather than starting from scratch)" + ], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/data/common/search/types.ts", + "deprecated": false }, { "parentPluginId": "data", @@ -19456,30 +19023,78 @@ "description": [], "signature": [ { - "pluginId": "dataViews", - "scope": "server", - "docId": "kibDataViewsPluginApi", - "section": "def-server.DataViewsServerPluginStart", - "text": "DataViewsServerPluginStart" - } - ], - "path": "src/plugins/data_views/server/types.ts", - "deprecated": false, - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-server.KueryNode", - "type": "Type", - "tags": [ - "deprecated" - ], - "label": "KueryNode", - "description": [], - "path": "src/plugins/data/common/es_query/index.ts", - "deprecated": true, - "removeBy": "8.1", - "references": [ + "pluginId": "dataViews", + "scope": "server", + "docId": "kibDataViewsPluginApi", + "section": "def-server.DataViewsServerPluginStart", + "text": "DataViewsServerPluginStart" + } + ], + "path": "src/plugins/data_views/server/types.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-server.KueryNode", + "type": "Type", + "tags": [ + "deprecated" + ], + "label": "KueryNode", + "description": [], + "path": "src/plugins/data/common/es_query/index.ts", + "deprecated": true, + "removeBy": "8.1", + "references": [ + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.test.ts" + }, { "plugin": "dataEnhanced", "path": "x-pack/plugins/data_enhanced/server/search/session/types.ts" @@ -20795,19 +20410,6 @@ "path": "src/plugins/data/server/plugin.ts", "deprecated": false, "children": [ - { - "parentPluginId": "data", - "id": "def-server.DataPluginSetup.autocomplete", - "type": "Object", - "tags": [], - "label": "autocomplete", - "description": [], - "signature": [ - "{ getAutocompleteSettings: () => { terminateAfter: number; timeout: number; }; }" - ], - "path": "src/plugins/data/server/plugin.ts", - "deprecated": false - }, { "parentPluginId": "data", "id": "def-server.DataPluginSetup.search", @@ -25044,26 +24646,6 @@ "plugin": "dataViewEditor", "path": "src/plugins/data_view_editor/public/open_editor.tsx" }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/hooks/update_kuery_string.ts" - }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/hooks/update_kuery_string.ts" - }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx" - }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx" - }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx" - }, { "plugin": "maps", "path": "x-pack/plugins/maps/public/classes/tooltips/es_tooltip_property.test.ts" @@ -29492,6 +29074,50 @@ "plugin": "dataViews", "path": "src/plugins/data_views/common/data_views/data_view.ts" }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts" + }, { "plugin": "unifiedSearch", "path": "src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts" @@ -29526,31 +29152,27 @@ }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" + "path": "src/plugins/unified_search/server/autocomplete/terms_enum.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" + "path": "src/plugins/unified_search/server/autocomplete/terms_enum.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" + "path": "src/plugins/unified_search/server/autocomplete/terms_agg.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" + "path": "src/plugins/unified_search/server/autocomplete/terms_agg.ts" }, { - "plugin": "dataViews", - "path": "src/plugins/data_views/server/utils.ts" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/server/utils.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/server/autocomplete/terms_agg.ts" }, { - "plugin": "dataViews", - "path": "src/plugins/data_views/server/utils.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/server/autocomplete/terms_agg.ts" }, { "plugin": "unifiedSearch", @@ -29577,24 +29199,28 @@ "path": "src/plugins/unified_search/public/filter_bar/filter_editor/value_input_type.tsx" }, { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/utils.test.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" }, { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/utils.test.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" }, { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/fields/fields.mocks.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" }, { "plugin": "dataViews", - "path": "src/plugins/data_views/common/fields/fields.mocks.ts" + "path": "src/plugins/data_views/common/utils.test.ts" }, { "plugin": "dataViews", - "path": "src/plugins/data_views/common/fields/fields.mocks.ts" + "path": "src/plugins/data_views/common/utils.test.ts" } ], "children": [ @@ -29894,155 +29520,31 @@ }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/query_string_input.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/query_string_input.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/query_string_input.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/query_string_input.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/query_string_input.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/components/kuery_bar/with_kuery_autocompletion.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/components/kuery_bar/with_kuery_autocompletion.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/components/kuery_bar/index.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/components/kuery_bar/index.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/lib/kuery.ts" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/lib/kuery.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/phrase_suggestor.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/phrase_suggestor.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_item.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_item.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_bar.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_bar.tsx" + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/search_bar/search_bar.tsx" + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/search_bar/search_bar.tsx" + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/apply_filters/apply_filter_popover_content.tsx" + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/apply_filters/apply_filter_popover_content.tsx" + "path": "src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/apply_filters/apply_filters_popover.tsx" + "path": "src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/apply_filters/apply_filters_popover.tsx" - }, - { - "plugin": "stackAlerts", - "path": "x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx" - }, - { - "plugin": "stackAlerts", - "path": "x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx" + "path": "src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts" } ], "children": [ @@ -32586,14 +32088,6 @@ "plugin": "dataViews", "path": "src/plugins/data_views/public/index.ts" }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/fetch_index_patterns.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/fetch_index_patterns.ts" - }, { "plugin": "unifiedSearch", "path": "src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx" @@ -32648,6 +32142,54 @@ "deprecated": true, "removeBy": "8.1", "references": [ + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.test.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.test.ts" + }, { "plugin": "dataEnhanced", "path": "x-pack/plugins/data_enhanced/server/search/session/types.ts" @@ -32815,7 +32357,7 @@ "signature": [ "Pick<", "Toast", - ", \"children\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"className\" | \"security\" | \"defaultValue\" | \"hidden\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\"> & { title?: string | ", + ", \"children\" | \"color\" | \"className\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"hidden\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\"> & { title?: string | ", { "pluginId": "core", "scope": "public", diff --git a/api_docs/data.mdx b/api_docs/data.mdx index 354f58d2afd80..a876abb895181 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github summary: API docs for the data plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3426 | 40 | 2816 | 20 | +| 3414 | 38 | 2802 | 18 | ## Client diff --git a/api_docs/data_autocomplete.devdocs.json b/api_docs/data_autocomplete.devdocs.json deleted file mode 100644 index 63229979a6082..0000000000000 --- a/api_docs/data_autocomplete.devdocs.json +++ /dev/null @@ -1,434 +0,0 @@ -{ - "id": "data.autocomplete", - "client": { - "classes": [], - "functions": [], - "interfaces": [ - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionBasic", - "type": "Interface", - "tags": [], - "label": "QuerySuggestionBasic", - "description": [], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionBasic.type", - "type": "Enum", - "tags": [], - "label": "type", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "public", - "docId": "kibDataAutocompletePluginApi", - "section": "def-public.QuerySuggestionTypes", - "text": "QuerySuggestionTypes" - } - ], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionBasic.description", - "type": "CompoundType", - "tags": [], - "label": "description", - "description": [], - "signature": [ - "string | JSX.Element | undefined" - ], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionBasic.end", - "type": "number", - "tags": [], - "label": "end", - "description": [], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionBasic.start", - "type": "number", - "tags": [], - "label": "start", - "description": [], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionBasic.text", - "type": "string", - "tags": [], - "label": "text", - "description": [], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionBasic.cursorIndex", - "type": "number", - "tags": [], - "label": "cursorIndex", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionField", - "type": "Interface", - "tags": [], - "label": "QuerySuggestionField", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "public", - "docId": "kibDataAutocompletePluginApi", - "section": "def-public.QuerySuggestionField", - "text": "QuerySuggestionField" - }, - " extends ", - { - "pluginId": "data", - "scope": "public", - "docId": "kibDataAutocompletePluginApi", - "section": "def-public.QuerySuggestionBasic", - "text": "QuerySuggestionBasic" - } - ], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionField.type", - "type": "string", - "tags": [], - "label": "type", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "public", - "docId": "kibDataAutocompletePluginApi", - "section": "def-public.QuerySuggestionTypes", - "text": "QuerySuggestionTypes" - }, - ".Field" - ], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionField.field", - "type": "Object", - "tags": [], - "label": "field", - "description": [], - "signature": [ - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.IFieldType", - "text": "IFieldType" - } - ], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionGetFnArgs", - "type": "Interface", - "tags": [], - "label": "QuerySuggestionGetFnArgs", - "description": [], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionGetFnArgs.language", - "type": "string", - "tags": [], - "label": "language", - "description": [], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionGetFnArgs.indexPatterns", - "type": "Array", - "tags": [], - "label": "indexPatterns", - "description": [], - "signature": [ - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.IIndexPattern", - "text": "IIndexPattern" - }, - "[]" - ], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionGetFnArgs.query", - "type": "string", - "tags": [], - "label": "query", - "description": [], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionGetFnArgs.selectionStart", - "type": "number", - "tags": [], - "label": "selectionStart", - "description": [], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionGetFnArgs.selectionEnd", - "type": "number", - "tags": [], - "label": "selectionEnd", - "description": [], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionGetFnArgs.signal", - "type": "Object", - "tags": [], - "label": "signal", - "description": [], - "signature": [ - "AbortSignal | undefined" - ], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionGetFnArgs.useTimeRange", - "type": "CompoundType", - "tags": [], - "label": "useTimeRange", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionGetFnArgs.boolFilter", - "type": "Any", - "tags": [], - "label": "boolFilter", - "description": [], - "signature": [ - "any" - ], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false - }, - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionGetFnArgs.method", - "type": "CompoundType", - "tags": [], - "label": "method", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataPluginApi", - "section": "def-common.ValueSuggestionsMethod", - "text": "ValueSuggestionsMethod" - }, - " | undefined" - ], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false - } - ], - "initialIsOpen": false - } - ], - "enums": [ - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionTypes", - "type": "Enum", - "tags": [], - "label": "QuerySuggestionTypes", - "description": [], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false, - "initialIsOpen": false - } - ], - "misc": [ - { - "parentPluginId": "data", - "id": "def-public.AutocompleteStart", - "type": "Type", - "tags": [], - "label": "AutocompleteStart", - "description": [], - "signature": [ - "{ getQuerySuggestions: ", - { - "pluginId": "data", - "scope": "public", - "docId": "kibDataAutocompletePluginApi", - "section": "def-public.QuerySuggestionGetFn", - "text": "QuerySuggestionGetFn" - }, - "; hasQuerySuggestions: (language: string) => boolean; getValueSuggestions: ", - "ValueSuggestionsGetFn", - "; }" - ], - "path": "src/plugins/data/public/autocomplete/autocomplete_service.ts", - "deprecated": false, - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestion", - "type": "Type", - "tags": [], - "label": "QuerySuggestion", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "public", - "docId": "kibDataAutocompletePluginApi", - "section": "def-public.QuerySuggestionBasic", - "text": "QuerySuggestionBasic" - }, - " | ", - { - "pluginId": "data", - "scope": "public", - "docId": "kibDataAutocompletePluginApi", - "section": "def-public.QuerySuggestionField", - "text": "QuerySuggestionField" - } - ], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false, - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionGetFn", - "type": "Type", - "tags": [], - "label": "QuerySuggestionGetFn", - "description": [], - "signature": [ - "(args: ", - { - "pluginId": "data", - "scope": "public", - "docId": "kibDataAutocompletePluginApi", - "section": "def-public.QuerySuggestionGetFnArgs", - "text": "QuerySuggestionGetFnArgs" - }, - ") => Promise<", - { - "pluginId": "data", - "scope": "public", - "docId": "kibDataAutocompletePluginApi", - "section": "def-public.QuerySuggestion", - "text": "QuerySuggestion" - }, - "[]> | undefined" - ], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "data", - "id": "def-public.QuerySuggestionGetFn.$1", - "type": "Object", - "tags": [], - "label": "args", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "public", - "docId": "kibDataAutocompletePluginApi", - "section": "def-public.QuerySuggestionGetFnArgs", - "text": "QuerySuggestionGetFnArgs" - } - ], - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts", - "deprecated": false - } - ], - "initialIsOpen": false - } - ], - "objects": [] - }, - "server": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - }, - "common": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - } -} \ No newline at end of file diff --git a/api_docs/data_autocomplete.mdx b/api_docs/data_autocomplete.mdx deleted file mode 100644 index 731ed5bb655e7..0000000000000 --- a/api_docs/data_autocomplete.mdx +++ /dev/null @@ -1,33 +0,0 @@ ---- -id: kibDataAutocompletePluginApi -slug: /kibana-dev-docs/api/data-autocomplete -title: "data.autocomplete" -image: https://source.unsplash.com/400x175/?github -summary: API docs for the data.autocomplete plugin -date: 2022-04-05 -tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.autocomplete'] -warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. ---- -import dataAutocompleteObj from './data_autocomplete.devdocs.json'; - -Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. - -Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) for questions regarding this plugin. - -**Code health stats** - -| Public API count | Any count | Items lacking comments | Missing exports | -|-------------------|-----------|------------------------|-----------------| -| 3426 | 40 | 2816 | 20 | - -## Client - -### Interfaces - - -### Enums - - -### Consts, variables and types - - diff --git a/api_docs/data_enhanced.mdx b/api_docs/data_enhanced.mdx index 03a5d056398c2..6eb3ac5dc589d 100644 --- a/api_docs/data_enhanced.mdx +++ b/api_docs/data_enhanced.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/dataEnhanced title: "dataEnhanced" image: https://source.unsplash.com/400x175/?github summary: API docs for the dataEnhanced plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataEnhanced'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/data_query.devdocs.json b/api_docs/data_query.devdocs.json index 4cccb61a48547..db5f5e436135d 100644 --- a/api_docs/data_query.devdocs.json +++ b/api_docs/data_query.devdocs.json @@ -863,6 +863,347 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "data", + "id": "def-public.QueryService", + "type": "Class", + "tags": [], + "label": "QueryService", + "description": [], + "path": "src/plugins/data/public/query/query_service.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-public.QueryService.filterManager", + "type": "Object", + "tags": [], + "label": "filterManager", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.FilterManager", + "text": "FilterManager" + } + ], + "path": "src/plugins/data/public/query/query_service.ts", + "deprecated": false + }, + { + "parentPluginId": "data", + "id": "def-public.QueryService.timefilter", + "type": "Object", + "tags": [], + "label": "timefilter", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.TimefilterSetup", + "text": "TimefilterSetup" + } + ], + "path": "src/plugins/data/public/query/query_service.ts", + "deprecated": false + }, + { + "parentPluginId": "data", + "id": "def-public.QueryService.queryStringManager", + "type": "Object", + "tags": [], + "label": "queryStringManager", + "description": [], + "signature": [ + "{ getDefaultQuery: () => { query: string; language: any; }; formatQuery: (query: string | ", + "Query", + " | undefined) => ", + "Query", + "; getUpdates$: () => ", + "Observable", + "<", + "Query", + ">; getQuery: () => ", + "Query", + "; setQuery: (query: ", + "Query", + ") => void; clearQuery: () => void; }" + ], + "path": "src/plugins/data/public/query/query_service.ts", + "deprecated": false + }, + { + "parentPluginId": "data", + "id": "def-public.QueryService.state$", + "type": "Object", + "tags": [], + "label": "state$", + "description": [], + "signature": [ + "Observable", + "<{ changes: ", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.QueryStateChange", + "text": "QueryStateChange" + }, + "; state: ", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.QueryState", + "text": "QueryState" + }, + "; }>" + ], + "path": "src/plugins/data/public/query/query_service.ts", + "deprecated": false + }, + { + "parentPluginId": "data", + "id": "def-public.QueryService.setup", + "type": "Function", + "tags": [], + "label": "setup", + "description": [], + "signature": [ + "({ storage, uiSettings, nowProvider }: QueryServiceSetupDependencies) => { filterManager: ", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.FilterManager", + "text": "FilterManager" + }, + "; timefilter: ", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.TimefilterSetup", + "text": "TimefilterSetup" + }, + "; queryString: ", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.QueryStringContract", + "text": "QueryStringContract" + }, + "; state$: ", + "Observable", + "<{ changes: ", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.QueryStateChange", + "text": "QueryStateChange" + }, + "; state: ", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.QueryState", + "text": "QueryState" + }, + "; }>; }" + ], + "path": "src/plugins/data/public/query/query_service.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-public.QueryService.setup.$1", + "type": "Object", + "tags": [], + "label": "{ storage, uiSettings, nowProvider }", + "description": [], + "signature": [ + "QueryServiceSetupDependencies" + ], + "path": "src/plugins/data/public/query/query_service.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "data", + "id": "def-public.QueryService.start", + "type": "Function", + "tags": [], + "label": "start", + "description": [], + "signature": [ + "({ storage, uiSettings, http }: QueryServiceStartDependencies) => { addToQueryLog: (appName: string, { language, query }: ", + "Query", + ") => void; filterManager: ", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.FilterManager", + "text": "FilterManager" + }, + "; queryString: ", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.QueryStringContract", + "text": "QueryStringContract" + }, + "; savedQueries: { createQuery: (attributes: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.SavedQueryAttributes", + "text": "SavedQueryAttributes" + }, + ", { overwrite }?: { overwrite?: boolean | undefined; }) => Promise<", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.SavedQuery", + "text": "SavedQuery" + }, + ">; updateQuery: (id: string, attributes: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.SavedQueryAttributes", + "text": "SavedQueryAttributes" + }, + ") => Promise<", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.SavedQuery", + "text": "SavedQuery" + }, + ">; getAllSavedQueries: () => Promise<", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.SavedQuery", + "text": "SavedQuery" + }, + "[]>; findSavedQueries: (search?: string, perPage?: number, page?: number) => Promise<{ total: number; queries: ", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.SavedQuery", + "text": "SavedQuery" + }, + "[]; }>; getSavedQuery: (id: string) => Promise<", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.SavedQuery", + "text": "SavedQuery" + }, + ">; deleteSavedQuery: (id: string) => Promise<{}>; getSavedQueryCount: () => Promise; }; state$: ", + "Observable", + "<{ changes: ", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.QueryStateChange", + "text": "QueryStateChange" + }, + "; state: ", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.QueryState", + "text": "QueryState" + }, + "; }>; timefilter: ", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.TimefilterSetup", + "text": "TimefilterSetup" + }, + "; getEsQuery: (indexPattern: ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.IndexPattern", + "text": "IndexPattern" + }, + ", timeRange?: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, + " | undefined) => { bool: ", + "BoolQuery", + "; }; }" + ], + "path": "src/plugins/data/public/query/query_service.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-public.QueryService.start.$1", + "type": "Object", + "tags": [], + "label": "{ storage, uiSettings, http }", + "description": [], + "signature": [ + "QueryServiceStartDependencies" + ], + "path": "src/plugins/data/public/query/query_service.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "data", + "id": "def-public.QueryService.stop", + "type": "Function", + "tags": [], + "label": "stop", + "description": [], + "signature": [ + "() => void" + ], + "path": "src/plugins/data/public/query/query_service.ts", + "deprecated": false, + "children": [], + "returnComment": [] + } + ], + "initialIsOpen": false + }, { "parentPluginId": "data", "id": "def-public.TimeHistory", @@ -1118,7 +1459,13 @@ "text": "QueryState" }, "; }>; timefilter: ", - "TimefilterSetup", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.TimefilterSetup", + "text": "TimefilterSetup" + }, "; getEsQuery: (indexPattern: ", { "pluginId": "dataViews", @@ -1146,7 +1493,13 @@ "text": "FilterManager" }, "; timefilter: ", - "TimefilterSetup", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.TimefilterSetup", + "text": "TimefilterSetup" + }, "; queryString: ", { "pluginId": "data", @@ -1289,7 +1642,13 @@ "text": "QueryState" }, "; }>; timefilter: ", - "TimefilterSetup", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.TimefilterSetup", + "text": "TimefilterSetup" + }, "; getEsQuery: (indexPattern: ", { "pluginId": "dataViews", @@ -1317,7 +1676,13 @@ "text": "FilterManager" }, "; timefilter: ", - "TimefilterSetup", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.TimefilterSetup", + "text": "TimefilterSetup" + }, "; queryString: ", { "pluginId": "data", @@ -1780,8 +2145,8 @@ "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.IIndexPattern", - "text": "IIndexPattern" + "section": "def-common.DataView", + "text": "DataView" }, "[]) => string" ], @@ -1814,8 +2179,8 @@ "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.IIndexPattern", - "text": "IIndexPattern" + "section": "def-common.DataView", + "text": "DataView" }, "[]" ], @@ -1842,16 +2207,16 @@ "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.IIndexPattern", - "text": "IIndexPattern" + "section": "def-common.DataView", + "text": "DataView" }, "[]) => ", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.IIndexPattern", - "text": "IIndexPattern" + "section": "def-common.DataView", + "text": "DataView" }, " | undefined" ], @@ -1884,8 +2249,8 @@ "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.IIndexPattern", - "text": "IIndexPattern" + "section": "def-common.DataView", + "text": "DataView" }, "[]" ], @@ -2036,7 +2401,13 @@ "text": "QueryState" }, "; }>; timefilter: ", - "TimefilterSetup", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.TimefilterSetup", + "text": "TimefilterSetup" + }, "; getEsQuery: (indexPattern: ", { "pluginId": "dataViews", @@ -2064,7 +2435,13 @@ "text": "FilterManager" }, "; timefilter: ", - "TimefilterSetup", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.TimefilterSetup", + "text": "TimefilterSetup" + }, "; queryString: ", { "pluginId": "data", @@ -2205,7 +2582,13 @@ "text": "QueryState" }, "; }>; timefilter: ", - "TimefilterSetup", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.TimefilterSetup", + "text": "TimefilterSetup" + }, "; getEsQuery: (indexPattern: ", { "pluginId": "dataViews", @@ -2233,7 +2616,13 @@ "text": "FilterManager" }, "; timefilter: ", - "TimefilterSetup", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.TimefilterSetup", + "text": "TimefilterSetup" + }, "; queryString: ", { "pluginId": "data", @@ -2740,6 +3129,211 @@ } ], "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-public.TimefilterSetup", + "type": "Interface", + "tags": [], + "label": "TimefilterSetup", + "description": [], + "path": "src/plugins/data/public/query/timefilter/timefilter_service.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-public.TimefilterSetup.timefilter", + "type": "Object", + "tags": [], + "label": "timefilter", + "description": [], + "signature": [ + "{ isTimeRangeSelectorEnabled: () => boolean; isAutoRefreshSelectorEnabled: () => boolean; isTimeTouched: () => boolean; isRefreshIntervalTouched: () => boolean; getEnabledUpdated$: () => ", + "Observable", + "; getTimeUpdate$: () => ", + "Observable", + "; getRefreshIntervalUpdate$: () => ", + "Observable", + "; getAutoRefreshFetch$: () => ", + "Observable", + "<", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.AutoRefreshDoneFn", + "text": "AutoRefreshDoneFn" + }, + ">; getFetch$: () => ", + "Observable", + "; getTime: () => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, + "; getAbsoluteTime: () => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, + "; setTime: (time: ", + "InputTimeRange", + ") => void; getRefreshInterval: () => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.RefreshInterval", + "text": "RefreshInterval" + }, + "; setRefreshInterval: (refreshInterval: Partial<", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.RefreshInterval", + "text": "RefreshInterval" + }, + ">) => void; createFilter: (indexPattern: ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.IIndexPattern", + "text": "IIndexPattern" + }, + ", timeRange?: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, + " | undefined) => ", + "RangeFilter", + " | ", + "ScriptedRangeFilter", + " | MatchAllRangeFilter | undefined; createRelativeFilter: (indexPattern: ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.IIndexPattern", + "text": "IIndexPattern" + }, + ", timeRange?: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, + " | undefined) => ", + "RangeFilter", + " | ", + "ScriptedRangeFilter", + " | MatchAllRangeFilter | undefined; getBounds: () => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRangeBounds", + "text": "TimeRangeBounds" + }, + "; calculateBounds: (timeRange: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, + ") => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRangeBounds", + "text": "TimeRangeBounds" + }, + "; getActiveBounds: () => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRangeBounds", + "text": "TimeRangeBounds" + }, + " | undefined; enableTimeRangeSelector: () => void; disableTimeRangeSelector: () => void; enableAutoRefreshSelector: () => void; disableAutoRefreshSelector: () => void; getTimeDefaults: () => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, + "; getRefreshIntervalDefaults: () => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.RefreshInterval", + "text": "RefreshInterval" + }, + "; }" + ], + "path": "src/plugins/data/public/query/timefilter/timefilter_service.ts", + "deprecated": false + }, + { + "parentPluginId": "data", + "id": "def-public.TimefilterSetup.history", + "type": "Object", + "tags": [], + "label": "history", + "description": [], + "signature": [ + "{ get$: () => ", + "Observable", + "<", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, + "[]>; add: (time: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, + ") => void; get: () => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, + "[]; }" + ], + "path": "src/plugins/data/public/query/timefilter/timefilter_service.ts", + "deprecated": false + } + ], + "initialIsOpen": false } ], "enums": [], @@ -2777,7 +3371,13 @@ "text": "FilterManager" }, "; timefilter: ", - "TimefilterSetup", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.TimefilterSetup", + "text": "TimefilterSetup" + }, "; queryString: ", { "pluginId": "data", @@ -2911,7 +3511,13 @@ "text": "QueryState" }, "; }>; timefilter: ", - "TimefilterSetup", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.TimefilterSetup", + "text": "TimefilterSetup" + }, "; getEsQuery: (indexPattern: ", { "pluginId": "dataViews", @@ -3003,9 +3609,9 @@ "Observable", "; getTimeUpdate$: () => ", "Observable", - "; getRefreshIntervalUpdate$: () => ", + "; getRefreshIntervalUpdate$: () => ", "Observable", - "; getAutoRefreshFetch$: () => ", + "; getAutoRefreshFetch$: () => ", "Observable", "<", { @@ -3017,7 +3623,7 @@ }, ">; getFetch$: () => ", "Observable", - "; getTime: () => ", + "; getTime: () => ", { "pluginId": "data", "scope": "common", diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index c4ef7a0a5710b..76b3bbc03583e 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github summary: API docs for the data.query plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3426 | 40 | 2816 | 20 | +| 3414 | 38 | 2802 | 18 | ## Client diff --git a/api_docs/data_search.devdocs.json b/api_docs/data_search.devdocs.json index 3519424309902..733c32b8df845 100644 --- a/api_docs/data_search.devdocs.json +++ b/api_docs/data_search.devdocs.json @@ -1474,55 +1474,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "data", - "id": "def-server.DataRequestHandlerContext", - "type": "Interface", - "tags": [], - "label": "DataRequestHandlerContext", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "server", - "docId": "kibDataSearchPluginApi", - "section": "def-server.DataRequestHandlerContext", - "text": "DataRequestHandlerContext" - }, - " extends ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCorePluginApi", - "section": "def-server.RequestHandlerContext", - "text": "RequestHandlerContext" - } - ], - "path": "src/plugins/data/server/search/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "data", - "id": "def-server.DataRequestHandlerContext.search", - "type": "Object", - "tags": [], - "label": "search", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "server", - "docId": "kibDataSearchPluginApi", - "section": "def-server.IScopedSearchClient", - "text": "IScopedSearchClient" - } - ], - "path": "src/plugins/data/server/search/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "data", "id": "def-server.IScopedSearchClient", @@ -2636,6 +2587,35 @@ ], "enums": [], "misc": [ + { + "parentPluginId": "data", + "id": "def-server.DataRequestHandlerContext", + "type": "Type", + "tags": [], + "label": "DataRequestHandlerContext", + "description": [], + "signature": [ + { + "pluginId": "core", + "scope": "server", + "docId": "kibCorePluginApi", + "section": "def-server.RequestHandlerContext", + "text": "RequestHandlerContext" + }, + " & { search: Promise<", + { + "pluginId": "data", + "scope": "server", + "docId": "kibDataSearchPluginApi", + "section": "def-server.IScopedSearchClient", + "text": "IScopedSearchClient" + }, + ">; }" + ], + "path": "src/plugins/data/server/search/types.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "data", "id": "def-server.SearchRequestHandlerContext", @@ -7599,6 +7579,117 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "data", + "id": "def-common.MultiFieldKey", + "type": "Class", + "tags": [], + "label": "MultiFieldKey", + "description": [], + "path": "src/plugins/data/common/search/aggs/buckets/multi_field_key.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.MultiFieldKey.id", + "type": "string", + "tags": [], + "label": "[id]", + "description": [], + "path": "src/plugins/data/common/search/aggs/buckets/multi_field_key.ts", + "deprecated": false + }, + { + "parentPluginId": "data", + "id": "def-common.MultiFieldKey.keys", + "type": "Array", + "tags": [], + "label": "keys", + "description": [], + "signature": [ + "string[]" + ], + "path": "src/plugins/data/common/search/aggs/buckets/multi_field_key.ts", + "deprecated": false + }, + { + "parentPluginId": "data", + "id": "def-common.MultiFieldKey.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "src/plugins/data/common/search/aggs/buckets/multi_field_key.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.MultiFieldKey.Unnamed.$1", + "type": "Unknown", + "tags": [], + "label": "bucket", + "description": [], + "signature": [ + "unknown" + ], + "path": "src/plugins/data/common/search/aggs/buckets/multi_field_key.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "data", + "id": "def-common.MultiFieldKey.idBucket", + "type": "Function", + "tags": [], + "label": "idBucket", + "description": [], + "signature": [ + "(bucket: unknown) => string" + ], + "path": "src/plugins/data/common/search/aggs/buckets/multi_field_key.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.MultiFieldKey.idBucket.$1", + "type": "Unknown", + "tags": [], + "label": "bucket", + "description": [], + "signature": [ + "unknown" + ], + "path": "src/plugins/data/common/search/aggs/buckets/multi_field_key.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "data", + "id": "def-common.MultiFieldKey.toString", + "type": "Function", + "tags": [], + "label": "toString", + "description": [], + "signature": [ + "() => string" + ], + "path": "src/plugins/data/common/search/aggs/buckets/multi_field_key.ts", + "deprecated": false, + "children": [], + "returnComment": [] + } + ], + "initialIsOpen": false + }, { "parentPluginId": "data", "id": "def-common.OptionedParamType", @@ -17986,6 +18077,19 @@ "path": "src/plugins/data/common/search/aggs/buckets/multi_terms.ts", "deprecated": false }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsMultiTerms.shardSize", + "type": "number", + "tags": [], + "label": "shardSize", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/multi_terms.ts", + "deprecated": false + }, { "parentPluginId": "data", "id": "def-common.AggParamsMultiTerms.otherBucket", @@ -18778,6 +18882,19 @@ "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", "deprecated": false }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsTerms.shardSize", + "type": "number", + "tags": [], + "label": "shardSize", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", + "deprecated": false + }, { "parentPluginId": "data", "id": "def-common.AggParamsTerms.missingBucket", @@ -24348,7 +24465,7 @@ "label": "AggConfigOptions", "description": [], "signature": [ - "{ type: ", + "{ id?: string | undefined; type: ", { "pluginId": "data", "scope": "common", @@ -24356,7 +24473,7 @@ "section": "def-common.IAggType", "text": "IAggType" }, - "; id?: string | undefined; enabled?: boolean | undefined; params?: {} | ", + "; enabled?: boolean | undefined; params?: {} | ", "SerializableRecord", " | undefined; schema?: string | undefined; }" ], @@ -25058,7 +25175,7 @@ "label": "CreateAggConfigParams", "description": [], "signature": [ - "{ type: string | ", + "{ id?: string | undefined; type: string | ", { "pluginId": "data", "scope": "common", @@ -25066,7 +25183,7 @@ "section": "def-common.IAggType", "text": "IAggType" }, - "; id?: string | undefined; enabled?: boolean | undefined; params?: {} | ", + "; enabled?: boolean | undefined; params?: {} | ", "SerializableRecord", " | undefined; schema?: string | undefined; }" ], diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index 608be3044f659..ae24c35139513 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github summary: API docs for the data.search plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3426 | 40 | 2816 | 20 | +| 3414 | 38 | 2802 | 18 | ## Client diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index 8a11bfeccdeab..01bc3bf40b471 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github summary: API docs for the dataViewEditor plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewEditor'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/data_view_field_editor.mdx b/api_docs/data_view_field_editor.mdx index 7a72bfa2e79d6..27b12a115195c 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github summary: API docs for the dataViewFieldEditor plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewFieldEditor'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/data_view_management.mdx b/api_docs/data_view_management.mdx index 1d26cc3a65daa..b1bfe293c7c92 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github summary: API docs for the dataViewManagement plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/data_views.devdocs.json b/api_docs/data_views.devdocs.json index 5ad402626c258..327d6e36ba3f4 100644 --- a/api_docs/data_views.devdocs.json +++ b/api_docs/data_views.devdocs.json @@ -4107,26 +4107,6 @@ "plugin": "dataViewEditor", "path": "src/plugins/data_view_editor/public/open_editor.tsx" }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/hooks/update_kuery_string.ts" - }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/hooks/update_kuery_string.ts" - }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx" - }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx" - }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx" - }, { "plugin": "maps", "path": "x-pack/plugins/maps/public/classes/tooltips/es_tooltip_property.test.ts" @@ -7104,14 +7084,6 @@ "plugin": "data", "path": "src/plugins/data/public/search/search_service.ts" }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/fetch_index_patterns.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/fetch_index_patterns.ts" - }, { "plugin": "unifiedSearch", "path": "src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx" @@ -8116,8 +8088,8 @@ "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.IFieldType", - "text": "IFieldType" + "section": "def-common.FieldSpec", + "text": "FieldSpec" }, " | undefined" ], @@ -15771,26 +15743,6 @@ "plugin": "dataViewEditor", "path": "src/plugins/data_view_editor/public/open_editor.tsx" }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/hooks/update_kuery_string.ts" - }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/hooks/update_kuery_string.ts" - }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx" - }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx" - }, - { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx" - }, { "plugin": "maps", "path": "x-pack/plugins/maps/public/classes/tooltips/es_tooltip_property.test.ts" @@ -18995,89 +18947,61 @@ "plugin": "data", "path": "src/plugins/data/public/query/filter_manager/lib/generate_filters.ts" }, - { - "plugin": "data", - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/public/autocomplete/providers/value_suggestion_provider.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/public/autocomplete/providers/value_suggestion_provider.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/public/autocomplete/providers/value_suggestion_provider.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/public/autocomplete/providers/value_suggestion_provider.ts" - }, { "plugin": "data", "path": "src/plugins/data/public/index.ts" }, { "plugin": "data", - "path": "src/plugins/data/public/autocomplete/providers/kql_query_suggestion/field.tsx" - }, - { - "plugin": "data", - "path": "src/plugins/data/public/autocomplete/providers/kql_query_suggestion/field.tsx" + "path": "src/plugins/data/public/actions/filters/create_filters_from_range_select.ts" }, { "plugin": "data", - "path": "src/plugins/data/public/autocomplete/providers/kql_query_suggestion/field.tsx" + "path": "src/plugins/data/public/actions/filters/create_filters_from_range_select.ts" }, { - "plugin": "data", - "path": "src/plugins/data/public/autocomplete/providers/kql_query_suggestion/value.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx" }, { - "plugin": "data", - "path": "src/plugins/data/public/autocomplete/providers/kql_query_suggestion/value.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx" }, { - "plugin": "data", - "path": "src/plugins/data/public/actions/filters/create_filters_from_range_select.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx" }, { - "plugin": "data", - "path": "src/plugins/data/public/actions/filters/create_filters_from_range_select.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts" }, { - "plugin": "data", - "path": "src/plugins/data/server/autocomplete/terms_enum.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts" }, { - "plugin": "data", - "path": "src/plugins/data/server/autocomplete/terms_enum.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts" }, { - "plugin": "data", - "path": "src/plugins/data/server/autocomplete/terms_agg.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts" }, { - "plugin": "data", - "path": "src/plugins/data/server/autocomplete/terms_agg.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts" }, { - "plugin": "data", - "path": "src/plugins/data/server/autocomplete/terms_agg.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts" }, { - "plugin": "data", - "path": "src/plugins/data/server/autocomplete/terms_agg.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts" }, { - "plugin": "data", - "path": "src/plugins/data/server/index.ts" + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts" }, { "plugin": "unifiedSearch", @@ -19113,19 +19037,27 @@ }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" + "path": "src/plugins/unified_search/server/autocomplete/terms_enum.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" + "path": "src/plugins/unified_search/server/autocomplete/terms_enum.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" + "path": "src/plugins/unified_search/server/autocomplete/terms_agg.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" + "path": "src/plugins/unified_search/server/autocomplete/terms_agg.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/server/autocomplete/terms_agg.ts" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/server/autocomplete/terms_agg.ts" }, { "plugin": "data", @@ -19174,6 +19106,22 @@ { "plugin": "unifiedSearch", "path": "src/plugins/unified_search/public/filter_bar/filter_editor/value_input_type.tsx" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" + }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" } ], "children": [ @@ -19511,30 +19459,6 @@ "plugin": "data", "path": "src/plugins/data/public/query/filter_manager/lib/generate_filters.ts" }, - { - "plugin": "data", - "path": "src/plugins/data/public/query/filter_manager/lib/get_index_pattern_from_filter.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/public/query/filter_manager/lib/get_index_pattern_from_filter.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/public/query/filter_manager/lib/get_index_pattern_from_filter.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/public/query/filter_manager/lib/get_display_value.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/public/query/filter_manager/lib/get_display_value.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/public/query/filter_manager/lib/get_display_value.ts" - }, { "plugin": "data", "path": "src/plugins/data/public/query/timefilter/timefilter.ts" @@ -19547,189 +19471,37 @@ "plugin": "data", "path": "src/plugins/data/public/query/timefilter/timefilter.ts" }, - { - "plugin": "data", - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/public/autocomplete/providers/value_suggestion_provider.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/public/autocomplete/providers/value_suggestion_provider.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/public/autocomplete/providers/value_suggestion_provider.ts" - }, { "plugin": "data", "path": "src/plugins/data/public/index.ts" }, - { - "plugin": "data", - "path": "src/plugins/data/public/autocomplete/providers/kql_query_suggestion/value.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/public/autocomplete/providers/kql_query_suggestion/value.ts" - }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/query_string_input.tsx" + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/query_string_input.tsx" + "path": "src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/query_string_input.tsx" + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/query_string_input.tsx" + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/query_string_input.tsx" + "path": "src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx" + "path": "src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts" }, { "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/components/kuery_bar/with_kuery_autocompletion.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/components/kuery_bar/with_kuery_autocompletion.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/components/kuery_bar/index.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/components/kuery_bar/index.tsx" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/lib/kuery.ts" - }, - { - "plugin": "monitoring", - "path": "x-pack/plugins/monitoring/public/lib/kuery.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/phrase_suggestor.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/phrase_suggestor.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_item.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_item.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_bar.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/filter_bar/filter_bar.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/search_bar/search_bar.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/search_bar/search_bar.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/apply_filters/apply_filter_popover_content.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/apply_filters/apply_filter_popover_content.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/apply_filters/apply_filters_popover.tsx" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/apply_filters/apply_filters_popover.tsx" - }, - { - "plugin": "stackAlerts", - "path": "x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx" - }, - { - "plugin": "stackAlerts", - "path": "x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx" + "path": "src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts" }, { "plugin": "data", @@ -22132,14 +21904,6 @@ "plugin": "data", "path": "src/plugins/data/public/search/search_service.ts" }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/fetch_index_patterns.ts" - }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/public/query_string_input/fetch_index_patterns.ts" - }, { "plugin": "unifiedSearch", "path": "src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx" @@ -22286,7 +22050,7 @@ "signature": [ "Pick<", "Toast", - ", \"children\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"className\" | \"security\" | \"defaultValue\" | \"hidden\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\"> & { title?: string | ", + ", \"children\" | \"color\" | \"className\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"hidden\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\"> & { title?: string | ", { "pluginId": "core", "scope": "public", diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index b595999839c2c..24669a558c24f 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github summary: API docs for the dataViews plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx index 7bc87154c95ff..dba30154fefa5 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github summary: API docs for the dataVisualizer plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index 8db17bbe8bee3..a9ce0254cea52 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -3,7 +3,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API summary: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. --- @@ -15,40 +15,39 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | ---------------|-----------|-----------| | | dataViews, maps, data | - | | | dataViews, unifiedSearch, maps, data | - | -| | dataViews, discover, ux, savedObjects, dataViewEditor, uptime, maps, visDefaultEditor, data | - | +| | dataViews, discover, ux, savedObjects, dataViewEditor, maps, visDefaultEditor, data | - | | | dataViews, dataViewEditor, maps, visDefaultEditor, data | - | -| | dataViews, unifiedSearch, monitoring, stackAlerts | - | +| | dataViews, unifiedSearch | - | | | dataViews, canvas | - | -| | dataViews, unifiedSearch, monitoring, stackAlerts, data | - | +| | dataViews, unifiedSearch, data | - | | | dataViews, canvas, data | - | | | dataViews, unifiedSearch, maps, data | - | | | dataViews, dataViewEditor, maps, visDefaultEditor, data | - | | | dataViews, maps, data | - | | | dataViews | - | -| | dataViews, discover, ux, savedObjects, dataViewEditor, uptime, maps, visDefaultEditor, data | - | +| | dataViews, discover, ux, savedObjects, dataViewEditor, maps, visDefaultEditor, data | - | | | dataViews, maps | - | | | dataViewManagement, dataViews | - | | | visTypeTimeseries, graph, dataViewManagement, dataViews | - | | | dataViews, dataViewManagement | - | | | dataViews, canvas | - | | | dataViews, dataViewEditor, maps, visDefaultEditor | - | -| | dataViews, discover, ux, savedObjects, dataViewEditor, uptime, maps, visDefaultEditor | - | +| | dataViews, discover, ux, savedObjects, dataViewEditor, maps, visDefaultEditor | - | | | dataViews, maps | - | | | dataViews, maps | - | | | dataViewManagement, dataViews | - | | | visTypeTimeseries, graph, dataViewManagement, dataViews | - | | | dataViews, dataViewManagement | - | -| | unifiedSearch, discover, maps, infra, graph, monitoring, securitySolution, stackAlerts, uptime, inputControlVis, savedObjects | - | +| | unifiedSearch, discover, maps, infra, graph, securitySolution, stackAlerts, inputControlVis, savedObjects | - | | | maps | - | | | data, infra, maps | - | -| | dashboard, maps | - | | | discover | - | | | discover | - | | | data, discover, embeddable | - | | | advancedSettings, discover | - | | | advancedSettings, discover | - | -| | esUiShared, home, spaces, fleet, visualizations, lens, observability, dataEnhanced, ml, apm, cloudSecurityPosture, indexLifecycleManagement, upgradeAssistant, uptime, ux, kibanaOverview, savedObjectsManagement | - | -| | dashboard, lens, stackAlerts, visTypeTable, visTypeTimeseries, visTypeXy, visTypeVislib, expressionPartitionVis | - | +| | management, observability, infra, apm, cloudSecurityPosture, enterpriseSearch, securitySolution, synthetics, ux, kibanaOverview | - | +| | esUiShared, home, spaces, fleet, visualizations, lens, observability, dataEnhanced, ml, apm, cloudSecurityPosture, indexLifecycleManagement, synthetics, upgradeAssistant, ux, kibanaOverview, savedObjectsManagement | - | | | canvas, visTypeXy | - | | | canvas | - | | | canvas | - | @@ -59,41 +58,40 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | canvas | - | | | canvas | - | | | canvas, visTypeXy | - | +| | management, spaces, observability, ml, canvas, cloudSecurityPosture, enterpriseSearch, osquery, securitySolution, kibanaOverview | - | +| | dashboard, lens, stackAlerts, visTypeTable, visTypeTimeseries, visTypeXy, visTypeVislib, expressionPartitionVis | - | | | visTypeTimeseries, graph, dataViewManagement | - | | | encryptedSavedObjects, actions, cloud, ml, dataEnhanced, logstash, securitySolution | - | +| | dashboard | - | | | visTypeTimeseries | - | | | dataViewManagement | - | | | dataViewManagement | - | +| | actions, ml, enterpriseSearch, savedObjectsTagging | - | | | spaces, savedObjectsManagement | - | | | spaces, savedObjectsManagement | - | -| | actions, ml, enterpriseSearch, savedObjectsTagging | - | | | visTypeGauge | - | | | visTypePie | - | | | visTypePie | - | | | actions, alerting | - | | | console | - | | | unifiedSearch | 8.1 | +| | unifiedSearch, dataEnhanced | 8.1 | | | unifiedSearch, discover, dashboard, urlDrilldown, stackAlerts | 8.1 | | | unifiedSearch | 8.1 | | | unifiedSearch | 8.1 | | | unifiedSearch, discover, dashboard, urlDrilldown, stackAlerts | 8.1 | +| | unifiedSearch, dataEnhanced | 8.1 | | | unifiedSearch, discover, dashboard, urlDrilldown, stackAlerts | 8.1 | +| | unifiedSearch, dataEnhanced | 8.1 | | | discover, stackAlerts, inputControlVis | 8.1 | | | discover, stackAlerts, inputControlVis | 8.1 | -| | dataEnhanced | 8.1 | | | dataEnhanced | 8.1 | -| | dataEnhanced | 8.1 | -| | dataEnhanced | 8.1 | | | apm | 8.1 | | | dataViews, unifiedSearch | 8.2 | | | dataViews, unifiedSearch, data | 8.2 | -| | dataViews, unifiedSearch | 8.2 | -| | visualizations, dashboard, maps, graph | 8.8.0 | | | visualizations, dashboard, lens, maps, ml, securitySolution, security | 8.8.0 | | | lens, dashboard, maps | 8.8.0 | -| | embeddable, presentationUtil, discover, dashboard, graph | 8.8.0 | -| | monitoring, visTypeVega | 8.8.0 | -| | monitoring, kibanaUsageCollection | 8.8.0 | +| | embeddable, discover, presentationUtil, dashboard, graph | 8.8.0 | | | spaces, security, actions, alerting, ml, remoteClusters, graph, indexLifecycleManagement, mapsEms, painlessLab, rollup, searchprofiler, snapshotRestore, transform, upgradeAssistant | 8.8.0 | | | apm, security, securitySolution | 8.8.0 | | | apm, security, securitySolution | 8.8.0 | @@ -102,14 +100,16 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | dashboard | 8.8.0 | | | cloud, apm | 8.8.0 | | | security, licenseManagement, ml, apm, crossClusterReplication, logstash, painlessLab, searchprofiler, watcher | 8.8.0 | +| | management, fleet, security, kibanaOverview | 8.8.0 | | | spaces, security, alerting | 8.8.0 | | | security, fleet | 8.8.0 | | | security, fleet | 8.8.0 | | | security, fleet | 8.8.0 | -| | management, fleet, security, kibanaOverview | 8.8.0 | | | security | 8.8.0 | | | mapsEms | 8.8.0 | | | visTypeVega | 8.8.0 | +| | monitoring, visTypeVega | 8.8.0 | +| | monitoring, kibanaUsageCollection | 8.8.0 | | | ml | 8.8.0 Note to maintainers: when looking at usages, mind that typical use could be inside a `catch` block, @@ -201,6 +201,7 @@ Safe to remove. | | expressions | | | expressions | | | expressions | +| | savedObjects | | | licensing | | | licensing | | | licensing | diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 0005cd3853b72..bc9d1dac3a021 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -3,7 +3,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin summary: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. --- @@ -45,6 +45,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | ---------------|-----------|-----------| | | [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx#:~:text=esKuery), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx#:~:text=esKuery), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx#:~:text=esKuery) | 8.1 | | | [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/plugin.ts#:~:text=environment) | 8.8.0 | +| | [no_data_config.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/routing/templates/no_data_config.ts#:~:text=KibanaPageTemplateProps), [no_data_config.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/routing/templates/no_data_config.ts#:~:text=KibanaPageTemplateProps), [apm_main_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx#:~:text=KibanaPageTemplateProps), [apm_main_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx#:~:text=KibanaPageTemplateProps), [service_group_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/routing/templates/service_group_template.tsx#:~:text=KibanaPageTemplateProps), [service_group_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/routing/templates/service_group_template.tsx#:~:text=KibanaPageTemplateProps) | - | | | [app_root.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/routing/app_root.tsx#:~:text=RedirectAppLinks), [app_root.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/routing/app_root.tsx#:~:text=RedirectAppLinks), [app_root.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/routing/app_root.tsx#:~:text=RedirectAppLinks) | - | | | [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode)+ 2 more | 8.8.0 | | | [license_context.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/context/license/license_context.tsx#:~:text=license%24) | 8.8.0 | @@ -59,16 +60,17 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [es_service.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/lib/es_service.ts#:~:text=IndexPatternAttributes), [es_service.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/lib/es_service.ts#:~:text=IndexPatternAttributes), [es_service.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/lib/es_service.ts#:~:text=IndexPatternAttributes) | - | | | [es_service.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/lib/es_service.ts#:~:text=IndexPatternAttributes), [es_service.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/lib/es_service.ts#:~:text=IndexPatternAttributes), [es_service.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/lib/es_service.ts#:~:text=IndexPatternAttributes), [es_service.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/lib/es_service.ts#:~:text=IndexPatternAttributes), [es_service.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/lib/es_service.ts#:~:text=IndexPatternAttributes), [es_service.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/lib/es_service.ts#:~:text=IndexPatternAttributes) | - | | | [es_service.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/lib/es_service.ts#:~:text=IndexPatternAttributes), [es_service.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/lib/es_service.ts#:~:text=IndexPatternAttributes), [es_service.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/lib/es_service.ts#:~:text=IndexPatternAttributes) | - | -| | [embeddable.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.ts#:~:text=context), [filters.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/common/functions/filters.ts#:~:text=context), [escount.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/escount.ts#:~:text=context), [esdocs.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/esdocs.ts#:~:text=context), [essql.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/essql.ts#:~:text=context), [neq.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/common/neq.ts#:~:text=context), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts#:~:text=context), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/server/demodata/index.ts#:~:text=context) | - | +| | [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/server/demodata/index.ts#:~:text=context), [embeddable.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.ts#:~:text=context), [esdocs.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/esdocs.ts#:~:text=context), [essql.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/essql.ts#:~:text=context), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts#:~:text=context), [filters.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/common/functions/filters.ts#:~:text=context), [escount.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/escount.ts#:~:text=context), [neq.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/common/neq.ts#:~:text=context) | - | | | [setup_expressions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/setup_expressions.ts#:~:text=getFunction) | - | | | [application.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/application.tsx#:~:text=getFunctions), [functions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/server/routes/functions/functions.ts#:~:text=getFunctions), [functions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/server/routes/functions/functions.ts#:~:text=getFunctions), [functions.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/server/routes/functions/functions.test.ts#:~:text=getFunctions) | - | | | [setup_expressions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/setup_expressions.ts#:~:text=getTypes), [application.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/application.tsx#:~:text=getTypes), [functions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/server/routes/functions/functions.ts#:~:text=getTypes) | - | | | [state.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/types/state.ts#:~:text=Render), [state.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/types/state.ts#:~:text=Render), [markdown.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/markdown.ts#:~:text=Render), [markdown.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/markdown.ts#:~:text=Render), [timefilterControl.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/common/timefilterControl.ts#:~:text=Render), [timefilterControl.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/common/timefilterControl.ts#:~:text=Render), [pie.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/functions/pie.ts#:~:text=Render), [pie.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/functions/pie.ts#:~:text=Render), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/functions/plot/index.ts#:~:text=Render), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/functions/plot/index.ts#:~:text=Render)+ 2 more | - | -| | [embeddable.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.ts#:~:text=context), [filters.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/common/functions/filters.ts#:~:text=context), [escount.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/escount.ts#:~:text=context), [esdocs.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/esdocs.ts#:~:text=context), [essql.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/essql.ts#:~:text=context), [neq.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/common/neq.ts#:~:text=context), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts#:~:text=context), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/server/demodata/index.ts#:~:text=context) | - | +| | [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/server/demodata/index.ts#:~:text=context), [embeddable.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.ts#:~:text=context), [esdocs.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/esdocs.ts#:~:text=context), [essql.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/essql.ts#:~:text=context), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts#:~:text=context), [filters.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/common/functions/filters.ts#:~:text=context), [escount.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/escount.ts#:~:text=context), [neq.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/common/neq.ts#:~:text=context) | - | | | [setup_expressions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/setup_expressions.ts#:~:text=getFunction) | - | | | [application.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/application.tsx#:~:text=getFunctions), [functions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/server/routes/functions/functions.ts#:~:text=getFunctions), [functions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/server/routes/functions/functions.ts#:~:text=getFunctions), [functions.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/server/routes/functions/functions.test.ts#:~:text=getFunctions) | - | | | [setup_expressions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/setup_expressions.ts#:~:text=getTypes), [application.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/application.tsx#:~:text=getTypes), [functions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/server/routes/functions/functions.ts#:~:text=getTypes) | - | -| | [embeddable.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.ts#:~:text=context), [filters.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/common/functions/filters.ts#:~:text=context), [escount.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/escount.ts#:~:text=context), [esdocs.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/esdocs.ts#:~:text=context), [essql.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/essql.ts#:~:text=context), [neq.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/common/neq.ts#:~:text=context), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts#:~:text=context), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/server/demodata/index.ts#:~:text=context) | - | +| | [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/server/demodata/index.ts#:~:text=context), [embeddable.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.ts#:~:text=context), [esdocs.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/esdocs.ts#:~:text=context), [essql.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/essql.ts#:~:text=context), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts#:~:text=context), [filters.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/common/functions/filters.ts#:~:text=context), [escount.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/escount.ts#:~:text=context), [neq.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/canvas_plugin_src/functions/common/neq.ts#:~:text=context) | - | +| | [home.component.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/components/home/home.component.tsx#:~:text=KibanaPageTemplate), [home.component.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/components/home/home.component.tsx#:~:text=KibanaPageTemplate), [home.component.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/canvas/public/components/home/home.component.tsx#:~:text=KibanaPageTemplate) | - | @@ -85,6 +87,8 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| +| | [csp_page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/cloud_security_posture/public/components/csp_page_template.tsx#:~:text=KibanaPageTemplateProps), [csp_page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/cloud_security_posture/public/components/csp_page_template.tsx#:~:text=KibanaPageTemplateProps), [csp_page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/cloud_security_posture/public/components/csp_page_template.tsx#:~:text=KibanaPageTemplateProps), [csp_page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/cloud_security_posture/public/components/csp_page_template.tsx#:~:text=KibanaPageTemplateProps), [csp_page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/cloud_security_posture/public/components/csp_page_template.tsx#:~:text=KibanaPageTemplateProps), [csp_page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/cloud_security_posture/public/components/csp_page_template.tsx#:~:text=KibanaPageTemplateProps), [csp_page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/cloud_security_posture/public/components/csp_page_template.tsx#:~:text=KibanaPageTemplateProps), [csp_page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/cloud_security_posture/public/components/csp_page_template.tsx#:~:text=KibanaPageTemplateProps), [compliance_dashboard.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.tsx#:~:text=KibanaPageTemplateProps), [compliance_dashboard.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.tsx#:~:text=KibanaPageTemplateProps)+ 2 more | - | +| | [csp_page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/cloud_security_posture/public/components/csp_page_template.tsx#:~:text=KibanaPageTemplate), [csp_page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/cloud_security_posture/public/components/csp_page_template.tsx#:~:text=KibanaPageTemplate), [csp_page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/cloud_security_posture/public/components/csp_page_template.tsx#:~:text=KibanaPageTemplate) | - | | | [app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/cloud_security_posture/public/application/app.tsx#:~:text=RedirectAppLinks), [app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/cloud_security_posture/public/application/app.tsx#:~:text=RedirectAppLinks), [app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/cloud_security_posture/public/application/app.tsx#:~:text=RedirectAppLinks) | - | @@ -117,7 +121,6 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [saved_objects.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/services/saved_objects.ts#:~:text=SavedObjectSaveModal), [save_modal.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/top_nav/save_modal.tsx#:~:text=SavedObjectSaveModal), [save_modal.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/top_nav/save_modal.tsx#:~:text=SavedObjectSaveModal) | 8.8.0 | | | [saved_object_loader.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/services/saved_object_loader.ts#:~:text=SavedObject), [saved_object_loader.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/services/saved_object_loader.ts#:~:text=SavedObject), [saved_object_loader.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/services/saved_object_loader.ts#:~:text=SavedObject), [saved_objects.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/services/saved_objects.ts#:~:text=SavedObject), [saved_dashboard.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/saved_dashboards/saved_dashboard.ts#:~:text=SavedObject), [saved_dashboard.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/saved_dashboards/saved_dashboard.ts#:~:text=SavedObject), [dashboard_tagging.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/dashboard_tagging.ts#:~:text=SavedObject), [dashboard_tagging.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/dashboard_tagging.ts#:~:text=SavedObject), [clone_panel_action.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/actions/clone_panel_action.tsx#:~:text=SavedObject), [clone_panel_action.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/actions/clone_panel_action.tsx#:~:text=SavedObject)+ 1 more | 8.8.0 | | | [saved_dashboard.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/saved_dashboards/saved_dashboard.ts#:~:text=SavedObjectClass) | 8.8.0 | -| | [dashboard_listing.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx#:~:text=settings), [dashboard_listing.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx#:~:text=settings) | 8.8.0 | | | [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/types.ts#:~:text=onAppLeave), [dashboard_router.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/dashboard_router.tsx#:~:text=onAppLeave), [plugin.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/plugin.tsx#:~:text=onAppLeave) | 8.8.0 | | | [migrations_730.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/server/saved_objects/migrations_730.ts#:~:text=warning), [migrations_730.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/server/saved_objects/migrations_730.ts#:~:text=warning) | 8.8.0 | @@ -131,9 +134,9 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IndexPatternsContract), [create_search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/create_search_source.ts#:~:text=IndexPatternsContract), [create_search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/create_search_source.ts#:~:text=IndexPatternsContract), [search_source_service.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source_service.ts#:~:text=IndexPatternsContract), [search_source_service.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source_service.ts#:~:text=IndexPatternsContract), [esaggs_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/expressions/esaggs/esaggs_fn.ts#:~:text=IndexPatternsContract), [esaggs_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/expressions/esaggs/esaggs_fn.ts#:~:text=IndexPatternsContract), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/search/types.ts#:~:text=IndexPatternsContract), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/search/types.ts#:~:text=IndexPatternsContract), [create_search_source.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/create_search_source.test.ts#:~:text=IndexPatternsContract)+ 19 more | - | | | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IndexPatternsService), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/server/index.ts#:~:text=IndexPatternsService), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/server/index.ts#:~:text=IndexPatternsService), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/server/index.ts#:~:text=IndexPatternsService), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/index.ts#:~:text=IndexPatternsService) | - | | | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/types.ts#:~:text=IndexPattern), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPattern), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPattern), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPattern), [tabify_docs.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/tabify/tabify_docs.ts#:~:text=IndexPattern), [tabify_docs.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/tabify/tabify_docs.ts#:~:text=IndexPattern)+ 89 more | - | -| | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IFieldType), [date_histogram.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/buckets/date_histogram.ts#:~:text=IFieldType), [date_histogram.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/buckets/date_histogram.ts#:~:text=IFieldType), [generate_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts#:~:text=IFieldType), [generate_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts#:~:text=IFieldType), [generate_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts#:~:text=IFieldType), [generate_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts#:~:text=IFieldType), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IFieldType), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType)+ 24 more | 8.2 | +| | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IFieldType), [date_histogram.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/buckets/date_histogram.ts#:~:text=IFieldType), [date_histogram.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/buckets/date_histogram.ts#:~:text=IFieldType), [generate_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts#:~:text=IFieldType), [generate_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts#:~:text=IFieldType), [generate_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts#:~:text=IFieldType), [generate_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts#:~:text=IFieldType), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/index.ts#:~:text=IFieldType), [create_filters_from_range_select.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/actions/filters/create_filters_from_range_select.ts#:~:text=IFieldType), [create_filters_from_range_select.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/actions/filters/create_filters_from_range_select.ts#:~:text=IFieldType)+ 6 more | 8.2 | | | [field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/param_types/field.ts#:~:text=IndexPatternField), [field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/param_types/field.ts#:~:text=IndexPatternField), [field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/param_types/field.ts#:~:text=IndexPatternField), [field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/param_types/field.ts#:~:text=IndexPatternField), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IndexPatternField), [kibana_context_type.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/expressions/kibana_context_type.ts#:~:text=IndexPatternField), [kibana_context_type.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/expressions/kibana_context_type.ts#:~:text=IndexPatternField), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPatternField), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPatternField), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPatternField)+ 16 more | - | -| | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IIndexPattern), [get_time.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/query/timefilter/get_time.ts#:~:text=IIndexPattern), [get_time.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/query/timefilter/get_time.ts#:~:text=IIndexPattern), [get_time.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/query/timefilter/get_time.ts#:~:text=IIndexPattern), [get_time.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/query/timefilter/get_time.ts#:~:text=IIndexPattern), [normalize_sort_request.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/normalize_sort_request.ts#:~:text=IIndexPattern), [normalize_sort_request.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/normalize_sort_request.ts#:~:text=IIndexPattern), [normalize_sort_request.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/normalize_sort_request.ts#:~:text=IIndexPattern), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IIndexPattern), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IIndexPattern)+ 36 more | - | +| | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IIndexPattern), [get_time.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/query/timefilter/get_time.ts#:~:text=IIndexPattern), [get_time.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/query/timefilter/get_time.ts#:~:text=IIndexPattern), [get_time.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/query/timefilter/get_time.ts#:~:text=IIndexPattern), [get_time.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/query/timefilter/get_time.ts#:~:text=IIndexPattern), [normalize_sort_request.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/normalize_sort_request.ts#:~:text=IIndexPattern), [normalize_sort_request.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/normalize_sort_request.ts#:~:text=IIndexPattern), [normalize_sort_request.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/normalize_sort_request.ts#:~:text=IIndexPattern), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IIndexPattern), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IIndexPattern)+ 23 more | - | | | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IndexPatternAttributes), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/index.ts#:~:text=IndexPatternAttributes), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/server/index.ts#:~:text=IndexPatternAttributes) | - | | | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IndexPatternsContract), [create_search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/create_search_source.ts#:~:text=IndexPatternsContract), [create_search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/create_search_source.ts#:~:text=IndexPatternsContract), [search_source_service.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source_service.ts#:~:text=IndexPatternsContract), [search_source_service.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source_service.ts#:~:text=IndexPatternsContract), [esaggs_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/expressions/esaggs/esaggs_fn.ts#:~:text=IndexPatternsContract), [esaggs_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/expressions/esaggs/esaggs_fn.ts#:~:text=IndexPatternsContract), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/search/types.ts#:~:text=IndexPatternsContract), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/search/types.ts#:~:text=IndexPatternsContract), [create_search_source.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/create_search_source.test.ts#:~:text=IndexPatternsContract)+ 19 more | - | | | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IndexPatternsService), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/server/index.ts#:~:text=IndexPatternsService), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/server/index.ts#:~:text=IndexPatternsService), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/server/index.ts#:~:text=IndexPatternsService), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/index.ts#:~:text=IndexPatternsService) | - | @@ -194,9 +197,9 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPattern), [data_view_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.test.ts#:~:text=IndexPattern), [data_view_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.test.ts#:~:text=IndexPattern), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/public/index.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern) | - | | | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPatternField), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/public/index.ts#:~:text=IndexPatternField), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPatternField), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPatternField), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPatternField), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPatternField), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPatternField), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPatternField), [data_view_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.test.ts#:~:text=IndexPatternField), [data_view_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.test.ts#:~:text=IndexPatternField)+ 2 more | - | | | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IIndexPattern), [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=IIndexPattern), [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=IIndexPattern) | - | -| | [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType)+ 13 more | 8.2 | +| | [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType)+ 7 more | 8.2 | | | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPatternAttributes) | - | -| | [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType)+ 13 more | 8.2 | +| | [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType)+ 7 more | 8.2 | | | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IIndexPattern), [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=IIndexPattern), [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=IIndexPattern) | - | | | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPatternAttributes) | - | | | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPatternsContract), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/public/index.ts#:~:text=IndexPatternsContract) | - | @@ -208,7 +211,6 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=removeScriptedField) | - | | | [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=getNonScriptedFields) | - | | | [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=getScriptedFields), [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=getScriptedFields), [data_views.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_views.ts#:~:text=getScriptedFields), [register_index_pattern_usage_collection.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/server/register_index_pattern_usage_collection.ts#:~:text=getScriptedFields), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=getScriptedFields), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=getScriptedFields), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=getScriptedFields), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=getScriptedFields), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=getScriptedFields) | - | -| | [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType)+ 13 more | 8.2 | | | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPatternAttributes) | - | | | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPatternField), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/public/index.ts#:~:text=IndexPatternField), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPatternField), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPatternField), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPatternField), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPatternField), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPatternField), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPatternField), [data_view_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.test.ts#:~:text=IndexPatternField), [data_view_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.test.ts#:~:text=IndexPatternField)+ 2 more | - | | | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPattern), [data_view_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.test.ts#:~:text=IndexPattern), [data_view_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.test.ts#:~:text=IndexPattern), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/public/index.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern) | - | @@ -263,6 +265,8 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| +| | [page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/enterprise_search/public/applications/shared/layout/page_template.tsx#:~:text=KibanaPageTemplateProps), [page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/enterprise_search/public/applications/shared/layout/page_template.tsx#:~:text=KibanaPageTemplateProps) | - | +| | [version_mismatch_page.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/enterprise_search/public/applications/shared/version_mismatch/version_mismatch_page.tsx#:~:text=KibanaPageTemplate), [version_mismatch_page.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/enterprise_search/public/applications/shared/version_mismatch/version_mismatch_page.tsx#:~:text=KibanaPageTemplate), [version_mismatch_page.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/enterprise_search/public/applications/shared/version_mismatch/version_mismatch_page.tsx#:~:text=KibanaPageTemplate), [error_connecting.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/error_connecting/error_connecting.tsx#:~:text=KibanaPageTemplate), [error_connecting.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/error_connecting/error_connecting.tsx#:~:text=KibanaPageTemplate), [error_connecting.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/error_connecting/error_connecting.tsx#:~:text=KibanaPageTemplate), [product_selector.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/product_selector/product_selector.tsx#:~:text=KibanaPageTemplate), [product_selector.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/product_selector/product_selector.tsx#:~:text=KibanaPageTemplate), [product_selector.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/product_selector/product_selector.tsx#:~:text=KibanaPageTemplate), [page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/enterprise_search/public/applications/shared/layout/page_template.tsx#:~:text=KibanaPageTemplate)+ 11 more | - | | | [check_access.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/enterprise_search/server/lib/check_access.ts#:~:text=authz), [check_access.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/enterprise_search/server/lib/check_access.ts#:~:text=authz), [check_access.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/enterprise_search/server/lib/check_access.ts#:~:text=authz) | - | @@ -304,7 +308,6 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [deserialize.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/graph/public/services/persistence/deserialize.ts#:~:text=getNonScriptedFields), [datasource.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/graph/public/state_management/datasource.test.ts#:~:text=getNonScriptedFields), [deserialize.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/graph/public/services/persistence/deserialize.test.ts#:~:text=getNonScriptedFields), [deserialize.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/graph/public/services/persistence/deserialize.test.ts#:~:text=getNonScriptedFields) | - | | | [deserialize.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/graph/public/services/persistence/deserialize.ts#:~:text=getNonScriptedFields), [datasource.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/graph/public/state_management/datasource.test.ts#:~:text=getNonScriptedFields), [deserialize.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/graph/public/services/persistence/deserialize.test.ts#:~:text=getNonScriptedFields), [deserialize.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/graph/public/services/persistence/deserialize.test.ts#:~:text=getNonScriptedFields) | - | | | [save_modal.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/graph/public/components/save_modal.tsx#:~:text=SavedObjectSaveModal), [save_modal.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/graph/public/components/save_modal.tsx#:~:text=SavedObjectSaveModal) | 8.8.0 | -| | [listing_route.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/graph/public/apps/listing_route.tsx#:~:text=settings), [listing_route.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/graph/public/apps/listing_route.tsx#:~:text=settings) | 8.8.0 | | | [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/graph/server/plugin.ts#:~:text=license%24) | 8.8.0 | @@ -332,6 +335,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | ---------------|-----------|-----------| | | [use_kibana_index_patterns.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/hooks/use_kibana_index_patterns.ts#:~:text=indexPatterns) | - | | | [kibana_framework_adapter.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts#:~:text=indexPatternsServiceFactory) | - | +| | [page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/logs/page_template.tsx#:~:text=KibanaPageTemplateProps), [page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/logs/page_template.tsx#:~:text=KibanaPageTemplateProps), [page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/page_template.tsx#:~:text=KibanaPageTemplateProps), [page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/infra/public/pages/metrics/page_template.tsx#:~:text=KibanaPageTemplateProps) | - | @@ -349,6 +353,8 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| +| | [overview.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/kibana_overview/public/components/overview/overview.tsx#:~:text=KibanaPageTemplateProps), [overview.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/kibana_overview/public/components/overview/overview.tsx#:~:text=KibanaPageTemplateProps) | - | +| | [overview.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/kibana_overview/public/components/overview/overview.tsx#:~:text=KibanaPageTemplate), [overview.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/kibana_overview/public/components/overview/overview.tsx#:~:text=KibanaPageTemplate), [overview.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/kibana_overview/public/components/overview/overview.tsx#:~:text=KibanaPageTemplate) | - | | | [add_data.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/kibana_overview/public/components/add_data/add_data.tsx#:~:text=RedirectAppLinks), [add_data.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/kibana_overview/public/components/add_data/add_data.tsx#:~:text=RedirectAppLinks), [add_data.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/kibana_overview/public/components/add_data/add_data.tsx#:~:text=RedirectAppLinks), [manage_data.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/kibana_overview/public/components/manage_data/manage_data.tsx#:~:text=RedirectAppLinks), [manage_data.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/kibana_overview/public/components/manage_data/manage_data.tsx#:~:text=RedirectAppLinks), [manage_data.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/kibana_overview/public/components/manage_data/manage_data.tsx#:~:text=RedirectAppLinks), [overview.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/kibana_overview/public/components/overview/overview.tsx#:~:text=RedirectAppLinks), [overview.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/kibana_overview/public/components/overview/overview.tsx#:~:text=RedirectAppLinks), [overview.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/kibana_overview/public/components/overview/overview.tsx#:~:text=RedirectAppLinks), [overview.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/kibana_overview/public/components/overview/overview.tsx#:~:text=RedirectAppLinks)+ 1 more | - | | | [application.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/kibana_overview/public/application.tsx#:~:text=appBasePath) | 8.8.0 | @@ -395,6 +401,8 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| +| | [management_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/management/public/components/management_app/management_app.tsx#:~:text=KibanaPageTemplateProps), [management_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/management/public/components/management_app/management_app.tsx#:~:text=KibanaPageTemplateProps) | - | +| | [management_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/management/public/components/management_app/management_app.tsx#:~:text=KibanaPageTemplate), [management_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/management/public/components/management_app/management_app.tsx#:~:text=KibanaPageTemplate), [management_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/management/public/components/management_app/management_app.tsx#:~:text=KibanaPageTemplate) | - | | | [application.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/management/public/application.tsx#:~:text=appBasePath) | 8.8.0 | @@ -419,8 +427,6 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [es_search_source.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx#:~:text=flattenHit), [es_search_source.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx#:~:text=flattenHit) | - | | | [es_search_source.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx#:~:text=flattenHit), [es_search_source.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx#:~:text=flattenHit) | - | | | [kibana_server_services.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/kibana_server_services.ts#:~:text=indexPatternsServiceFactory), [indexing_routes.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/data_indexing/indexing_routes.ts#:~:text=indexPatternsServiceFactory) | - | -| | [map_container.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/connected_components/map_container/map_container.tsx#:~:text=ExitFullScreenButton), [map_container.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/connected_components/map_container/map_container.tsx#:~:text=ExitFullScreenButton) | - | -| | [maps_list_view.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx#:~:text=settings), [maps_list_view.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx#:~:text=settings), [maps_list_view.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx#:~:text=settings) | 8.8.0 | | | [render_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/render_app.tsx#:~:text=onAppLeave), [map_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx#:~:text=onAppLeave), [map_page.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/routes/map_page/map_page.tsx#:~:text=onAppLeave) | 8.8.0 | | | [saved_object_migrations.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/saved_objects/saved_object_migrations.ts#:~:text=warning) | 8.8.0 | @@ -439,6 +445,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| +| | [ml_page.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/components/ml_page/ml_page.tsx#:~:text=KibanaPageTemplate), [ml_page.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/components/ml_page/ml_page.tsx#:~:text=KibanaPageTemplate), [ml_page.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/components/ml_page/ml_page.tsx#:~:text=KibanaPageTemplate) | - | | | [ml_page.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/components/ml_page/ml_page.tsx#:~:text=RedirectAppLinks), [ml_page.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/components/ml_page/ml_page.tsx#:~:text=RedirectAppLinks), [ml_page.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/components/ml_page/ml_page.tsx#:~:text=RedirectAppLinks), [jobs_list_page.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx#:~:text=RedirectAppLinks), [jobs_list_page.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx#:~:text=RedirectAppLinks), [jobs_list_page.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx#:~:text=RedirectAppLinks) | - | | | [check_license.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/application/license/check_license.tsx#:~:text=license%24), [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/public/plugin.ts#:~:text=license%24) | 8.8.0 | | | [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/plugin.ts#:~:text=license%24), [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ml/server/plugin.ts#:~:text=license%24) | 8.8.0 | @@ -456,9 +463,6 @@ so TS and code-reference navigation might not highlight them. | | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| -| | [use_derived_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx#:~:text=IIndexPattern), [use_derived_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx#:~:text=IIndexPattern), [with_kuery_autocompletion.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/components/kuery_bar/with_kuery_autocompletion.tsx#:~:text=IIndexPattern), [with_kuery_autocompletion.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/components/kuery_bar/with_kuery_autocompletion.tsx#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/components/kuery_bar/index.tsx#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/components/kuery_bar/index.tsx#:~:text=IIndexPattern), [kuery.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/lib/kuery.ts#:~:text=IIndexPattern), [kuery.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/lib/kuery.ts#:~:text=IIndexPattern) | - | -| | [use_derived_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx#:~:text=indexPatterns), [use_derived_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx#:~:text=indexPatterns) | - | -| | [use_derived_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx#:~:text=IIndexPattern), [use_derived_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx#:~:text=IIndexPattern), [with_kuery_autocompletion.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/components/kuery_bar/with_kuery_autocompletion.tsx#:~:text=IIndexPattern), [with_kuery_autocompletion.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/components/kuery_bar/with_kuery_autocompletion.tsx#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/components/kuery_bar/index.tsx#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/components/kuery_bar/index.tsx#:~:text=IIndexPattern), [kuery.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/lib/kuery.ts#:~:text=IIndexPattern), [kuery.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/lib/kuery.ts#:~:text=IIndexPattern), [use_derived_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx#:~:text=IIndexPattern), [use_derived_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx#:~:text=IIndexPattern)+ 6 more | - | | | [legacy_shims.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/legacy_shims.ts#:~:text=injectedMetadata) | 8.8.0 | | | [bulk_uploader.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/server/kibana_monitoring/bulk_uploader.ts#:~:text=process) | 8.8.0 | @@ -468,10 +472,20 @@ so TS and code-reference navigation might not highlight them. | | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| +| | [page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/observability/public/components/shared/page_template/page_template.tsx#:~:text=KibanaPageTemplateProps), [page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/observability/public/components/shared/page_template/page_template.tsx#:~:text=KibanaPageTemplateProps), [no_data_config.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/observability/public/utils/no_data_config.ts#:~:text=KibanaPageTemplateProps), [no_data_config.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/observability/public/utils/no_data_config.ts#:~:text=KibanaPageTemplateProps) | - | +| | [page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/observability/public/components/shared/page_template/page_template.tsx#:~:text=KibanaPageTemplate), [page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/observability/public/components/shared/page_template/page_template.tsx#:~:text=KibanaPageTemplate), [page_template.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/observability/public/components/shared/page_template/page_template.tsx#:~:text=KibanaPageTemplate) | - | | | [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/observability/public/application/index.tsx#:~:text=RedirectAppLinks), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/observability/public/application/index.tsx#:~:text=RedirectAppLinks), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/observability/public/application/index.tsx#:~:text=RedirectAppLinks) | - | +## osquery + +| Deprecated API | Reference location(s) | Remove By | +| ---------------|-----------|-----------| +| | [empty_state.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/components/empty_state.tsx#:~:text=KibanaPageTemplate), [empty_state.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/components/empty_state.tsx#:~:text=KibanaPageTemplate) | - | + + + ## painlessLab | Deprecated API | Reference location(s) | Remove By | @@ -582,6 +596,8 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| | | [middleware.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=indexPatterns), [dependencies_start_mock.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/mock/endpoint/dependencies_start_mock.ts#:~:text=indexPatterns) | - | +| | [use_primary_navigation.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_primary_navigation.tsx#:~:text=KibanaPageTemplateProps), [use_primary_navigation.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_primary_navigation.tsx#:~:text=KibanaPageTemplateProps), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/app/home/template_wrapper/bottom_bar/index.tsx#:~:text=KibanaPageTemplateProps), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/app/home/template_wrapper/bottom_bar/index.tsx#:~:text=KibanaPageTemplateProps) | - | +| | [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx#:~:text=KibanaPageTemplate), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx#:~:text=KibanaPageTemplate) | - | | | [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [isolation.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts#:~:text=mode), [isolation.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts#:~:text=mode)+ 2 more | 8.8.0 | | | [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [isolation.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts#:~:text=mode), [isolation.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts#:~:text=mode)+ 2 more | 8.8.0 | | | [request_context_factory.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/request_context_factory.ts#:~:text=authc), [request_context_factory.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/request_context_factory.ts#:~:text=authc), [create_signals_migration_route.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/create_signals_migration_route.ts#:~:text=authc), [delete_signals_migration_route.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/delete_signals_migration_route.ts#:~:text=authc), [finalize_signals_migration_route.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/finalize_signals_migration_route.ts#:~:text=authc), [open_close_signals_route.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts#:~:text=authc), [preview_rules_route.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/preview_rules_route.ts#:~:text=authc), [common.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/timeline/utils/common.ts#:~:text=authc) | - | @@ -602,6 +618,7 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| +| | [space_selector.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/spaces/public/space_selector/space_selector.tsx#:~:text=KibanaPageTemplate), [space_selector.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/spaces/public/space_selector/space_selector.tsx#:~:text=KibanaPageTemplate), [space_selector.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/spaces/public/space_selector/space_selector.tsx#:~:text=KibanaPageTemplate) | - | | | [spaces_management_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/spaces/public/management/spaces_management_app.tsx#:~:text=RedirectAppLinks), [spaces_management_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/spaces/public/management/spaces_management_app.tsx#:~:text=RedirectAppLinks), [spaces_management_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/spaces/public/management/spaces_management_app.tsx#:~:text=RedirectAppLinks) | - | | | [on_post_auth_interceptor.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/spaces/server/lib/request_interceptors/on_post_auth_interceptor.ts#:~:text=getKibanaFeatures), [spaces_usage_collector.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.ts#:~:text=getKibanaFeatures), [on_post_auth_interceptor.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/spaces/server/lib/request_interceptors/on_post_auth_interceptor.test.ts#:~:text=getKibanaFeatures) | 8.8.0 | | | [spaces_usage_collector.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.ts#:~:text=license%24), [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/spaces/server/plugin.ts#:~:text=license%24), [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/spaces/server/plugin.ts#:~:text=license%24), [spaces_usage_collector.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.test.ts#:~:text=license%24) | 8.8.0 | @@ -614,18 +631,25 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| -| | [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=IIndexPattern), [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=IIndexPattern) | - | | | [fetch_search_source_query.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/lib/fetch_search_source_query.ts#:~:text=fetch), [alert_type.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/alert_type.test.ts#:~:text=fetch), [alert_type.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/alert_type.test.ts#:~:text=fetch) | 8.1 | | | [entity_index_expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/entity_index_expression.tsx#:~:text=indexPatterns), [boundary_index_expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/boundary_index_expression.tsx#:~:text=indexPatterns), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/index.tsx#:~:text=indexPatterns), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/index.tsx#:~:text=indexPatterns), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/index.tsx#:~:text=indexPatterns) | - | | | [expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/threshold/expression.tsx#:~:text=fieldFormats) | - | | | [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=Filter), [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=Filter), [search_source_expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression.tsx#:~:text=Filter), [search_source_expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression.tsx#:~:text=Filter) | 8.1 | | | [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=Filter), [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=Filter), [search_source_expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression.tsx#:~:text=Filter), [search_source_expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression.tsx#:~:text=Filter) | 8.1 | -| | [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=IIndexPattern), [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=IIndexPattern), [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=IIndexPattern), [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=IIndexPattern) | - | | | [fetch_search_source_query.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/lib/fetch_search_source_query.ts#:~:text=fetch), [alert_type.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/alert_type.test.ts#:~:text=fetch), [alert_type.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/alert_type.test.ts#:~:text=fetch) | 8.1 | | | [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=Filter), [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=Filter), [search_source_expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression.tsx#:~:text=Filter), [search_source_expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression.tsx#:~:text=Filter) | 8.1 | +## synthetics + +| Deprecated API | Reference location(s) | Remove By | +| ---------------|-----------|-----------| +| | [use_no_data_config.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/apps/use_no_data_config.ts#:~:text=KibanaPageTemplateProps), [use_no_data_config.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/apps/use_no_data_config.ts#:~:text=KibanaPageTemplateProps) | - | +| | [alert_messages.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/lib/alert_types/alert_messages.tsx#:~:text=RedirectAppLinks), [alert_messages.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/lib/alert_types/alert_messages.tsx#:~:text=RedirectAppLinks), [alert_messages.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/lib/alert_types/alert_messages.tsx#:~:text=RedirectAppLinks), [uptime_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/apps/uptime_app.tsx#:~:text=RedirectAppLinks), [uptime_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/apps/uptime_app.tsx#:~:text=RedirectAppLinks), [uptime_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/apps/uptime_app.tsx#:~:text=RedirectAppLinks) | - | + + + ## transform | Deprecated API | Reference location(s) | Remove By | @@ -638,20 +662,22 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| -| | [fetch_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/fetch_index_patterns.ts#:~:text=IndexPatternsContract), [fetch_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/fetch_index_patterns.ts#:~:text=IndexPatternsContract), [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract), [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract), [create_index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/create_index_pattern_select.tsx#:~:text=IndexPatternsContract), [create_index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/create_index_pattern_select.tsx#:~:text=IndexPatternsContract), [fetch_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/fetch_index_patterns.ts#:~:text=IndexPatternsContract), [fetch_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/fetch_index_patterns.ts#:~:text=IndexPatternsContract), [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract), [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract)+ 2 more | - | -| | [query_string_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/query_string_input.tsx#:~:text=IIndexPattern), [query_string_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/query_string_input.tsx#:~:text=IIndexPattern), [query_string_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/query_string_input.tsx#:~:text=IIndexPattern), [query_string_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/query_string_input.tsx#:~:text=IIndexPattern), [query_string_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/query_string_input.tsx#:~:text=IIndexPattern), [query_bar_top_row.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx#:~:text=IIndexPattern), [query_bar_top_row.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx#:~:text=IIndexPattern), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IIndexPattern), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IIndexPattern), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IIndexPattern)+ 18 more | - | -| | [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [phrase_suggestor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/phrase_suggestor.tsx#:~:text=IFieldType), [phrase_suggestor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/phrase_suggestor.tsx#:~:text=IFieldType), [range_value_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/range_value_input.tsx#:~:text=IFieldType), [range_value_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/range_value_input.tsx#:~:text=IFieldType), [index.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx#:~:text=IFieldType), [index.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx#:~:text=IFieldType)+ 8 more | 8.2 | +| | [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract), [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract), [create_index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/create_index_pattern_select.tsx#:~:text=IndexPatternsContract), [create_index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/create_index_pattern_select.tsx#:~:text=IndexPatternsContract), [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract), [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract), [create_index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/create_index_pattern_select.tsx#:~:text=IndexPatternsContract), [create_index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/create_index_pattern_select.tsx#:~:text=IndexPatternsContract) | - | +| | [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IIndexPattern), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IIndexPattern), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IIndexPattern), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IIndexPattern), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IIndexPattern), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IIndexPattern), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IIndexPattern) | - | +| | [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IFieldType), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType)+ 25 more | 8.2 | | | [query_string_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/query_string_input.tsx#:~:text=indexPatterns) | - | | | [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=esFilters), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=esFilters), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=esFilters) | 8.1 | +| | [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [value.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.test.ts#:~:text=KueryNode)+ 2 more | 8.1 | | | [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=Filter)+ 10 more | 8.1 | | | [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS) | 8.1 | | | [filter_editor_utils.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts#:~:text=toggleFilterNegated), [filter_editor_utils.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts#:~:text=toggleFilterNegated), [filter_editor_utils.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts#:~:text=toggleFilterNegated), [filter_editor_utils.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts#:~:text=toggleFilterNegated), [filter_editor_utils.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts#:~:text=toggleFilterNegated) | 8.1 | | | [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=Filter)+ 10 more | 8.1 | -| | [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [phrase_suggestor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/phrase_suggestor.tsx#:~:text=IFieldType), [phrase_suggestor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/phrase_suggestor.tsx#:~:text=IFieldType), [range_value_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/range_value_input.tsx#:~:text=IFieldType), [range_value_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/range_value_input.tsx#:~:text=IFieldType), [index.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx#:~:text=IFieldType), [index.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx#:~:text=IFieldType)+ 26 more | 8.2 | -| | [query_string_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/query_string_input.tsx#:~:text=IIndexPattern), [query_string_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/query_string_input.tsx#:~:text=IIndexPattern), [query_string_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/query_string_input.tsx#:~:text=IIndexPattern), [query_string_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/query_string_input.tsx#:~:text=IIndexPattern), [query_string_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/query_string_input.tsx#:~:text=IIndexPattern), [query_bar_top_row.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx#:~:text=IIndexPattern), [query_bar_top_row.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx#:~:text=IIndexPattern), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IIndexPattern), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IIndexPattern), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IIndexPattern)+ 46 more | - | -| | [fetch_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/fetch_index_patterns.ts#:~:text=IndexPatternsContract), [fetch_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/fetch_index_patterns.ts#:~:text=IndexPatternsContract), [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract), [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract), [create_index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/create_index_pattern_select.tsx#:~:text=IndexPatternsContract), [create_index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/create_index_pattern_select.tsx#:~:text=IndexPatternsContract), [fetch_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/fetch_index_patterns.ts#:~:text=IndexPatternsContract), [fetch_index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/fetch_index_patterns.ts#:~:text=IndexPatternsContract), [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract), [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract)+ 2 more | - | -| | [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [phrase_suggestor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/phrase_suggestor.tsx#:~:text=IFieldType), [phrase_suggestor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/phrase_suggestor.tsx#:~:text=IFieldType), [range_value_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/range_value_input.tsx#:~:text=IFieldType), [range_value_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/range_value_input.tsx#:~:text=IFieldType), [index.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx#:~:text=IFieldType), [index.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx#:~:text=IFieldType)+ 8 more | 8.2 | +| | [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [value.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.test.ts#:~:text=KueryNode)+ 2 more | 8.1 | +| | [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IFieldType), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType)+ 60 more | 8.2 | +| | [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IIndexPattern), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IIndexPattern), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IIndexPattern), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IIndexPattern), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IIndexPattern), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IIndexPattern), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IIndexPattern), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IIndexPattern), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IIndexPattern), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IIndexPattern)+ 4 more | - | +| | [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract), [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract), [create_index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/create_index_pattern_select.tsx#:~:text=IndexPatternsContract), [create_index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/create_index_pattern_select.tsx#:~:text=IndexPatternsContract), [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract), [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract), [create_index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/create_index_pattern_select.tsx#:~:text=IndexPatternsContract), [create_index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/create_index_pattern_select.tsx#:~:text=IndexPatternsContract) | - | | | [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=Filter)+ 10 more | 8.1 | +| | [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [value.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.test.ts#:~:text=KueryNode)+ 2 more | 8.1 | @@ -664,18 +690,6 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ -## uptime - -| Deprecated API | Reference location(s) | Remove By | -| ---------------|-----------|-----------| -| | [update_kuery_string.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/hooks/update_kuery_string.ts#:~:text=IndexPattern), [update_kuery_string.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/hooks/update_kuery_string.ts#:~:text=IndexPattern), [uptime_index_pattern_context.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx#:~:text=IndexPattern), [uptime_index_pattern_context.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx#:~:text=IndexPattern), [uptime_index_pattern_context.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx#:~:text=IndexPattern), [update_kuery_string.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/hooks/update_kuery_string.ts#:~:text=IndexPattern), [update_kuery_string.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/hooks/update_kuery_string.ts#:~:text=IndexPattern), [uptime_index_pattern_context.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx#:~:text=IndexPattern), [uptime_index_pattern_context.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx#:~:text=IndexPattern), [uptime_index_pattern_context.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx#:~:text=IndexPattern) | - | -| | [uptime_index_pattern_context.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx#:~:text=indexPatterns) | - | -| | [update_kuery_string.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/hooks/update_kuery_string.ts#:~:text=IndexPattern), [update_kuery_string.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/hooks/update_kuery_string.ts#:~:text=IndexPattern), [uptime_index_pattern_context.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx#:~:text=IndexPattern), [uptime_index_pattern_context.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx#:~:text=IndexPattern), [uptime_index_pattern_context.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx#:~:text=IndexPattern), [update_kuery_string.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/hooks/update_kuery_string.ts#:~:text=IndexPattern), [update_kuery_string.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/hooks/update_kuery_string.ts#:~:text=IndexPattern), [uptime_index_pattern_context.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx#:~:text=IndexPattern), [uptime_index_pattern_context.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx#:~:text=IndexPattern), [uptime_index_pattern_context.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx#:~:text=IndexPattern) | - | -| | [update_kuery_string.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/hooks/update_kuery_string.ts#:~:text=IndexPattern), [update_kuery_string.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/hooks/update_kuery_string.ts#:~:text=IndexPattern), [uptime_index_pattern_context.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx#:~:text=IndexPattern), [uptime_index_pattern_context.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx#:~:text=IndexPattern), [uptime_index_pattern_context.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/contexts/uptime_index_pattern_context.tsx#:~:text=IndexPattern) | - | -| | [alert_messages.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/lib/alert_types/alert_messages.tsx#:~:text=RedirectAppLinks), [alert_messages.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/lib/alert_types/alert_messages.tsx#:~:text=RedirectAppLinks), [alert_messages.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/lib/alert_types/alert_messages.tsx#:~:text=RedirectAppLinks), [uptime_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/apps/uptime_app.tsx#:~:text=RedirectAppLinks), [uptime_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/apps/uptime_app.tsx#:~:text=RedirectAppLinks), [uptime_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/uptime/public/apps/uptime_app.tsx#:~:text=RedirectAppLinks) | - | - - - ## urlDrilldown | Deprecated API | Reference location(s) | Remove By | @@ -693,6 +707,7 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | | [selected_filters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/selected_filters.tsx#:~:text=IndexPattern), [selected_filters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/selected_filters.tsx#:~:text=IndexPattern), [selected_wildcards.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/selected_wildcards.tsx#:~:text=IndexPattern), [selected_wildcards.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/selected_wildcards.tsx#:~:text=IndexPattern), [selected_filters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/selected_filters.tsx#:~:text=IndexPattern), [selected_filters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/selected_filters.tsx#:~:text=IndexPattern), [selected_wildcards.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/selected_wildcards.tsx#:~:text=IndexPattern), [selected_wildcards.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/selected_wildcards.tsx#:~:text=IndexPattern) | - | | | [selected_filters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/selected_filters.tsx#:~:text=IndexPattern), [selected_filters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/selected_filters.tsx#:~:text=IndexPattern), [selected_wildcards.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/selected_wildcards.tsx#:~:text=IndexPattern), [selected_wildcards.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/selected_wildcards.tsx#:~:text=IndexPattern), [selected_filters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/selected_filters.tsx#:~:text=IndexPattern), [selected_filters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/selected_filters.tsx#:~:text=IndexPattern), [selected_wildcards.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/selected_wildcards.tsx#:~:text=IndexPattern), [selected_wildcards.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/selected_wildcards.tsx#:~:text=IndexPattern) | - | | | [selected_filters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/selected_filters.tsx#:~:text=IndexPattern), [selected_filters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/selected_filters.tsx#:~:text=IndexPattern), [selected_wildcards.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/selected_wildcards.tsx#:~:text=IndexPattern), [selected_wildcards.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/selected_wildcards.tsx#:~:text=IndexPattern) | - | +| | [rum_home.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/components/app/rum_dashboard/rum_home.tsx#:~:text=KibanaPageTemplateProps), [rum_home.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/components/app/rum_dashboard/rum_home.tsx#:~:text=KibanaPageTemplateProps) | - | | | [ux_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/application/ux_app.tsx#:~:text=RedirectAppLinks), [ux_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/application/ux_app.tsx#:~:text=RedirectAppLinks), [ux_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/ux/public/application/ux_app.tsx#:~:text=RedirectAppLinks) | - | @@ -782,7 +797,6 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | ---------------|-----------|-----------| | | [get_table_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/utils/get_table_columns.tsx#:~:text=RedirectAppLinks), [get_table_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/utils/get_table_columns.tsx#:~:text=RedirectAppLinks), [get_table_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/utils/get_table_columns.tsx#:~:text=RedirectAppLinks) | - | | | [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject) | 8.8.0 | -| | [visualize_listing.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx#:~:text=settings), [visualize_listing.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx#:~:text=settings) | 8.8.0 | | | [visualize_top_nav.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/components/visualize_top_nav.tsx#:~:text=onAppLeave), [visualize_editor_common.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/components/visualize_editor_common.tsx#:~:text=onAppLeave), [app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/app.tsx#:~:text=onAppLeave), [index.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/index.tsx#:~:text=onAppLeave) | 8.8.0 | diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 43a36e5f1cf9d..aab61180e9dc8 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -3,7 +3,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team summary: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. --- @@ -25,9 +25,8 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Plugin | Deprecated API | Reference location(s) | Remove By | | --------|-------|-----------|-----------| -| dataViews | | [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType)+ 13 more | 8.2 | -| dataViews | | [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType)+ 47 more | 8.2 | -| dataViews | | [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType)+ 13 more | 8.2 | +| dataViews | | [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType)+ 7 more | 8.2 | +| dataViews | | [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType)+ 23 more | 8.2 | | dataEnhanced | | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/types.ts#:~:text=KueryNode), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/types.ts#:~:text=KueryNode), [get_search_session_page.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/get_search_session_page.ts#:~:text=KueryNode), [get_search_session_page.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/get_search_session_page.ts#:~:text=KueryNode), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=KueryNode), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=KueryNode), [check_non_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.ts#:~:text=KueryNode), [check_non_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.ts#:~:text=KueryNode), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=KueryNode), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=KueryNode) | 8.1 | | dataEnhanced | | [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=nodeBuilder), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=nodeBuilder), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=nodeBuilder), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=nodeBuilder), [check_non_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.ts#:~:text=nodeBuilder), [check_non_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.ts#:~:text=nodeBuilder), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=nodeBuilder), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=nodeBuilder), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=nodeBuilder), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=nodeBuilder)+ 2 more | 8.1 | | dataEnhanced | | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/types.ts#:~:text=KueryNode), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/types.ts#:~:text=KueryNode), [get_search_session_page.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/get_search_session_page.ts#:~:text=KueryNode), [get_search_session_page.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/get_search_session_page.ts#:~:text=KueryNode), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=KueryNode), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=KueryNode), [check_non_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.ts#:~:text=KueryNode), [check_non_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.ts#:~:text=KueryNode), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=KueryNode), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=KueryNode) | 8.1 | @@ -49,7 +48,6 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | discover | | [anchor.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/context/services/anchor.ts#:~:text=fetch), [fetch_hits_in_interval.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/context/utils/fetch_hits_in_interval.ts#:~:text=fetch) | 8.1 | | discover | | [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=Filter), [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=Filter) | 8.1 | | discover | | [on_save_search.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx#:~:text=SavedObjectSaveModal), [on_save_search.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx#:~:text=SavedObjectSaveModal), [save_modal.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/graph/public/components/save_modal.tsx#:~:text=SavedObjectSaveModal), [save_modal.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/graph/public/components/save_modal.tsx#:~:text=SavedObjectSaveModal) | 8.8.0 | -| graph | | [listing_route.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/graph/public/apps/listing_route.tsx#:~:text=settings), [listing_route.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/graph/public/apps/listing_route.tsx#:~:text=settings) | 8.8.0 | | graph | | [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/graph/server/plugin.ts#:~:text=license%24) | 8.8.0 | @@ -69,7 +67,6 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Plugin | Deprecated API | Reference location(s) | Remove By | | --------|-------|-----------|-----------| -| maps | | [maps_list_view.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx#:~:text=settings), [maps_list_view.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx#:~:text=settings), [maps_list_view.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx#:~:text=settings) | 8.8.0 | | maps | | [render_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/render_app.tsx#:~:text=onAppLeave), [map_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx#:~:text=onAppLeave), [map_page.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/routes/map_page/map_page.tsx#:~:text=onAppLeave) | 8.8.0 | | maps | | [saved_object_migrations.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/saved_objects/saved_object_migrations.ts#:~:text=warning) | 8.8.0 | | mapsEms | | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/maps_ems/server/index.ts#:~:text=license%24) | 8.8.0 | @@ -99,7 +96,6 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | dashboard | | [saved_objects.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/services/saved_objects.ts#:~:text=SavedObjectSaveModal), [save_modal.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/top_nav/save_modal.tsx#:~:text=SavedObjectSaveModal), [save_modal.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/top_nav/save_modal.tsx#:~:text=SavedObjectSaveModal), [saved_object_save_modal_dashboard.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/saved_object_save_modal_dashboard.tsx#:~:text=SavedObjectSaveModal), [saved_object_save_modal_dashboard.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/saved_object_save_modal_dashboard.tsx#:~:text=SavedObjectSaveModal) | 8.8.0 | | dashboard | | [saved_object_loader.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/services/saved_object_loader.ts#:~:text=SavedObject), [saved_object_loader.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/services/saved_object_loader.ts#:~:text=SavedObject), [saved_object_loader.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/services/saved_object_loader.ts#:~:text=SavedObject), [saved_objects.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/services/saved_objects.ts#:~:text=SavedObject), [saved_dashboard.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/saved_dashboards/saved_dashboard.ts#:~:text=SavedObject), [saved_dashboard.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/saved_dashboards/saved_dashboard.ts#:~:text=SavedObject), [dashboard_tagging.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/dashboard_tagging.ts#:~:text=SavedObject), [dashboard_tagging.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/dashboard_tagging.ts#:~:text=SavedObject), [clone_panel_action.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/actions/clone_panel_action.tsx#:~:text=SavedObject), [clone_panel_action.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/actions/clone_panel_action.tsx#:~:text=SavedObject)+ 1 more | 8.8.0 | | dashboard | | [saved_dashboard.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/saved_dashboards/saved_dashboard.ts#:~:text=SavedObjectClass) | 8.8.0 | -| dashboard | | [dashboard_listing.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx#:~:text=settings), [dashboard_listing.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx#:~:text=settings) | 8.8.0 | | dashboard | | [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/types.ts#:~:text=onAppLeave), [dashboard_router.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/dashboard_router.tsx#:~:text=onAppLeave), [plugin.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/plugin.tsx#:~:text=onAppLeave) | 8.8.0 | | dashboard | | [migrations_730.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/server/saved_objects/migrations_730.ts#:~:text=warning), [migrations_730.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/server/saved_objects/migrations_730.ts#:~:text=warning) | 8.8.0 | @@ -208,15 +204,17 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | Plugin | Deprecated API | Reference location(s) | Remove By | | --------|-------|-----------|-----------| -| unifiedSearch | | [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [phrase_suggestor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/phrase_suggestor.tsx#:~:text=IFieldType), [phrase_suggestor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/phrase_suggestor.tsx#:~:text=IFieldType), [range_value_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/range_value_input.tsx#:~:text=IFieldType), [range_value_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/range_value_input.tsx#:~:text=IFieldType), [index.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx#:~:text=IFieldType), [index.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx#:~:text=IFieldType)+ 8 more | 8.2 | +| unifiedSearch | | [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IFieldType), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType)+ 25 more | 8.2 | | unifiedSearch | | [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=esFilters), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=esFilters), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=esFilters) | 8.1 | +| unifiedSearch | | [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [value.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.test.ts#:~:text=KueryNode)+ 2 more | 8.1 | | unifiedSearch | | [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=Filter)+ 10 more | 8.1 | | unifiedSearch | | [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS) | 8.1 | | unifiedSearch | | [filter_editor_utils.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts#:~:text=toggleFilterNegated), [filter_editor_utils.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts#:~:text=toggleFilterNegated), [filter_editor_utils.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts#:~:text=toggleFilterNegated), [filter_editor_utils.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts#:~:text=toggleFilterNegated), [filter_editor_utils.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts#:~:text=toggleFilterNegated) | 8.1 | | unifiedSearch | | [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=Filter)+ 10 more | 8.1 | -| unifiedSearch | | [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [phrase_suggestor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/phrase_suggestor.tsx#:~:text=IFieldType), [phrase_suggestor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/phrase_suggestor.tsx#:~:text=IFieldType), [range_value_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/range_value_input.tsx#:~:text=IFieldType), [range_value_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/range_value_input.tsx#:~:text=IFieldType), [index.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx#:~:text=IFieldType), [index.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx#:~:text=IFieldType)+ 26 more | 8.2 | -| unifiedSearch | | [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [filter_editor_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.ts#:~:text=IFieldType), [phrase_suggestor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/phrase_suggestor.tsx#:~:text=IFieldType), [phrase_suggestor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/phrase_suggestor.tsx#:~:text=IFieldType), [range_value_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/range_value_input.tsx#:~:text=IFieldType), [range_value_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/range_value_input.tsx#:~:text=IFieldType), [index.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx#:~:text=IFieldType), [index.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/index.tsx#:~:text=IFieldType)+ 8 more | 8.2 | +| unifiedSearch | | [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [value.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.test.ts#:~:text=KueryNode)+ 2 more | 8.1 | +| unifiedSearch | | [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IFieldType), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType)+ 60 more | 8.2 | | unifiedSearch | | [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=Filter)+ 10 more | 8.1 | +| unifiedSearch | | [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [value.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.test.ts#:~:text=KueryNode)+ 2 more | 8.1 | @@ -227,7 +225,6 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | lens | | [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject), [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject) | 8.8.0 | | lens | | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/types.ts#:~:text=onAppLeave), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/types.ts#:~:text=onAppLeave), [mounter.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/mounter.tsx#:~:text=onAppLeave), [visualize_top_nav.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/components/visualize_top_nav.tsx#:~:text=onAppLeave), [visualize_editor_common.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/components/visualize_editor_common.tsx#:~:text=onAppLeave), [app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/app.tsx#:~:text=onAppLeave), [index.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/index.tsx#:~:text=onAppLeave) | 8.8.0 | | lens | | [saved_object_migrations.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/migrations/saved_object_migrations.ts#:~:text=warning), [saved_object_migrations.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/migrations/saved_object_migrations.ts#:~:text=warning) | 8.8.0 | -| visualizations | | [visualize_listing.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx#:~:text=settings), [visualize_listing.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx#:~:text=settings) | 8.8.0 | | management | | [application.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/management/public/application.tsx#:~:text=appBasePath) | 8.8.0 | | visTypeVega | | [plugin.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/vega/public/plugin.ts#:~:text=injectedMetadata) | 8.8.0 | | visTypeVega | | [search_api.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/vega/public/data_model/search_api.ts#:~:text=injectedMetadata), [plugin.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/vega/public/plugin.ts#:~:text=injectedMetadata) | 8.8.0 | \ No newline at end of file diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index fefa3a0c3391c..21a175173b3f6 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github summary: API docs for the devTools plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/discover.devdocs.json b/api_docs/discover.devdocs.json index 4f5f940b63275..e4d6e9e749105 100644 --- a/api_docs/discover.devdocs.json +++ b/api_docs/discover.devdocs.json @@ -1222,20 +1222,6 @@ "interfaces": [], "enums": [], "misc": [ - { - "parentPluginId": "discover", - "id": "def-common.APP_ID", - "type": "string", - "tags": [], - "label": "APP_ID", - "description": [], - "signature": [ - "\"discover\"" - ], - "path": "src/plugins/discover/common/index.ts", - "deprecated": false, - "initialIsOpen": false - }, { "parentPluginId": "discover", "id": "def-common.CONTEXT_DEFAULT_SIZE_SETTING", diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index 43970283258bf..960d60c26777d 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github summary: API docs for the discover plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-disco | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 77 | 0 | 61 | 7 | +| 76 | 0 | 60 | 7 | ## Client diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index 76d0262f5cfe8..e8c18b01c1cfc 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github summary: API docs for the discoverEnhanced plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/elastic_analytics.devdocs.json b/api_docs/elastic_analytics.devdocs.json deleted file mode 100644 index 0d1df6975ed2f..0000000000000 --- a/api_docs/elastic_analytics.devdocs.json +++ /dev/null @@ -1,1726 +0,0 @@ -{ - "id": "@elastic/analytics", - "client": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - }, - "server": { - "classes": [], - "functions": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.createAnalytics", - "type": "Function", - "tags": [], - "label": "createAnalytics", - "description": [ - "\nCreates an {@link AnalyticsClient}." - ], - "signature": [ - "(initContext: ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.AnalyticsClientInitContext", - "text": "AnalyticsClientInitContext" - }, - ") => ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.IAnalyticsClient", - "text": "IAnalyticsClient" - } - ], - "path": "packages/elastic-analytics/src/index.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.createAnalytics.$1", - "type": "Object", - "tags": [], - "label": "initContext", - "description": [ - "The initial context to create the client {@link AnalyticsClientInitContext }" - ], - "signature": [ - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.AnalyticsClientInitContext", - "text": "AnalyticsClientInitContext" - } - ], - "path": "packages/elastic-analytics/src/index.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - } - ], - "interfaces": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.AnalyticsClientInitContext", - "type": "Interface", - "tags": [], - "label": "AnalyticsClientInitContext", - "description": [ - "\nGeneral settings of the analytics client" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.AnalyticsClientInitContext.isDev", - "type": "boolean", - "tags": [], - "label": "isDev", - "description": [ - "\nBoolean indicating if it's running in developer mode." - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.AnalyticsClientInitContext.sendTo", - "type": "CompoundType", - "tags": [], - "label": "sendTo", - "description": [ - "\nSpecify if the shippers should send their data to the production or staging environments." - ], - "signature": [ - "\"staging\" | \"production\"" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.AnalyticsClientInitContext.logger", - "type": "Object", - "tags": [], - "label": "logger", - "description": [ - "\nApplication-provided logger." - ], - "signature": [ - "Logger" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.ContextProviderOpts", - "type": "Interface", - "tags": [], - "label": "ContextProviderOpts", - "description": [ - "\nDefinition of a context provider" - ], - "signature": [ - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.ContextProviderOpts", - "text": "ContextProviderOpts" - }, - "" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.ContextProviderOpts.name", - "type": "string", - "tags": [], - "label": "name", - "description": [ - "\nThe name of the provider." - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.ContextProviderOpts.context$", - "type": "Object", - "tags": [], - "label": "context$", - "description": [ - "\nObservable that emits the custom context." - ], - "signature": [ - "Observable", - "" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.ContextProviderOpts.schema", - "type": "Object", - "tags": [], - "label": "schema", - "description": [ - "\nSchema declaring and documenting the expected output in the context$\n" - ], - "signature": [ - "{ [Key in keyof Required]: ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaValue", - "text": "SchemaValue" - }, - "; }" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.Event", - "type": "Interface", - "tags": [], - "label": "Event", - "description": [ - "\nDefinition of the full event structure" - ], - "path": "packages/elastic-analytics/src/events/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.Event.timestamp", - "type": "string", - "tags": [], - "label": "timestamp", - "description": [ - "\nThe time the event was generated in ISO format." - ], - "path": "packages/elastic-analytics/src/events/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.Event.event_type", - "type": "string", - "tags": [], - "label": "event_type", - "description": [ - "\nThe event type." - ], - "path": "packages/elastic-analytics/src/events/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.Event.properties", - "type": "Object", - "tags": [], - "label": "properties", - "description": [ - "\nThe specific properties of the event type." - ], - "signature": [ - "{ [x: string]: unknown; }" - ], - "path": "packages/elastic-analytics/src/events/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.Event.context", - "type": "Object", - "tags": [], - "label": "context", - "description": [ - "\nThe {@link EventContext} enriched during the processing pipeline." - ], - "signature": [ - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.EventContext", - "text": "EventContext" - } - ], - "path": "packages/elastic-analytics/src/events/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.EventContext", - "type": "Interface", - "tags": [], - "label": "EventContext", - "description": [], - "path": "packages/elastic-analytics/src/events/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.EventContext.Unnamed", - "type": "IndexSignature", - "tags": [], - "label": "[key: string]: unknown", - "description": [], - "signature": [ - "[key: string]: unknown" - ], - "path": "packages/elastic-analytics/src/events/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.EventTypeOpts", - "type": "Interface", - "tags": [], - "label": "EventTypeOpts", - "description": [ - "\nDefinition of an Event Type." - ], - "signature": [ - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.EventTypeOpts", - "text": "EventTypeOpts" - }, - "" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.EventTypeOpts.eventType", - "type": "string", - "tags": [], - "label": "eventType", - "description": [ - "\nThe event type's unique name." - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.EventTypeOpts.schema", - "type": "Object", - "tags": [], - "label": "schema", - "description": [ - "\nSchema declaring and documenting the expected structure of this event type.\n" - ], - "signature": [ - "{ [Key in keyof Required]: ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaValue", - "text": "SchemaValue" - }, - "; }" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IAnalyticsClient", - "type": "Interface", - "tags": [], - "label": "IAnalyticsClient", - "description": [ - "\nAnalytics client's public APIs" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IAnalyticsClient.reportEvent", - "type": "Function", - "tags": [], - "label": "reportEvent", - "description": [ - "\nReports a telemetry event." - ], - "signature": [ - ">(eventType: string, eventData: EventTypeData) => void" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IAnalyticsClient.reportEvent.$1", - "type": "string", - "tags": [], - "label": "eventType", - "description": [ - "The event type registered via the `registerEventType` API." - ], - "signature": [ - "string" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IAnalyticsClient.reportEvent.$2", - "type": "Uncategorized", - "tags": [], - "label": "eventData", - "description": [ - "The properties matching the schema declared in the `registerEventType` API." - ], - "signature": [ - "EventTypeData" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IAnalyticsClient.registerEventType", - "type": "Function", - "tags": [], - "label": "registerEventType", - "description": [ - "\nRegisters the event type that will be emitted via the reportEvent API." - ], - "signature": [ - "(eventTypeOps: ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.EventTypeOpts", - "text": "EventTypeOpts" - }, - ") => void" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IAnalyticsClient.registerEventType.$1", - "type": "Object", - "tags": [], - "label": "eventTypeOps", - "description": [], - "signature": [ - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.EventTypeOpts", - "text": "EventTypeOpts" - }, - "" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IAnalyticsClient.registerShipper", - "type": "Function", - "tags": [], - "label": "registerShipper", - "description": [ - "\nSet up the shipper that will be used to report the telemetry events." - ], - "signature": [ - "(Shipper: ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.ShipperClassConstructor", - "text": "ShipperClassConstructor" - }, - ", shipperConfig: ShipperConfig, opts?: ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.RegisterShipperOpts", - "text": "RegisterShipperOpts" - }, - " | undefined) => void" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IAnalyticsClient.registerShipper.$1", - "type": "Object", - "tags": [], - "label": "Shipper", - "description": [ - "The {@link IShipper } class to instantiate the shipper." - ], - "signature": [ - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.ShipperClassConstructor", - "text": "ShipperClassConstructor" - }, - "" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IAnalyticsClient.registerShipper.$2", - "type": "Uncategorized", - "tags": [], - "label": "shipperConfig", - "description": [ - "The config specific to the Shipper to instantiate." - ], - "signature": [ - "ShipperConfig" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IAnalyticsClient.registerShipper.$3", - "type": "Object", - "tags": [], - "label": "opts", - "description": [ - "Additional options to register the shipper {@link RegisterShipperOpts }." - ], - "signature": [ - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.RegisterShipperOpts", - "text": "RegisterShipperOpts" - }, - " | undefined" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IAnalyticsClient.optIn", - "type": "Function", - "tags": [], - "label": "optIn", - "description": [ - "\nUsed to control the user's consent to report the data.\nIn the advanced mode, it allows to \"cherry-pick\" which events and shippers are enabled/disabled." - ], - "signature": [ - "(optInConfig: ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.OptInConfig", - "text": "OptInConfig" - }, - ") => void" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IAnalyticsClient.optIn.$1", - "type": "Object", - "tags": [], - "label": "optInConfig", - "description": [ - "{@link OptInConfig }" - ], - "signature": [ - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.OptInConfig", - "text": "OptInConfig" - } - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IAnalyticsClient.registerContextProvider", - "type": "Function", - "tags": [], - "label": "registerContextProvider", - "description": [ - "\nRegisters the context provider to enrich the any reported events." - ], - "signature": [ - "(contextProviderOpts: ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.ContextProviderOpts", - "text": "ContextProviderOpts" - }, - ") => void" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IAnalyticsClient.registerContextProvider.$1", - "type": "Object", - "tags": [], - "label": "contextProviderOpts", - "description": [ - "{@link ContextProviderOpts }" - ], - "signature": [ - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.ContextProviderOpts", - "text": "ContextProviderOpts" - }, - "" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IAnalyticsClient.removeContextProvider", - "type": "Function", - "tags": [], - "label": "removeContextProvider", - "description": [ - "\nRemoves the context provider and stop enriching the events from its context." - ], - "signature": [ - "(contextProviderName: string) => void" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IAnalyticsClient.removeContextProvider.$1", - "type": "string", - "tags": [], - "label": "contextProviderName", - "description": [ - "The name of the context provider to remove." - ], - "signature": [ - "string" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IAnalyticsClient.telemetryCounter$", - "type": "Object", - "tags": [], - "label": "telemetryCounter$", - "description": [ - "\nObservable to emit the stats of the processed events." - ], - "signature": [ - "Observable", - "<", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.TelemetryCounter", - "text": "TelemetryCounter" - }, - ">" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IShipper", - "type": "Interface", - "tags": [], - "label": "IShipper", - "description": [ - "\nBasic structure of a Shipper" - ], - "path": "packages/elastic-analytics/src/shippers/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IShipper.reportEvents", - "type": "Function", - "tags": [], - "label": "reportEvents", - "description": [ - "\nAdapts and ships the event to the persisting/analytics solution." - ], - "signature": [ - "(events: ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.Event", - "text": "Event" - }, - "[]) => void" - ], - "path": "packages/elastic-analytics/src/shippers/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IShipper.reportEvents.$1", - "type": "Array", - "tags": [], - "label": "events", - "description": [ - "batched events {@link Event }" - ], - "signature": [ - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.Event", - "text": "Event" - }, - "[]" - ], - "path": "packages/elastic-analytics/src/shippers/types.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IShipper.optIn", - "type": "Function", - "tags": [], - "label": "optIn", - "description": [ - "\nStops/restarts the shipping mechanism based on the value of isOptedIn" - ], - "signature": [ - "(isOptedIn: boolean) => void" - ], - "path": "packages/elastic-analytics/src/shippers/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IShipper.optIn.$1", - "type": "boolean", - "tags": [], - "label": "isOptedIn", - "description": [ - "`true` for resume sending events. `false` to stop." - ], - "signature": [ - "boolean" - ], - "path": "packages/elastic-analytics/src/shippers/types.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IShipper.extendContext", - "type": "Function", - "tags": [], - "label": "extendContext", - "description": [ - "\nPerform any necessary calls to the persisting/analytics solution to set the event's context." - ], - "signature": [ - "((newContext: ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.EventContext", - "text": "EventContext" - }, - ") => void) | undefined" - ], - "path": "packages/elastic-analytics/src/shippers/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IShipper.extendContext.$1", - "type": "Object", - "tags": [], - "label": "newContext", - "description": [], - "signature": [ - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.EventContext", - "text": "EventContext" - } - ], - "path": "packages/elastic-analytics/src/shippers/types.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.IShipper.telemetryCounter$", - "type": "Object", - "tags": [], - "label": "telemetryCounter$", - "description": [ - "\nObservable to emit the stats of the processed events." - ], - "signature": [ - "Observable", - "<", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.TelemetryCounter", - "text": "TelemetryCounter" - }, - "> | undefined" - ], - "path": "packages/elastic-analytics/src/shippers/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.OptInConfig", - "type": "Interface", - "tags": [], - "label": "OptInConfig", - "description": [ - "\n" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.OptInConfig.global", - "type": "Object", - "tags": [], - "label": "global", - "description": [ - "\nControls the global enabled/disabled behaviour of the client and shippers." - ], - "signature": [ - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.OptInConfigPerType", - "text": "OptInConfigPerType" - } - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.OptInConfig.event_types", - "type": "Object", - "tags": [], - "label": "event_types", - "description": [ - "\nControls if an event type should be disabled for a specific type of shipper." - ], - "signature": [ - "Record | undefined" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.OptInConfigPerType", - "type": "Interface", - "tags": [], - "label": "OptInConfigPerType", - "description": [ - "\nSets whether a type of event is enabled/disabled globally or per shipper." - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.OptInConfigPerType.enabled", - "type": "boolean", - "tags": [], - "label": "enabled", - "description": [ - "\nThe event type is globally enabled." - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.OptInConfigPerType.shippers", - "type": "Object", - "tags": [], - "label": "shippers", - "description": [ - "\nControls if an event type should be disabled for a specific type of shipper." - ], - "signature": [ - "Record | undefined" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.RegisterShipperOpts", - "type": "Interface", - "tags": [], - "label": "RegisterShipperOpts", - "description": [ - "\nOptional options to register a shipper" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "children": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.SchemaArray", - "type": "Interface", - "tags": [], - "label": "SchemaArray", - "description": [ - "\nSchema to represent an array" - ], - "signature": [ - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaArray", - "text": "SchemaArray" - }, - " extends ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaMeta", - "text": "SchemaMeta" - }, - "" - ], - "path": "packages/elastic-analytics/src/schema/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.SchemaArray.type", - "type": "string", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "\"array\"" - ], - "path": "packages/elastic-analytics/src/schema/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.SchemaArray.items", - "type": "CompoundType", - "tags": [], - "label": "items", - "description": [], - "signature": [ - "{ type: \"pass_through\"; _meta: { description: string; } & ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaMetaOptional", - "text": "SchemaMetaOptional" - }, - "; } | (unknown extends Value ? ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaArray", - "text": "SchemaArray" - }, - " | ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaObject", - "text": "SchemaObject" - }, - " | ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaChildValue", - "text": "SchemaChildValue" - }, - " : NonNullable extends (infer U)[] ? ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaArray", - "text": "SchemaArray" - }, - " : NonNullable extends object ? ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaObject", - "text": "SchemaObject" - }, - " : ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaChildValue", - "text": "SchemaChildValue" - }, - ")" - ], - "path": "packages/elastic-analytics/src/schema/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.SchemaChildValue", - "type": "Interface", - "tags": [], - "label": "SchemaChildValue", - "description": [], - "signature": [ - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaChildValue", - "text": "SchemaChildValue" - }, - "" - ], - "path": "packages/elastic-analytics/src/schema/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.SchemaChildValue.type", - "type": "Uncategorized", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "NonNullable extends string ? ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.AllowedSchemaStringTypes", - "text": "AllowedSchemaStringTypes" - }, - " : NonNullable extends number ? ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.AllowedSchemaNumberTypes", - "text": "AllowedSchemaNumberTypes" - }, - " : NonNullable extends boolean ? \"boolean\" : ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.AllowedSchemaTypes", - "text": "AllowedSchemaTypes" - } - ], - "path": "packages/elastic-analytics/src/schema/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.SchemaChildValue._meta", - "type": "CompoundType", - "tags": [], - "label": "_meta", - "description": [], - "signature": [ - "{ description: string; } & ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaMetaOptional", - "text": "SchemaMetaOptional" - }, - "" - ], - "path": "packages/elastic-analytics/src/schema/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.SchemaMeta", - "type": "Interface", - "tags": [], - "label": "SchemaMeta", - "description": [ - "\nSchema meta with optional description" - ], - "signature": [ - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaMeta", - "text": "SchemaMeta" - }, - "" - ], - "path": "packages/elastic-analytics/src/schema/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.SchemaMeta._meta", - "type": "CompoundType", - "tags": [], - "label": "_meta", - "description": [], - "signature": [ - "({ description?: string | undefined; } & ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaMetaOptional", - "text": "SchemaMetaOptional" - }, - ") | undefined" - ], - "path": "packages/elastic-analytics/src/schema/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.SchemaObject", - "type": "Interface", - "tags": [], - "label": "SchemaObject", - "description": [ - "\nSchema to represent an object" - ], - "signature": [ - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaObject", - "text": "SchemaObject" - }, - " extends ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaMeta", - "text": "SchemaMeta" - }, - "" - ], - "path": "packages/elastic-analytics/src/schema/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.SchemaObject.properties", - "type": "Object", - "tags": [], - "label": "properties", - "description": [], - "signature": [ - "{ [Key in keyof Required]: ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaValue", - "text": "SchemaValue" - }, - "; }" - ], - "path": "packages/elastic-analytics/src/schema/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.ShipperClassConstructor", - "type": "Interface", - "tags": [], - "label": "ShipperClassConstructor", - "description": [ - "\nConstructor of a {@link IShipper}" - ], - "signature": [ - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.ShipperClassConstructor", - "text": "ShipperClassConstructor" - }, - "" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.ShipperClassConstructor.shipperName", - "type": "string", - "tags": [], - "label": "shipperName", - "description": [ - "\nThe shipper's unique name" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.ShipperClassConstructor.Unnamed", - "type": "Any", - "tags": [], - "label": "Unnamed", - "description": [ - "\nThe constructor" - ], - "signature": [ - "any" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.TelemetryCounter", - "type": "Interface", - "tags": [], - "label": "TelemetryCounter", - "description": [ - "\nShape of the events emitted by the telemetryCounter$ observable" - ], - "path": "packages/elastic-analytics/src/events/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.TelemetryCounter.type", - "type": "Enum", - "tags": [], - "label": "type", - "description": [ - "\nIndicates if the event contains data about succeeded, failed or dropped events." - ], - "signature": [ - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.TelemetryCounterType", - "text": "TelemetryCounterType" - } - ], - "path": "packages/elastic-analytics/src/events/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.TelemetryCounter.source", - "type": "string", - "tags": [], - "label": "source", - "description": [ - "\nWho emitted the event? It can be \"client\" or the name of the shipper." - ], - "path": "packages/elastic-analytics/src/events/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.TelemetryCounter.event_type", - "type": "string", - "tags": [], - "label": "event_type", - "description": [ - "\nThe event type the success/failure/drop event refers to." - ], - "path": "packages/elastic-analytics/src/events/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.TelemetryCounter.code", - "type": "string", - "tags": [], - "label": "code", - "description": [ - "\nCode to provide additional information about the success or failure. Examples are 200/400/504/ValidationError/UnknownError" - ], - "path": "packages/elastic-analytics/src/events/types.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.TelemetryCounter.count", - "type": "number", - "tags": [], - "label": "count", - "description": [ - "\nThe number of events that this counter refers to." - ], - "path": "packages/elastic-analytics/src/events/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - } - ], - "enums": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.TelemetryCounterType", - "type": "Enum", - "tags": [], - "label": "TelemetryCounterType", - "description": [ - "\nTypes of the Telemetry Counter: It allows to differentiate what happened to the events" - ], - "path": "packages/elastic-analytics/src/events/types.ts", - "deprecated": false, - "initialIsOpen": false - } - ], - "misc": [ - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.AllowedSchemaBooleanTypes", - "type": "Type", - "tags": [], - "label": "AllowedSchemaBooleanTypes", - "description": [ - "Types matching boolean values" - ], - "signature": [ - "\"boolean\"" - ], - "path": "packages/elastic-analytics/src/schema/types.ts", - "deprecated": false, - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.AllowedSchemaNumberTypes", - "type": "Type", - "tags": [], - "label": "AllowedSchemaNumberTypes", - "description": [ - "Types matching number values" - ], - "signature": [ - "\"date\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"double\"" - ], - "path": "packages/elastic-analytics/src/schema/types.ts", - "deprecated": false, - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.AllowedSchemaStringTypes", - "type": "Type", - "tags": [], - "label": "AllowedSchemaStringTypes", - "description": [ - "Types matching string values" - ], - "signature": [ - "\"keyword\" | \"date\" | \"text\"" - ], - "path": "packages/elastic-analytics/src/schema/types.ts", - "deprecated": false, - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.AllowedSchemaTypes", - "type": "Type", - "tags": [], - "label": "AllowedSchemaTypes", - "description": [ - "\nPossible type values in the schema" - ], - "signature": [ - "\"boolean\" | \"keyword\" | \"date\" | \"text\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"double\"" - ], - "path": "packages/elastic-analytics/src/schema/types.ts", - "deprecated": false, - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.EventType", - "type": "Type", - "tags": [], - "label": "EventType", - "description": [ - "\nEvent Type used for indexed structures. Only used to improve the readability of the types" - ], - "signature": [ - "string" - ], - "path": "packages/elastic-analytics/src/events/types.ts", - "deprecated": false, - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.PossibleSchemaTypes", - "type": "Type", - "tags": [], - "label": "PossibleSchemaTypes", - "description": [ - "\nHelper to ensure the declared types match the schema types" - ], - "signature": [ - "Value extends string ? ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.AllowedSchemaStringTypes", - "text": "AllowedSchemaStringTypes" - }, - " : Value extends number ? ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.AllowedSchemaNumberTypes", - "text": "AllowedSchemaNumberTypes" - }, - " : Value extends boolean ? \"boolean\" : ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.AllowedSchemaTypes", - "text": "AllowedSchemaTypes" - } - ], - "path": "packages/elastic-analytics/src/schema/types.ts", - "deprecated": false, - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.RootSchema", - "type": "Type", - "tags": [], - "label": "RootSchema", - "description": [ - "\nSchema definition to match the structure of the properties provided.\n" - ], - "signature": [ - "{ [Key in keyof Required]: ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaValue", - "text": "SchemaValue" - }, - "; }" - ], - "path": "packages/elastic-analytics/src/schema/types.ts", - "deprecated": false, - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.SchemaMetaOptional", - "type": "Type", - "tags": [], - "label": "SchemaMetaOptional", - "description": [ - "\nEnforces { optional: true } if the value can be undefined" - ], - "signature": [ - "unknown extends Value ? { optional?: boolean | undefined; } : undefined extends Value ? { optional: true; } : { optional?: false | undefined; }" - ], - "path": "packages/elastic-analytics/src/schema/types.ts", - "deprecated": false, - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.SchemaValue", - "type": "Type", - "tags": [], - "label": "SchemaValue", - "description": [ - "\nType that defines all the possible values that the Schema accepts.\nThese types definitions are helping to identify earlier the possible missing `properties` nesting when\nmanually defining the schemas." - ], - "signature": [ - "{ type: \"pass_through\"; _meta: { description: string; } & ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaMetaOptional", - "text": "SchemaMetaOptional" - }, - "; } | (unknown extends Value ? ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaArray", - "text": "SchemaArray" - }, - " | ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaObject", - "text": "SchemaObject" - }, - " | ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaChildValue", - "text": "SchemaChildValue" - }, - " : NonNullable extends (infer U)[] ? ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaArray", - "text": "SchemaArray" - }, - " : NonNullable extends object ? ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaObject", - "text": "SchemaObject" - }, - " : ", - { - "pluginId": "@elastic/analytics", - "scope": "server", - "docId": "kibElasticAnalyticsPluginApi", - "section": "def-server.SchemaChildValue", - "text": "SchemaChildValue" - }, - ")" - ], - "path": "packages/elastic-analytics/src/schema/types.ts", - "deprecated": false, - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/analytics", - "id": "def-server.ShipperName", - "type": "Type", - "tags": [], - "label": "ShipperName", - "description": [ - "\nShipper Name used for indexed structures. Only used to improve the readability of the types" - ], - "signature": [ - "string" - ], - "path": "packages/elastic-analytics/src/analytics_client/types.ts", - "deprecated": false, - "initialIsOpen": false - } - ], - "objects": [] - }, - "common": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - } -} \ No newline at end of file diff --git a/api_docs/elastic_analytics.mdx b/api_docs/elastic_analytics.mdx deleted file mode 100644 index 2d00c52f5e6a0..0000000000000 --- a/api_docs/elastic_analytics.mdx +++ /dev/null @@ -1,36 +0,0 @@ ---- -id: kibElasticAnalyticsPluginApi -slug: /kibana-dev-docs/api/elastic-analytics -title: "@elastic/analytics" -image: https://source.unsplash.com/400x175/?github -summary: API docs for the @elastic/analytics plugin -date: 2022-04-05 -tags: ['contributor', 'dev', 'apidocs', 'kibana', '@elastic/analytics'] -warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. ---- -import elasticAnalyticsObj from './elastic_analytics.devdocs.json'; - - - -Contact [Owner missing] for questions regarding this plugin. - -**Code health stats** - -| Public API count | Any count | Items lacking comments | Missing exports | -|-------------------|-----------|------------------------|-----------------| -| 82 | 1 | 11 | 0 | - -## Server - -### Functions - - -### Interfaces - - -### Enums - - -### Consts, variables and types - - diff --git a/api_docs/elastic_apm_synthtrace.devdocs.json b/api_docs/elastic_apm_synthtrace.devdocs.json index 0e802d55936c3..aa59d75c2508a 100644 --- a/api_docs/elastic_apm_synthtrace.devdocs.json +++ b/api_docs/elastic_apm_synthtrace.devdocs.json @@ -64,20 +64,36 @@ { "parentPluginId": "@elastic/apm-synthtrace", "id": "def-server.ApmSynthtraceEsClient.Unnamed.$3", - "type": "boolean", + "type": "Object", "tags": [], - "label": "forceDataStreams", + "label": "options", "description": [], "signature": [ - "boolean" + "ApmSynthtraceEsClientOptions", + " | undefined" ], "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, - "isRequired": true + "isRequired": false } ], "returnComment": [] }, + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.ApmSynthtraceEsClient.runningVersion", + "type": "Function", + "tags": [], + "label": "runningVersion", + "description": [], + "signature": [ + "() => Promise" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, { "parentPluginId": "@elastic/apm-synthtrace", "id": "def-server.ApmSynthtraceEsClient.clean", @@ -123,6 +139,53 @@ ], "returnComment": [] }, + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.ApmSynthtraceEsClient.registerGcpRepository", + "type": "Function", + "tags": [], + "label": "registerGcpRepository", + "description": [], + "signature": [ + "(connectionString: string) => Promise" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.ApmSynthtraceEsClient.registerGcpRepository.$1", + "type": "string", + "tags": [], + "label": "connectionString", + "description": [], + "signature": [ + "string" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.ApmSynthtraceEsClient.refresh", + "type": "Function", + "tags": [], + "label": "refresh", + "description": [], + "signature": [ + "() => Promise<", + "ShardsOperationResponseBase", + ">" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, { "parentPluginId": "@elastic/apm-synthtrace", "id": "def-server.ApmSynthtraceEsClient.index", @@ -131,27 +194,43 @@ "label": "index", "description": [], "signature": [ - "(events: ", + "(events: ", { "pluginId": "@elastic/apm-synthtrace", "scope": "server", "docId": "kibElasticApmSynthtracePluginApi", - "section": "def-server.SpanIterable", - "text": "SpanIterable" + "section": "def-server.EntityIterable", + "text": "EntityIterable" }, - " | ", + " | ", { "pluginId": "@elastic/apm-synthtrace", "scope": "server", "docId": "kibElasticApmSynthtracePluginApi", - "section": "def-server.SpanIterable", - "text": "SpanIterable" + "section": "def-server.EntityIterable", + "text": "EntityIterable" }, - "[], options?: ", + "[], options?: ", "StreamToBulkOptions", - " | undefined) => Promise<", - "ShardsOperationResponseBase", - ">" + "<", + { + "pluginId": "@elastic/apm-synthtrace", + "scope": "server", + "docId": "kibElasticApmSynthtracePluginApi", + "section": "def-server.ApmFields", + "text": "ApmFields" + }, + "> | undefined, streamProcessor?: ", + "StreamProcessor", + "<", + { + "pluginId": "@elastic/apm-synthtrace", + "scope": "server", + "docId": "kibElasticApmSynthtracePluginApi", + "section": "def-server.ApmFields", + "text": "ApmFields" + }, + "> | undefined) => Promise" ], "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, @@ -168,18 +247,18 @@ "pluginId": "@elastic/apm-synthtrace", "scope": "server", "docId": "kibElasticApmSynthtracePluginApi", - "section": "def-server.SpanIterable", - "text": "SpanIterable" + "section": "def-server.EntityIterable", + "text": "EntityIterable" }, - " | ", + " | ", { "pluginId": "@elastic/apm-synthtrace", "scope": "server", "docId": "kibElasticApmSynthtracePluginApi", - "section": "def-server.SpanIterable", - "text": "SpanIterable" + "section": "def-server.EntityIterable", + "text": "EntityIterable" }, - "[]" + "[]" ], "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, @@ -194,7 +273,38 @@ "description": [], "signature": [ "StreamToBulkOptions", - " | undefined" + "<", + { + "pluginId": "@elastic/apm-synthtrace", + "scope": "server", + "docId": "kibElasticApmSynthtracePluginApi", + "section": "def-server.ApmFields", + "text": "ApmFields" + }, + "> | undefined" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", + "deprecated": false, + "isRequired": false + }, + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.ApmSynthtraceEsClient.index.$3", + "type": "Object", + "tags": [], + "label": "streamProcessor", + "description": [], + "signature": [ + "StreamProcessor", + "<", + { + "pluginId": "@elastic/apm-synthtrace", + "scope": "server", + "docId": "kibElasticApmSynthtracePluginApi", + "section": "def-server.ApmFields", + "text": "ApmFields" + }, + "> | undefined" ], "path": "packages/elastic-apm-synthtrace/src/lib/apm/client/apm_synthtrace_es_client.ts", "deprecated": false, @@ -208,34 +318,35 @@ }, { "parentPluginId": "@elastic/apm-synthtrace", - "id": "def-server.SpanArrayIterable", + "id": "def-server.EntityArrayIterable", "type": "Class", "tags": [], - "label": "SpanArrayIterable", + "label": "EntityArrayIterable", "description": [], "signature": [ { "pluginId": "@elastic/apm-synthtrace", "scope": "server", "docId": "kibElasticApmSynthtracePluginApi", - "section": "def-server.SpanArrayIterable", - "text": "SpanArrayIterable" + "section": "def-server.EntityArrayIterable", + "text": "EntityArrayIterable" }, - " implements ", + " implements ", { "pluginId": "@elastic/apm-synthtrace", "scope": "server", "docId": "kibElasticApmSynthtracePluginApi", - "section": "def-server.SpanIterable", - "text": "SpanIterable" - } + "section": "def-server.EntityIterable", + "text": "EntityIterable" + }, + "" ], - "path": "packages/elastic-apm-synthtrace/src/lib/span_iterable.ts", + "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [ { "parentPluginId": "@elastic/apm-synthtrace", - "id": "def-server.SpanArrayIterable.Unnamed", + "id": "def-server.EntityArrayIterable.Unnamed", "type": "Function", "tags": [], "label": "Constructor", @@ -243,21 +354,20 @@ "signature": [ "any" ], - "path": "packages/elastic-apm-synthtrace/src/lib/span_iterable.ts", + "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [ { "parentPluginId": "@elastic/apm-synthtrace", - "id": "def-server.SpanArrayIterable.Unnamed.$1", + "id": "def-server.EntityArrayIterable.Unnamed.$1", "type": "Array", "tags": [], "label": "fields", "description": [], "signature": [ - "ApmFields", - "[]" + "TFields[]" ], - "path": "packages/elastic-apm-synthtrace/src/lib/span_iterable.ts", + "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "isRequired": true } @@ -266,7 +376,7 @@ }, { "parentPluginId": "@elastic/apm-synthtrace", - "id": "def-server.SpanArrayIterable.order", + "id": "def-server.EntityArrayIterable.order", "type": "Function", "tags": [], "label": "order", @@ -274,51 +384,62 @@ "signature": [ "() => \"asc\" | \"desc\"" ], - "path": "packages/elastic-apm-synthtrace/src/lib/span_iterable.ts", + "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [], "returnComment": [] }, { "parentPluginId": "@elastic/apm-synthtrace", - "id": "def-server.SpanArrayIterable.Symbol.asyncIterator", + "id": "def-server.EntityArrayIterable.ratePerMinute", + "type": "Function", + "tags": [], + "label": "ratePerMinute", + "description": [], + "signature": [ + "() => number" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.EntityArrayIterable.Symbol.asyncIterator", "type": "Function", "tags": [], "label": "[Symbol.asyncIterator]", "description": [], "signature": [ - "() => AsyncIterator<", - "ApmFields", - ", any, undefined>" + "() => AsyncIterator" ], - "path": "packages/elastic-apm-synthtrace/src/lib/span_iterable.ts", + "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [], "returnComment": [] }, { "parentPluginId": "@elastic/apm-synthtrace", - "id": "def-server.SpanArrayIterable.Symbol.iterator", + "id": "def-server.EntityArrayIterable.Symbol.iterator", "type": "Function", "tags": [], "label": "[Symbol.iterator]", "description": [], "signature": [ - "() => Iterator<", - "ApmFields", - ", any, undefined>" + "() => Iterator" ], - "path": "packages/elastic-apm-synthtrace/src/lib/span_iterable.ts", + "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [], "returnComment": [] }, { "parentPluginId": "@elastic/apm-synthtrace", - "id": "def-server.SpanArrayIterable.concat", + "id": "def-server.EntityArrayIterable.merge", "type": "Function", "tags": [], - "label": "concat", + "label": "merge", "description": [], "signature": [ "(...iterables: ", @@ -326,18 +447,19 @@ "pluginId": "@elastic/apm-synthtrace", "scope": "server", "docId": "kibElasticApmSynthtracePluginApi", - "section": "def-server.SpanIterable", - "text": "SpanIterable" + "section": "def-server.EntityIterable", + "text": "EntityIterable" }, - "[]) => ", - "SpanGeneratorsUnion" + "[]) => ", + "EntityStreams", + "" ], - "path": "packages/elastic-apm-synthtrace/src/lib/span_iterable.ts", + "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [ { "parentPluginId": "@elastic/apm-synthtrace", - "id": "def-server.SpanArrayIterable.concat.$1", + "id": "def-server.EntityArrayIterable.merge.$1", "type": "Array", "tags": [], "label": "iterables", @@ -347,12 +469,12 @@ "pluginId": "@elastic/apm-synthtrace", "scope": "server", "docId": "kibElasticApmSynthtracePluginApi", - "section": "def-server.SpanIterable", - "text": "SpanIterable" + "section": "def-server.EntityIterable", + "text": "EntityIterable" }, - "[]" + "[]" ], - "path": "packages/elastic-apm-synthtrace/src/lib/span_iterable.ts", + "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "isRequired": true } @@ -361,17 +483,15 @@ }, { "parentPluginId": "@elastic/apm-synthtrace", - "id": "def-server.SpanArrayIterable.toArray", + "id": "def-server.EntityArrayIterable.toArray", "type": "Function", "tags": [], "label": "toArray", "description": [], "signature": [ - "() => ", - "ApmFields", - "[]" + "() => TFields[]" ], - "path": "packages/elastic-apm-synthtrace/src/lib/span_iterable.ts", + "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [], "returnComment": [] @@ -569,57 +689,27 @@ }, { "parentPluginId": "@elastic/apm-synthtrace", - "id": "def-server.Fields", - "type": "Interface", - "tags": [], - "label": "Fields", - "description": [], - "path": "packages/elastic-apm-synthtrace/src/lib/entity.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/apm-synthtrace", - "id": "def-server.Fields.timestamp", - "type": "number", - "tags": [], - "label": "'@timestamp'", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "packages/elastic-apm-synthtrace/src/lib/entity.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/apm-synthtrace", - "id": "def-server.SpanIterable", + "id": "def-server.EntityIterable", "type": "Interface", "tags": [], - "label": "SpanIterable", + "label": "EntityIterable", "description": [], "signature": [ { "pluginId": "@elastic/apm-synthtrace", "scope": "server", "docId": "kibElasticApmSynthtracePluginApi", - "section": "def-server.SpanIterable", - "text": "SpanIterable" + "section": "def-server.EntityIterable", + "text": "EntityIterable" }, - " extends Iterable<", - "ApmFields", - ">,AsyncIterable<", - "ApmFields", - ">" + " extends Iterable,AsyncIterable" ], - "path": "packages/elastic-apm-synthtrace/src/lib/span_iterable.ts", + "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [ { "parentPluginId": "@elastic/apm-synthtrace", - "id": "def-server.SpanIterable.order", + "id": "def-server.EntityIterable.order", "type": "Function", "tags": [], "label": "order", @@ -627,34 +717,55 @@ "signature": [ "() => \"asc\" | \"desc\"" ], - "path": "packages/elastic-apm-synthtrace/src/lib/span_iterable.ts", + "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [], "returnComment": [] }, { "parentPluginId": "@elastic/apm-synthtrace", - "id": "def-server.SpanIterable.toArray", + "id": "def-server.EntityIterable.ratePerMinute", + "type": "Function", + "tags": [], + "label": "ratePerMinute", + "description": [], + "signature": [ + "() => number" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.EntityIterable.toArray", "type": "Function", "tags": [], "label": "toArray", "description": [], "signature": [ "() => ", - "ApmFields", + { + "pluginId": "@elastic/apm-synthtrace", + "scope": "server", + "docId": "kibElasticApmSynthtracePluginApi", + "section": "def-server.ApmFields", + "text": "ApmFields" + }, "[]" ], - "path": "packages/elastic-apm-synthtrace/src/lib/span_iterable.ts", + "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [], "returnComment": [] }, { "parentPluginId": "@elastic/apm-synthtrace", - "id": "def-server.SpanIterable.concat", + "id": "def-server.EntityIterable.merge", "type": "Function", "tags": [], - "label": "concat", + "label": "merge", "description": [], "signature": [ "(...iterables: ", @@ -662,18 +773,19 @@ "pluginId": "@elastic/apm-synthtrace", "scope": "server", "docId": "kibElasticApmSynthtracePluginApi", - "section": "def-server.SpanIterable", - "text": "SpanIterable" + "section": "def-server.EntityIterable", + "text": "EntityIterable" }, - "[]) => ", - "SpanGeneratorsUnion" + "[]) => ", + "EntityStreams", + "" ], - "path": "packages/elastic-apm-synthtrace/src/lib/span_iterable.ts", + "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "children": [ { "parentPluginId": "@elastic/apm-synthtrace", - "id": "def-server.SpanIterable.concat.$1", + "id": "def-server.EntityIterable.merge.$1", "type": "Array", "tags": [], "label": "iterables", @@ -683,12 +795,12 @@ "pluginId": "@elastic/apm-synthtrace", "scope": "server", "docId": "kibElasticApmSynthtracePluginApi", - "section": "def-server.SpanIterable", - "text": "SpanIterable" + "section": "def-server.EntityIterable", + "text": "EntityIterable" }, - "[]" + "[]" ], - "path": "packages/elastic-apm-synthtrace/src/lib/span_iterable.ts", + "path": "packages/elastic-apm-synthtrace/src/lib/entity_iterable.ts", "deprecated": false, "isRequired": true } @@ -697,6 +809,32 @@ } ], "initialIsOpen": false + }, + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.Fields", + "type": "Interface", + "tags": [], + "label": "Fields", + "description": [], + "path": "packages/elastic-apm-synthtrace/src/lib/entity.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.Fields.timestamp", + "type": "number", + "tags": [], + "label": "'@timestamp'", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/entity.ts", + "deprecated": false + } + ], + "initialIsOpen": false } ], "enums": [ @@ -712,7 +850,39 @@ "initialIsOpen": false } ], - "misc": [], + "misc": [ + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.ApmFields", + "type": "Type", + "tags": [], + "label": "ApmFields", + "description": [], + "signature": [ + { + "pluginId": "@elastic/apm-synthtrace", + "scope": "server", + "docId": "kibElasticApmSynthtracePluginApi", + "section": "def-server.Fields", + "text": "Fields" + }, + " & Partial<{ 'timestamp.us'?: number | undefined; 'agent.name': string; 'agent.version': string; 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'error.id': string; 'error.exception': ", + { + "pluginId": "@elastic/apm-synthtrace", + "scope": "server", + "docId": "kibElasticApmSynthtracePluginApi", + "section": "def-server.ApmException", + "text": "ApmException" + }, + "[]; 'error.grouping_name': string; 'error.grouping_key': string; 'host.name': string; 'kubernetes.pod.uid': string; 'metricset.name': string; observer: ", + "Observer", + "; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.version': string; 'service.environment': string; 'service.node.name': string; 'service.runtime.name': string; 'service.runtime.version': string; 'service.framework.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; 'span.self_time.sum.us': number; 'cloud.provider': string; 'cloud.project.name': string; 'cloud.service.name': string; 'cloud.availability_zone': string; 'cloud.machine.type': string; 'cloud.region': string; 'host.os.platform': string; 'faas.id': string; 'faas.coldstart': boolean; 'faas.execution': string; 'faas.trigger.type': string; 'faas.trigger.request_id': string; }> & Partial<{ 'system.process.memory.size': number; 'system.memory.actual.free': number; 'system.memory.total': number; 'system.cpu.total.norm.pct': number; 'system.process.memory.rss.bytes': number; 'system.process.cpu.total.norm.pct': number; 'jvm.memory.heap.used': number; 'jvm.memory.non_heap.used': number; 'jvm.thread.count': number; }>" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/apm/apm_fields.ts", + "deprecated": false, + "initialIsOpen": false + } + ], "objects": [ { "parentPluginId": "@elastic/apm-synthtrace", @@ -830,7 +1000,13 @@ "description": [], "signature": [ "(events: ", - "ApmFields", + { + "pluginId": "@elastic/apm-synthtrace", + "scope": "server", + "docId": "kibElasticApmSynthtracePluginApi", + "section": "def-server.ApmFields", + "text": "ApmFields" + }, "[]) => { 'metricset.name': string; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; _doc_count: number; '@timestamp'?: number | undefined; 'timestamp.us'?: number | undefined; 'agent.name'?: string | undefined; 'agent.version'?: string | undefined; 'container.id'?: string | undefined; 'ecs.version'?: string | undefined; 'event.outcome'?: string | undefined; 'event.ingested'?: number | undefined; 'error.id'?: string | undefined; 'error.exception'?: ", { "pluginId": "@elastic/apm-synthtrace", @@ -855,7 +1031,13 @@ "label": "events", "description": [], "signature": [ - "ApmFields", + { + "pluginId": "@elastic/apm-synthtrace", + "scope": "server", + "docId": "kibElasticApmSynthtracePluginApi", + "section": "def-server.ApmFields", + "text": "ApmFields" + }, "[]" ], "path": "packages/elastic-apm-synthtrace/src/lib/apm/processors/get_transaction_metrics.ts", @@ -872,7 +1054,13 @@ "description": [], "signature": [ "(events: ", - "ApmFields", + { + "pluginId": "@elastic/apm-synthtrace", + "scope": "server", + "docId": "kibElasticApmSynthtracePluginApi", + "section": "def-server.ApmFields", + "text": "ApmFields" + }, "[]) => { \"metricset.name\": string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; '@timestamp'?: number | undefined; 'timestamp.us'?: number | undefined; 'agent.name'?: string | undefined; 'agent.version'?: string | undefined; 'container.id'?: string | undefined; 'ecs.version'?: string | undefined; 'event.outcome'?: string | undefined; 'event.ingested'?: number | undefined; 'error.id'?: string | undefined; 'error.exception'?: ", { "pluginId": "@elastic/apm-synthtrace", @@ -897,7 +1085,13 @@ "label": "events", "description": [], "signature": [ - "ApmFields", + { + "pluginId": "@elastic/apm-synthtrace", + "scope": "server", + "docId": "kibElasticApmSynthtracePluginApi", + "section": "def-server.ApmFields", + "text": "ApmFields" + }, "[]" ], "path": "packages/elastic-apm-synthtrace/src/lib/apm/processors/get_span_destination_metrics.ts", @@ -929,9 +1123,21 @@ "description": [], "signature": [ "(events: ", - "ApmFields", + { + "pluginId": "@elastic/apm-synthtrace", + "scope": "server", + "docId": "kibElasticApmSynthtracePluginApi", + "section": "def-server.ApmFields", + "text": "ApmFields" + }, "[]) => ", - "ApmFields", + { + "pluginId": "@elastic/apm-synthtrace", + "scope": "server", + "docId": "kibElasticApmSynthtracePluginApi", + "section": "def-server.ApmFields", + "text": "ApmFields" + }, "[]" ], "path": "packages/elastic-apm-synthtrace/src/lib/apm/index.ts", @@ -946,7 +1152,13 @@ "label": "events", "description": [], "signature": [ - "ApmFields", + { + "pluginId": "@elastic/apm-synthtrace", + "scope": "server", + "docId": "kibElasticApmSynthtracePluginApi", + "section": "def-server.ApmFields", + "text": "ApmFields" + }, "[]" ], "path": "packages/elastic-apm-synthtrace/src/lib/apm/processors/get_breakdown_metrics.ts", @@ -962,9 +1174,9 @@ "label": "getApmWriteTargets", "description": [], "signature": [ - "({ client, forceDataStreams, }: { client: ", + "({ client, forceLegacyIndices, }: { client: ", "default", - "; forceDataStreams?: boolean | undefined; }) => Promise<", + "; forceLegacyIndices?: boolean | undefined; }) => Promise<", "ApmElasticsearchOutputWriteTargets", ">" ], @@ -982,7 +1194,7 @@ "signature": [ "{ client: ", "default", - "; forceDataStreams?: boolean | undefined; }" + "; forceLegacyIndices?: boolean | undefined; }" ], "path": "packages/elastic-apm-synthtrace/src/lib/apm/utils/get_apm_write_targets.ts", "deprecated": false diff --git a/api_docs/elastic_apm_synthtrace.mdx b/api_docs/elastic_apm_synthtrace.mdx index a1ce9ad2020bd..727d8b367a3a2 100644 --- a/api_docs/elastic_apm_synthtrace.mdx +++ b/api_docs/elastic_apm_synthtrace.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/elastic-apm-synthtrace title: "@elastic/apm-synthtrace" image: https://source.unsplash.com/400x175/?github summary: API docs for the @elastic/apm-synthtrace plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@elastic/apm-synthtrace'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 62 | 0 | 62 | 9 | +| 70 | 0 | 70 | 10 | ## Server @@ -37,3 +37,6 @@ Contact [Owner missing] for questions regarding this plugin. ### Enums +### Consts, variables and types + + diff --git a/api_docs/elastic_datemath.devdocs.json b/api_docs/elastic_datemath.devdocs.json deleted file mode 100644 index 166f816481b33..0000000000000 --- a/api_docs/elastic_datemath.devdocs.json +++ /dev/null @@ -1,578 +0,0 @@ -{ - "id": "@elastic/datemath", - "client": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - }, - "server": { - "classes": [], - "functions": [ - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.parse", - "type": "Function", - "tags": [], - "label": "parse", - "description": [], - "signature": [ - "(input: string, options: { roundUp?: boolean | undefined; momentInstance?: typeof moment | undefined; forceNow?: Date | undefined; }) => moment.Moment | undefined" - ], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.parse.$1", - "type": "string", - "tags": [], - "label": "input", - "description": [], - "signature": [ - "string" - ], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.parse.$2", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.parse.$2.roundUp", - "type": "CompoundType", - "tags": [], - "label": "roundUp", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.parse.$2.momentInstance", - "type": "Function", - "tags": [], - "label": "momentInstance", - "description": [], - "signature": [ - "typeof moment | undefined" - ], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.parse.$2.forceNow", - "type": "Object", - "tags": [], - "label": "forceNow", - "description": [], - "signature": [ - "Date | undefined" - ], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - } - ] - } - ], - "returnComment": [], - "initialIsOpen": false - } - ], - "interfaces": [], - "enums": [], - "misc": [ - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.Unit", - "type": "Type", - "tags": [], - "label": "Unit", - "description": [], - "signature": [ - "\"y\" | \"M\" | \"w\" | \"d\" | \"h\" | \"m\" | \"s\" | \"ms\"" - ], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false, - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.units", - "type": "Array", - "tags": [], - "label": "units", - "description": [], - "signature": [ - { - "pluginId": "@elastic/datemath", - "scope": "server", - "docId": "kibElasticDatemathPluginApi", - "section": "def-server.Unit", - "text": "Unit" - }, - "[]" - ], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false, - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsAsc", - "type": "Array", - "tags": [], - "label": "unitsAsc", - "description": [], - "signature": [ - { - "pluginId": "@elastic/datemath", - "scope": "server", - "docId": "kibElasticDatemathPluginApi", - "section": "def-server.Unit", - "text": "Unit" - }, - "[]" - ], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false, - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsDesc", - "type": "Array", - "tags": [], - "label": "unitsDesc", - "description": [], - "signature": [ - { - "pluginId": "@elastic/datemath", - "scope": "server", - "docId": "kibElasticDatemathPluginApi", - "section": "def-server.Unit", - "text": "Unit" - }, - "[]" - ], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false, - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.UnitsMap", - "type": "Type", - "tags": [], - "label": "UnitsMap", - "description": [], - "signature": [ - "{ y: { weight: number; type: \"calendar\" | \"fixed\" | \"mixed\"; base: number; }; M: { weight: number; type: \"calendar\" | \"fixed\" | \"mixed\"; base: number; }; w: { weight: number; type: \"calendar\" | \"fixed\" | \"mixed\"; base: number; }; d: { weight: number; type: \"calendar\" | \"fixed\" | \"mixed\"; base: number; }; h: { weight: number; type: \"calendar\" | \"fixed\" | \"mixed\"; base: number; }; m: { weight: number; type: \"calendar\" | \"fixed\" | \"mixed\"; base: number; }; s: { weight: number; type: \"calendar\" | \"fixed\" | \"mixed\"; base: number; }; ms: { weight: number; type: \"calendar\" | \"fixed\" | \"mixed\"; base: number; }; }" - ], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false, - "initialIsOpen": false - } - ], - "objects": [ - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap", - "type": "Object", - "tags": [], - "label": "unitsMap", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.ms", - "type": "Object", - "tags": [], - "label": "ms", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.ms.weight", - "type": "number", - "tags": [], - "label": "weight", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.ms.type", - "type": "string", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "\"fixed\"" - ], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.ms.base", - "type": "number", - "tags": [], - "label": "base", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - } - ] - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.s", - "type": "Object", - "tags": [], - "label": "s", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.s.weight", - "type": "number", - "tags": [], - "label": "weight", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.s.type", - "type": "string", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "\"fixed\"" - ], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.s.base", - "type": "number", - "tags": [], - "label": "base", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - } - ] - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.m", - "type": "Object", - "tags": [], - "label": "m", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.m.weight", - "type": "number", - "tags": [], - "label": "weight", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.m.type", - "type": "string", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "\"mixed\"" - ], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.m.base", - "type": "number", - "tags": [], - "label": "base", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - } - ] - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.h", - "type": "Object", - "tags": [], - "label": "h", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.h.weight", - "type": "number", - "tags": [], - "label": "weight", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.h.type", - "type": "string", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "\"mixed\"" - ], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.h.base", - "type": "number", - "tags": [], - "label": "base", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - } - ] - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.d", - "type": "Object", - "tags": [], - "label": "d", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.d.weight", - "type": "number", - "tags": [], - "label": "weight", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.d.type", - "type": "string", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "\"mixed\"" - ], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.d.base", - "type": "number", - "tags": [], - "label": "base", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - } - ] - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.w", - "type": "Object", - "tags": [], - "label": "w", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.w.weight", - "type": "number", - "tags": [], - "label": "weight", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.w.type", - "type": "string", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "\"calendar\"" - ], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.w.base", - "type": "number", - "tags": [], - "label": "base", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - } - ] - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.M", - "type": "Object", - "tags": [], - "label": "M", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.M.weight", - "type": "number", - "tags": [], - "label": "weight", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.M.type", - "type": "string", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "\"calendar\"" - ], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.M.base", - "type": "number", - "tags": [], - "label": "base", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - } - ] - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.y", - "type": "Object", - "tags": [], - "label": "y", - "description": [ - "// q: { weight: 8, type: 'calendar' }, // TODO: moment duration does not support quarter" - ], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.y.weight", - "type": "number", - "tags": [], - "label": "weight", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.y.type", - "type": "string", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "\"calendar\"" - ], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - }, - { - "parentPluginId": "@elastic/datemath", - "id": "def-server.unitsMap.y.base", - "type": "number", - "tags": [], - "label": "base", - "description": [], - "path": "packages/elastic-datemath/src/index.ts", - "deprecated": false - } - ] - } - ], - "initialIsOpen": false - } - ] - }, - "common": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - } -} \ No newline at end of file diff --git a/api_docs/elastic_datemath.mdx b/api_docs/elastic_datemath.mdx deleted file mode 100644 index 14fd7fef84034..0000000000000 --- a/api_docs/elastic_datemath.mdx +++ /dev/null @@ -1,33 +0,0 @@ ---- -id: kibElasticDatemathPluginApi -slug: /kibana-dev-docs/api/elastic-datemath -title: "@elastic/datemath" -image: https://source.unsplash.com/400x175/?github -summary: API docs for the @elastic/datemath plugin -date: 2022-04-05 -tags: ['contributor', 'dev', 'apidocs', 'kibana', '@elastic/datemath'] -warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. ---- -import elasticDatemathObj from './elastic_datemath.devdocs.json'; - -elasticsearch datemath parser, used in kibana - -Contact [Owner missing] for questions regarding this plugin. - -**Code health stats** - -| Public API count | Any count | Items lacking comments | Missing exports | -|-------------------|-----------|------------------------|-----------------| -| 44 | 0 | 43 | 0 | - -## Server - -### Objects - - -### Functions - - -### Consts, variables and types - - diff --git a/api_docs/embeddable.devdocs.json b/api_docs/embeddable.devdocs.json index 4ff19a79a26b4..d8d5fd3006360 100644 --- a/api_docs/embeddable.devdocs.json +++ b/api_docs/embeddable.devdocs.json @@ -8749,7 +8749,7 @@ "section": "def-public.EmbeddableFactory", "text": "EmbeddableFactory" }, - ", \"type\" | \"create\" | \"isEditable\" | \"getDisplayName\"> & Partial, \"create\" | \"type\" | \"isEditable\" | \"getDisplayName\"> & Partial; readonly accessCheckTimeout: number; readonly accessCheckTimeoutWarning: number; }" + "{ readonly host?: string | undefined; readonly customHeaders?: Readonly<{} & {}> | undefined; readonly ssl: Readonly<{ certificateAuthorities?: string | string[] | undefined; } & { verificationMode: \"none\" | \"full\" | \"certificate\"; }>; readonly accessCheckTimeout: number; readonly accessCheckTimeoutWarning: number; }" ], "path": "x-pack/plugins/enterprise_search/server/index.ts", "deprecated": false, @@ -51,7 +51,9 @@ "Type", "; verificationMode: ", "Type", - "<\"none\" | \"full\" | \"certificate\">; }>; }>" + "<\"none\" | \"full\" | \"certificate\">; }>; customHeaders: ", + "Type", + " | undefined>; }>" ], "path": "x-pack/plugins/enterprise_search/server/index.ts", "deprecated": false, diff --git a/api_docs/enterprise_search.mdx b/api_docs/enterprise_search.mdx index 8ea1f6d5c47b3..4e4c43e2977c1 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github summary: API docs for the enterpriseSearch plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index 3f8b8a4e25633..937c0be2c8ba3 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github summary: API docs for the esUiShared plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index db8d13ecbffad..5e3d34fcae086 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github summary: API docs for the eventAnnotation plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/event_log.devdocs.json b/api_docs/event_log.devdocs.json index cf94115cf3b25..1a4840efc4729 100644 --- a/api_docs/event_log.devdocs.json +++ b/api_docs/event_log.devdocs.json @@ -1047,7 +1047,7 @@ "label": "data", "description": [], "signature": [ - "(Readonly<{ user?: Readonly<{ name?: string | undefined; } & {}> | undefined; message?: string | undefined; error?: Readonly<{ message?: string | undefined; type?: string | undefined; id?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; tags?: string[] | undefined; kibana?: Readonly<{ alert?: Readonly<{ rule?: Readonly<{ consumer?: string | undefined; execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ number_of_triggered_actions?: number | undefined; number_of_scheduled_actions?: number | undefined; number_of_searches?: number | undefined; total_indexing_duration_ms?: number | undefined; es_search_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; rule_type_id?: string | undefined; } & {}> | undefined; } & {}> | undefined; version?: string | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; namespace?: string | undefined; rel?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ id?: string | undefined; schedule_delay?: number | undefined; scheduled?: string | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; outcome?: string | undefined; category?: string[] | undefined; url?: string | undefined; end?: string | undefined; original?: string | undefined; duration?: number | undefined; code?: string | undefined; action?: string | undefined; kind?: string | undefined; hash?: string | undefined; severity?: number | undefined; created?: string | undefined; dataset?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; } & {}> | undefined)[]" + "(Readonly<{ error?: Readonly<{ message?: string | undefined; id?: string | undefined; type?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; message?: string | undefined; tags?: string[] | undefined; kibana?: Readonly<{ alert?: Readonly<{ rule?: Readonly<{ consumer?: string | undefined; execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ number_of_triggered_actions?: number | undefined; number_of_generated_actions?: number | undefined; number_of_new_alerts?: number | undefined; number_of_active_alerts?: number | undefined; number_of_recovered_alerts?: number | undefined; total_number_of_alerts?: number | undefined; number_of_searches?: number | undefined; total_indexing_duration_ms?: number | undefined; es_search_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; rule_type_id?: string | undefined; } & {}> | undefined; } & {}> | undefined; version?: string | undefined; saved_objects?: Readonly<{ id?: string | undefined; type?: string | undefined; namespace?: string | undefined; rel?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ id?: string | undefined; schedule_delay?: number | undefined; scheduled?: string | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; event?: Readonly<{ start?: string | undefined; id?: string | undefined; type?: string[] | undefined; outcome?: string | undefined; category?: string[] | undefined; url?: string | undefined; end?: string | undefined; original?: string | undefined; duration?: number | undefined; code?: string | undefined; action?: string | undefined; kind?: string | undefined; hash?: string | undefined; severity?: number | undefined; created?: string | undefined; dataset?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; } & {}> | undefined)[]" ], "path": "x-pack/plugins/event_log/server/es/cluster_client_adapter.ts", "deprecated": false @@ -1066,7 +1066,7 @@ "label": "IEvent", "description": [], "signature": [ - "DeepPartial | undefined; message?: string | undefined; error?: Readonly<{ message?: string | undefined; type?: string | undefined; id?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; tags?: string[] | undefined; kibana?: Readonly<{ alert?: Readonly<{ rule?: Readonly<{ consumer?: string | undefined; execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ number_of_triggered_actions?: number | undefined; number_of_scheduled_actions?: number | undefined; number_of_searches?: number | undefined; total_indexing_duration_ms?: number | undefined; es_search_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; rule_type_id?: string | undefined; } & {}> | undefined; } & {}> | undefined; version?: string | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; namespace?: string | undefined; rel?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ id?: string | undefined; schedule_delay?: number | undefined; scheduled?: string | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; outcome?: string | undefined; category?: string[] | undefined; url?: string | undefined; end?: string | undefined; original?: string | undefined; duration?: number | undefined; code?: string | undefined; action?: string | undefined; kind?: string | undefined; hash?: string | undefined; severity?: number | undefined; created?: string | undefined; dataset?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; } & {}>>> | undefined" + "DeepPartial | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; message?: string | undefined; tags?: string[] | undefined; kibana?: Readonly<{ alert?: Readonly<{ rule?: Readonly<{ consumer?: string | undefined; execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ number_of_triggered_actions?: number | undefined; number_of_generated_actions?: number | undefined; number_of_new_alerts?: number | undefined; number_of_active_alerts?: number | undefined; number_of_recovered_alerts?: number | undefined; total_number_of_alerts?: number | undefined; number_of_searches?: number | undefined; total_indexing_duration_ms?: number | undefined; es_search_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; rule_type_id?: string | undefined; } & {}> | undefined; } & {}> | undefined; version?: string | undefined; saved_objects?: Readonly<{ id?: string | undefined; type?: string | undefined; namespace?: string | undefined; rel?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ id?: string | undefined; schedule_delay?: number | undefined; scheduled?: string | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; event?: Readonly<{ start?: string | undefined; id?: string | undefined; type?: string[] | undefined; outcome?: string | undefined; category?: string[] | undefined; url?: string | undefined; end?: string | undefined; original?: string | undefined; duration?: number | undefined; code?: string | undefined; action?: string | undefined; kind?: string | undefined; hash?: string | undefined; severity?: number | undefined; created?: string | undefined; dataset?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; } & {}>>> | undefined" ], "path": "x-pack/plugins/event_log/generated/schemas.ts", "deprecated": false, @@ -1080,7 +1080,7 @@ "label": "IValidatedEvent", "description": [], "signature": [ - "Readonly<{ user?: Readonly<{ name?: string | undefined; } & {}> | undefined; message?: string | undefined; error?: Readonly<{ message?: string | undefined; type?: string | undefined; id?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; tags?: string[] | undefined; kibana?: Readonly<{ alert?: Readonly<{ rule?: Readonly<{ consumer?: string | undefined; execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ number_of_triggered_actions?: number | undefined; number_of_scheduled_actions?: number | undefined; number_of_searches?: number | undefined; total_indexing_duration_ms?: number | undefined; es_search_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; rule_type_id?: string | undefined; } & {}> | undefined; } & {}> | undefined; version?: string | undefined; saved_objects?: Readonly<{ type?: string | undefined; id?: string | undefined; namespace?: string | undefined; rel?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ id?: string | undefined; schedule_delay?: number | undefined; scheduled?: string | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; event?: Readonly<{ start?: string | undefined; type?: string[] | undefined; id?: string | undefined; outcome?: string | undefined; category?: string[] | undefined; url?: string | undefined; end?: string | undefined; original?: string | undefined; duration?: number | undefined; code?: string | undefined; action?: string | undefined; kind?: string | undefined; hash?: string | undefined; severity?: number | undefined; created?: string | undefined; dataset?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; } & {}> | undefined" + "Readonly<{ error?: Readonly<{ message?: string | undefined; id?: string | undefined; type?: string | undefined; code?: string | undefined; stack_trace?: string | undefined; } & {}> | undefined; user?: Readonly<{ name?: string | undefined; } & {}> | undefined; message?: string | undefined; tags?: string[] | undefined; kibana?: Readonly<{ alert?: Readonly<{ rule?: Readonly<{ consumer?: string | undefined; execution?: Readonly<{ status?: string | undefined; metrics?: Readonly<{ number_of_triggered_actions?: number | undefined; number_of_generated_actions?: number | undefined; number_of_new_alerts?: number | undefined; number_of_active_alerts?: number | undefined; number_of_recovered_alerts?: number | undefined; total_number_of_alerts?: number | undefined; number_of_searches?: number | undefined; total_indexing_duration_ms?: number | undefined; es_search_duration_ms?: number | undefined; total_search_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; } & {}> | undefined; uuid?: string | undefined; status_order?: number | undefined; } & {}> | undefined; rule_type_id?: string | undefined; } & {}> | undefined; } & {}> | undefined; version?: string | undefined; saved_objects?: Readonly<{ id?: string | undefined; type?: string | undefined; namespace?: string | undefined; rel?: string | undefined; type_id?: string | undefined; } & {}>[] | undefined; alerting?: Readonly<{ status?: string | undefined; instance_id?: string | undefined; action_group_id?: string | undefined; action_subgroup?: string | undefined; } & {}> | undefined; server_uuid?: string | undefined; task?: Readonly<{ id?: string | undefined; schedule_delay?: number | undefined; scheduled?: string | undefined; } & {}> | undefined; space_ids?: string[] | undefined; } & {}> | undefined; log?: Readonly<{ logger?: string | undefined; level?: string | undefined; } & {}> | undefined; ecs?: Readonly<{ version?: string | undefined; } & {}> | undefined; rule?: Readonly<{ id?: string | undefined; description?: string | undefined; name?: string | undefined; version?: string | undefined; license?: string | undefined; category?: string | undefined; reference?: string | undefined; author?: string[] | undefined; ruleset?: string | undefined; uuid?: string | undefined; } & {}> | undefined; event?: Readonly<{ start?: string | undefined; id?: string | undefined; type?: string[] | undefined; outcome?: string | undefined; category?: string[] | undefined; url?: string | undefined; end?: string | undefined; original?: string | undefined; duration?: number | undefined; code?: string | undefined; action?: string | undefined; kind?: string | undefined; hash?: string | undefined; severity?: number | undefined; created?: string | undefined; dataset?: string | undefined; ingested?: string | undefined; module?: string | undefined; provider?: string | undefined; reason?: string | undefined; reference?: string | undefined; risk_score?: number | undefined; risk_score_norm?: number | undefined; sequence?: number | undefined; timezone?: string | undefined; } & {}> | undefined; '@timestamp'?: string | undefined; } & {}> | undefined" ], "path": "x-pack/plugins/event_log/generated/schemas.ts", "deprecated": false, diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index 40049f0fbe11d..562f7fee9dbbb 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github summary: API docs for the eventLog plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventLog'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expression_error.mdx b/api_docs/expression_error.mdx index 47da67003080d..22245b38031d1 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionError plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionError'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expression_gauge.devdocs.json b/api_docs/expression_gauge.devdocs.json index 63e409a1a6c3a..111082f04d28a 100644 --- a/api_docs/expression_gauge.devdocs.json +++ b/api_docs/expression_gauge.devdocs.json @@ -103,13 +103,7 @@ "text": "Accessors" }, " | undefined, paletteParams?: ", - { - "pluginId": "expressionGauge", - "scope": "common", - "docId": "kibExpressionGaugePluginApi", - "section": "def-common.CustomPaletteParams", - "text": "CustomPaletteParams" - }, + "CustomPaletteParams", " | undefined, isRespectRanges?: boolean | undefined) => number" ], "path": "src/plugins/chart_expressions/expression_gauge/public/components/utils/accessors.ts", @@ -165,13 +159,7 @@ "label": "paletteParams", "description": [], "signature": [ - { - "pluginId": "expressionGauge", - "scope": "common", - "docId": "kibExpressionGaugePluginApi", - "section": "def-common.CustomPaletteParams", - "text": "CustomPaletteParams" - }, + "CustomPaletteParams", " | undefined" ], "path": "src/plugins/chart_expressions/expression_gauge/public/components/utils/accessors.ts", @@ -221,13 +209,7 @@ "text": "Accessors" }, " | undefined, paletteParams?: ", - { - "pluginId": "expressionGauge", - "scope": "common", - "docId": "kibExpressionGaugePluginApi", - "section": "def-common.CustomPaletteParams", - "text": "CustomPaletteParams" - }, + "CustomPaletteParams", " | undefined, isRespectRanges?: boolean | undefined) => any" ], "path": "src/plugins/chart_expressions/expression_gauge/public/components/utils/accessors.ts", @@ -283,13 +265,7 @@ "label": "paletteParams", "description": [], "signature": [ - { - "pluginId": "expressionGauge", - "scope": "common", - "docId": "kibExpressionGaugePluginApi", - "section": "def-common.CustomPaletteParams", - "text": "CustomPaletteParams" - }, + "CustomPaletteParams", " | undefined" ], "path": "src/plugins/chart_expressions/expression_gauge/public/components/utils/accessors.ts", @@ -551,196 +527,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "expressionGauge", - "id": "def-common.ColorStop", - "type": "Interface", - "tags": [], - "label": "ColorStop", - "description": [], - "path": "src/plugins/chart_expressions/expression_gauge/common/types/expression_renderers.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "expressionGauge", - "id": "def-common.ColorStop.color", - "type": "string", - "tags": [], - "label": "color", - "description": [], - "path": "src/plugins/chart_expressions/expression_gauge/common/types/expression_renderers.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionGauge", - "id": "def-common.ColorStop.stop", - "type": "number", - "tags": [], - "label": "stop", - "description": [], - "path": "src/plugins/chart_expressions/expression_gauge/common/types/expression_renderers.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "expressionGauge", - "id": "def-common.CustomPaletteParams", - "type": "Interface", - "tags": [], - "label": "CustomPaletteParams", - "description": [], - "path": "src/plugins/chart_expressions/expression_gauge/common/types/expression_renderers.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "expressionGauge", - "id": "def-common.CustomPaletteParams.name", - "type": "string", - "tags": [], - "label": "name", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/chart_expressions/expression_gauge/common/types/expression_renderers.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionGauge", - "id": "def-common.CustomPaletteParams.reverse", - "type": "CompoundType", - "tags": [], - "label": "reverse", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/chart_expressions/expression_gauge/common/types/expression_renderers.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionGauge", - "id": "def-common.CustomPaletteParams.rangeType", - "type": "CompoundType", - "tags": [], - "label": "rangeType", - "description": [], - "signature": [ - "\"number\" | \"percent\" | undefined" - ], - "path": "src/plugins/chart_expressions/expression_gauge/common/types/expression_renderers.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionGauge", - "id": "def-common.CustomPaletteParams.continuity", - "type": "CompoundType", - "tags": [], - "label": "continuity", - "description": [], - "signature": [ - "\"above\" | \"below\" | \"none\" | \"all\" | undefined" - ], - "path": "src/plugins/chart_expressions/expression_gauge/common/types/expression_renderers.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionGauge", - "id": "def-common.CustomPaletteParams.progression", - "type": "string", - "tags": [], - "label": "progression", - "description": [], - "signature": [ - "\"fixed\" | undefined" - ], - "path": "src/plugins/chart_expressions/expression_gauge/common/types/expression_renderers.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionGauge", - "id": "def-common.CustomPaletteParams.rangeMin", - "type": "number", - "tags": [], - "label": "rangeMin", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "src/plugins/chart_expressions/expression_gauge/common/types/expression_renderers.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionGauge", - "id": "def-common.CustomPaletteParams.rangeMax", - "type": "number", - "tags": [], - "label": "rangeMax", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "src/plugins/chart_expressions/expression_gauge/common/types/expression_renderers.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionGauge", - "id": "def-common.CustomPaletteParams.stops", - "type": "Array", - "tags": [], - "label": "stops", - "description": [], - "signature": [ - { - "pluginId": "expressionGauge", - "scope": "common", - "docId": "kibExpressionGaugePluginApi", - "section": "def-common.ColorStop", - "text": "ColorStop" - }, - "[] | undefined" - ], - "path": "src/plugins/chart_expressions/expression_gauge/common/types/expression_renderers.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionGauge", - "id": "def-common.CustomPaletteParams.colorStops", - "type": "Array", - "tags": [], - "label": "colorStops", - "description": [], - "signature": [ - { - "pluginId": "expressionGauge", - "scope": "common", - "docId": "kibExpressionGaugePluginApi", - "section": "def-common.ColorStop", - "text": "ColorStop" - }, - "[] | undefined" - ], - "path": "src/plugins/chart_expressions/expression_gauge/common/types/expression_renderers.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionGauge", - "id": "def-common.CustomPaletteParams.steps", - "type": "number", - "tags": [], - "label": "steps", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "src/plugins/chart_expressions/expression_gauge/common/types/expression_renderers.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "expressionGauge", "id": "def-common.GaugeExpressionProps", @@ -796,13 +582,7 @@ "; colorMode: ", "GaugeColorMode", "; palette?: ", - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, + "PaletteOutput", "<", { "pluginId": "charts", @@ -1014,21 +794,9 @@ "label": "palette", "description": [], "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, + "PaletteOutput", "<", - { - "pluginId": "expressionGauge", - "scope": "common", - "docId": "kibExpressionGaugePluginApi", - "section": "def-common.CustomPaletteParams", - "text": "CustomPaletteParams" - }, + "CustomPaletteParams", "> | undefined" ], "path": "src/plugins/chart_expressions/expression_gauge/common/types/expression_functions.ts", @@ -1208,13 +976,7 @@ "; colorMode: ", "GaugeColorMode", "; palette?: ", - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, + "PaletteOutput", "<", { "pluginId": "charts", @@ -1340,13 +1102,7 @@ "; chartsThemeService: ", "Theme", "; paletteService: ", - { - "pluginId": "charts", - "scope": "public", - "docId": "kibChartsPluginApi", - "section": "def-public.PaletteRegistry", - "text": "PaletteRegistry" - }, + "PaletteRegistry", "; uiState: ", { "pluginId": "visualizations", @@ -1416,36 +1172,6 @@ "path": "src/plugins/chart_expressions/expression_gauge/common/index.ts", "deprecated": false, "initialIsOpen": false - }, - { - "parentPluginId": "expressionGauge", - "id": "def-common.RequiredPaletteParamTypes", - "type": "Type", - "tags": [], - "label": "RequiredPaletteParamTypes", - "description": [], - "signature": [ - "{ name: string; reverse: boolean; rangeType: \"number\" | \"percent\"; continuity: \"above\" | \"below\" | \"none\" | \"all\"; progression: \"fixed\"; rangeMin: number; rangeMax: number; stops: ", - { - "pluginId": "expressionGauge", - "scope": "common", - "docId": "kibExpressionGaugePluginApi", - "section": "def-common.ColorStop", - "text": "ColorStop" - }, - "[]; colorStops: ", - { - "pluginId": "expressionGauge", - "scope": "common", - "docId": "kibExpressionGaugePluginApi", - "section": "def-common.ColorStop", - "text": "ColorStop" - }, - "[]; steps: number; }" - ], - "path": "src/plugins/chart_expressions/expression_gauge/common/types/expression_renderers.ts", - "deprecated": false, - "initialIsOpen": false } ], "objects": [ diff --git a/api_docs/expression_gauge.mdx b/api_docs/expression_gauge.mdx index b99d793cc0063..f83a1b80f6f29 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionGauge plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionGauge'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 76 | 0 | 76 | 2 | +| 61 | 0 | 61 | 2 | ## Client diff --git a/api_docs/expression_heatmap.devdocs.json b/api_docs/expression_heatmap.devdocs.json index fa4e095495ed6..e686e8a1e7b76 100644 --- a/api_docs/expression_heatmap.devdocs.json +++ b/api_docs/expression_heatmap.devdocs.json @@ -121,196 +121,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "expressionHeatmap", - "id": "def-common.ColorStop", - "type": "Interface", - "tags": [], - "label": "ColorStop", - "description": [], - "path": "src/plugins/chart_expressions/expression_heatmap/common/types/expression_renderers.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "expressionHeatmap", - "id": "def-common.ColorStop.color", - "type": "string", - "tags": [], - "label": "color", - "description": [], - "path": "src/plugins/chart_expressions/expression_heatmap/common/types/expression_renderers.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionHeatmap", - "id": "def-common.ColorStop.stop", - "type": "number", - "tags": [], - "label": "stop", - "description": [], - "path": "src/plugins/chart_expressions/expression_heatmap/common/types/expression_renderers.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "expressionHeatmap", - "id": "def-common.CustomPaletteParams", - "type": "Interface", - "tags": [], - "label": "CustomPaletteParams", - "description": [], - "path": "src/plugins/chart_expressions/expression_heatmap/common/types/expression_renderers.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "expressionHeatmap", - "id": "def-common.CustomPaletteParams.name", - "type": "string", - "tags": [], - "label": "name", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/chart_expressions/expression_heatmap/common/types/expression_renderers.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionHeatmap", - "id": "def-common.CustomPaletteParams.reverse", - "type": "CompoundType", - "tags": [], - "label": "reverse", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/chart_expressions/expression_heatmap/common/types/expression_renderers.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionHeatmap", - "id": "def-common.CustomPaletteParams.rangeType", - "type": "CompoundType", - "tags": [], - "label": "rangeType", - "description": [], - "signature": [ - "\"number\" | \"percent\" | undefined" - ], - "path": "src/plugins/chart_expressions/expression_heatmap/common/types/expression_renderers.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionHeatmap", - "id": "def-common.CustomPaletteParams.continuity", - "type": "CompoundType", - "tags": [], - "label": "continuity", - "description": [], - "signature": [ - "\"above\" | \"below\" | \"none\" | \"all\" | undefined" - ], - "path": "src/plugins/chart_expressions/expression_heatmap/common/types/expression_renderers.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionHeatmap", - "id": "def-common.CustomPaletteParams.progression", - "type": "string", - "tags": [], - "label": "progression", - "description": [], - "signature": [ - "\"fixed\" | undefined" - ], - "path": "src/plugins/chart_expressions/expression_heatmap/common/types/expression_renderers.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionHeatmap", - "id": "def-common.CustomPaletteParams.rangeMin", - "type": "number", - "tags": [], - "label": "rangeMin", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "src/plugins/chart_expressions/expression_heatmap/common/types/expression_renderers.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionHeatmap", - "id": "def-common.CustomPaletteParams.rangeMax", - "type": "number", - "tags": [], - "label": "rangeMax", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "src/plugins/chart_expressions/expression_heatmap/common/types/expression_renderers.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionHeatmap", - "id": "def-common.CustomPaletteParams.stops", - "type": "Array", - "tags": [], - "label": "stops", - "description": [], - "signature": [ - { - "pluginId": "expressionHeatmap", - "scope": "common", - "docId": "kibExpressionHeatmapPluginApi", - "section": "def-common.ColorStop", - "text": "ColorStop" - }, - "[] | undefined" - ], - "path": "src/plugins/chart_expressions/expression_heatmap/common/types/expression_renderers.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionHeatmap", - "id": "def-common.CustomPaletteParams.colorStops", - "type": "Array", - "tags": [], - "label": "colorStops", - "description": [], - "signature": [ - { - "pluginId": "expressionHeatmap", - "scope": "common", - "docId": "kibExpressionHeatmapPluginApi", - "section": "def-common.ColorStop", - "text": "ColorStop" - }, - "[] | undefined" - ], - "path": "src/plugins/chart_expressions/expression_heatmap/common/types/expression_renderers.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionHeatmap", - "id": "def-common.CustomPaletteParams.steps", - "type": "number", - "tags": [], - "label": "steps", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "src/plugins/chart_expressions/expression_heatmap/common/types/expression_renderers.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "expressionHeatmap", "id": "def-common.FilterEvent", @@ -428,13 +238,7 @@ "label": "palette", "description": [], "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, + "PaletteOutput", "<", { "pluginId": "charts", @@ -805,13 +609,7 @@ "text": "Datatable" }, "; column: number; range: number[]; timeFieldName?: string | undefined; }) => void; paletteService: ", - { - "pluginId": "charts", - "scope": "public", - "docId": "kibChartsPluginApi", - "section": "def-public.PaletteRegistry", - "text": "PaletteRegistry" - }, + "PaletteRegistry", "; uiState: ", { "pluginId": "visualizations", @@ -853,36 +651,6 @@ "path": "src/plugins/chart_expressions/expression_heatmap/common/index.ts", "deprecated": false, "initialIsOpen": false - }, - { - "parentPluginId": "expressionHeatmap", - "id": "def-common.RequiredPaletteParamTypes", - "type": "Type", - "tags": [], - "label": "RequiredPaletteParamTypes", - "description": [], - "signature": [ - "{ name: string; reverse: boolean; rangeType: \"number\" | \"percent\"; continuity: \"above\" | \"below\" | \"none\" | \"all\"; progression: \"fixed\"; rangeMin: number; rangeMax: number; stops: ", - { - "pluginId": "expressionHeatmap", - "scope": "common", - "docId": "kibExpressionHeatmapPluginApi", - "section": "def-common.ColorStop", - "text": "ColorStop" - }, - "[]; colorStops: ", - { - "pluginId": "expressionHeatmap", - "scope": "common", - "docId": "kibExpressionHeatmapPluginApi", - "section": "def-common.ColorStop", - "text": "ColorStop" - }, - "[]; steps: number; }" - ], - "path": "src/plugins/chart_expressions/expression_heatmap/common/types/expression_renderers.ts", - "deprecated": false, - "initialIsOpen": false } ], "objects": [ diff --git a/api_docs/expression_heatmap.mdx b/api_docs/expression_heatmap.mdx index aad7b2efe25d8..d828747b22637 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionHeatmap plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionHeatmap'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 119 | 0 | 115 | 3 | +| 104 | 0 | 100 | 3 | ## Client diff --git a/api_docs/expression_image.mdx b/api_docs/expression_image.mdx index feea2fe660d34..093aecd94cd99 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionImage plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionImage'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expression_metric.mdx b/api_docs/expression_metric.mdx index 8affa769b01a2..527d9a85c187c 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionMetric plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetric'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expression_metric_vis.devdocs.json b/api_docs/expression_metric_vis.devdocs.json index 43cb1a3470887..de4956164a459 100644 --- a/api_docs/expression_metric_vis.devdocs.json +++ b/api_docs/expression_metric_vis.devdocs.json @@ -150,13 +150,7 @@ "label": "palette", "description": [], "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, + "PaletteOutput", "<", { "pluginId": "charts", diff --git a/api_docs/expression_metric_vis.mdx b/api_docs/expression_metric_vis.mdx index a428ff8611edf..e4d8c09eb36cd 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionMetricVis plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetricVis'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expression_partition_vis.devdocs.json b/api_docs/expression_partition_vis.devdocs.json index 6511db71b8625..4953f5401fb20 100644 --- a/api_docs/expression_partition_vis.devdocs.json +++ b/api_docs/expression_partition_vis.devdocs.json @@ -609,13 +609,7 @@ "label": "palette", "description": [], "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, + "PaletteOutput", "<{ [key: string]: unknown; }>" ], "path": "src/plugins/chart_expressions/expression_partition_vis/common/types/expression_renderers.ts", diff --git a/api_docs/expression_partition_vis.mdx b/api_docs/expression_partition_vis.mdx index 2ed4287363bf1..97c89c561e56c 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionPartitionVis plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionPartitionVis'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expression_repeat_image.mdx b/api_docs/expression_repeat_image.mdx index 30b19d8b19abb..5b0af3d5efbc8 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionRepeatImage plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRepeatImage'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expression_reveal_image.mdx b/api_docs/expression_reveal_image.mdx index 8e270f3640f04..c7eca19a624cb 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionRevealImage plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRevealImage'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expression_shape.mdx b/api_docs/expression_shape.mdx index 54a9aa6e92925..f3ee5306578c3 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionShape plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionShape'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expression_tagcloud.mdx b/api_docs/expression_tagcloud.mdx index e3f34e10096c9..8331a345d07cc 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionTagcloud plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionTagcloud'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expression_x_y.devdocs.json b/api_docs/expression_x_y.devdocs.json index c8e2d0f579833..7064fd2035207 100644 --- a/api_docs/expression_x_y.devdocs.json +++ b/api_docs/expression_x_y.devdocs.json @@ -452,13 +452,7 @@ "label": "palette", "description": [], "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, + "PaletteOutput", "<{ [key: string]: unknown; }>" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", @@ -3086,7 +3080,7 @@ "label": "types", "description": [], "signature": [ - "(\"palette\" | \"system_palette\")[]" + "(\"system_palette\" | \"palette\")[]" ], "path": "src/plugins/chart_expressions/expression_xy/common/expression_functions/data_layer_config.ts", "deprecated": false @@ -3156,13 +3150,7 @@ "text": "XScaleType" }, "; isHistogram: boolean; palette: ", - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, + "PaletteOutput", "<{ [key: string]: unknown; }>; yConfig?: ", { "pluginId": "expressionXY", diff --git a/api_docs/expression_x_y.mdx b/api_docs/expression_x_y.mdx index 1bb894548102d..90fa5545dffd1 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionXY plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionXY'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expressions.devdocs.json b/api_docs/expressions.devdocs.json index 5da80bd20a369..193a9d90ba337 100644 --- a/api_docs/expressions.devdocs.json +++ b/api_docs/expressions.devdocs.json @@ -6361,7 +6361,13 @@ "description": [], "signature": [ "(nodeRef: React.RefObject, {\n debounce,\n expression,\n hasCustomErrorRenderer,\n onData$,\n onEvent,\n onRender$,\n reload$,\n ...loaderParams\n }: ", - "ExpressionRendererParams", + { + "pluginId": "expressions", + "scope": "public", + "docId": "kibExpressionsPluginApi", + "section": "def-public.ExpressionRendererParams", + "text": "ExpressionRendererParams" + }, ") => ExpressionRendererState" ], "path": "src/plugins/expressions/public/react_expression_renderer/use_expression_renderer.ts", @@ -6389,7 +6395,13 @@ "label": "{\n debounce,\n expression,\n hasCustomErrorRenderer,\n onData$,\n onEvent,\n onRender$,\n reload$,\n ...loaderParams\n }", "description": [], "signature": [ - "ExpressionRendererParams" + { + "pluginId": "expressions", + "scope": "public", + "docId": "kibExpressionsPluginApi", + "section": "def-public.ExpressionRendererParams", + "text": "ExpressionRendererParams" + } ], "path": "src/plugins/expressions/public/react_expression_renderer/use_expression_renderer.ts", "deprecated": false, @@ -7877,35 +7889,35 @@ "references": [ { "plugin": "canvas", - "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.ts" + "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/server/demodata/index.ts" }, { "plugin": "canvas", - "path": "x-pack/plugins/canvas/common/functions/filters.ts" + "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.ts" }, { "plugin": "canvas", - "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/browser/escount.ts" + "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/browser/esdocs.ts" }, { "plugin": "canvas", - "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/browser/esdocs.ts" + "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/browser/essql.ts" }, { "plugin": "canvas", - "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/browser/essql.ts" + "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts" }, { "plugin": "canvas", - "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/common/neq.ts" + "path": "x-pack/plugins/canvas/common/functions/filters.ts" }, { "plugin": "canvas", - "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts" + "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/browser/escount.ts" }, { "plugin": "canvas", - "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/server/demodata/index.ts" + "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/common/neq.ts" }, { "plugin": "visTypeXy", @@ -8612,6 +8624,230 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "expressions", + "id": "def-public.ExpressionRendererParams", + "type": "Interface", + "tags": [], + "label": "ExpressionRendererParams", + "description": [], + "signature": [ + { + "pluginId": "expressions", + "scope": "public", + "docId": "kibExpressionsPluginApi", + "section": "def-public.ExpressionRendererParams", + "text": "ExpressionRendererParams" + }, + " extends ", + { + "pluginId": "expressions", + "scope": "public", + "docId": "kibExpressionsPluginApi", + "section": "def-public.IExpressionLoaderParams", + "text": "IExpressionLoaderParams" + } + ], + "path": "src/plugins/expressions/public/react_expression_renderer/use_expression_renderer.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "expressions", + "id": "def-public.ExpressionRendererParams.debounce", + "type": "number", + "tags": [], + "label": "debounce", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/expressions/public/react_expression_renderer/use_expression_renderer.ts", + "deprecated": false + }, + { + "parentPluginId": "expressions", + "id": "def-public.ExpressionRendererParams.expression", + "type": "CompoundType", + "tags": [], + "label": "expression", + "description": [], + "signature": [ + "string | ", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.ExpressionAstExpression", + "text": "ExpressionAstExpression" + } + ], + "path": "src/plugins/expressions/public/react_expression_renderer/use_expression_renderer.ts", + "deprecated": false + }, + { + "parentPluginId": "expressions", + "id": "def-public.ExpressionRendererParams.hasCustomErrorRenderer", + "type": "CompoundType", + "tags": [], + "label": "hasCustomErrorRenderer", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/expressions/public/react_expression_renderer/use_expression_renderer.ts", + "deprecated": false + }, + { + "parentPluginId": "expressions", + "id": "def-public.ExpressionRendererParams.onData$", + "type": "Function", + "tags": [], + "label": "onData$", + "description": [], + "signature": [ + "((data: TData, adapters?: TInspectorAdapters | undefined, partial?: boolean | undefined) => void) | undefined" + ], + "path": "src/plugins/expressions/public/react_expression_renderer/use_expression_renderer.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "expressions", + "id": "def-public.ExpressionRendererParams.onData$.$1", + "type": "Uncategorized", + "tags": [], + "label": "data", + "description": [], + "signature": [ + "TData" + ], + "path": "src/plugins/expressions/public/react_expression_renderer/use_expression_renderer.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "expressions", + "id": "def-public.ExpressionRendererParams.onData$.$2", + "type": "Uncategorized", + "tags": [], + "label": "adapters", + "description": [], + "signature": [ + "TInspectorAdapters | undefined" + ], + "path": "src/plugins/expressions/public/react_expression_renderer/use_expression_renderer.ts", + "deprecated": false, + "isRequired": false + }, + { + "parentPluginId": "expressions", + "id": "def-public.ExpressionRendererParams.onData$.$3", + "type": "CompoundType", + "tags": [], + "label": "partial", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/expressions/public/react_expression_renderer/use_expression_renderer.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "expressions", + "id": "def-public.ExpressionRendererParams.onEvent", + "type": "Function", + "tags": [], + "label": "onEvent", + "description": [], + "signature": [ + "((event: ", + { + "pluginId": "expressions", + "scope": "public", + "docId": "kibExpressionsPluginApi", + "section": "def-public.ExpressionRendererEvent", + "text": "ExpressionRendererEvent" + }, + ") => void) | undefined" + ], + "path": "src/plugins/expressions/public/react_expression_renderer/use_expression_renderer.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "expressions", + "id": "def-public.ExpressionRendererParams.onEvent.$1", + "type": "Object", + "tags": [], + "label": "event", + "description": [], + "signature": [ + { + "pluginId": "expressions", + "scope": "public", + "docId": "kibExpressionsPluginApi", + "section": "def-public.ExpressionRendererEvent", + "text": "ExpressionRendererEvent" + } + ], + "path": "src/plugins/expressions/public/react_expression_renderer/use_expression_renderer.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "expressions", + "id": "def-public.ExpressionRendererParams.onRender$", + "type": "Function", + "tags": [], + "label": "onRender$", + "description": [], + "signature": [ + "((item: number) => void) | undefined" + ], + "path": "src/plugins/expressions/public/react_expression_renderer/use_expression_renderer.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "expressions", + "id": "def-public.ExpressionRendererParams.onRender$.$1", + "type": "number", + "tags": [], + "label": "item", + "description": [], + "signature": [ + "number" + ], + "path": "src/plugins/expressions/public/react_expression_renderer/use_expression_renderer.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "expressions", + "id": "def-public.ExpressionRendererParams.reload$", + "type": "Object", + "tags": [], + "label": "reload$", + "description": [ + "\nAn observable which can be used to re-run the expression without destroying the component" + ], + "signature": [ + "Observable", + " | undefined" + ], + "path": "src/plugins/expressions/public/react_expression_renderer/use_expression_renderer.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "expressions", "id": "def-public.ExpressionRenderError", @@ -10366,7 +10602,13 @@ "text": "ReactExpressionRendererProps" }, " extends Omit<", - "ExpressionRendererParams", + { + "pluginId": "expressions", + "scope": "public", + "docId": "kibExpressionsPluginApi", + "section": "def-public.ExpressionRendererParams", + "text": "ExpressionRendererParams" + }, ", \"hasCustomErrorRenderer\">" ], "path": "src/plugins/expressions/public/react_expression_renderer/react_expression_renderer.tsx", @@ -11266,7 +11508,7 @@ "\nAllowed column names in a PointSeries" ], "signature": [ - "\"color\" | \"y\" | \"x\" | \"size\" | \"text\"" + "\"color\" | \"size\" | \"text\" | \"y\" | \"x\"" ], "path": "src/plugins/expressions/common/expression_types/specs/pointseries.ts", "deprecated": false, @@ -17996,35 +18238,35 @@ "references": [ { "plugin": "canvas", - "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.ts" + "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/server/demodata/index.ts" }, { "plugin": "canvas", - "path": "x-pack/plugins/canvas/common/functions/filters.ts" + "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.ts" }, { "plugin": "canvas", - "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/browser/escount.ts" + "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/browser/esdocs.ts" }, { "plugin": "canvas", - "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/browser/esdocs.ts" + "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/browser/essql.ts" }, { "plugin": "canvas", - "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/browser/essql.ts" + "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts" }, { "plugin": "canvas", - "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/common/neq.ts" + "path": "x-pack/plugins/canvas/common/functions/filters.ts" }, { "plugin": "canvas", - "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts" + "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/browser/escount.ts" }, { "plugin": "canvas", - "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/server/demodata/index.ts" + "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/common/neq.ts" }, { "plugin": "visTypeXy", @@ -20218,7 +20460,7 @@ "\nAllowed column names in a PointSeries" ], "signature": [ - "\"color\" | \"y\" | \"x\" | \"size\" | \"text\"" + "\"color\" | \"size\" | \"text\" | \"y\" | \"x\"" ], "path": "src/plugins/expressions/common/expression_types/specs/pointseries.ts", "deprecated": false, @@ -29735,35 +29977,35 @@ "references": [ { "plugin": "canvas", - "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.ts" + "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/server/demodata/index.ts" }, { "plugin": "canvas", - "path": "x-pack/plugins/canvas/common/functions/filters.ts" + "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.ts" }, { "plugin": "canvas", - "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/browser/escount.ts" + "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/browser/esdocs.ts" }, { "plugin": "canvas", - "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/browser/esdocs.ts" + "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/browser/essql.ts" }, { "plugin": "canvas", - "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/browser/essql.ts" + "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts" }, { "plugin": "canvas", - "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/common/neq.ts" + "path": "x-pack/plugins/canvas/common/functions/filters.ts" }, { "plugin": "canvas", - "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts" + "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/browser/escount.ts" }, { "plugin": "canvas", - "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/server/demodata/index.ts" + "path": "x-pack/plugins/canvas/canvas_plugin_src/functions/common/neq.ts" }, { "plugin": "visTypeXy", @@ -34299,7 +34541,7 @@ "\nAllowed column names in a PointSeries" ], "signature": [ - "\"color\" | \"y\" | \"x\" | \"size\" | \"text\"" + "\"color\" | \"size\" | \"text\" | \"y\" | \"x\"" ], "path": "src/plugins/expressions/common/expression_types/specs/pointseries.ts", "deprecated": false, @@ -38006,7 +38248,15 @@ "section": "def-common.DatatableRow", "text": "DatatableRow" }, - "[]; type: \"datatable\"; meta?: ", + "[] | (", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.DatatableRow", + "text": "DatatableRow" + }, + " | { [x: string]: any; })[]; type: \"datatable\"; meta?: ", "DatatableMeta", " | undefined; }>" ], diff --git a/api_docs/expressions.mdx b/api_docs/expressions.mdx index 8470b4f8a9643..48f344a1fc219 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressions plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressions'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2145 | 17 | 1701 | 6 | +| 2158 | 17 | 1713 | 5 | ## Client diff --git a/api_docs/features.mdx b/api_docs/features.mdx index 19443c000875b..27dc3a6e8652a 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github summary: API docs for the features plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'features'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/field_formats.devdocs.json b/api_docs/field_formats.devdocs.json index 3128c6077b0c5..fbe312ee376af 100644 --- a/api_docs/field_formats.devdocs.json +++ b/api_docs/field_formats.devdocs.json @@ -4807,7 +4807,7 @@ "label": "FieldFormatsContentType", "description": [], "signature": [ - "\"html\" | \"text\"" + "\"text\" | \"html\"" ], "path": "src/plugins/field_formats/common/types.ts", "deprecated": false, @@ -5083,7 +5083,7 @@ "label": "HTML_CONTEXT_TYPE", "description": [], "signature": [ - "\"html\" | \"text\"" + "\"text\" | \"html\"" ], "path": "src/plugins/field_formats/common/content_types/html_content_type.ts", "deprecated": false, @@ -5361,7 +5361,7 @@ "label": "TEXT_CONTEXT_TYPE", "description": [], "signature": [ - "\"html\" | \"text\"" + "\"text\" | \"html\"" ], "path": "src/plugins/field_formats/common/content_types/text_content_type.ts", "deprecated": false, diff --git a/api_docs/field_formats.mdx b/api_docs/field_formats.mdx index 41c16cfcde6a2..c425ca2c5924c 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github summary: API docs for the fieldFormats plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index 5361e280670e0..670175e6463d6 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github summary: API docs for the fileUpload plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fileUpload'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/fleet.devdocs.json b/api_docs/fleet.devdocs.json index 71cb3650bbbce..530b55d549f63 100644 --- a/api_docs/fleet.devdocs.json +++ b/api_docs/fleet.devdocs.json @@ -6882,7 +6882,7 @@ "label": "runExternalCallbacks", "description": [], "signature": [ - "(externalCallbackType: A, packagePolicy: A extends \"postPackagePolicyDelete\" ? ", + "(externalCallbackType: A, packagePolicy: A extends \"postPackagePolicyDelete\" ? ", { "pluginId": "fleet", "scope": "common", @@ -6890,6 +6890,14 @@ "section": "def-common.DeletePackagePoliciesResponse", "text": "DeletePackagePoliciesResponse" }, + " : A extends \"packagePolicyPostCreate\" ? ", + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.PackagePolicy", + "text": "PackagePolicy" + }, " : ", { "pluginId": "fleet", @@ -6914,7 +6922,15 @@ "section": "def-server.KibanaRequest", "text": "KibanaRequest" }, - ") => Promise) => Promise) => Promise<", + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.PackagePolicy", + "text": "PackagePolicy" + }, + ">" + ], + "path": "x-pack/plugins/fleet/server/types/extensions.ts", + "deprecated": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "fleet", + "id": "def-server.PostPackagePolicyPostCreateCallback.$1", + "type": "Object", + "tags": [], + "label": "packagePolicy", + "description": [], + "signature": [ + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.PackagePolicy", + "text": "PackagePolicy" + } + ], + "path": "x-pack/plugins/fleet/server/types/extensions.ts", + "deprecated": false + }, + { + "parentPluginId": "fleet", + "id": "def-server.PostPackagePolicyPostCreateCallback.$2", + "type": "Object", + "tags": [], + "label": "context", + "description": [], + "signature": [ + { + "pluginId": "core", + "scope": "server", + "docId": "kibCorePluginApi", + "section": "def-server.RequestHandlerContext", + "text": "RequestHandlerContext" + } + ], + "path": "x-pack/plugins/fleet/server/types/extensions.ts", + "deprecated": false + }, + { + "parentPluginId": "fleet", + "id": "def-server.PostPackagePolicyPostCreateCallback.$3", + "type": "Object", + "tags": [], + "label": "request", + "description": [], + "signature": [ + { + "pluginId": "core", + "scope": "server", + "docId": "kibCoreHttpPluginApi", + "section": "def-server.KibanaRequest", + "text": "KibanaRequest" + }, + "" + ], + "path": "x-pack/plugins/fleet/server/types/extensions.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-server.PutPackagePolicyUpdateCallback", @@ -11410,7 +11543,7 @@ "\nLst checkin status" ], "signature": [ - "\"online\" | \"error\" | \"updating\" | \"degraded\" | undefined" + "\"error\" | \"online\" | \"updating\" | \"degraded\" | undefined" ], "path": "x-pack/plugins/fleet/common/types/models/agent.ts", "deprecated": false @@ -12800,7 +12933,20 @@ "label": "missing_requirements", "description": [], "signature": [ - "(\"fleet_server\" | \"security_required\" | \"tls_required\" | \"api_keys\" | \"fleet_admin_user\" | \"encrypted_saved_object_encryption_key_required\")[]" + "(\"fleet_server\" | \"security_required\" | \"tls_required\" | \"api_keys\" | \"fleet_admin_user\")[]" + ], + "path": "x-pack/plugins/fleet/common/types/rest_spec/fleet_setup.ts", + "deprecated": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.GetFleetStatusResponse.missing_optional_features", + "type": "Array", + "tags": [], + "label": "missing_optional_features", + "description": [], + "signature": [ + "\"encrypted_saved_object_encryption_key_required\"[]" ], "path": "x-pack/plugins/fleet/common/types/rest_spec/fleet_setup.ts", "deprecated": false @@ -13411,7 +13557,7 @@ "label": "query", "description": [], "signature": [ - "{ category?: string | undefined; experimental?: boolean | undefined; }" + "{ category?: string | undefined; experimental?: boolean | undefined; excludeInstallStatus?: boolean | undefined; }" ], "path": "x-pack/plugins/fleet/common/types/rest_spec/epm.ts", "deprecated": false @@ -18630,7 +18776,7 @@ "label": "AgentStatus", "description": [], "signature": [ - "\"offline\" | \"online\" | \"error\" | \"warning\" | \"inactive\" | \"enrolling\" | \"unenrolling\" | \"updating\" | \"degraded\"" + "\"error\" | \"offline\" | \"online\" | \"warning\" | \"inactive\" | \"enrolling\" | \"unenrolling\" | \"updating\" | \"degraded\"" ], "path": "x-pack/plugins/fleet/common/types/models/agent.ts", "deprecated": false, @@ -19661,6 +19807,14 @@ "label": "Installable", "description": [], "signature": [ + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.InstallStatusExcluded", + "text": "InstallStatusExcluded" + }, + " | ", { "pluginId": "fleet", "scope": "common", @@ -19838,6 +19992,20 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-common.InstallStatusExcluded", + "type": "Type", + "tags": [], + "label": "InstallStatusExcluded", + "description": [], + "signature": [ + "T & { status: undefined; }" + ], + "path": "x-pack/plugins/fleet/common/types/models/epm.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-common.InstallType", @@ -20194,7 +20362,7 @@ "section": "def-common.NewOutput", "text": "NewOutput" }, - " & { output_id?: string | undefined; }" + " & { output_id?: string | undefined; ssl?: string | undefined; }" ], "path": "x-pack/plugins/fleet/common/types/models/output.ts", "deprecated": false, @@ -20749,7 +20917,7 @@ "label": "RegistrySearchResult", "description": [], "signature": [ - "{ download: string; type?: \"integration\" | undefined; title: string; description: string; icons?: (", + "{ download: string; title: string; type?: \"integration\" | undefined; description: string; icons?: (", { "pluginId": "fleet", "scope": "common", diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index 35b1cf07adef1..221ed6ae0e6e0 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github summary: API docs for the fleet plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Fleet](https://github.com/orgs/elastic/teams/fleet) for questions regar | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 1379 | 8 | 1262 | 9 | +| 1385 | 8 | 1268 | 10 | ## Client diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index 9f756367f808c..31f9aa31263a9 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github summary: API docs for the globalSearch plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'globalSearch'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/home.devdocs.json b/api_docs/home.devdocs.json index 56a7ef14f9710..516a1e6965511 100644 --- a/api_docs/home.devdocs.json +++ b/api_docs/home.devdocs.json @@ -368,20 +368,14 @@ { "parentPluginId": "home", "id": "def-public.FeatureCatalogueEntry.category", - "type": "Enum", + "type": "CompoundType", "tags": [], "label": "category", "description": [ "{@link FeatureCatalogueCategory} to display this feature in." ], "signature": [ - { - "pluginId": "home", - "scope": "public", - "docId": "kibHomePluginApi", - "section": "def-public.FeatureCatalogueCategory", - "text": "FeatureCatalogueCategory" - } + "\"data\" | \"other\" | \"admin\"" ], "path": "src/plugins/home/public/services/feature_catalogue/feature_catalogue_registry.ts", "deprecated": false @@ -682,19 +676,7 @@ "initialIsOpen": false } ], - "enums": [ - { - "parentPluginId": "home", - "id": "def-public.FeatureCatalogueCategory", - "type": "Enum", - "tags": [], - "label": "FeatureCatalogueCategory", - "description": [], - "path": "src/plugins/home/public/services/feature_catalogue/feature_catalogue_registry.ts", - "deprecated": false, - "initialIsOpen": false - } - ], + "enums": [], "misc": [ { "parentPluginId": "home", @@ -718,6 +700,20 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "home", + "id": "def-public.FeatureCatalogueCategory", + "type": "Type", + "tags": [], + "label": "FeatureCatalogueCategory", + "description": [], + "signature": [ + "\"data\" | \"other\" | \"admin\"" + ], + "path": "src/plugins/home/public/services/feature_catalogue/feature_catalogue_registry.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "home", "id": "def-public.FeatureCatalogueSetup", @@ -1577,7 +1573,7 @@ "label": "InstructionSetSchema", "description": [], "signature": [ - "{ readonly title?: string | undefined; readonly callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; readonly statusCheck?: Readonly<{ title?: string | undefined; error?: string | undefined; text?: string | undefined; success?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; readonly instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }" + "{ readonly title?: string | undefined; readonly callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; readonly statusCheck?: Readonly<{ error?: string | undefined; success?: string | undefined; text?: string | undefined; title?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; readonly instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }" ], "path": "src/plugins/home/server/services/tutorials/lib/tutorial_schema.ts", "deprecated": false, @@ -1591,7 +1587,7 @@ "label": "InstructionsSchema", "description": [], "signature": [ - "{ readonly params?: Readonly<{ defaultValue?: any; } & { label: string; type: \"string\" | \"number\"; id: string; }>[] | undefined; readonly instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ title?: string | undefined; error?: string | undefined; text?: string | undefined; success?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }" + "{ readonly params?: Readonly<{ defaultValue?: any; } & { label: string; id: string; type: \"string\" | \"number\"; }>[] | undefined; readonly instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ error?: string | undefined; success?: string | undefined; text?: string | undefined; title?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }" ], "path": "src/plugins/home/server/services/tutorials/lib/tutorial_schema.ts", "deprecated": false, @@ -1607,7 +1603,7 @@ "signature": [ "{ getSampleDatasets: () => ", "Writable", - "[]; defaultIndex: string; previewImagePath: string; overviewDashboard: string; dataIndices: Readonly<{} & { id: string; fields: Record; timeFields: string[]; dataPath: string; currentTimeMarker: string; preserveDayOfWeekTimeOfDay: boolean; }>[]; }>>[]; addSavedObjectsToSampleDataset: (id: string, savedObjects: ", + "[]; defaultIndex: string; previewImagePath: string; overviewDashboard: string; dataIndices: Readonly<{} & { id: string; fields: Record; timeFields: string[]; dataPath: string; currentTimeMarker: string; preserveDayOfWeekTimeOfDay: boolean; }>[]; }>>[]; addSavedObjectsToSampleDataset: (id: string, savedObjects: ", "SavedObject", "[]) => void; addAppLinksToSampleDataset: (id: string, appLinks: ", { @@ -1641,7 +1637,7 @@ "signature": [ "() => ", "Writable", - "[]; defaultIndex: string; previewImagePath: string; overviewDashboard: string; dataIndices: Readonly<{} & { id: string; fields: Record; timeFields: string[]; dataPath: string; currentTimeMarker: string; preserveDayOfWeekTimeOfDay: boolean; }>[]; }>>" + "[]; defaultIndex: string; previewImagePath: string; overviewDashboard: string; dataIndices: Readonly<{} & { id: string; fields: Record; timeFields: string[]; dataPath: string; currentTimeMarker: string; preserveDayOfWeekTimeOfDay: boolean; }>[]; }>>" ], "path": "src/plugins/home/server/services/sample_data/lib/sample_dataset_registry_types.ts", "deprecated": false, @@ -1695,7 +1691,7 @@ "section": "def-server.TutorialContext", "text": "TutorialContext" }, - ") => Readonly<{ isBeta?: boolean | undefined; savedObjects?: any[] | undefined; euiIconType?: string | undefined; previewImagePath?: string | undefined; moduleName?: string | undefined; completionTimeMinutes?: number | undefined; elasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { label: string; type: \"string\" | \"number\"; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ title?: string | undefined; error?: string | undefined; text?: string | undefined; success?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; onPremElasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { label: string; type: \"string\" | \"number\"; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ title?: string | undefined; error?: string | undefined; text?: string | undefined; success?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; artifacts?: Readonly<{ application?: Readonly<{} & { label: string; path: string; }> | undefined; exportedFields?: Readonly<{} & { documentationUrl: string; }> | undefined; } & { dashboards: Readonly<{ linkLabel?: string | undefined; } & { id: string; isOverview: boolean; }>[]; }> | undefined; savedObjectsInstallMsg?: string | undefined; customStatusCheckName?: string | undefined; integrationBrowserCategories?: string[] | undefined; eprPackageOverlap?: string | undefined; } & { id: string; name: string; category: \"other\" | \"security\" | \"metrics\" | \"logging\"; shortDescription: string; longDescription: string; onPrem: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { label: string; type: \"string\" | \"number\"; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ title?: string | undefined; error?: string | undefined; text?: string | undefined; success?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }>; }>" + ") => Readonly<{ isBeta?: boolean | undefined; savedObjects?: any[] | undefined; euiIconType?: string | undefined; previewImagePath?: string | undefined; moduleName?: string | undefined; completionTimeMinutes?: number | undefined; elasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { label: string; id: string; type: \"string\" | \"number\"; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ error?: string | undefined; success?: string | undefined; text?: string | undefined; title?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; onPremElasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { label: string; id: string; type: \"string\" | \"number\"; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ error?: string | undefined; success?: string | undefined; text?: string | undefined; title?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; artifacts?: Readonly<{ application?: Readonly<{} & { label: string; path: string; }> | undefined; exportedFields?: Readonly<{} & { documentationUrl: string; }> | undefined; } & { dashboards: Readonly<{ linkLabel?: string | undefined; } & { id: string; isOverview: boolean; }>[]; }> | undefined; savedObjectsInstallMsg?: string | undefined; customStatusCheckName?: string | undefined; integrationBrowserCategories?: string[] | undefined; eprPackageOverlap?: string | undefined; } & { id: string; name: string; category: \"other\" | \"security\" | \"metrics\" | \"logging\"; shortDescription: string; longDescription: string; onPrem: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { label: string; id: string; type: \"string\" | \"number\"; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ error?: string | undefined; success?: string | undefined; text?: string | undefined; title?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }>; }>" ], "path": "src/plugins/home/server/services/tutorials/lib/tutorials_registry_types.ts", "deprecated": false, @@ -1731,7 +1727,7 @@ "label": "TutorialSchema", "description": [], "signature": [ - "{ readonly isBeta?: boolean | undefined; readonly savedObjects?: any[] | undefined; readonly euiIconType?: string | undefined; readonly previewImagePath?: string | undefined; readonly moduleName?: string | undefined; readonly completionTimeMinutes?: number | undefined; readonly elasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { label: string; type: \"string\" | \"number\"; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ title?: string | undefined; error?: string | undefined; text?: string | undefined; success?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; readonly onPremElasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { label: string; type: \"string\" | \"number\"; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ title?: string | undefined; error?: string | undefined; text?: string | undefined; success?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; readonly artifacts?: Readonly<{ application?: Readonly<{} & { label: string; path: string; }> | undefined; exportedFields?: Readonly<{} & { documentationUrl: string; }> | undefined; } & { dashboards: Readonly<{ linkLabel?: string | undefined; } & { id: string; isOverview: boolean; }>[]; }> | undefined; readonly savedObjectsInstallMsg?: string | undefined; readonly customStatusCheckName?: string | undefined; readonly integrationBrowserCategories?: string[] | undefined; readonly eprPackageOverlap?: string | undefined; readonly id: string; readonly name: string; readonly category: \"other\" | \"security\" | \"metrics\" | \"logging\"; readonly shortDescription: string; readonly longDescription: string; readonly onPrem: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { label: string; type: \"string\" | \"number\"; id: string; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ title?: string | undefined; error?: string | undefined; text?: string | undefined; success?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }>; }" + "{ readonly isBeta?: boolean | undefined; readonly savedObjects?: any[] | undefined; readonly euiIconType?: string | undefined; readonly previewImagePath?: string | undefined; readonly moduleName?: string | undefined; readonly completionTimeMinutes?: number | undefined; readonly elasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { label: string; id: string; type: \"string\" | \"number\"; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ error?: string | undefined; success?: string | undefined; text?: string | undefined; title?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; readonly onPremElasticCloud?: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { label: string; id: string; type: \"string\" | \"number\"; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ error?: string | undefined; success?: string | undefined; text?: string | undefined; title?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }> | undefined; readonly artifacts?: Readonly<{ application?: Readonly<{} & { label: string; path: string; }> | undefined; exportedFields?: Readonly<{} & { documentationUrl: string; }> | undefined; } & { dashboards: Readonly<{ linkLabel?: string | undefined; } & { id: string; isOverview: boolean; }>[]; }> | undefined; readonly savedObjectsInstallMsg?: string | undefined; readonly customStatusCheckName?: string | undefined; readonly integrationBrowserCategories?: string[] | undefined; readonly eprPackageOverlap?: string | undefined; readonly id: string; readonly name: string; readonly category: \"other\" | \"security\" | \"metrics\" | \"logging\"; readonly shortDescription: string; readonly longDescription: string; readonly onPrem: Readonly<{ params?: Readonly<{ defaultValue?: any; } & { label: string; id: string; type: \"string\" | \"number\"; }>[] | undefined; } & { instructionSets: Readonly<{ title?: string | undefined; callOut?: Readonly<{ message?: string | undefined; iconType?: string | undefined; } & { title: string; }> | undefined; statusCheck?: Readonly<{ error?: string | undefined; success?: string | undefined; text?: string | undefined; title?: string | undefined; btnLabel?: string | undefined; } & { esHitsCheck: Readonly<{} & { query: Record; index: string | string[]; }>; }> | undefined; } & { instructionVariants: Readonly<{ initialSelected?: boolean | undefined; } & { id: string; instructions: Readonly<{ title?: string | undefined; commands?: string[] | undefined; textPre?: string | undefined; textPost?: string | undefined; customComponentName?: string | undefined; } & {}>[]; }>[]; }>[]; }>; }" ], "path": "src/plugins/home/server/services/tutorials/lib/tutorial_schema.ts", "deprecated": false, @@ -1990,7 +1986,7 @@ "signature": [ "{ getSampleDatasets: () => ", "Writable", - "[]; defaultIndex: string; previewImagePath: string; overviewDashboard: string; dataIndices: Readonly<{} & { id: string; fields: Record; timeFields: string[]; dataPath: string; currentTimeMarker: string; preserveDayOfWeekTimeOfDay: boolean; }>[]; }>>[]; addSavedObjectsToSampleDataset: (id: string, savedObjects: ", + "[]; defaultIndex: string; previewImagePath: string; overviewDashboard: string; dataIndices: Readonly<{} & { id: string; fields: Record; timeFields: string[]; dataPath: string; currentTimeMarker: string; preserveDayOfWeekTimeOfDay: boolean; }>[]; }>>[]; addSavedObjectsToSampleDataset: (id: string, savedObjects: ", "SavedObject", "[]) => void; addAppLinksToSampleDataset: (id: string, appLinks: ", { diff --git a/api_docs/home.mdx b/api_docs/home.mdx index ba9950de8c4df..2f65dcfe6a656 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github summary: API docs for the home plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'home'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -40,9 +40,6 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que ### Interfaces -### Enums - - ### Consts, variables and types diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index 4b3d1ee7c566a..3b508d1e26456 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github summary: API docs for the indexLifecycleManagement plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexLifecycleManagement'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/index_management.mdx b/api_docs/index_management.mdx index 9350e37eebf19..521963fb92b77 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github summary: API docs for the indexManagement plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index 1ad1b38648945..599b5bd6cfcab 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github summary: API docs for the infra plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index 5ebe20d7baa93..fff575d6b0e7c 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github summary: API docs for the inspector plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index 2e1ad77a61fb9..869fe720402e9 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github summary: API docs for the interactiveSetup plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index 28ed37ce7ba84..b937c8289d677 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/ace plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_alerts.mdx b/api_docs/kbn_alerts.mdx index feba71871e675..09fb9c17c487d 100644 --- a/api_docs/kbn_alerts.mdx +++ b/api_docs/kbn_alerts.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-alerts title: "@kbn/alerts" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/alerts plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_analytics.mdx b/api_docs/kbn_analytics.mdx index 523542b3a852d..045b97520eb11 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/analytics plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_analytics_client.devdocs.json b/api_docs/kbn_analytics_client.devdocs.json new file mode 100644 index 0000000000000..b2111b6f6fbfd --- /dev/null +++ b/api_docs/kbn_analytics_client.devdocs.json @@ -0,0 +1,1818 @@ +{ + "id": "@kbn/analytics-client", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.createAnalytics", + "type": "Function", + "tags": [], + "label": "createAnalytics", + "description": [ + "\nCreates an {@link AnalyticsClient}." + ], + "signature": [ + "(initContext: ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.AnalyticsClientInitContext", + "text": "AnalyticsClientInitContext" + }, + ") => ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.IAnalyticsClient", + "text": "IAnalyticsClient" + } + ], + "path": "packages/analytics/client/src/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.createAnalytics.$1", + "type": "Object", + "tags": [], + "label": "initContext", + "description": [ + "The initial context to create the client {@link AnalyticsClientInitContext }" + ], + "signature": [ + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.AnalyticsClientInitContext", + "text": "AnalyticsClientInitContext" + } + ], + "path": "packages/analytics/client/src/index.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.AnalyticsClientInitContext", + "type": "Interface", + "tags": [], + "label": "AnalyticsClientInitContext", + "description": [ + "\nGeneral settings of the analytics client" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.AnalyticsClientInitContext.isDev", + "type": "boolean", + "tags": [], + "label": "isDev", + "description": [ + "\nBoolean indicating if it's running in developer mode." + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.AnalyticsClientInitContext.sendTo", + "type": "CompoundType", + "tags": [], + "label": "sendTo", + "description": [ + "\nSpecify if the shippers should send their data to the production or staging environments." + ], + "signature": [ + "\"staging\" | \"production\"" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.AnalyticsClientInitContext.logger", + "type": "Object", + "tags": [], + "label": "logger", + "description": [ + "\nApplication-provided logger." + ], + "signature": [ + "Logger" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.ContextProviderOpts", + "type": "Interface", + "tags": [], + "label": "ContextProviderOpts", + "description": [ + "\nDefinition of a context provider" + ], + "signature": [ + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.ContextProviderOpts", + "text": "ContextProviderOpts" + }, + "" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.ContextProviderOpts.name", + "type": "string", + "tags": [], + "label": "name", + "description": [ + "\nThe name of the provider." + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.ContextProviderOpts.context$", + "type": "Object", + "tags": [], + "label": "context$", + "description": [ + "\nObservable that emits the custom context." + ], + "signature": [ + "Observable", + "" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.ContextProviderOpts.schema", + "type": "Object", + "tags": [], + "label": "schema", + "description": [ + "\nSchema declaring and documenting the expected output in the context$\n" + ], + "signature": [ + "{ [Key in keyof Required]: ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaValue", + "text": "SchemaValue" + }, + "; }" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.Event", + "type": "Interface", + "tags": [], + "label": "Event", + "description": [ + "\nDefinition of the full event structure" + ], + "path": "packages/analytics/client/src/events/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.Event.timestamp", + "type": "string", + "tags": [], + "label": "timestamp", + "description": [ + "\nThe time the event was generated in ISO format." + ], + "path": "packages/analytics/client/src/events/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.Event.event_type", + "type": "string", + "tags": [], + "label": "event_type", + "description": [ + "\nThe event type." + ], + "path": "packages/analytics/client/src/events/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.Event.properties", + "type": "Object", + "tags": [], + "label": "properties", + "description": [ + "\nThe specific properties of the event type." + ], + "signature": [ + "{ [x: string]: unknown; }" + ], + "path": "packages/analytics/client/src/events/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.Event.context", + "type": "Object", + "tags": [], + "label": "context", + "description": [ + "\nThe {@link EventContext} enriched during the processing pipeline." + ], + "signature": [ + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.EventContext", + "text": "EventContext" + } + ], + "path": "packages/analytics/client/src/events/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.EventContext", + "type": "Interface", + "tags": [], + "label": "EventContext", + "description": [ + "\nDefinition of the context that can be appended to the events through the {@link IAnalyticsClient.registerContextProvider}." + ], + "path": "packages/analytics/client/src/events/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.EventContext.userId", + "type": "string", + "tags": [], + "label": "userId", + "description": [ + "\nThe unique user ID." + ], + "signature": [ + "string | undefined" + ], + "path": "packages/analytics/client/src/events/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.EventContext.cloudId", + "type": "string", + "tags": [], + "label": "cloudId", + "description": [ + "\nThe Cloud ID." + ], + "signature": [ + "string | undefined" + ], + "path": "packages/analytics/client/src/events/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.EventContext.version", + "type": "string", + "tags": [], + "label": "version", + "description": [ + "\nThe product's version." + ], + "signature": [ + "string | undefined" + ], + "path": "packages/analytics/client/src/events/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.EventContext.pageName", + "type": "string", + "tags": [], + "label": "pageName", + "description": [ + "\nThe name of the current page." + ], + "signature": [ + "string | undefined" + ], + "path": "packages/analytics/client/src/events/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.EventContext.applicationId", + "type": "string", + "tags": [], + "label": "applicationId", + "description": [ + "\nThe current application ID." + ], + "signature": [ + "string | undefined" + ], + "path": "packages/analytics/client/src/events/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.EventContext.entityId", + "type": "string", + "tags": [], + "label": "entityId", + "description": [ + "\nThe current entity ID (dashboard ID, visualization ID, etc.)." + ], + "signature": [ + "string | undefined" + ], + "path": "packages/analytics/client/src/events/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.EventContext.Unnamed", + "type": "IndexSignature", + "tags": [], + "label": "[key: string]: unknown", + "description": [], + "signature": [ + "[key: string]: unknown" + ], + "path": "packages/analytics/client/src/events/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.EventTypeOpts", + "type": "Interface", + "tags": [], + "label": "EventTypeOpts", + "description": [ + "\nDefinition of an Event Type." + ], + "signature": [ + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.EventTypeOpts", + "text": "EventTypeOpts" + }, + "" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.EventTypeOpts.eventType", + "type": "string", + "tags": [], + "label": "eventType", + "description": [ + "\nThe event type's unique name." + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.EventTypeOpts.schema", + "type": "Object", + "tags": [], + "label": "schema", + "description": [ + "\nSchema declaring and documenting the expected structure of this event type.\n" + ], + "signature": [ + "{ [Key in keyof Required]: ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaValue", + "text": "SchemaValue" + }, + "; }" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IAnalyticsClient", + "type": "Interface", + "tags": [], + "label": "IAnalyticsClient", + "description": [ + "\nAnalytics client's public APIs" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IAnalyticsClient.reportEvent", + "type": "Function", + "tags": [], + "label": "reportEvent", + "description": [ + "\nReports a telemetry event." + ], + "signature": [ + ">(eventType: string, eventData: EventTypeData) => void" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IAnalyticsClient.reportEvent.$1", + "type": "string", + "tags": [], + "label": "eventType", + "description": [ + "The event type registered via the `registerEventType` API." + ], + "signature": [ + "string" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IAnalyticsClient.reportEvent.$2", + "type": "Uncategorized", + "tags": [], + "label": "eventData", + "description": [ + "The properties matching the schema declared in the `registerEventType` API." + ], + "signature": [ + "EventTypeData" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IAnalyticsClient.registerEventType", + "type": "Function", + "tags": [], + "label": "registerEventType", + "description": [ + "\nRegisters the event type that will be emitted via the reportEvent API." + ], + "signature": [ + "(eventTypeOps: ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.EventTypeOpts", + "text": "EventTypeOpts" + }, + ") => void" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IAnalyticsClient.registerEventType.$1", + "type": "Object", + "tags": [], + "label": "eventTypeOps", + "description": [], + "signature": [ + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.EventTypeOpts", + "text": "EventTypeOpts" + }, + "" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IAnalyticsClient.registerShipper", + "type": "Function", + "tags": [], + "label": "registerShipper", + "description": [ + "\nSet up the shipper that will be used to report the telemetry events." + ], + "signature": [ + "(Shipper: ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.ShipperClassConstructor", + "text": "ShipperClassConstructor" + }, + ", shipperConfig: ShipperConfig, opts?: ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.RegisterShipperOpts", + "text": "RegisterShipperOpts" + }, + " | undefined) => void" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IAnalyticsClient.registerShipper.$1", + "type": "Object", + "tags": [], + "label": "Shipper", + "description": [ + "The {@link IShipper } class to instantiate the shipper." + ], + "signature": [ + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.ShipperClassConstructor", + "text": "ShipperClassConstructor" + }, + "" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IAnalyticsClient.registerShipper.$2", + "type": "Uncategorized", + "tags": [], + "label": "shipperConfig", + "description": [ + "The config specific to the Shipper to instantiate." + ], + "signature": [ + "ShipperConfig" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IAnalyticsClient.registerShipper.$3", + "type": "Object", + "tags": [], + "label": "opts", + "description": [ + "Additional options to register the shipper {@link RegisterShipperOpts }." + ], + "signature": [ + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.RegisterShipperOpts", + "text": "RegisterShipperOpts" + }, + " | undefined" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IAnalyticsClient.optIn", + "type": "Function", + "tags": [], + "label": "optIn", + "description": [ + "\nUsed to control the user's consent to report the data.\nIn the advanced mode, it allows to \"cherry-pick\" which events and shippers are enabled/disabled." + ], + "signature": [ + "(optInConfig: ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.OptInConfig", + "text": "OptInConfig" + }, + ") => void" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IAnalyticsClient.optIn.$1", + "type": "Object", + "tags": [], + "label": "optInConfig", + "description": [ + "{@link OptInConfig }" + ], + "signature": [ + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.OptInConfig", + "text": "OptInConfig" + } + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IAnalyticsClient.registerContextProvider", + "type": "Function", + "tags": [], + "label": "registerContextProvider", + "description": [ + "\nRegisters the context provider to enrich the any reported events." + ], + "signature": [ + "(contextProviderOpts: ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.ContextProviderOpts", + "text": "ContextProviderOpts" + }, + ") => void" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IAnalyticsClient.registerContextProvider.$1", + "type": "Object", + "tags": [], + "label": "contextProviderOpts", + "description": [ + "{@link ContextProviderOpts }" + ], + "signature": [ + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.ContextProviderOpts", + "text": "ContextProviderOpts" + }, + "" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IAnalyticsClient.removeContextProvider", + "type": "Function", + "tags": [], + "label": "removeContextProvider", + "description": [ + "\nRemoves the context provider and stop enriching the events from its context." + ], + "signature": [ + "(contextProviderName: string) => void" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IAnalyticsClient.removeContextProvider.$1", + "type": "string", + "tags": [], + "label": "contextProviderName", + "description": [ + "The name of the context provider to remove." + ], + "signature": [ + "string" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IAnalyticsClient.telemetryCounter$", + "type": "Object", + "tags": [], + "label": "telemetryCounter$", + "description": [ + "\nObservable to emit the stats of the processed events." + ], + "signature": [ + "Observable", + "<", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.TelemetryCounter", + "text": "TelemetryCounter" + }, + ">" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IShipper", + "type": "Interface", + "tags": [], + "label": "IShipper", + "description": [ + "\nBasic structure of a Shipper" + ], + "path": "packages/analytics/client/src/shippers/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IShipper.reportEvents", + "type": "Function", + "tags": [], + "label": "reportEvents", + "description": [ + "\nAdapts and ships the event to the persisting/analytics solution." + ], + "signature": [ + "(events: ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.Event", + "text": "Event" + }, + "[]) => void" + ], + "path": "packages/analytics/client/src/shippers/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IShipper.reportEvents.$1", + "type": "Array", + "tags": [], + "label": "events", + "description": [ + "batched events {@link Event }" + ], + "signature": [ + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.Event", + "text": "Event" + }, + "[]" + ], + "path": "packages/analytics/client/src/shippers/types.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IShipper.optIn", + "type": "Function", + "tags": [], + "label": "optIn", + "description": [ + "\nStops/restarts the shipping mechanism based on the value of isOptedIn" + ], + "signature": [ + "(isOptedIn: boolean) => void" + ], + "path": "packages/analytics/client/src/shippers/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IShipper.optIn.$1", + "type": "boolean", + "tags": [], + "label": "isOptedIn", + "description": [ + "`true` for resume sending events. `false` to stop." + ], + "signature": [ + "boolean" + ], + "path": "packages/analytics/client/src/shippers/types.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IShipper.extendContext", + "type": "Function", + "tags": [], + "label": "extendContext", + "description": [ + "\nPerform any necessary calls to the persisting/analytics solution to set the event's context." + ], + "signature": [ + "((newContext: ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.EventContext", + "text": "EventContext" + }, + ") => void) | undefined" + ], + "path": "packages/analytics/client/src/shippers/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IShipper.extendContext.$1", + "type": "Object", + "tags": [], + "label": "newContext", + "description": [], + "signature": [ + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.EventContext", + "text": "EventContext" + } + ], + "path": "packages/analytics/client/src/shippers/types.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.IShipper.telemetryCounter$", + "type": "Object", + "tags": [], + "label": "telemetryCounter$", + "description": [ + "\nObservable to emit the stats of the processed events." + ], + "signature": [ + "Observable", + "<", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.TelemetryCounter", + "text": "TelemetryCounter" + }, + "> | undefined" + ], + "path": "packages/analytics/client/src/shippers/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.OptInConfig", + "type": "Interface", + "tags": [], + "label": "OptInConfig", + "description": [ + "\n" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.OptInConfig.global", + "type": "Object", + "tags": [], + "label": "global", + "description": [ + "\nControls the global enabled/disabled behaviour of the client and shippers." + ], + "signature": [ + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.OptInConfigPerType", + "text": "OptInConfigPerType" + } + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.OptInConfig.event_types", + "type": "Object", + "tags": [], + "label": "event_types", + "description": [ + "\nControls if an event type should be disabled for a specific type of shipper." + ], + "signature": [ + "Record | undefined" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.OptInConfigPerType", + "type": "Interface", + "tags": [], + "label": "OptInConfigPerType", + "description": [ + "\nSets whether a type of event is enabled/disabled globally or per shipper." + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.OptInConfigPerType.enabled", + "type": "boolean", + "tags": [], + "label": "enabled", + "description": [ + "\nThe event type is globally enabled." + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.OptInConfigPerType.shippers", + "type": "Object", + "tags": [], + "label": "shippers", + "description": [ + "\nControls if an event type should be disabled for a specific type of shipper." + ], + "signature": [ + "Record | undefined" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.RegisterShipperOpts", + "type": "Interface", + "tags": [], + "label": "RegisterShipperOpts", + "description": [ + "\nOptional options to register a shipper" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "children": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.SchemaArray", + "type": "Interface", + "tags": [], + "label": "SchemaArray", + "description": [ + "\nSchema to represent an array" + ], + "signature": [ + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaArray", + "text": "SchemaArray" + }, + " extends ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaMeta", + "text": "SchemaMeta" + }, + "" + ], + "path": "packages/analytics/client/src/schema/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.SchemaArray.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"array\"" + ], + "path": "packages/analytics/client/src/schema/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.SchemaArray.items", + "type": "CompoundType", + "tags": [], + "label": "items", + "description": [], + "signature": [ + "{ type: \"pass_through\"; _meta: { description: string; } & ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaMetaOptional", + "text": "SchemaMetaOptional" + }, + "; } | (unknown extends Value ? ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaArray", + "text": "SchemaArray" + }, + " | ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaObject", + "text": "SchemaObject" + }, + " | ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaChildValue", + "text": "SchemaChildValue" + }, + " : NonNullable extends (infer U)[] ? ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaArray", + "text": "SchemaArray" + }, + " : NonNullable extends object ? ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaObject", + "text": "SchemaObject" + }, + " : ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaChildValue", + "text": "SchemaChildValue" + }, + ")" + ], + "path": "packages/analytics/client/src/schema/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.SchemaChildValue", + "type": "Interface", + "tags": [], + "label": "SchemaChildValue", + "description": [], + "signature": [ + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaChildValue", + "text": "SchemaChildValue" + }, + "" + ], + "path": "packages/analytics/client/src/schema/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.SchemaChildValue.type", + "type": "Uncategorized", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "NonNullable extends string ? ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.AllowedSchemaStringTypes", + "text": "AllowedSchemaStringTypes" + }, + " : NonNullable extends number ? ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.AllowedSchemaNumberTypes", + "text": "AllowedSchemaNumberTypes" + }, + " : NonNullable extends boolean ? \"boolean\" : ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.AllowedSchemaTypes", + "text": "AllowedSchemaTypes" + } + ], + "path": "packages/analytics/client/src/schema/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.SchemaChildValue._meta", + "type": "CompoundType", + "tags": [], + "label": "_meta", + "description": [], + "signature": [ + "{ description: string; } & ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaMetaOptional", + "text": "SchemaMetaOptional" + }, + "" + ], + "path": "packages/analytics/client/src/schema/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.SchemaMeta", + "type": "Interface", + "tags": [], + "label": "SchemaMeta", + "description": [ + "\nSchema meta with optional description" + ], + "signature": [ + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaMeta", + "text": "SchemaMeta" + }, + "" + ], + "path": "packages/analytics/client/src/schema/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.SchemaMeta._meta", + "type": "CompoundType", + "tags": [], + "label": "_meta", + "description": [], + "signature": [ + "({ description?: string | undefined; } & ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaMetaOptional", + "text": "SchemaMetaOptional" + }, + ") | undefined" + ], + "path": "packages/analytics/client/src/schema/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.SchemaObject", + "type": "Interface", + "tags": [], + "label": "SchemaObject", + "description": [ + "\nSchema to represent an object" + ], + "signature": [ + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaObject", + "text": "SchemaObject" + }, + " extends ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaMeta", + "text": "SchemaMeta" + }, + "" + ], + "path": "packages/analytics/client/src/schema/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.SchemaObject.properties", + "type": "Object", + "tags": [], + "label": "properties", + "description": [], + "signature": [ + "{ [Key in keyof Required]: ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaValue", + "text": "SchemaValue" + }, + "; }" + ], + "path": "packages/analytics/client/src/schema/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.ShipperClassConstructor", + "type": "Interface", + "tags": [], + "label": "ShipperClassConstructor", + "description": [ + "\nConstructor of a {@link IShipper}" + ], + "signature": [ + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.ShipperClassConstructor", + "text": "ShipperClassConstructor" + }, + "" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.ShipperClassConstructor.shipperName", + "type": "string", + "tags": [], + "label": "shipperName", + "description": [ + "\nThe shipper's unique name" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.ShipperClassConstructor.Unnamed", + "type": "Any", + "tags": [], + "label": "Unnamed", + "description": [ + "\nThe constructor" + ], + "signature": [ + "any" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.TelemetryCounter", + "type": "Interface", + "tags": [], + "label": "TelemetryCounter", + "description": [ + "\nShape of the events emitted by the telemetryCounter$ observable" + ], + "path": "packages/analytics/client/src/events/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.TelemetryCounter.type", + "type": "Enum", + "tags": [], + "label": "type", + "description": [ + "\nIndicates if the event contains data about succeeded, failed or dropped events." + ], + "signature": [ + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.TelemetryCounterType", + "text": "TelemetryCounterType" + } + ], + "path": "packages/analytics/client/src/events/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.TelemetryCounter.source", + "type": "string", + "tags": [], + "label": "source", + "description": [ + "\nWho emitted the event? It can be \"client\" or the name of the shipper." + ], + "path": "packages/analytics/client/src/events/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.TelemetryCounter.event_type", + "type": "string", + "tags": [], + "label": "event_type", + "description": [ + "\nThe event type the success/failure/drop event refers to." + ], + "path": "packages/analytics/client/src/events/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.TelemetryCounter.code", + "type": "string", + "tags": [], + "label": "code", + "description": [ + "\nCode to provide additional information about the success or failure. Examples are 200/400/504/ValidationError/UnknownError" + ], + "path": "packages/analytics/client/src/events/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.TelemetryCounter.count", + "type": "number", + "tags": [], + "label": "count", + "description": [ + "\nThe number of events that this counter refers to." + ], + "path": "packages/analytics/client/src/events/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + } + ], + "enums": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.TelemetryCounterType", + "type": "Enum", + "tags": [], + "label": "TelemetryCounterType", + "description": [ + "\nTypes of the Telemetry Counter: It allows to differentiate what happened to the events" + ], + "path": "packages/analytics/client/src/events/types.ts", + "deprecated": false, + "initialIsOpen": false + } + ], + "misc": [ + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.AllowedSchemaBooleanTypes", + "type": "Type", + "tags": [], + "label": "AllowedSchemaBooleanTypes", + "description": [ + "Types matching boolean values" + ], + "signature": [ + "\"boolean\"" + ], + "path": "packages/analytics/client/src/schema/types.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.AllowedSchemaNumberTypes", + "type": "Type", + "tags": [], + "label": "AllowedSchemaNumberTypes", + "description": [ + "Types matching number values" + ], + "signature": [ + "\"date\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"double\"" + ], + "path": "packages/analytics/client/src/schema/types.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.AllowedSchemaStringTypes", + "type": "Type", + "tags": [], + "label": "AllowedSchemaStringTypes", + "description": [ + "Types matching string values" + ], + "signature": [ + "\"keyword\" | \"text\" | \"date\"" + ], + "path": "packages/analytics/client/src/schema/types.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.AllowedSchemaTypes", + "type": "Type", + "tags": [], + "label": "AllowedSchemaTypes", + "description": [ + "\nPossible type values in the schema" + ], + "signature": [ + "\"boolean\" | \"keyword\" | \"text\" | \"date\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"double\"" + ], + "path": "packages/analytics/client/src/schema/types.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.EventType", + "type": "Type", + "tags": [], + "label": "EventType", + "description": [ + "\nEvent Type used for indexed structures. Only used to improve the readability of the types" + ], + "signature": [ + "string" + ], + "path": "packages/analytics/client/src/events/types.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.PossibleSchemaTypes", + "type": "Type", + "tags": [], + "label": "PossibleSchemaTypes", + "description": [ + "\nHelper to ensure the declared types match the schema types" + ], + "signature": [ + "Value extends string ? ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.AllowedSchemaStringTypes", + "text": "AllowedSchemaStringTypes" + }, + " : Value extends number ? ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.AllowedSchemaNumberTypes", + "text": "AllowedSchemaNumberTypes" + }, + " : Value extends boolean ? \"boolean\" : ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.AllowedSchemaTypes", + "text": "AllowedSchemaTypes" + } + ], + "path": "packages/analytics/client/src/schema/types.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.RootSchema", + "type": "Type", + "tags": [], + "label": "RootSchema", + "description": [ + "\nSchema definition to match the structure of the properties provided.\n" + ], + "signature": [ + "{ [Key in keyof Required]: ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaValue", + "text": "SchemaValue" + }, + "; }" + ], + "path": "packages/analytics/client/src/schema/types.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.SchemaMetaOptional", + "type": "Type", + "tags": [], + "label": "SchemaMetaOptional", + "description": [ + "\nEnforces { optional: true } if the value can be undefined" + ], + "signature": [ + "unknown extends Value ? { optional?: boolean | undefined; } : undefined extends Value ? { optional: true; } : { optional?: false | undefined; }" + ], + "path": "packages/analytics/client/src/schema/types.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.SchemaValue", + "type": "Type", + "tags": [], + "label": "SchemaValue", + "description": [ + "\nType that defines all the possible values that the Schema accepts.\nThese types definitions are helping to identify earlier the possible missing `properties` nesting when\nmanually defining the schemas." + ], + "signature": [ + "{ type: \"pass_through\"; _meta: { description: string; } & ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaMetaOptional", + "text": "SchemaMetaOptional" + }, + "; } | (unknown extends Value ? ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaArray", + "text": "SchemaArray" + }, + " | ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaObject", + "text": "SchemaObject" + }, + " | ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaChildValue", + "text": "SchemaChildValue" + }, + " : NonNullable extends (infer U)[] ? ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaArray", + "text": "SchemaArray" + }, + " : NonNullable extends object ? ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaObject", + "text": "SchemaObject" + }, + " : ", + { + "pluginId": "@kbn/analytics-client", + "scope": "server", + "docId": "kibKbnAnalyticsClientPluginApi", + "section": "def-server.SchemaChildValue", + "text": "SchemaChildValue" + }, + ")" + ], + "path": "packages/analytics/client/src/schema/types.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/analytics-client", + "id": "def-server.ShipperName", + "type": "Type", + "tags": [], + "label": "ShipperName", + "description": [ + "\nShipper Name used for indexed structures. Only used to improve the readability of the types" + ], + "signature": [ + "string" + ], + "path": "packages/analytics/client/src/analytics_client/types.ts", + "deprecated": false, + "initialIsOpen": false + } + ], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx new file mode 100644 index 0000000000000..e51ae9a874e9f --- /dev/null +++ b/api_docs/kbn_analytics_client.mdx @@ -0,0 +1,36 @@ +--- +id: kibKbnAnalyticsClientPluginApi +slug: /kibana-dev-docs/api/kbn-analytics-client +title: "@kbn/analytics-client" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the @kbn/analytics-client plugin +date: 2022-04-26 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 88 | 1 | 10 | 0 | + +## Server + +### Functions + + +### Interfaces + + +### Enums + + +### Consts, variables and types + + diff --git a/api_docs/kbn_analytics_shippers_fullstory.devdocs.json b/api_docs/kbn_analytics_shippers_fullstory.devdocs.json new file mode 100644 index 0000000000000..3f79e43e3a09c --- /dev/null +++ b/api_docs/kbn_analytics_shippers_fullstory.devdocs.json @@ -0,0 +1,314 @@ +{ + "id": "@kbn/analytics-shippers-fullstory", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [ + { + "parentPluginId": "@kbn/analytics-shippers-fullstory", + "id": "def-server.FullStoryShipper", + "type": "Class", + "tags": [], + "label": "FullStoryShipper", + "description": [], + "signature": [ + { + "pluginId": "@kbn/analytics-shippers-fullstory", + "scope": "server", + "docId": "kibKbnAnalyticsShippersFullstoryPluginApi", + "section": "def-server.FullStoryShipper", + "text": "FullStoryShipper" + }, + " implements ", + "IShipper" + ], + "path": "packages/analytics/shippers/fullstory/src/fullstory_shipper.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-shippers-fullstory", + "id": "def-server.FullStoryShipper.shipperName", + "type": "string", + "tags": [], + "label": "shipperName", + "description": [], + "path": "packages/analytics/shippers/fullstory/src/fullstory_shipper.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-shippers-fullstory", + "id": "def-server.FullStoryShipper.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "packages/analytics/shippers/fullstory/src/fullstory_shipper.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-shippers-fullstory", + "id": "def-server.FullStoryShipper.Unnamed.$1", + "type": "Object", + "tags": [], + "label": "config", + "description": [], + "signature": [ + { + "pluginId": "@kbn/analytics-shippers-fullstory", + "scope": "server", + "docId": "kibKbnAnalyticsShippersFullstoryPluginApi", + "section": "def-server.FullStorySnippetConfig", + "text": "FullStorySnippetConfig" + } + ], + "path": "packages/analytics/shippers/fullstory/src/fullstory_shipper.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/analytics-shippers-fullstory", + "id": "def-server.FullStoryShipper.Unnamed.$2", + "type": "Object", + "tags": [], + "label": "initContext", + "description": [], + "signature": [ + "AnalyticsClientInitContext" + ], + "path": "packages/analytics/shippers/fullstory/src/fullstory_shipper.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/analytics-shippers-fullstory", + "id": "def-server.FullStoryShipper.extendContext", + "type": "Function", + "tags": [], + "label": "extendContext", + "description": [], + "signature": [ + "(newContext: ", + "EventContext", + ") => void" + ], + "path": "packages/analytics/shippers/fullstory/src/fullstory_shipper.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-shippers-fullstory", + "id": "def-server.FullStoryShipper.extendContext.$1", + "type": "Object", + "tags": [], + "label": "newContext", + "description": [], + "signature": [ + "EventContext" + ], + "path": "packages/analytics/shippers/fullstory/src/fullstory_shipper.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/analytics-shippers-fullstory", + "id": "def-server.FullStoryShipper.optIn", + "type": "Function", + "tags": [], + "label": "optIn", + "description": [], + "signature": [ + "(isOptedIn: boolean) => void" + ], + "path": "packages/analytics/shippers/fullstory/src/fullstory_shipper.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-shippers-fullstory", + "id": "def-server.FullStoryShipper.optIn.$1", + "type": "boolean", + "tags": [], + "label": "isOptedIn", + "description": [], + "signature": [ + "boolean" + ], + "path": "packages/analytics/shippers/fullstory/src/fullstory_shipper.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/analytics-shippers-fullstory", + "id": "def-server.FullStoryShipper.reportEvents", + "type": "Function", + "tags": [], + "label": "reportEvents", + "description": [], + "signature": [ + "(events: ", + "Event", + "[]) => void" + ], + "path": "packages/analytics/shippers/fullstory/src/fullstory_shipper.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-shippers-fullstory", + "id": "def-server.FullStoryShipper.reportEvents.$1", + "type": "Array", + "tags": [], + "label": "events", + "description": [], + "signature": [ + "Event", + "[]" + ], + "path": "packages/analytics/shippers/fullstory/src/fullstory_shipper.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + } + ], + "functions": [], + "interfaces": [ + { + "parentPluginId": "@kbn/analytics-shippers-fullstory", + "id": "def-server.FullStorySnippetConfig", + "type": "Interface", + "tags": [], + "label": "FullStorySnippetConfig", + "description": [], + "path": "packages/analytics/shippers/fullstory/src/load_snippet.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/analytics-shippers-fullstory", + "id": "def-server.FullStorySnippetConfig.fullStoryOrgId", + "type": "string", + "tags": [], + "label": "fullStoryOrgId", + "description": [ + "\nThe FullStory account id." + ], + "path": "packages/analytics/shippers/fullstory/src/load_snippet.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-shippers-fullstory", + "id": "def-server.FullStorySnippetConfig.host", + "type": "string", + "tags": [], + "label": "host", + "description": [ + "\nThe host to send the data to. Used to overcome AdBlockers by using custom DNSs.\nIf not specified, it defaults to `fullstory.com`." + ], + "signature": [ + "string | undefined" + ], + "path": "packages/analytics/shippers/fullstory/src/load_snippet.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-shippers-fullstory", + "id": "def-server.FullStorySnippetConfig.scriptUrl", + "type": "string", + "tags": [], + "label": "scriptUrl", + "description": [ + "\nThe URL to load the FullStory client from. Falls back to `edge.fullstory.com/s/fs.js` if not specified." + ], + "signature": [ + "string | undefined" + ], + "path": "packages/analytics/shippers/fullstory/src/load_snippet.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-shippers-fullstory", + "id": "def-server.FullStorySnippetConfig.debug", + "type": "CompoundType", + "tags": [], + "label": "debug", + "description": [ + "\nWhether the debug logs should be printed to the console." + ], + "signature": [ + "boolean | undefined" + ], + "path": "packages/analytics/shippers/fullstory/src/load_snippet.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/analytics-shippers-fullstory", + "id": "def-server.FullStorySnippetConfig.namespace", + "type": "string", + "tags": [], + "label": "namespace", + "description": [ + "\nThe name of the variable where the API is stored: `window[namespace]`. Defaults to `FS`." + ], + "signature": [ + "string | undefined" + ], + "path": "packages/analytics/shippers/fullstory/src/load_snippet.ts", + "deprecated": false + } + ], + "initialIsOpen": false + } + ], + "enums": [], + "misc": [ + { + "parentPluginId": "@kbn/analytics-shippers-fullstory", + "id": "def-server.FullStoryShipperConfig", + "type": "Type", + "tags": [], + "label": "FullStoryShipperConfig", + "description": [], + "signature": [ + { + "pluginId": "@kbn/analytics-shippers-fullstory", + "scope": "server", + "docId": "kibKbnAnalyticsShippersFullstoryPluginApi", + "section": "def-server.FullStorySnippetConfig", + "text": "FullStorySnippetConfig" + } + ], + "path": "packages/analytics/shippers/fullstory/src/fullstory_shipper.ts", + "deprecated": false, + "initialIsOpen": false + } + ], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx new file mode 100644 index 0000000000000..326388928255e --- /dev/null +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -0,0 +1,33 @@ +--- +id: kibKbnAnalyticsShippersFullstoryPluginApi +slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory +title: "@kbn/analytics-shippers-fullstory" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the @kbn/analytics-shippers-fullstory plugin +date: 2022-04-26 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 18 | 0 | 13 | 0 | + +## Server + +### Classes + + +### Interfaces + + +### Consts, variables and types + + diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index 2ed7dbdbfda88..5e544916f7581 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/apm-config-loader plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index 49fb44941d1dc..6b8bd73db26cd 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/apm-utils plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index 6acea95d20cc4..91196a5c6fff9 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/axe-config plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_bazel_packages.devdocs.json b/api_docs/kbn_bazel_packages.devdocs.json index babc54a49973c..993554aca7636 100644 --- a/api_docs/kbn_bazel_packages.devdocs.json +++ b/api_docs/kbn_bazel_packages.devdocs.json @@ -29,7 +29,7 @@ "tags": [], "label": "fromDir", "description": [ - "\nCreate a BazelPackage object from a package directory. Reads some files from the package and returns\na Promise for a BazelPackage instance" + "\nCreate a BazelPackage object from a package directory. Reads some files from the package and returns\na Promise for a BazelPackage instance." ], "signature": [ "(dir: string) => Promise<", @@ -154,6 +154,23 @@ "children": [], "returnComment": [] }, + { + "parentPluginId": "@kbn/bazel-packages", + "id": "def-server.BazelPackage.isDevOnly", + "type": "Function", + "tags": [], + "label": "isDevOnly", + "description": [ + "\nReturns true if the package is not intended to be in the build" + ], + "signature": [ + "() => boolean" + ], + "path": "packages/kbn-bazel-packages/src/bazel_package.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, { "parentPluginId": "@kbn/bazel-packages", "id": "def-server.BazelPackage.inspect.custom", @@ -176,17 +193,46 @@ } ], "functions": [ + { + "parentPluginId": "@kbn/bazel-packages", + "id": "def-server.discoverBazelPackageLocations", + "type": "Function", + "tags": [], + "label": "discoverBazelPackageLocations", + "description": [], + "signature": [ + "(repoRoot: string) => string[]" + ], + "path": "packages/kbn-bazel-packages/src/discover_packages.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/bazel-packages", + "id": "def-server.discoverBazelPackageLocations.$1", + "type": "string", + "tags": [], + "label": "repoRoot", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-bazel-packages/src/discover_packages.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/bazel-packages", "id": "def-server.discoverBazelPackages", "type": "Function", "tags": [], "label": "discoverBazelPackages", - "description": [ - "\nSearch the local Kibana repo for bazel packages and return an array of BazelPackage objects\nrepresenting each package found." - ], + "description": [], "signature": [ - "() => Promise<", + "(repoRoot: string) => Promise<", { "pluginId": "@kbn/bazel-packages", "scope": "server", @@ -198,6 +244,57 @@ ], "path": "packages/kbn-bazel-packages/src/discover_packages.ts", "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/bazel-packages", + "id": "def-server.discoverBazelPackages.$1", + "type": "string", + "tags": [], + "label": "repoRoot", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-bazel-packages/src/discover_packages.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/bazel-packages", + "id": "def-server.getAllBazelPackageDirs", + "type": "Function", + "tags": [], + "label": "getAllBazelPackageDirs", + "description": [ + "\nResolve all the BAZEL_PACKAGE_DIRS to absolute paths" + ], + "signature": [ + "() => EntryInternal[] & string[]" + ], + "path": "packages/kbn-bazel-packages/src/bazel_package_dirs.ts", + "deprecated": false, + "children": [], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/bazel-packages", + "id": "def-server.getAllRepoRelativeBazelPackageDirs", + "type": "Function", + "tags": [], + "label": "getAllRepoRelativeBazelPackageDirs", + "description": [ + "\nResolve all the BAZEL_PACKAGE_DIRS to repo-relative paths" + ], + "signature": [ + "() => string[]" + ], + "path": "packages/kbn-bazel-packages/src/bazel_package_dirs.ts", + "deprecated": false, "children": [], "returnComment": [], "initialIsOpen": false @@ -213,7 +310,7 @@ "tags": [], "label": "BAZEL_PACKAGE_DIRS", "description": [ - "\nThis is a list of repo-relative paths to directories containing packages. Do not\ninclude `**` in these, one or two `*` segments is acceptable, we need this search\nto be super fast so please avoid deep recursive searching.\n\n eg. src/vis-editors => would find a package at src/vis-editors/foo/package.json\n src/vis-editors/* => would find a package at src/vis-editors/foo/bar/package.json" + "\nThis is a list of repo-relative paths to directories containing packages. Do not\ninclude `**` in these, one or two `*` segments is acceptable, we need this search\nto be super fast so please avoid deep recursive searching.\n\n eg. src/vis_editors => would find a package at src/vis_editors/foo/package.json\n src/vis_editors/* => would find a package at src/vis_editors/foo/bar/package.json" ], "signature": [ "string[]" diff --git a/api_docs/kbn_bazel_packages.mdx b/api_docs/kbn_bazel_packages.mdx index 4cecba08dd051..a6dbbd7872270 100644 --- a/api_docs/kbn_bazel_packages.mdx +++ b/api_docs/kbn_bazel_packages.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-bazel-packages title: "@kbn/bazel-packages" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/bazel-packages plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/bazel-packages'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 12 | 0 | 5 | 1 | +| 18 | 0 | 9 | 1 | ## Server diff --git a/api_docs/kbn_bazel_runner.devdocs.json b/api_docs/kbn_bazel_runner.devdocs.json new file mode 100644 index 0000000000000..e5f5473949f65 --- /dev/null +++ b/api_docs/kbn_bazel_runner.devdocs.json @@ -0,0 +1,90 @@ +{ + "id": "@kbn/bazel-runner", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [ + { + "parentPluginId": "@kbn/bazel-runner", + "id": "def-server.runBazel", + "type": "Function", + "tags": [], + "label": "runBazel", + "description": [], + "signature": [ + "(options: BazelRunOptions) => Promise" + ], + "path": "packages/kbn-bazel-runner/src/bazel_runner.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/bazel-runner", + "id": "def-server.runBazel.$1", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "BazelRunOptions" + ], + "path": "packages/kbn-bazel-runner/src/bazel_runner.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/bazel-runner", + "id": "def-server.runIBazel", + "type": "Function", + "tags": [], + "label": "runIBazel", + "description": [], + "signature": [ + "(options: BazelRunOptions) => Promise" + ], + "path": "packages/kbn-bazel-runner/src/bazel_runner.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/bazel-runner", + "id": "def-server.runIBazel.$1", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "BazelRunOptions" + ], + "path": "packages/kbn-bazel-runner/src/bazel_runner.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_bazel_runner.mdx b/api_docs/kbn_bazel_runner.mdx new file mode 100644 index 0000000000000..e26e06d6d8241 --- /dev/null +++ b/api_docs/kbn_bazel_runner.mdx @@ -0,0 +1,27 @@ +--- +id: kibKbnBazelRunnerPluginApi +slug: /kibana-dev-docs/api/kbn-bazel-runner +title: "@kbn/bazel-runner" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the @kbn/bazel-runner plugin +date: 2022-04-26 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/bazel-runner'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import kbnBazelRunnerObj from './kbn_bazel_runner.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 4 | 0 | 4 | 0 | + +## Server + +### Functions + + diff --git a/api_docs/kbn_ci_stats_client.devdocs.json b/api_docs/kbn_ci_stats_client.devdocs.json new file mode 100644 index 0000000000000..bc6b6ba628f44 --- /dev/null +++ b/api_docs/kbn_ci_stats_client.devdocs.json @@ -0,0 +1,158 @@ +{ + "id": "@kbn/ci-stats-client", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [ + { + "parentPluginId": "@kbn/ci-stats-client", + "id": "def-server.CiStatsClient", + "type": "Class", + "tags": [], + "label": "CiStatsClient", + "description": [], + "path": "packages/kbn-ci-stats-client/src/ci_stats_client.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ci-stats-client", + "id": "def-server.CiStatsClient.fromEnv", + "type": "Function", + "tags": [], + "label": "fromEnv", + "description": [ + "\nCreate a CiStatsReporter by inspecting the ENV for the necessary config" + ], + "signature": [ + "(log: ", + "ToolingLog", + ") => ", + { + "pluginId": "@kbn/ci-stats-client", + "scope": "server", + "docId": "kibKbnCiStatsClientPluginApi", + "section": "def-server.CiStatsClient", + "text": "CiStatsClient" + } + ], + "path": "packages/kbn-ci-stats-client/src/ci_stats_client.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ci-stats-client", + "id": "def-server.CiStatsClient.fromEnv.$1", + "type": "Object", + "tags": [], + "label": "log", + "description": [], + "signature": [ + "ToolingLog" + ], + "path": "packages/kbn-ci-stats-client/src/ci_stats_client.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/ci-stats-client", + "id": "def-server.CiStatsClient.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "packages/kbn-ci-stats-client/src/ci_stats_client.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ci-stats-client", + "id": "def-server.CiStatsClient.Unnamed.$1", + "type": "Object", + "tags": [], + "label": "config", + "description": [], + "signature": [ + "Config", + " | undefined" + ], + "path": "packages/kbn-ci-stats-client/src/ci_stats_client.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/ci-stats-client", + "id": "def-server.CiStatsClient.isEnabled", + "type": "Function", + "tags": [], + "label": "isEnabled", + "description": [], + "signature": [ + "() => boolean" + ], + "path": "packages/kbn-ci-stats-client/src/ci_stats_client.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/ci-stats-client", + "id": "def-server.CiStatsClient.getLatestTestGroupStats", + "type": "Function", + "tags": [], + "label": "getLatestTestGroupStats", + "description": [], + "signature": [ + "(options: LatestTestGroupStatsOptions) => Promise" + ], + "path": "packages/kbn-ci-stats-client/src/ci_stats_client.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ci-stats-client", + "id": "def-server.CiStatsClient.getLatestTestGroupStats.$1", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "LatestTestGroupStatsOptions" + ], + "path": "packages/kbn-ci-stats-client/src/ci_stats_client.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + } + ], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_ci_stats_client.mdx b/api_docs/kbn_ci_stats_client.mdx new file mode 100644 index 0000000000000..7e081672825d1 --- /dev/null +++ b/api_docs/kbn_ci_stats_client.mdx @@ -0,0 +1,27 @@ +--- +id: kibKbnCiStatsClientPluginApi +slug: /kibana-dev-docs/api/kbn-ci-stats-client +title: "@kbn/ci-stats-client" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the @kbn/ci-stats-client plugin +date: 2022-04-26 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-client'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import kbnCiStatsClientObj from './kbn_ci_stats_client.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 8 | 0 | 7 | 0 | + +## Server + +### Classes + + diff --git a/api_docs/kbn_ci_stats_core.devdocs.json b/api_docs/kbn_ci_stats_core.devdocs.json new file mode 100644 index 0000000000000..d088822187665 --- /dev/null +++ b/api_docs/kbn_ci_stats_core.devdocs.json @@ -0,0 +1,139 @@ +{ + "id": "@kbn/ci-stats-core", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [ + { + "parentPluginId": "@kbn/ci-stats-core", + "id": "def-server.parseConfig", + "type": "Function", + "tags": [], + "label": "parseConfig", + "description": [], + "signature": [ + "(log: ", + "ToolingLog", + ") => ", + { + "pluginId": "@kbn/ci-stats-core", + "scope": "server", + "docId": "kibKbnCiStatsCorePluginApi", + "section": "def-server.Config", + "text": "Config" + }, + " | undefined" + ], + "path": "packages/kbn-ci-stats-core/src/ci_stats_config.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ci-stats-core", + "id": "def-server.parseConfig.$1", + "type": "Object", + "tags": [], + "label": "log", + "description": [], + "signature": [ + "ToolingLog" + ], + "path": "packages/kbn-ci-stats-core/src/ci_stats_config.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [ + { + "parentPluginId": "@kbn/ci-stats-core", + "id": "def-server.CiStatsMetadata", + "type": "Interface", + "tags": [], + "label": "CiStatsMetadata", + "description": [ + "Container for metadata that can be attached to different ci-stats objects" + ], + "path": "packages/kbn-ci-stats-core/src/ci_stats_metadata.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ci-stats-core", + "id": "def-server.CiStatsMetadata.Unnamed", + "type": "IndexSignature", + "tags": [], + "label": "[key: string]: string | number | boolean | string[] | undefined", + "description": [ + "\nArbitrary key-value pairs which can be attached to CiStatsTiming and CiStatsMetric\nobjects stored in the ci-stats service" + ], + "signature": [ + "[key: string]: string | number | boolean | string[] | undefined" + ], + "path": "packages/kbn-ci-stats-core/src/ci_stats_metadata.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ci-stats-core", + "id": "def-server.Config", + "type": "Interface", + "tags": [], + "label": "Config", + "description": [ + "\nInformation about how CiStatsReporter should talk to the ci-stats service. Normally\nit is read from a JSON environment variable using the `parseConfig()` function\nexported by this module." + ], + "path": "packages/kbn-ci-stats-core/src/ci_stats_config.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ci-stats-core", + "id": "def-server.Config.apiToken", + "type": "string", + "tags": [], + "label": "apiToken", + "description": [ + "ApiToken necessary for writing build data to ci-stats service" + ], + "path": "packages/kbn-ci-stats-core/src/ci_stats_config.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-core", + "id": "def-server.Config.buildId", + "type": "string", + "tags": [], + "label": "buildId", + "description": [ + "\nuuid which should be obtained by first creating a build with the\nci-stats service and then passing it to all subsequent steps" + ], + "path": "packages/kbn-ci-stats-core/src/ci_stats_config.ts", + "deprecated": false + } + ], + "initialIsOpen": false + } + ], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_ci_stats_core.mdx b/api_docs/kbn_ci_stats_core.mdx new file mode 100644 index 0000000000000..a309e10212e64 --- /dev/null +++ b/api_docs/kbn_ci_stats_core.mdx @@ -0,0 +1,30 @@ +--- +id: kibKbnCiStatsCorePluginApi +slug: /kibana-dev-docs/api/kbn-ci-stats-core +title: "@kbn/ci-stats-core" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the @kbn/ci-stats-core plugin +date: 2022-04-26 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-core'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import kbnCiStatsCoreObj from './kbn_ci_stats_core.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 7 | 0 | 2 | 0 | + +## Server + +### Functions + + +### Interfaces + + diff --git a/api_docs/kbn_ci_stats_reporter.devdocs.json b/api_docs/kbn_ci_stats_reporter.devdocs.json new file mode 100644 index 0000000000000..f579d304c08db --- /dev/null +++ b/api_docs/kbn_ci_stats_reporter.devdocs.json @@ -0,0 +1,968 @@ +{ + "id": "@kbn/ci-stats-reporter", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [ + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsReporter", + "type": "Class", + "tags": [], + "label": "CiStatsReporter", + "description": [ + "Object that helps report data to the ci-stats service" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsReporter.fromEnv", + "type": "Function", + "tags": [], + "label": "fromEnv", + "description": [ + "\nCreate a CiStatsReporter by inspecting the ENV for the necessary config" + ], + "signature": [ + "(log: ", + "ToolingLog", + ") => ", + { + "pluginId": "@kbn/ci-stats-reporter", + "scope": "server", + "docId": "kibKbnCiStatsReporterPluginApi", + "section": "def-server.CiStatsReporter", + "text": "CiStatsReporter" + } + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsReporter.fromEnv.$1", + "type": "Object", + "tags": [], + "label": "log", + "description": [], + "signature": [ + "ToolingLog" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsReporter.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsReporter.Unnamed.$1", + "type": "Object", + "tags": [], + "label": "config", + "description": [], + "signature": [ + "Config", + " | undefined" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false, + "isRequired": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsReporter.Unnamed.$2", + "type": "Object", + "tags": [], + "label": "log", + "description": [], + "signature": [ + "ToolingLog" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsReporter.isEnabled", + "type": "Function", + "tags": [], + "label": "isEnabled", + "description": [ + "\nDetermine if CI_STATS is explicitly disabled by the environment. To determine\nif the CiStatsReporter has enough information in the environment to send metrics\nfor builds use #hasBuildConfig()." + ], + "signature": [ + "() => boolean" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsReporter.hasBuildConfig", + "type": "Function", + "tags": [], + "label": "hasBuildConfig", + "description": [ + "\nDetermines if the CiStatsReporter is disabled by the environment, or properly\nconfigured and able to send stats" + ], + "signature": [ + "() => boolean" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsReporter.timings", + "type": "Function", + "tags": [], + "label": "timings", + "description": [ + "\nReport timings data to the ci-stats service. If running in CI then the reporter\nwill include the buildId in the report with the access token, otherwise the timings\ndata will be recorded as anonymous timing data." + ], + "signature": [ + "(options: ", + { + "pluginId": "@kbn/ci-stats-reporter", + "scope": "server", + "docId": "kibKbnCiStatsReporterPluginApi", + "section": "def-server.TimingsOptions", + "text": "TimingsOptions" + }, + ") => Promise" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsReporter.timings.$1", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + { + "pluginId": "@kbn/ci-stats-reporter", + "scope": "server", + "docId": "kibKbnCiStatsReporterPluginApi", + "section": "def-server.TimingsOptions", + "text": "TimingsOptions" + } + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsReporter.metrics", + "type": "Function", + "tags": [], + "label": "metrics", + "description": [ + "\nReport metrics data to the ci-stats service. If running outside of CI this method\ndoes nothing as metrics can only be reported when associated with a specific CI build." + ], + "signature": [ + "(metrics: ", + { + "pluginId": "@kbn/ci-stats-reporter", + "scope": "server", + "docId": "kibKbnCiStatsReporterPluginApi", + "section": "def-server.CiStatsMetric", + "text": "CiStatsMetric" + }, + "[], options?: ", + { + "pluginId": "@kbn/ci-stats-reporter", + "scope": "server", + "docId": "kibKbnCiStatsReporterPluginApi", + "section": "def-server.MetricsOptions", + "text": "MetricsOptions" + }, + " | undefined) => Promise" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsReporter.metrics.$1", + "type": "Array", + "tags": [], + "label": "metrics", + "description": [], + "signature": [ + { + "pluginId": "@kbn/ci-stats-reporter", + "scope": "server", + "docId": "kibKbnCiStatsReporterPluginApi", + "section": "def-server.CiStatsMetric", + "text": "CiStatsMetric" + }, + "[]" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsReporter.metrics.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + { + "pluginId": "@kbn/ci-stats-reporter", + "scope": "server", + "docId": "kibKbnCiStatsReporterPluginApi", + "section": "def-server.MetricsOptions", + "text": "MetricsOptions" + }, + " | undefined" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsReporter.reportTests", + "type": "Function", + "tags": [], + "label": "reportTests", + "description": [ + "\nSend test reports to ci-stats" + ], + "signature": [ + "({ group, testRuns }: ", + { + "pluginId": "@kbn/ci-stats-reporter", + "scope": "server", + "docId": "kibKbnCiStatsReporterPluginApi", + "section": "def-server.CiStatsReportTestsOptions", + "text": "CiStatsReportTestsOptions" + }, + ") => Promise" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsReporter.reportTests.$1", + "type": "Object", + "tags": [], + "label": "{ group, testRuns }", + "description": [], + "signature": [ + { + "pluginId": "@kbn/ci-stats-reporter", + "scope": "server", + "docId": "kibKbnCiStatsReporterPluginApi", + "section": "def-server.CiStatsReportTestsOptions", + "text": "CiStatsReportTestsOptions" + } + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + } + ], + "functions": [ + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.getTimeReporter", + "type": "Function", + "tags": [], + "label": "getTimeReporter", + "description": [], + "signature": [ + "(log: ", + "ToolingLog", + ", group: string) => (startTime: number, id: string, meta: Record) => Promise" + ], + "path": "packages/kbn-ci-stats-reporter/src/report_time.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.getTimeReporter.$1", + "type": "Object", + "tags": [], + "label": "log", + "description": [], + "signature": [ + "ToolingLog" + ], + "path": "packages/kbn-ci-stats-reporter/src/report_time.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.getTimeReporter.$2", + "type": "string", + "tags": [], + "label": "group", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-ci-stats-reporter/src/report_time.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [ + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsMetric", + "type": "Interface", + "tags": [], + "label": "CiStatsMetric", + "description": [ + "A ci-stats metric record" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsMetric.group", + "type": "string", + "tags": [], + "label": "group", + "description": [ + "Top-level categorization for the metric, e.g. \"page load bundle size\"" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsMetric.id", + "type": "string", + "tags": [], + "label": "id", + "description": [ + "Specific sub-set of the \"group\", e.g. \"dashboard\"" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsMetric.value", + "type": "number", + "tags": [], + "label": "value", + "description": [ + "integer value recorded as the value of this metric" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsMetric.limit", + "type": "number", + "tags": [], + "label": "limit", + "description": [ + "optional limit which will generate an error on PRs when the metric exceeds the limit" + ], + "signature": [ + "number | undefined" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsMetric.limitConfigPath", + "type": "string", + "tags": [], + "label": "limitConfigPath", + "description": [ + "\npath, relative to the repo, where the config file contianing limits\nis kept. Linked from PR comments instructing contributors how to fix\ntheir PRs." + ], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsMetric.meta", + "type": "Object", + "tags": [], + "label": "meta", + "description": [ + "Arbitrary key-value pairs which can be used for additional filtering/reporting" + ], + "signature": [ + "CiStatsMetadata", + " | undefined" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsReportTestsOptions", + "type": "Interface", + "tags": [], + "label": "CiStatsReportTestsOptions", + "description": [ + "Options for reporting tests to ci-stats" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsReportTestsOptions.group", + "type": "Object", + "tags": [], + "label": "group", + "description": [ + "\nInformation about the group of tests that were run" + ], + "signature": [ + { + "pluginId": "@kbn/ci-stats-reporter", + "scope": "server", + "docId": "kibKbnCiStatsReporterPluginApi", + "section": "def-server.CiStatsTestGroupInfo", + "text": "CiStatsTestGroupInfo" + } + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsReportTestsOptions.testRuns", + "type": "Array", + "tags": [], + "label": "testRuns", + "description": [ + "\nInformation about each test that ran, including failure information" + ], + "signature": [ + { + "pluginId": "@kbn/ci-stats-reporter", + "scope": "server", + "docId": "kibKbnCiStatsReporterPluginApi", + "section": "def-server.CiStatsTestRun", + "text": "CiStatsTestRun" + }, + "[]" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTestGroupInfo", + "type": "Interface", + "tags": [], + "label": "CiStatsTestGroupInfo", + "description": [], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTestGroupInfo.startTime", + "type": "string", + "tags": [], + "label": "startTime", + "description": [ + "\nISO-8601 formatted datetime representing when the group of tests started running" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTestGroupInfo.durationMs", + "type": "number", + "tags": [], + "label": "durationMs", + "description": [ + "\nThe number of miliseconds that the tests ran for" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTestGroupInfo.type", + "type": "string", + "tags": [], + "label": "type", + "description": [ + "\nThe type of tests run in this group, any value is valid but test groups are groupped by type in the UI so use something consistent" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTestGroupInfo.name", + "type": "string", + "tags": [], + "label": "name", + "description": [ + "\nThe name of this specific group (within the \"type\")" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTestGroupInfo.meta", + "type": "Object", + "tags": [], + "label": "meta", + "description": [ + "\nArbitrary metadata associated with this group. We currently look for a ciGroup metadata property for highlighting that when appropriate" + ], + "signature": [ + "CiStatsMetadata" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTestRun", + "type": "Interface", + "tags": [], + "label": "CiStatsTestRun", + "description": [], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTestRun.startTime", + "type": "string", + "tags": [], + "label": "startTime", + "description": [ + "\nISO-8601 formatted datetime representing when the tests started running" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTestRun.durationMs", + "type": "number", + "tags": [], + "label": "durationMs", + "description": [ + "\nDuration of the tests in milliseconds" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTestRun.seq", + "type": "number", + "tags": [], + "label": "seq", + "description": [ + "\nA sequence number, this is used to order the tests in a specific test run" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTestRun.type", + "type": "CompoundType", + "tags": [], + "label": "type", + "description": [ + "\nThe type of this \"test run\", usually this is just \"test\" but when reporting issues in hooks it can be set to the type of hook" + ], + "signature": [ + "\"after all hook\" | \"after each hook\" | \"before all hook\" | \"before each hook\" | \"test\"" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTestRun.result", + "type": "CompoundType", + "tags": [], + "label": "result", + "description": [ + "\n\"fail\", \"pass\" or \"skip\", the result of the tests" + ], + "signature": [ + "\"fail\" | \"pass\" | \"skip\"" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTestRun.suites", + "type": "Array", + "tags": [], + "label": "suites", + "description": [ + "\nThe list of suite names containing this test, the first being the outermost suite" + ], + "signature": [ + "string[]" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTestRun.name", + "type": "string", + "tags": [], + "label": "name", + "description": [ + "\nThe name of this specific test run" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTestRun.file", + "type": "string", + "tags": [], + "label": "file", + "description": [ + "\nRelative path from the root of the repo contianing this test" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTestRun.error", + "type": "string", + "tags": [], + "label": "error", + "description": [ + "\nError message if the test failed" + ], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTestRun.stdout", + "type": "string", + "tags": [], + "label": "stdout", + "description": [ + "\nDebug output/stdout produced by the test" + ], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTestRun.screenshots", + "type": "Array", + "tags": [], + "label": "screenshots", + "description": [ + "\nScreenshots captured during the test run" + ], + "signature": [ + "{ name: string; base64Png: string; }[] | undefined" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTiming", + "type": "Interface", + "tags": [], + "label": "CiStatsTiming", + "description": [ + "A ci-stats timing event" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTiming.group", + "type": "string", + "tags": [], + "label": "group", + "description": [ + "Top-level categorization for the timing, e.g. \"scripts/foo\", process type, etc." + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTiming.id", + "type": "string", + "tags": [], + "label": "id", + "description": [ + "Specific timing (witin the \"group\" being tracked) e.g. \"total\"" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTiming.ms", + "type": "number", + "tags": [], + "label": "ms", + "description": [ + "time in milliseconds which should be recorded" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTiming.meta", + "type": "Object", + "tags": [], + "label": "meta", + "description": [ + "hash of key-value pairs which will be stored with the timing for additional filtering and reporting" + ], + "signature": [ + "CiStatsMetadata", + " | undefined" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.MetricsOptions", + "type": "Interface", + "tags": [], + "label": "MetricsOptions", + "description": [ + "Options for reporting metrics to ci-stats" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.MetricsOptions.defaultMeta", + "type": "Object", + "tags": [], + "label": "defaultMeta", + "description": [ + "Default metadata to add to each metric" + ], + "signature": [ + "CiStatsMetadata", + " | undefined" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.TimingsOptions", + "type": "Interface", + "tags": [], + "label": "TimingsOptions", + "description": [ + "Options for reporting timings to ci-stats" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.TimingsOptions.timings", + "type": "Array", + "tags": [], + "label": "timings", + "description": [ + "list of timings to record" + ], + "signature": [ + { + "pluginId": "@kbn/ci-stats-reporter", + "scope": "server", + "docId": "kibKbnCiStatsReporterPluginApi", + "section": "def-server.CiStatsTiming", + "text": "CiStatsTiming" + }, + "[]" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.TimingsOptions.upstreamBranch", + "type": "string", + "tags": [], + "label": "upstreamBranch", + "description": [ + "master, 7.x, etc, automatically detected from package.json if not specified" + ], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.TimingsOptions.kibanaUuid", + "type": "CompoundType", + "tags": [], + "label": "kibanaUuid", + "description": [ + "value of data/uuid, automatically loaded if not specified" + ], + "signature": [ + "string | null | undefined" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts", + "deprecated": false + } + ], + "initialIsOpen": false + } + ], + "enums": [], + "misc": [ + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTestResult", + "type": "Type", + "tags": [], + "label": "CiStatsTestResult", + "description": [], + "signature": [ + "\"fail\" | \"pass\" | \"skip\"" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ci-stats-reporter", + "id": "def-server.CiStatsTestType", + "type": "Type", + "tags": [], + "label": "CiStatsTestType", + "description": [], + "signature": [ + "\"after all hook\" | \"after each hook\" | \"before all hook\" | \"before each hook\" | \"test\"" + ], + "path": "packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts", + "deprecated": false, + "initialIsOpen": false + } + ], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_ci_stats_reporter.mdx b/api_docs/kbn_ci_stats_reporter.mdx new file mode 100644 index 0000000000000..0cc182de00726 --- /dev/null +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -0,0 +1,36 @@ +--- +id: kibKbnCiStatsReporterPluginApi +slug: /kibana-dev-docs/api/kbn-ci-stats-reporter +title: "@kbn/ci-stats-reporter" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the @kbn/ci-stats-reporter plugin +date: 2022-04-26 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-reporter'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import kbnCiStatsReporterObj from './kbn_ci_stats_reporter.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 59 | 0 | 15 | 0 | + +## Server + +### Functions + + +### Classes + + +### Interfaces + + +### Consts, variables and types + + diff --git a/api_docs/kbn_cli_dev_mode.mdx b/api_docs/kbn_cli_dev_mode.mdx index c3491abc76979..5f3a928f804bc 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/cli-dev-mode plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_coloring.devdocs.json b/api_docs/kbn_coloring.devdocs.json new file mode 100644 index 0000000000000..b6c631706bfaf --- /dev/null +++ b/api_docs/kbn_coloring.devdocs.json @@ -0,0 +1,1791 @@ +{ + "id": "@kbn/coloring", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.checkIsMaxContinuity", + "type": "Function", + "tags": [], + "label": "checkIsMaxContinuity", + "description": [], + "signature": [ + "(continuity: ", + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.PaletteContinuity", + "text": "PaletteContinuity" + }, + " | undefined) => boolean" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.checkIsMaxContinuity.$1", + "type": "CompoundType", + "tags": [], + "label": "continuity", + "description": [], + "signature": [ + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.PaletteContinuity", + "text": "PaletteContinuity" + }, + " | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.checkIsMinContinuity", + "type": "Function", + "tags": [], + "label": "checkIsMinContinuity", + "description": [], + "signature": [ + "(continuity: ", + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.PaletteContinuity", + "text": "PaletteContinuity" + }, + " | undefined) => boolean" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.checkIsMinContinuity.$1", + "type": "CompoundType", + "tags": [], + "label": "continuity", + "description": [], + "signature": [ + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.PaletteContinuity", + "text": "PaletteContinuity" + }, + " | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.CustomizablePalette", + "type": "Function", + "tags": [], + "label": "CustomizablePalette", + "description": [ + "\nA `CustomizablePalette` component that is wrapped by the `withSuspense` HOC. This component can\nbe used directly by consumers and will load the `KibanaPageTemplateSolutionNavAvatarLazy` component lazily with\na predefined fallback and error boundary." + ], + "signature": [ + "React.ForwardRefExoticComponent<", + "CustomizablePaletteProps", + " & React.RefAttributes<{}>>" + ], + "path": "packages/kbn-coloring/src/shared_components/index.ts", + "deprecated": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.CustomizablePalette.$1", + "type": "Uncategorized", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "P" + ], + "path": "node_modules/@types/react/index.d.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.CustomizablePaletteLazy", + "type": "Function", + "tags": [], + "label": "CustomizablePaletteLazy", + "description": [ + "\nThe Lazily-loaded `CustomizablePalette` component. Consumers should use `React.Suspense` or\nthe withSuspense` HOC to load this component." + ], + "signature": [ + "React.ExoticComponent<", + "CustomizablePaletteProps", + "> & { readonly _result: ({ palettes, activePalette, setPalette, dataBounds, showExtraActions, showRangeTypeSelector, disableSwitchingContinuity, }: ", + "CustomizablePaletteProps", + ") => JSX.Element; }" + ], + "path": "packages/kbn-coloring/src/shared_components/index.ts", + "deprecated": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.CustomizablePaletteLazy.$1", + "type": "Uncategorized", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "P" + ], + "path": "node_modules/@types/react/index.d.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.getDataMinMax", + "type": "Function", + "tags": [], + "label": "getDataMinMax", + "description": [], + "signature": [ + "(rangeType: \"number\" | \"percent\" | undefined, dataBounds: ", + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.DataBounds", + "text": "DataBounds" + }, + ") => { min: number; max: number; }" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.getDataMinMax.$1", + "type": "CompoundType", + "tags": [], + "label": "rangeType", + "description": [], + "signature": [ + "\"number\" | \"percent\" | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "isRequired": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.getDataMinMax.$2", + "type": "Object", + "tags": [], + "label": "dataBounds", + "description": [], + "signature": [ + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.DataBounds", + "text": "DataBounds" + } + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.getFallbackDataBounds", + "type": "Function", + "tags": [], + "label": "getFallbackDataBounds", + "description": [], + "signature": [ + "(rangeType?: \"number\" | \"percent\" | undefined) => ", + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.DataBounds", + "text": "DataBounds" + } + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.getFallbackDataBounds.$1", + "type": "CompoundType", + "tags": [], + "label": "rangeType", + "description": [], + "signature": [ + "\"number\" | \"percent\" | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.getPaletteStops", + "type": "Function", + "tags": [], + "label": "getPaletteStops", + "description": [ + "\nThis is a generic function to compute stops from the current parameters." + ], + "signature": [ + "(palettes: ", + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.PaletteRegistry", + "text": "PaletteRegistry" + }, + ", activePaletteParams: ", + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.CustomPaletteParams", + "text": "CustomPaletteParams" + }, + ", {\n prevPalette,\n dataBounds,\n mapFromMinValue,\n defaultPaletteName,\n }: { prevPalette?: string | undefined; dataBounds: ", + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.DataBounds", + "text": "DataBounds" + }, + "; mapFromMinValue?: boolean | undefined; defaultPaletteName?: string | undefined; }) => { stop: number; color: string; }[]" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.getPaletteStops.$1", + "type": "Object", + "tags": [], + "label": "palettes", + "description": [], + "signature": [ + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.PaletteRegistry", + "text": "PaletteRegistry" + } + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.getPaletteStops.$2", + "type": "Object", + "tags": [], + "label": "activePaletteParams", + "description": [], + "signature": [ + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.CustomPaletteParams", + "text": "CustomPaletteParams" + } + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.getPaletteStops.$3", + "type": "Object", + "tags": [], + "label": "{\n prevPalette,\n dataBounds,\n mapFromMinValue,\n defaultPaletteName,\n }", + "description": [], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.getPaletteStops.$3.prevPalette", + "type": "string", + "tags": [], + "label": "prevPalette", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.getPaletteStops.$3.dataBounds", + "type": "Object", + "tags": [], + "label": "dataBounds", + "description": [], + "signature": [ + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.DataBounds", + "text": "DataBounds" + } + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.getPaletteStops.$3.mapFromMinValue", + "type": "CompoundType", + "tags": [], + "label": "mapFromMinValue", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.getPaletteStops.$3.defaultPaletteName", + "type": "string", + "tags": [], + "label": "defaultPaletteName", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false + } + ] + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.getStepValue", + "type": "Function", + "tags": [], + "label": "getStepValue", + "description": [], + "signature": [ + "(colorStops: ", + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.ColorStop", + "text": "ColorStop" + }, + "[], newColorStops: ", + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.ColorStop", + "text": "ColorStop" + }, + "[], max: number) => number" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.getStepValue.$1", + "type": "Array", + "tags": [], + "label": "colorStops", + "description": [], + "signature": [ + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.ColorStop", + "text": "ColorStop" + }, + "[]" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.getStepValue.$2", + "type": "Array", + "tags": [], + "label": "newColorStops", + "description": [], + "signature": [ + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.ColorStop", + "text": "ColorStop" + }, + "[]" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.getStepValue.$3", + "type": "number", + "tags": [], + "label": "max", + "description": [], + "signature": [ + "number" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.remapStopsByNewInterval", + "type": "Function", + "tags": [], + "label": "remapStopsByNewInterval", + "description": [], + "signature": [ + "(controlStops: ", + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.ColorStop", + "text": "ColorStop" + }, + "[], {\n newInterval,\n oldInterval,\n newMin,\n oldMin,\n }: { newInterval: number; oldInterval: number; newMin: number; oldMin: number; }) => { color: string; stop: number; }[]" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.remapStopsByNewInterval.$1", + "type": "Array", + "tags": [], + "label": "controlStops", + "description": [], + "signature": [ + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.ColorStop", + "text": "ColorStop" + }, + "[]" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.remapStopsByNewInterval.$2", + "type": "Object", + "tags": [], + "label": "{\n newInterval,\n oldInterval,\n newMin,\n oldMin,\n }", + "description": [], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.remapStopsByNewInterval.$2.newInterval", + "type": "number", + "tags": [], + "label": "newInterval", + "description": [], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.remapStopsByNewInterval.$2.oldInterval", + "type": "number", + "tags": [], + "label": "oldInterval", + "description": [], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.remapStopsByNewInterval.$2.newMin", + "type": "number", + "tags": [], + "label": "newMin", + "description": [], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.remapStopsByNewInterval.$2.oldMin", + "type": "number", + "tags": [], + "label": "oldMin", + "description": [], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false + } + ] + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.reversePalette", + "type": "Function", + "tags": [], + "label": "reversePalette", + "description": [], + "signature": [ + "(paletteColorRepresentation: ", + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.ColorStop", + "text": "ColorStop" + }, + "[]) => { color: string; stop: number; }[]" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.reversePalette.$1", + "type": "Array", + "tags": [], + "label": "paletteColorRepresentation", + "description": [], + "signature": [ + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.ColorStop", + "text": "ColorStop" + }, + "[]" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.roundValue", + "type": "Function", + "tags": [], + "label": "roundValue", + "description": [], + "signature": [ + "(value: number, fractionDigits: number) => number" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.roundValue.$1", + "type": "number", + "tags": [], + "label": "value", + "description": [], + "signature": [ + "number" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.roundValue.$2", + "type": "number", + "tags": [], + "label": "fractionDigits", + "description": [], + "signature": [ + "number" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.shiftPalette", + "type": "Function", + "tags": [], + "label": "shiftPalette", + "description": [], + "signature": [ + "(stops: ", + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.ColorStop", + "text": "ColorStop" + }, + "[], max: number) => { stop: number; color: string; }[]" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.shiftPalette.$1", + "type": "Array", + "tags": [], + "label": "stops", + "description": [], + "signature": [ + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.ColorStop", + "text": "ColorStop" + }, + "[]" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.shiftPalette.$2", + "type": "number", + "tags": [], + "label": "max", + "description": [], + "signature": [ + "number" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.ChartColorConfiguration", + "type": "Interface", + "tags": [], + "label": "ChartColorConfiguration", + "description": [ + "\nInformation about the structure of a chart to determine the color of a series within it." + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.ChartColorConfiguration.totalSeries", + "type": "number", + "tags": [], + "label": "totalSeries", + "description": [ + "\nOverall number of series in the current chart" + ], + "signature": [ + "number | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.ChartColorConfiguration.maxDepth", + "type": "number", + "tags": [], + "label": "maxDepth", + "description": [ + "\nMax nesting depth of the series tree" + ], + "signature": [ + "number | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.ChartColorConfiguration.behindText", + "type": "CompoundType", + "tags": [], + "label": "behindText", + "description": [ + "\nFlag whether the color will be used behind text. The palette can use this information to\nadjust colors for better a11y. Might be ignored depending on the palette." + ], + "signature": [ + "boolean | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.ChartColorConfiguration.syncColors", + "type": "CompoundType", + "tags": [], + "label": "syncColors", + "description": [ + "\nFlag whether a color assignment to a given key should be remembered and re-used the next time the key shows up.\nThis setting might be ignored based on the palette." + ], + "signature": [ + "boolean | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.ColorStop", + "type": "Interface", + "tags": [], + "label": "ColorStop", + "description": [], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.ColorStop.color", + "type": "string", + "tags": [], + "label": "color", + "description": [], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.ColorStop.stop", + "type": "number", + "tags": [], + "label": "stop", + "description": [], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.CustomPaletteParams", + "type": "Interface", + "tags": [], + "label": "CustomPaletteParams", + "description": [], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.CustomPaletteParams.name", + "type": "string", + "tags": [], + "label": "name", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.CustomPaletteParams.reverse", + "type": "CompoundType", + "tags": [], + "label": "reverse", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.CustomPaletteParams.rangeType", + "type": "CompoundType", + "tags": [], + "label": "rangeType", + "description": [], + "signature": [ + "\"number\" | \"percent\" | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.CustomPaletteParams.continuity", + "type": "CompoundType", + "tags": [], + "label": "continuity", + "description": [], + "signature": [ + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.PaletteContinuity", + "text": "PaletteContinuity" + }, + " | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.CustomPaletteParams.progression", + "type": "string", + "tags": [], + "label": "progression", + "description": [], + "signature": [ + "\"fixed\" | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.CustomPaletteParams.rangeMin", + "type": "number", + "tags": [], + "label": "rangeMin", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.CustomPaletteParams.rangeMax", + "type": "number", + "tags": [], + "label": "rangeMax", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.CustomPaletteParams.stops", + "type": "Array", + "tags": [], + "label": "stops", + "description": [], + "signature": [ + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.ColorStop", + "text": "ColorStop" + }, + "[] | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.CustomPaletteParams.colorStops", + "type": "Array", + "tags": [], + "label": "colorStops", + "description": [], + "signature": [ + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.ColorStop", + "text": "ColorStop" + }, + "[] | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.CustomPaletteParams.steps", + "type": "number", + "tags": [], + "label": "steps", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.CustomPaletteParams.maxSteps", + "type": "number", + "tags": [], + "label": "maxSteps", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.DataBounds", + "type": "Interface", + "tags": [], + "label": "DataBounds", + "description": [], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.DataBounds.min", + "type": "number", + "tags": [], + "label": "min", + "description": [], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.DataBounds.max", + "type": "number", + "tags": [], + "label": "max", + "description": [], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.DataBounds.fallback", + "type": "CompoundType", + "tags": [], + "label": "fallback", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteDefinition", + "type": "Interface", + "tags": [], + "label": "PaletteDefinition", + "description": [ + "\nDefinition of a global palette.\n\nA palette controls the appearance of Lens charts on an editor level.\nThe palette wont get reset when switching charts.\n\nA palette can hold internal state (e.g. for customizations) and also includes\nan editor component to edit the internal state." + ], + "signature": [ + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.PaletteDefinition", + "text": "PaletteDefinition" + }, + "" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteDefinition.id", + "type": "string", + "tags": [], + "label": "id", + "description": [ + "\nUnique id of the palette (this will be persisted along with the visualization state)" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteDefinition.title", + "type": "string", + "tags": [], + "label": "title", + "description": [ + "\nUser facing title (should be i18n-ized)" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteDefinition.internal", + "type": "CompoundType", + "tags": [], + "label": "internal", + "description": [ + "\nFlag indicating whether users should be able to pick this palette manually." + ], + "signature": [ + "boolean | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteDefinition.toExpression", + "type": "Function", + "tags": [], + "label": "toExpression", + "description": [ + "\nSerialize the internal state of the palette into an expression function.\nThis function should be used to pass the palette to the expression function applying color and other styles" + ], + "signature": [ + "(state?: T | undefined) => ", + "Ast" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteDefinition.toExpression.$1", + "type": "Uncategorized", + "tags": [], + "label": "state", + "description": [ + "The internal state of the palette" + ], + "signature": [ + "T | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteDefinition.getCategoricalColor", + "type": "Function", + "tags": [], + "label": "getCategoricalColor", + "description": [ + "\nColor a series according to the internal rules of the palette." + ], + "signature": [ + "(series: ", + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.SeriesLayer", + "text": "SeriesLayer" + }, + "[], chartConfiguration?: ", + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.ChartColorConfiguration", + "text": "ChartColorConfiguration" + }, + " | undefined, state?: T | undefined) => string | null" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteDefinition.getCategoricalColor.$1", + "type": "Array", + "tags": [], + "label": "series", + "description": [ + "The current series along with its ancestors." + ], + "signature": [ + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.SeriesLayer", + "text": "SeriesLayer" + }, + "[]" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteDefinition.getCategoricalColor.$2", + "type": "Object", + "tags": [], + "label": "chartConfiguration", + "description": [], + "signature": [ + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.ChartColorConfiguration", + "text": "ChartColorConfiguration" + }, + " | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "isRequired": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteDefinition.getCategoricalColor.$3", + "type": "Uncategorized", + "tags": [], + "label": "state", + "description": [ + "The internal state of the palette" + ], + "signature": [ + "T | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteDefinition.getCategoricalColors", + "type": "Function", + "tags": [], + "label": "getCategoricalColors", + "description": [ + "\nGet a spectrum of colors of the current palette.\nThis can be used if the chart wants to control color assignment locally." + ], + "signature": [ + "(size: number, state?: T | undefined) => string[]" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteDefinition.getCategoricalColors.$1", + "type": "number", + "tags": [], + "label": "size", + "description": [], + "signature": [ + "number" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteDefinition.getCategoricalColors.$2", + "type": "Uncategorized", + "tags": [], + "label": "state", + "description": [], + "signature": [ + "T | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteDefinition.canDynamicColoring", + "type": "CompoundType", + "tags": [], + "label": "canDynamicColoring", + "description": [ + "\nDefine whether a palette supports dynamic coloring (i.e. gradient colors mapped to number values)" + ], + "signature": [ + "boolean | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteDefinition.getColorForValue", + "type": "Function", + "tags": [], + "label": "getColorForValue", + "description": [ + "\nGet the assigned color for the given value based on its data domain and state settings.\nThis can be used for dynamic coloring based on uniform color distribution or custom stops." + ], + "signature": [ + "((value: number | undefined, state: T, { min, max }: { min: number; max: number; }) => string | undefined) | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteDefinition.getColorForValue.$1", + "type": "number", + "tags": [], + "label": "value", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "isRequired": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteDefinition.getColorForValue.$2", + "type": "Uncategorized", + "tags": [], + "label": "state", + "description": [], + "signature": [ + "T" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteDefinition.getColorForValue.$3", + "type": "Object", + "tags": [], + "label": "{ min, max }", + "description": [], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteDefinition.getColorForValue.$3.min", + "type": "number", + "tags": [], + "label": "min", + "description": [], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteDefinition.getColorForValue.$3.max", + "type": "number", + "tags": [], + "label": "max", + "description": [], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + } + ] + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteOutput", + "type": "Interface", + "tags": [], + "label": "PaletteOutput", + "description": [], + "signature": [ + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.PaletteOutput", + "text": "PaletteOutput" + }, + "" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteOutput.type", + "type": "CompoundType", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"system_palette\" | \"palette\"" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteOutput.name", + "type": "string", + "tags": [], + "label": "name", + "description": [], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteOutput.params", + "type": "Uncategorized", + "tags": [], + "label": "params", + "description": [], + "signature": [ + "T | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteRegistry", + "type": "Interface", + "tags": [], + "label": "PaletteRegistry", + "description": [], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteRegistry.get", + "type": "Function", + "tags": [], + "label": "get", + "description": [], + "signature": [ + "(name: string) => ", + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.PaletteDefinition", + "text": "PaletteDefinition" + }, + "" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteRegistry.get.$1", + "type": "string", + "tags": [], + "label": "name", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteRegistry.getAll", + "type": "Function", + "tags": [], + "label": "getAll", + "description": [], + "signature": [ + "() => ", + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.PaletteDefinition", + "text": "PaletteDefinition" + }, + "[]" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "children": [], + "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.SeriesLayer", + "type": "Interface", + "tags": [], + "label": "SeriesLayer", + "description": [ + "\nInformation about a series in a chart used to determine its color.\nSeries layers can be nested, this means each series layer can have an ancestor." + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.SeriesLayer.name", + "type": "string", + "tags": [], + "label": "name", + "description": [ + "\nName of the series (can be used for lookup-based coloring)" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.SeriesLayer.rankAtDepth", + "type": "number", + "tags": [], + "label": "rankAtDepth", + "description": [ + "\nRank of the series compared to siblings with the same ancestor" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.SeriesLayer.totalSeriesAtDepth", + "type": "number", + "tags": [], + "label": "totalSeriesAtDepth", + "description": [ + "\nTotal number of series with the same ancestor" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false + } + ], + "enums": [], + "misc": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.CUSTOM_PALETTE", + "type": "string", + "tags": [], + "label": "CUSTOM_PALETTE", + "description": [], + "signature": [ + "\"custom\"" + ], + "path": "packages/kbn-coloring/src/palettes/constants.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.DEFAULT_COLOR_STEPS", + "type": "number", + "tags": [], + "label": "DEFAULT_COLOR_STEPS", + "description": [], + "signature": [ + "5" + ], + "path": "packages/kbn-coloring/src/palettes/constants.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.DEFAULT_CONTINUITY", + "type": "string", + "tags": [], + "label": "DEFAULT_CONTINUITY", + "description": [], + "signature": [ + "\"above\"" + ], + "path": "packages/kbn-coloring/src/palettes/constants.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.DEFAULT_MAX_STOP", + "type": "number", + "tags": [], + "label": "DEFAULT_MAX_STOP", + "description": [], + "signature": [ + "100" + ], + "path": "packages/kbn-coloring/src/palettes/constants.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.DEFAULT_MIN_STOP", + "type": "number", + "tags": [], + "label": "DEFAULT_MIN_STOP", + "description": [], + "signature": [ + "0" + ], + "path": "packages/kbn-coloring/src/palettes/constants.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.DEFAULT_PALETTE_NAME", + "type": "string", + "tags": [], + "label": "DEFAULT_PALETTE_NAME", + "description": [], + "signature": [ + "\"positive\"" + ], + "path": "packages/kbn-coloring/src/palettes/constants.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.DEFAULT_RANGE_TYPE", + "type": "string", + "tags": [], + "label": "DEFAULT_RANGE_TYPE", + "description": [], + "signature": [ + "\"percent\"" + ], + "path": "packages/kbn-coloring/src/palettes/constants.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.FIXED_PROGRESSION", + "type": "string", + "tags": [], + "label": "FIXED_PROGRESSION", + "description": [], + "signature": [ + "\"fixed\"" + ], + "path": "packages/kbn-coloring/src/palettes/constants.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.PaletteContinuity", + "type": "Type", + "tags": [], + "label": "PaletteContinuity", + "description": [], + "signature": [ + "\"above\" | \"below\" | \"none\" | \"all\"" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.RequiredPaletteParamTypes", + "type": "Type", + "tags": [], + "label": "RequiredPaletteParamTypes", + "description": [], + "signature": [ + "{ name: string; reverse: boolean; rangeMin: number; rangeType: \"number\" | \"percent\"; continuity: ", + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.PaletteContinuity", + "text": "PaletteContinuity" + }, + "; progression: \"fixed\"; rangeMax: number; stops: ", + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.ColorStop", + "text": "ColorStop" + }, + "[]; colorStops: ", + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.ColorStop", + "text": "ColorStop" + }, + "[]; steps: number; maxSteps?: number | undefined; }" + ], + "path": "packages/kbn-coloring/src/palettes/types.ts", + "deprecated": false, + "initialIsOpen": false + } + ], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx new file mode 100644 index 0000000000000..6138cd2a95837 --- /dev/null +++ b/api_docs/kbn_coloring.mdx @@ -0,0 +1,33 @@ +--- +id: kibKbnColoringPluginApi +slug: /kibana-dev-docs/api/kbn-coloring +title: "@kbn/coloring" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the @kbn/coloring plugin +date: 2022-04-26 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/coloring'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import kbnColoringObj from './kbn_coloring.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 106 | 0 | 80 | 1 | + +## Common + +### Functions + + +### Interfaces + + +### Consts, variables and types + + diff --git a/api_docs/kbn_config.devdocs.json b/api_docs/kbn_config.devdocs.json index 383df777d15f6..f87e73f517cbe 100644 --- a/api_docs/kbn_config.devdocs.json +++ b/api_docs/kbn_config.devdocs.json @@ -55,37 +55,6 @@ } ], "functions": [ - { - "parentPluginId": "@kbn/config", - "id": "def-server.getPluginSearchPaths", - "type": "Function", - "tags": [], - "label": "getPluginSearchPaths", - "description": [], - "signature": [ - "({ rootDir, oss, examples }: SearchOptions) => string[]" - ], - "path": "packages/kbn-config/src/plugins/plugin_search_paths.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/config", - "id": "def-server.getPluginSearchPaths.$1", - "type": "Object", - "tags": [], - "label": "{ rootDir, oss, examples }", - "description": [], - "signature": [ - "SearchOptions" - ], - "path": "packages/kbn-config/src/plugins/plugin_search_paths.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, { "parentPluginId": "@kbn/config", "id": "def-server.hasConfigPathIntersection", diff --git a/api_docs/kbn_config.mdx b/api_docs/kbn_config.mdx index ae52de0962bce..1ce3218bfedb3 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/config plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 66 | 0 | 46 | 2 | +| 64 | 0 | 44 | 2 | ## Server diff --git a/api_docs/kbn_config_schema.devdocs.json b/api_docs/kbn_config_schema.devdocs.json index b2c350d51f4ce..b765279edb5d2 100644 --- a/api_docs/kbn_config_schema.devdocs.json +++ b/api_docs/kbn_config_schema.devdocs.json @@ -1031,6 +1031,29 @@ ], "returnComment": [] }, + { + "parentPluginId": "@kbn/config-schema", + "id": "def-server.Type.getSchemaStructure", + "type": "Function", + "tags": [], + "label": "getSchemaStructure", + "description": [], + "signature": [ + "() => ", + { + "pluginId": "@kbn/config-schema", + "scope": "server", + "docId": "kibKbnConfigSchemaPluginApi", + "section": "def-server.SchemaStructureEntry", + "text": "SchemaStructureEntry" + }, + "[]" + ], + "path": "packages/kbn-config-schema/src/types/type.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, { "parentPluginId": "@kbn/config-schema", "id": "def-server.Type.handleError", @@ -1207,7 +1230,44 @@ "initialIsOpen": false } ], - "interfaces": [], + "interfaces": [ + { + "parentPluginId": "@kbn/config-schema", + "id": "def-server.SchemaStructureEntry", + "type": "Interface", + "tags": [], + "label": "SchemaStructureEntry", + "description": [], + "path": "packages/kbn-config-schema/src/types/type.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/config-schema", + "id": "def-server.SchemaStructureEntry.path", + "type": "Array", + "tags": [], + "label": "path", + "description": [], + "signature": [ + "string[]" + ], + "path": "packages/kbn-config-schema/src/types/type.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/config-schema", + "id": "def-server.SchemaStructureEntry.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "path": "packages/kbn-config-schema/src/types/type.ts", + "deprecated": false + } + ], + "initialIsOpen": false + } + ], "enums": [], "misc": [ { diff --git a/api_docs/kbn_config_schema.mdx b/api_docs/kbn_config_schema.mdx index 2eebafa2279fe..784035631256b 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/config-schema plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-schema'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 125 | 3 | 123 | 17 | +| 129 | 3 | 127 | 17 | ## Server @@ -31,6 +31,9 @@ Contact [Owner missing] for questions regarding this plugin. ### Classes +### Interfaces + + ### Consts, variables and types diff --git a/api_docs/kbn_crypto.mdx b/api_docs/kbn_crypto.mdx index de871c1b01bbd..f044e9213163c 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/crypto plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_datemath.devdocs.json b/api_docs/kbn_datemath.devdocs.json new file mode 100644 index 0000000000000..4905365143524 --- /dev/null +++ b/api_docs/kbn_datemath.devdocs.json @@ -0,0 +1,578 @@ +{ + "id": "@kbn/datemath", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [ + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.parse", + "type": "Function", + "tags": [], + "label": "parse", + "description": [], + "signature": [ + "(input: string, options: { roundUp?: boolean | undefined; momentInstance?: typeof moment | undefined; forceNow?: Date | undefined; }) => moment.Moment | undefined" + ], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.parse.$1", + "type": "string", + "tags": [], + "label": "input", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.parse.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.parse.$2.roundUp", + "type": "CompoundType", + "tags": [], + "label": "roundUp", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.parse.$2.momentInstance", + "type": "Function", + "tags": [], + "label": "momentInstance", + "description": [], + "signature": [ + "typeof moment | undefined" + ], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.parse.$2.forceNow", + "type": "Object", + "tags": [], + "label": "forceNow", + "description": [], + "signature": [ + "Date | undefined" + ], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + } + ] + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [], + "enums": [], + "misc": [ + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.Unit", + "type": "Type", + "tags": [], + "label": "Unit", + "description": [], + "signature": [ + "\"y\" | \"M\" | \"w\" | \"d\" | \"h\" | \"m\" | \"s\" | \"ms\"" + ], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.units", + "type": "Array", + "tags": [], + "label": "units", + "description": [], + "signature": [ + { + "pluginId": "@kbn/datemath", + "scope": "server", + "docId": "kibKbnDatemathPluginApi", + "section": "def-server.Unit", + "text": "Unit" + }, + "[]" + ], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsAsc", + "type": "Array", + "tags": [], + "label": "unitsAsc", + "description": [], + "signature": [ + { + "pluginId": "@kbn/datemath", + "scope": "server", + "docId": "kibKbnDatemathPluginApi", + "section": "def-server.Unit", + "text": "Unit" + }, + "[]" + ], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsDesc", + "type": "Array", + "tags": [], + "label": "unitsDesc", + "description": [], + "signature": [ + { + "pluginId": "@kbn/datemath", + "scope": "server", + "docId": "kibKbnDatemathPluginApi", + "section": "def-server.Unit", + "text": "Unit" + }, + "[]" + ], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.UnitsMap", + "type": "Type", + "tags": [], + "label": "UnitsMap", + "description": [], + "signature": [ + "{ y: { weight: number; type: \"calendar\" | \"fixed\" | \"mixed\"; base: number; }; M: { weight: number; type: \"calendar\" | \"fixed\" | \"mixed\"; base: number; }; w: { weight: number; type: \"calendar\" | \"fixed\" | \"mixed\"; base: number; }; d: { weight: number; type: \"calendar\" | \"fixed\" | \"mixed\"; base: number; }; h: { weight: number; type: \"calendar\" | \"fixed\" | \"mixed\"; base: number; }; m: { weight: number; type: \"calendar\" | \"fixed\" | \"mixed\"; base: number; }; s: { weight: number; type: \"calendar\" | \"fixed\" | \"mixed\"; base: number; }; ms: { weight: number; type: \"calendar\" | \"fixed\" | \"mixed\"; base: number; }; }" + ], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false, + "initialIsOpen": false + } + ], + "objects": [ + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap", + "type": "Object", + "tags": [], + "label": "unitsMap", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.ms", + "type": "Object", + "tags": [], + "label": "ms", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.ms.weight", + "type": "number", + "tags": [], + "label": "weight", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.ms.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"fixed\"" + ], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.ms.base", + "type": "number", + "tags": [], + "label": "base", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.s", + "type": "Object", + "tags": [], + "label": "s", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.s.weight", + "type": "number", + "tags": [], + "label": "weight", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.s.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"fixed\"" + ], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.s.base", + "type": "number", + "tags": [], + "label": "base", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.m", + "type": "Object", + "tags": [], + "label": "m", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.m.weight", + "type": "number", + "tags": [], + "label": "weight", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.m.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"mixed\"" + ], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.m.base", + "type": "number", + "tags": [], + "label": "base", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.h", + "type": "Object", + "tags": [], + "label": "h", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.h.weight", + "type": "number", + "tags": [], + "label": "weight", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.h.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"mixed\"" + ], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.h.base", + "type": "number", + "tags": [], + "label": "base", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.d", + "type": "Object", + "tags": [], + "label": "d", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.d.weight", + "type": "number", + "tags": [], + "label": "weight", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.d.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"mixed\"" + ], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.d.base", + "type": "number", + "tags": [], + "label": "base", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.w", + "type": "Object", + "tags": [], + "label": "w", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.w.weight", + "type": "number", + "tags": [], + "label": "weight", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.w.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"calendar\"" + ], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.w.base", + "type": "number", + "tags": [], + "label": "base", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.M", + "type": "Object", + "tags": [], + "label": "M", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.M.weight", + "type": "number", + "tags": [], + "label": "weight", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.M.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"calendar\"" + ], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.M.base", + "type": "number", + "tags": [], + "label": "base", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.y", + "type": "Object", + "tags": [], + "label": "y", + "description": [ + "// q: { weight: 8, type: 'calendar' }, // TODO: moment duration does not support quarter" + ], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.y.weight", + "type": "number", + "tags": [], + "label": "weight", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.y.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"calendar\"" + ], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/datemath", + "id": "def-server.unitsMap.y.base", + "type": "number", + "tags": [], + "label": "base", + "description": [], + "path": "packages/kbn-datemath/src/index.ts", + "deprecated": false + } + ] + } + ], + "initialIsOpen": false + } + ] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx new file mode 100644 index 0000000000000..782b942ba952b --- /dev/null +++ b/api_docs/kbn_datemath.mdx @@ -0,0 +1,33 @@ +--- +id: kibKbnDatemathPluginApi +slug: /kibana-dev-docs/api/kbn-datemath +title: "@kbn/datemath" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the @kbn/datemath plugin +date: 2022-04-26 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/datemath'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import kbnDatemathObj from './kbn_datemath.devdocs.json'; + +elasticsearch datemath parser, used in kibana + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 44 | 0 | 43 | 0 | + +## Server + +### Objects + + +### Functions + + +### Consts, variables and types + + diff --git a/api_docs/kbn_dev_utils.devdocs.json b/api_docs/kbn_dev_utils.devdocs.json index c45d0515c0bb4..7ffb74a9f9220 100644 --- a/api_docs/kbn_dev_utils.devdocs.json +++ b/api_docs/kbn_dev_utils.devdocs.json @@ -12,61 +12,42 @@ "classes": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsClient", + "id": "def-server.ProcRunner", "type": "Class", - "tags": [], - "label": "CiStatsClient", - "description": [], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_client.ts", + "tags": [ + "class" + ], + "label": "ProcRunner", + "description": [ + "\n Helper for starting and managing processes. In many ways it resembles the\n API from `grunt_run`, processes are named and can be started, waited for,\n backgrounded once they log something matching a RegExp...\n" + ], + "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsClient.fromEnv", + "id": "def-server.ProcRunner.Unnamed", "type": "Function", "tags": [], - "label": "fromEnv", - "description": [ - "\nCreate a CiStatsReporter by inspecting the ENV for the necessary config" - ], + "label": "Constructor", + "description": [], "signature": [ - "(log: ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.ToolingLog", - "text": "ToolingLog" - }, - ") => ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.CiStatsClient", - "text": "CiStatsClient" - } + "any" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_client.ts", + "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsClient.fromEnv.$1", + "id": "def-server.ProcRunner.Unnamed.$1", "type": "Object", "tags": [], "label": "log", "description": [], "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.ToolingLog", - "text": "ToolingLog" - } + "ToolingLog" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_client.ts", + "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", "deprecated": false, "isRequired": true } @@ -75,157 +56,181 @@ }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsClient.Unnamed", + "id": "def-server.ProcRunner.run", "type": "Function", - "tags": [], - "label": "Constructor", - "description": [], + "tags": [ + "property", + "property", + "property", + "property", + "return" + ], + "label": "run", + "description": [ + "\n Start a process, tracking it by `name`" + ], "signature": [ - "any" + "(name: string, options: RunOptions) => Promise" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_client.ts", + "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsClient.Unnamed.$1", + "id": "def-server.ProcRunner.run.$1", + "type": "string", + "tags": [], + "label": "name", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.ProcRunner.run.$2", "type": "Object", "tags": [], - "label": "config", + "label": "options", "description": [], "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.Config", - "text": "Config" - }, - " | undefined" + "RunOptions" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_client.ts", + "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", "deprecated": false, - "isRequired": false + "isRequired": true } ], "returnComment": [] }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsClient.isEnabled", + "id": "def-server.ProcRunner.stop", "type": "Function", "tags": [], - "label": "isEnabled", - "description": [], - "signature": [ - "() => boolean" + "label": "stop", + "description": [ + "\n Stop a named proc" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_client.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsClient.getLatestTestGroupStats", - "type": "Function", - "tags": [], - "label": "getLatestTestGroupStats", - "description": [], "signature": [ - "(options: LatestTestGroupStatsOptions) => Promise" + "(name: string, signal?: NodeJS.Signals) => Promise" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_client.ts", + "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsClient.getLatestTestGroupStats.$1", - "type": "Object", + "id": "def-server.ProcRunner.stop.$1", + "type": "string", "tags": [], - "label": "options", + "label": "name", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.ProcRunner.stop.$2", + "type": "CompoundType", + "tags": [], + "label": "signal", "description": [], "signature": [ - "LatestTestGroupStatsOptions" + "NodeJS.Signals" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_client.ts", + "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", "deprecated": false, "isRequired": true } ], "returnComment": [] - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsReporter", - "type": "Class", - "tags": [], - "label": "CiStatsReporter", - "description": [ - "Object that helps report data to the ci-stats service" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false, - "children": [ + }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsReporter.fromEnv", + "id": "def-server.ProcRunner.waitForAllToStop", "type": "Function", - "tags": [], - "label": "fromEnv", + "tags": [ + "return" + ], + "label": "waitForAllToStop", "description": [ - "\nCreate a CiStatsReporter by inspecting the ENV for the necessary config" + "\n Wait for all running processes to stop naturally" ], "signature": [ - "(log: ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.ToolingLog", - "text": "ToolingLog" - }, - ") => ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.CiStatsReporter", - "text": "CiStatsReporter" - } + "() => Promise" + ], + "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.ProcRunner.teardown", + "type": "Function", + "tags": [ + "return" + ], + "label": "teardown", + "description": [ + "\n Close the ProcRunner and stop all running\n processes with `signal`\n" + ], + "signature": [ + "(signal?: \"exit\" | NodeJS.Signals) => Promise" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsReporter.fromEnv.$1", - "type": "Object", + "id": "def-server.ProcRunner.teardown.$1", + "type": "CompoundType", "tags": [], - "label": "log", + "label": "signal", "description": [], "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.ToolingLog", - "text": "ToolingLog" - } + "\"exit\" | NodeJS.Signals" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", "deprecated": false, "isRequired": true } ], "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.RunWithCommands", + "type": "Class", + "tags": [], + "label": "RunWithCommands", + "description": [], + "signature": [ + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.RunWithCommands", + "text": "RunWithCommands" }, + "" + ], + "path": "packages/kbn-dev-utils/src/run/run_with_commands.ts", + "deprecated": false, + "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsReporter.Unnamed", + "id": "def-server.RunWithCommands.Unnamed", "type": "Function", "tags": [], "label": "Constructor", @@ -233,47 +238,48 @@ "signature": [ "any" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "path": "packages/kbn-dev-utils/src/run/run_with_commands.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsReporter.Unnamed.$1", + "id": "def-server.RunWithCommands.Unnamed.$1", "type": "Object", "tags": [], - "label": "config", + "label": "options", "description": [], "signature": [ { "pluginId": "@kbn/dev-utils", "scope": "server", "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.Config", - "text": "Config" + "section": "def-server.RunWithCommandsOptions", + "text": "RunWithCommandsOptions" }, - " | undefined" + "" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "path": "packages/kbn-dev-utils/src/run/run_with_commands.ts", "deprecated": false, - "isRequired": false + "isRequired": true }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsReporter.Unnamed.$2", - "type": "Object", + "id": "def-server.RunWithCommands.Unnamed.$2", + "type": "Array", "tags": [], - "label": "log", + "label": "commands", "description": [], "signature": [ { "pluginId": "@kbn/dev-utils", "scope": "server", "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.ToolingLog", - "text": "ToolingLog" - } + "section": "def-server.Command", + "text": "Command" + }, + "[]" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "path": "packages/kbn-dev-utils/src/run/run_with_commands.ts", "deprecated": false, "isRequired": true } @@ -282,139 +288,36 @@ }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsReporter.isEnabled", - "type": "Function", - "tags": [], - "label": "isEnabled", - "description": [ - "\nDetermine if CI_STATS is explicitly disabled by the environment. To determine\nif the CiStatsReporter has enough information in the environment to send metrics\nfor builds use #hasBuildConfig()." - ], - "signature": [ - "() => boolean" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsReporter.hasBuildConfig", - "type": "Function", - "tags": [], - "label": "hasBuildConfig", - "description": [ - "\nDetermines if the CiStatsReporter is disabled by the environment, or properly\nconfigured and able to send stats" - ], - "signature": [ - "() => boolean" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsReporter.timings", + "id": "def-server.RunWithCommands.command", "type": "Function", "tags": [], - "label": "timings", - "description": [ - "\nReport timings data to the ci-stats service. If running in CI then the reporter\nwill include the buildId in the report with the access token, otherwise the timings\ndata will be recorded as anonymous timing data." - ], + "label": "command", + "description": [], "signature": [ "(options: ", { "pluginId": "@kbn/dev-utils", "scope": "server", "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.TimingsOptions", - "text": "TimingsOptions" + "section": "def-server.Command", + "text": "Command" }, - ") => Promise" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsReporter.timings.$1", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.TimingsOptions", - "text": "TimingsOptions" - } - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsReporter.metrics", - "type": "Function", - "tags": [], - "label": "metrics", - "description": [ - "\nReport metrics data to the ci-stats service. If running outside of CI this method\ndoes nothing as metrics can only be reported when associated with a specific CI build." - ], - "signature": [ - "(metrics: ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.CiStatsMetric", - "text": "CiStatsMetric" - }, - "[], options?: ", + ") => ", { "pluginId": "@kbn/dev-utils", "scope": "server", "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.MetricsOptions", - "text": "MetricsOptions" + "section": "def-server.RunWithCommands", + "text": "RunWithCommands" }, - " | undefined) => Promise" + "" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "path": "packages/kbn-dev-utils/src/run/run_with_commands.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsReporter.metrics.$1", - "type": "Array", - "tags": [], - "label": "metrics", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.CiStatsMetric", - "text": "CiStatsMetric" - }, - "[]" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsReporter.metrics.$2", + "id": "def-server.RunWithCommands.command.$1", "type": "Object", "tags": [], "label": "options", @@ -424,1968 +327,138 @@ "pluginId": "@kbn/dev-utils", "scope": "server", "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.MetricsOptions", - "text": "MetricsOptions" + "section": "def-server.Command", + "text": "Command" }, - " | undefined" + "" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "path": "packages/kbn-dev-utils/src/run/run_with_commands.ts", "deprecated": false, - "isRequired": false + "isRequired": true } ], "returnComment": [] }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsReporter.reportTests", + "id": "def-server.RunWithCommands.execute", "type": "Function", "tags": [], - "label": "reportTests", - "description": [ - "\nSend test reports to ci-stats" - ], + "label": "execute", + "description": [], "signature": [ - "({ group, testRuns }: ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.CiStatsReportTestsOptions", - "text": "CiStatsReportTestsOptions" - }, - ") => Promise" + "() => Promise" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "path": "packages/kbn-dev-utils/src/run/run_with_commands.ts", "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsReporter.reportTests.$1", - "type": "Object", - "tags": [], - "label": "{ group, testRuns }", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.CiStatsReportTestsOptions", - "text": "CiStatsReportTestsOptions" - } - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false, - "isRequired": true - } - ], + "children": [], "returnComment": [] } ], "initialIsOpen": false - }, + } + ], + "functions": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ProcRunner", - "type": "Class", - "tags": [ - "class" - ], - "label": "ProcRunner", - "description": [ - "\n Helper for starting and managing processes. In many ways it resembles the\n API from `grunt_run`, processes are named and can be started, waited for,\n backgrounded once they log something matching a RegExp...\n" + "id": "def-server.combineErrors", + "type": "Function", + "tags": [], + "label": "combineErrors", + "description": [], + "signature": [ + "(errors: (Error | FailError)[]) => Error" ], - "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", + "path": "packages/kbn-dev-utils/src/run/fail.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ProcRunner.Unnamed", - "type": "Function", + "id": "def-server.combineErrors.$1", + "type": "Array", "tags": [], - "label": "Constructor", + "label": "errors", "description": [], "signature": [ - "any" + "(Error | FailError)[]" ], - "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", + "path": "packages/kbn-dev-utils/src/run/fail.ts", "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ProcRunner.Unnamed.$1", - "type": "Object", - "tags": [], - "label": "log", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.ToolingLog", - "text": "ToolingLog" - } - ], - "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.createFailError", + "type": "Function", + "tags": [], + "label": "createFailError", + "description": [], + "signature": [ + "(reason: string, options: FailErrorOptions) => FailError" + ], + "path": "packages/kbn-dev-utils/src/run/fail.ts", + "deprecated": false, + "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ProcRunner.run", - "type": "Function", - "tags": [ - "property", - "property", - "property", - "property", - "return" - ], - "label": "run", - "description": [ - "\n Start a process, tracking it by `name`" - ], + "id": "def-server.createFailError.$1", + "type": "string", + "tags": [], + "label": "reason", + "description": [], "signature": [ - "(name: string, options: RunOptions) => Promise" + "string" ], - "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", + "path": "packages/kbn-dev-utils/src/run/fail.ts", "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ProcRunner.run.$1", - "type": "string", - "tags": [], - "label": "name", - "description": [], - "signature": [ - "string" - ], - "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ProcRunner.run.$2", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "signature": [ - "RunOptions" - ], - "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] + "isRequired": true }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ProcRunner.stop", - "type": "Function", + "id": "def-server.createFailError.$2", + "type": "Object", "tags": [], - "label": "stop", - "description": [ - "\n Stop a named proc" + "label": "options", + "description": [], + "signature": [ + "FailErrorOptions" ], + "path": "packages/kbn-dev-utils/src/run/fail.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.createFlagError", + "type": "Function", + "tags": [], + "label": "createFlagError", + "description": [], + "signature": [ + "(reason: string) => FailError" + ], + "path": "packages/kbn-dev-utils/src/run/fail.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.createFlagError.$1", + "type": "string", + "tags": [], + "label": "reason", + "description": [], "signature": [ - "(name: string, signal?: NodeJS.Signals) => Promise" + "string" ], - "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ProcRunner.stop.$1", - "type": "string", - "tags": [], - "label": "name", - "description": [], - "signature": [ - "string" - ], - "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ProcRunner.stop.$2", - "type": "CompoundType", - "tags": [], - "label": "signal", - "description": [], - "signature": [ - "NodeJS.Signals" - ], - "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ProcRunner.waitForAllToStop", - "type": "Function", - "tags": [ - "return" - ], - "label": "waitForAllToStop", - "description": [ - "\n Wait for all running processes to stop naturally" - ], - "signature": [ - "() => Promise" - ], - "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ProcRunner.teardown", - "type": "Function", - "tags": [ - "return" - ], - "label": "teardown", - "description": [ - "\n Close the ProcRunner and stop all running\n processes with `signal`\n" - ], - "signature": [ - "(signal?: \"exit\" | NodeJS.Signals) => Promise" - ], - "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ProcRunner.teardown.$1", - "type": "CompoundType", - "tags": [], - "label": "signal", - "description": [], - "signature": [ - "\"exit\" | NodeJS.Signals" - ], - "path": "packages/kbn-dev-utils/src/proc_runner/proc_runner.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.RunWithCommands", - "type": "Class", - "tags": [], - "label": "RunWithCommands", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.RunWithCommands", - "text": "RunWithCommands" - }, - "" - ], - "path": "packages/kbn-dev-utils/src/run/run_with_commands.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.RunWithCommands.Unnamed", - "type": "Function", - "tags": [], - "label": "Constructor", - "description": [], - "signature": [ - "any" - ], - "path": "packages/kbn-dev-utils/src/run/run_with_commands.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.RunWithCommands.Unnamed.$1", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.RunWithCommandsOptions", - "text": "RunWithCommandsOptions" - }, - "" - ], - "path": "packages/kbn-dev-utils/src/run/run_with_commands.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.RunWithCommands.Unnamed.$2", - "type": "Array", - "tags": [], - "label": "commands", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.Command", - "text": "Command" - }, - "[]" - ], - "path": "packages/kbn-dev-utils/src/run/run_with_commands.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.RunWithCommands.command", - "type": "Function", - "tags": [], - "label": "command", - "description": [], - "signature": [ - "(options: ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.Command", - "text": "Command" - }, - ") => ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.RunWithCommands", - "text": "RunWithCommands" - }, - "" - ], - "path": "packages/kbn-dev-utils/src/run/run_with_commands.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.RunWithCommands.command.$1", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.Command", - "text": "Command" - }, - "" - ], - "path": "packages/kbn-dev-utils/src/run/run_with_commands.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.RunWithCommands.execute", - "type": "Function", - "tags": [], - "label": "execute", - "description": [], - "signature": [ - "() => Promise" - ], - "path": "packages/kbn-dev-utils/src/run/run_with_commands.ts", - "deprecated": false, - "children": [], - "returnComment": [] - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog", - "type": "Class", - "tags": [], - "label": "ToolingLog", - "description": [], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.Unnamed", - "type": "Function", - "tags": [], - "label": "Constructor", - "description": [], - "signature": [ - "any" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.Unnamed.$1", - "type": "Object", - "tags": [], - "label": "writerConfig", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.ToolingLogTextWriterConfig", - "text": "ToolingLogTextWriterConfig" - }, - " | undefined" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "isRequired": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.Unnamed.$2", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.ToolingLogOptions", - "text": "ToolingLogOptions" - }, - " | undefined" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.getIndent", - "type": "Function", - "tags": [], - "label": "getIndent", - "description": [ - "\nGet the current indentation level of the ToolingLog" - ], - "signature": [ - "() => number" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.indent", - "type": "Function", - "tags": [], - "label": "indent", - "description": [], - "signature": [ - "{ (delta: number): void; (delta: number, block: () => Promise): Promise; (delta: number, block: () => T): T; }" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.indent.$1", - "type": "number", - "tags": [], - "label": "delta", - "description": [], - "signature": [ - "number" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.indent.$2", - "type": "Function", - "tags": [], - "label": "block", - "description": [], - "signature": [ - "(() => T | Promise) | undefined" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.verbose", - "type": "Function", - "tags": [], - "label": "verbose", - "description": [], - "signature": [ - "(...args: any[]) => void" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.verbose.$1", - "type": "Array", - "tags": [], - "label": "args", - "description": [], - "signature": [ - "any[]" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.debug", - "type": "Function", - "tags": [], - "label": "debug", - "description": [], - "signature": [ - "(...args: any[]) => void" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.debug.$1", - "type": "Array", - "tags": [], - "label": "args", - "description": [], - "signature": [ - "any[]" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.info", - "type": "Function", - "tags": [], - "label": "info", - "description": [], - "signature": [ - "(...args: any[]) => void" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.info.$1", - "type": "Array", - "tags": [], - "label": "args", - "description": [], - "signature": [ - "any[]" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.success", - "type": "Function", - "tags": [], - "label": "success", - "description": [], - "signature": [ - "(...args: any[]) => void" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.success.$1", - "type": "Array", - "tags": [], - "label": "args", - "description": [], - "signature": [ - "any[]" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.warning", - "type": "Function", - "tags": [], - "label": "warning", - "description": [], - "signature": [ - "(...args: any[]) => void" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.warning.$1", - "type": "Array", - "tags": [], - "label": "args", - "description": [], - "signature": [ - "any[]" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.error", - "type": "Function", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "(error: string | Error) => void" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.error.$1", - "type": "CompoundType", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "string | Error" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.write", - "type": "Function", - "tags": [], - "label": "write", - "description": [], - "signature": [ - "(...args: any[]) => void" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.write.$1", - "type": "Array", - "tags": [], - "label": "args", - "description": [], - "signature": [ - "any[]" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.getWriters", - "type": "Function", - "tags": [], - "label": "getWriters", - "description": [], - "signature": [ - "() => ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.Writer", - "text": "Writer" - }, - "[]" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.setWriters", - "type": "Function", - "tags": [], - "label": "setWriters", - "description": [], - "signature": [ - "(writers: ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.Writer", - "text": "Writer" - }, - "[]) => void" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.setWriters.$1", - "type": "Array", - "tags": [], - "label": "writers", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.Writer", - "text": "Writer" - }, - "[]" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.getWritten$", - "type": "Function", - "tags": [], - "label": "getWritten$", - "description": [], - "signature": [ - "() => ", - "Observable", - "<", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.Message", - "text": "Message" - }, - ">" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.withType", - "type": "Function", - "tags": [], - "label": "withType", - "description": [ - "\nCreate a new ToolingLog which sets a different \"type\", allowing messages to be filtered out by \"source\"" - ], - "signature": [ - "(type: string) => ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.ToolingLog", - "text": "ToolingLog" - } - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLog.withType.$1", - "type": "string", - "tags": [], - "label": "type", - "description": [ - "A string that will be passed along with messages from this logger which can be used to filter messages with `ignoreSources`" - ], - "signature": [ - "string" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogCollectingWriter", - "type": "Class", - "tags": [], - "label": "ToolingLogCollectingWriter", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.ToolingLogCollectingWriter", - "text": "ToolingLogCollectingWriter" - }, - " extends ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.ToolingLogTextWriter", - "text": "ToolingLogTextWriter" - } - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_collecting_writer.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogCollectingWriter.messages", - "type": "Array", - "tags": [], - "label": "messages", - "description": [], - "signature": [ - "string[]" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_collecting_writer.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogCollectingWriter.Unnamed", - "type": "Function", - "tags": [], - "label": "Constructor", - "description": [], - "signature": [ - "any" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_collecting_writer.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogCollectingWriter.Unnamed.$1", - "type": "CompoundType", - "tags": [], - "label": "level", - "description": [], - "signature": [ - "\"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\"" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_collecting_writer.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogCollectingWriter.write", - "type": "Function", - "tags": [], - "label": "write", - "description": [ - "\nCalled by ToolingLog, extends messages with the source if message includes one." - ], - "signature": [ - "(msg: ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.Message", - "text": "Message" - }, - ") => boolean" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_collecting_writer.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogCollectingWriter.write.$1", - "type": "Object", - "tags": [], - "label": "msg", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.Message", - "text": "Message" - } - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_collecting_writer.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogTextWriter", - "type": "Class", - "tags": [], - "label": "ToolingLogTextWriter", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.ToolingLogTextWriter", - "text": "ToolingLogTextWriter" - }, - " implements ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.Writer", - "text": "Writer" - } - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogTextWriter.level", - "type": "Object", - "tags": [], - "label": "level", - "description": [], - "signature": [ - "{ name: \"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\"; flags: { error: boolean; info: boolean; success: boolean; warning: boolean; debug: boolean; silent: boolean; verbose: boolean; }; }" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogTextWriter.writeTo", - "type": "Object", - "tags": [], - "label": "writeTo", - "description": [], - "signature": [ - "{ write(msg: string): void; }" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogTextWriter.Unnamed", - "type": "Function", - "tags": [], - "label": "Constructor", - "description": [], - "signature": [ - "any" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogTextWriter.Unnamed.$1", - "type": "Object", - "tags": [], - "label": "config", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.ToolingLogTextWriterConfig", - "text": "ToolingLogTextWriterConfig" - } - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogTextWriter.write", - "type": "Function", - "tags": [], - "label": "write", - "description": [], - "signature": [ - "(msg: ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.Message", - "text": "Message" - }, - ") => boolean" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogTextWriter.write.$1", - "type": "Object", - "tags": [], - "label": "msg", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.Message", - "text": "Message" - } - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogTextWriter.write", - "type": "Function", - "tags": [], - "label": "write", - "description": [], - "signature": [ - "(writeTo: { write(msg: string): void; }, prefix: string, msg: ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.Message", - "text": "Message" - }, - ") => void" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogTextWriter.write.$1", - "type": "Object", - "tags": [], - "label": "writeTo", - "description": [], - "signature": [ - "{ write(msg: string): void; }" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogTextWriter.write.$2", - "type": "string", - "tags": [], - "label": "prefix", - "description": [], - "signature": [ - "string" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogTextWriter.write.$3", - "type": "Object", - "tags": [], - "label": "msg", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.Message", - "text": "Message" - } - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - } - ], - "initialIsOpen": false - } - ], - "functions": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.combineErrors", - "type": "Function", - "tags": [], - "label": "combineErrors", - "description": [], - "signature": [ - "(errors: (Error | FailError)[]) => Error" - ], - "path": "packages/kbn-dev-utils/src/run/fail.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.combineErrors.$1", - "type": "Array", - "tags": [], - "label": "errors", - "description": [], - "signature": [ - "(Error | FailError)[]" - ], - "path": "packages/kbn-dev-utils/src/run/fail.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.createAbsolutePathSerializer", - "type": "Function", - "tags": [], - "label": "createAbsolutePathSerializer", - "description": [], - "signature": [ - "(rootPath: string, replacement: string) => { test: (value: any) => boolean; serialize: (value: string) => string; }" - ], - "path": "packages/kbn-dev-utils/src/serializers/absolute_path_serializer.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.createAbsolutePathSerializer.$1", - "type": "string", - "tags": [], - "label": "rootPath", - "description": [], - "signature": [ - "string" - ], - "path": "packages/kbn-dev-utils/src/serializers/absolute_path_serializer.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.createAbsolutePathSerializer.$2", - "type": "string", - "tags": [], - "label": "replacement", - "description": [], - "signature": [ - "string" - ], - "path": "packages/kbn-dev-utils/src/serializers/absolute_path_serializer.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.createAnyInstanceSerializer", - "type": "Function", - "tags": [], - "label": "createAnyInstanceSerializer", - "description": [], - "signature": [ - "(Class: Function, name: string | ((instance: any) => string) | undefined) => { test: (v: any) => boolean; serialize: (v: any) => string; }" - ], - "path": "packages/kbn-dev-utils/src/serializers/any_instance_serizlizer.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.createAnyInstanceSerializer.$1", - "type": "Object", - "tags": [], - "label": "Class", - "description": [], - "signature": [ - "Function" - ], - "path": "packages/kbn-dev-utils/src/serializers/any_instance_serizlizer.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.createAnyInstanceSerializer.$2", - "type": "CompoundType", - "tags": [], - "label": "name", - "description": [], - "signature": [ - "string | ((instance: any) => string) | undefined" - ], - "path": "packages/kbn-dev-utils/src/serializers/any_instance_serizlizer.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.createFailError", - "type": "Function", - "tags": [], - "label": "createFailError", - "description": [], - "signature": [ - "(reason: string, options: FailErrorOptions) => FailError" - ], - "path": "packages/kbn-dev-utils/src/run/fail.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.createFailError.$1", - "type": "string", - "tags": [], - "label": "reason", - "description": [], - "signature": [ - "string" - ], - "path": "packages/kbn-dev-utils/src/run/fail.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.createFailError.$2", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "signature": [ - "FailErrorOptions" - ], - "path": "packages/kbn-dev-utils/src/run/fail.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.createFlagError", - "type": "Function", - "tags": [], - "label": "createFlagError", - "description": [], - "signature": [ - "(reason: string) => FailError" - ], - "path": "packages/kbn-dev-utils/src/run/fail.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.createFlagError.$1", - "type": "string", - "tags": [], - "label": "reason", - "description": [], - "signature": [ - "string" - ], - "path": "packages/kbn-dev-utils/src/run/fail.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.createRecursiveSerializer", - "type": "Function", - "tags": [], - "label": "createRecursiveSerializer", - "description": [], - "signature": [ - "(test: (v: any) => boolean, print: (v: any, printRaw: (v: string) => RawPrint) => string | RawPrint) => { test: (v: any) => boolean; serialize: (v: any, ...rest: any[]) => any; }" - ], - "path": "packages/kbn-dev-utils/src/serializers/recursive_serializer.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.createRecursiveSerializer.$1", - "type": "Function", - "tags": [], - "label": "test", - "description": [], - "signature": [ - "(v: any) => boolean" - ], - "path": "packages/kbn-dev-utils/src/serializers/recursive_serializer.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.createRecursiveSerializer.$2", - "type": "Function", - "tags": [], - "label": "print", - "description": [], - "signature": [ - "(v: any, printRaw: (v: string) => RawPrint) => string | RawPrint" - ], - "path": "packages/kbn-dev-utils/src/serializers/recursive_serializer.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.createReplaceSerializer", - "type": "Function", - "tags": [], - "label": "createReplaceSerializer", - "description": [], - "signature": [ - "(toReplace: string | RegExp, replaceWith: string | Replacer) => { test: (v: any) => boolean; serialize: (v: any, ...rest: any[]) => any; }" - ], - "path": "packages/kbn-dev-utils/src/serializers/replace_serializer.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.createReplaceSerializer.$1", - "type": "CompoundType", - "tags": [], - "label": "toReplace", - "description": [], - "signature": [ - "string | RegExp" - ], - "path": "packages/kbn-dev-utils/src/serializers/replace_serializer.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.createReplaceSerializer.$2", - "type": "CompoundType", - "tags": [], - "label": "replaceWith", - "description": [], - "signature": [ - "string | Replacer" - ], - "path": "packages/kbn-dev-utils/src/serializers/replace_serializer.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.createStripAnsiSerializer", - "type": "Function", - "tags": [], - "label": "createStripAnsiSerializer", - "description": [], - "signature": [ - "() => { test: (v: any) => boolean; serialize: (v: any, ...rest: any[]) => any; }" - ], - "path": "packages/kbn-dev-utils/src/serializers/strip_ansi_serializer.ts", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.diffStrings", - "type": "Function", - "tags": [], - "label": "diffStrings", - "description": [ - "\nProduces a diff string which is nicely formatted to show the differences between two strings. This will\nbe a multi-line string so it's generally a good idea to include a `\\n` before this first line of the diff\nif you are concatenating it with another message." - ], - "signature": [ - "(expected: string, received: string) => string | undefined" - ], - "path": "packages/kbn-dev-utils/src/diff_strings.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.diffStrings.$1", - "type": "string", - "tags": [], - "label": "expected", - "description": [], - "signature": [ - "string" - ], - "path": "packages/kbn-dev-utils/src/diff_strings.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.diffStrings.$2", - "type": "string", - "tags": [], - "label": "received", - "description": [], - "signature": [ - "string" - ], - "path": "packages/kbn-dev-utils/src/diff_strings.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.extract", - "type": "Function", - "tags": [], - "label": "extract", - "description": [ - "\nExtract tar and zip archives using a single function, supporting stripComponents\nfor both archive types, only tested with familiar archives we create so might not\nsupport some weird exotic zip features we don't use in our own snapshot/build tooling" - ], - "signature": [ - "({\n archivePath,\n targetDir,\n stripComponents = 0,\n setModifiedTimes,\n}: Options) => Promise" - ], - "path": "packages/kbn-dev-utils/src/extract.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.extract.$1", - "type": "Object", - "tags": [], - "label": "{\n archivePath,\n targetDir,\n stripComponents = 0,\n setModifiedTimes,\n}", - "description": [], - "signature": [ - "Options" - ], - "path": "packages/kbn-dev-utils/src/extract.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.getFlags", - "type": "Function", - "tags": [], - "label": "getFlags", - "description": [], - "signature": [ - "(argv: string[], flagOptions: ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.FlagOptions", - "text": "FlagOptions" - }, - " | undefined, defaultLogLevel: string) => ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.Flags", - "text": "Flags" - } - ], - "path": "packages/kbn-dev-utils/src/run/flags.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.getFlags.$1", - "type": "Array", - "tags": [], - "label": "argv", - "description": [], - "signature": [ - "string[]" - ], - "path": "packages/kbn-dev-utils/src/run/flags.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.getFlags.$2", - "type": "Object", - "tags": [], - "label": "flagOptions", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.FlagOptions", - "text": "FlagOptions" - }, - " | undefined" - ], - "path": "packages/kbn-dev-utils/src/run/flags.ts", - "deprecated": false, - "isRequired": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.getFlags.$3", - "type": "string", - "tags": [], - "label": "defaultLogLevel", - "description": [], - "signature": [ - "string" - ], - "path": "packages/kbn-dev-utils/src/run/flags.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.getTimeReporter", - "type": "Function", - "tags": [], - "label": "getTimeReporter", - "description": [], - "signature": [ - "(log: ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.ToolingLog", - "text": "ToolingLog" - }, - ", group: string) => (startTime: number, id: string, meta: Record) => Promise" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/report_time.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.getTimeReporter.$1", - "type": "Object", - "tags": [], - "label": "log", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.ToolingLog", - "text": "ToolingLog" - } - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/report_time.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.getTimeReporter.$2", - "type": "string", - "tags": [], - "label": "group", - "description": [], - "signature": [ - "string" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/report_time.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.isAxiosRequestError", - "type": "Function", - "tags": [], - "label": "isAxiosRequestError", - "description": [], - "signature": [ - "(error: any) => error is ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.AxiosRequestError", - "text": "AxiosRequestError" - } - ], - "path": "packages/kbn-dev-utils/src/axios/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.isAxiosRequestError.$1", - "type": "Any", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "any" - ], - "path": "packages/kbn-dev-utils/src/axios/errors.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.isAxiosResponseError", - "type": "Function", - "tags": [], - "label": "isAxiosResponseError", - "description": [], - "signature": [ - "(error: any) => error is ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.AxiosResponseError", - "text": "AxiosResponseError" - }, - "" - ], - "path": "packages/kbn-dev-utils/src/axios/errors.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.isAxiosResponseError.$1", - "type": "Any", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "any" - ], - "path": "packages/kbn-dev-utils/src/axios/errors.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.isFailError", - "type": "Function", - "tags": [], - "label": "isFailError", - "description": [], - "signature": [ - "(error: any) => boolean" - ], - "path": "packages/kbn-dev-utils/src/run/fail.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.isFailError.$1", - "type": "Any", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "any" - ], - "path": "packages/kbn-dev-utils/src/run/fail.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.mergeFlagOptions", - "type": "Function", - "tags": [], - "label": "mergeFlagOptions", - "description": [], - "signature": [ - "(global: ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.FlagOptions", - "text": "FlagOptions" - }, - ", local: ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.FlagOptions", - "text": "FlagOptions" - }, - ") => ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.FlagOptions", - "text": "FlagOptions" - } - ], - "path": "packages/kbn-dev-utils/src/run/flags.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.mergeFlagOptions.$1", - "type": "Object", - "tags": [], - "label": "global", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.FlagOptions", - "text": "FlagOptions" - } - ], - "path": "packages/kbn-dev-utils/src/run/flags.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.mergeFlagOptions.$2", - "type": "Object", - "tags": [], - "label": "local", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.FlagOptions", - "text": "FlagOptions" - } - ], - "path": "packages/kbn-dev-utils/src/run/flags.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.observeLines", - "type": "Function", - "tags": [ - "return" - ], - "label": "observeLines", - "description": [ - "\n Creates an Observable from a Readable Stream that:\n - splits data from `readable` into lines\n - completes when `readable` emits \"end\"\n - fails if `readable` emits \"errors\"\n" - ], - "signature": [ - "(readable: ", - "Readable", - ") => ", - "Observable", - "" - ], - "path": "packages/kbn-dev-utils/src/stdio/observe_lines.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.observeLines.$1", - "type": "Object", - "tags": [], - "label": "readable", - "description": [], - "signature": [ - "Readable" - ], - "path": "packages/kbn-dev-utils/src/stdio/observe_lines.ts", + "path": "packages/kbn-dev-utils/src/run/fail.ts", "deprecated": false, "isRequired": true } @@ -2395,315 +468,44 @@ }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.observeReadable", + "id": "def-server.diffStrings", "type": "Function", "tags": [], - "label": "observeReadable", + "label": "diffStrings", "description": [ - "\n Produces an Observable from a ReadableSteam that:\n - completes on the first \"end\" event\n - fails on the first \"error\" event" - ], - "signature": [ - "(readable: ", - "Readable", - ") => ", - "Observable", - "" - ], - "path": "packages/kbn-dev-utils/src/stdio/observe_readable.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.observeReadable.$1", - "type": "Object", - "tags": [], - "label": "readable", - "description": [], - "signature": [ - "Readable" - ], - "path": "packages/kbn-dev-utils/src/stdio/observe_readable.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.parseLogLevel", - "type": "Function", - "tags": [], - "label": "parseLogLevel", - "description": [], - "signature": [ - "(name: \"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\") => { name: \"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\"; flags: { error: boolean; info: boolean; success: boolean; warning: boolean; debug: boolean; silent: boolean; verbose: boolean; }; }" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/log_levels.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.parseLogLevel.$1", - "type": "CompoundType", - "tags": [], - "label": "name", - "description": [], - "signature": [ - "\"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\"" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/log_levels.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.pickLevelFromFlags", - "type": "Function", - "tags": [], - "label": "pickLevelFromFlags", - "description": [], - "signature": [ - "(flags: Record, options: { default?: \"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\" | undefined; }) => \"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\"" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/log_levels.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.pickLevelFromFlags.$1", - "type": "Object", - "tags": [], - "label": "flags", - "description": [], - "signature": [ - "Record" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/log_levels.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.pickLevelFromFlags.$2", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "path": "packages/kbn-dev-utils/src/tooling_log/log_levels.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.pickLevelFromFlags.$2.default", - "type": "CompoundType", - "tags": [], - "label": "default", - "description": [], - "signature": [ - "\"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\" | undefined" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/log_levels.ts", - "deprecated": false - } - ] - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.run", - "type": "Function", - "tags": [], - "label": "run", - "description": [], - "signature": [ - "(fn: ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.RunFn", - "text": "RunFn" - }, - ", options: ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.RunOptions", - "text": "RunOptions" - }, - ") => Promise" - ], - "path": "packages/kbn-dev-utils/src/run/run.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.run.$1", - "type": "Function", - "tags": [], - "label": "fn", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.RunFn", - "text": "RunFn" - } - ], - "path": "packages/kbn-dev-utils/src/run/run.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.run.$2", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.RunOptions", - "text": "RunOptions" - } - ], - "path": "packages/kbn-dev-utils/src/run/run.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.runPluginListCli", - "type": "Function", - "tags": [], - "label": "runPluginListCli", - "description": [], - "signature": [ - "() => void" - ], - "path": "packages/kbn-dev-utils/src/plugin_list/run_plugin_list_cli.ts", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.runUpdateVscodeConfigCli", - "type": "Function", - "tags": [], - "label": "runUpdateVscodeConfigCli", - "description": [], - "signature": [ - "() => void" - ], - "path": "packages/kbn-dev-utils/src/vscode_config/update_vscode_config_cli.ts", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.shipCiStatsCli", - "type": "Function", - "tags": [], - "label": "shipCiStatsCli", - "description": [], - "signature": [ - "() => void" + "\nProduces a diff string which is nicely formatted to show the differences between two strings. This will\nbe a multi-line string so it's generally a good idea to include a `\\n` before this first line of the diff\nif you are concatenating it with another message." ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ship_ci_stats_cli.ts", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.sortPackageJson", - "type": "Function", - "tags": [], - "label": "sortPackageJson", - "description": [], "signature": [ - "(json: string) => string" + "(expected: string, received: string) => string | undefined" ], - "path": "packages/kbn-dev-utils/src/sort_package_json.ts", + "path": "packages/kbn-dev-utils/src/diff_strings.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.sortPackageJson.$1", + "id": "def-server.diffStrings.$1", "type": "string", "tags": [], - "label": "json", + "label": "expected", "description": [], "signature": [ "string" ], - "path": "packages/kbn-dev-utils/src/sort_package_json.ts", + "path": "packages/kbn-dev-utils/src/diff_strings.ts", "deprecated": false, "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.transformFileStream", - "type": "Function", - "tags": [], - "label": "transformFileStream", - "description": [ - "\nCreate a transform stream that processes Vinyl fs streams and\ncalls a function for each file, allowing the function to either\nmutate the file, replace it with another file (return a new File\nobject), or drop it from the stream (return null)" - ], - "signature": [ - "(fn: (file: BufferedFile) => void | ", - "node_modules/@types/vinyl/index", - " | Promise | null) => ", - "Transform" - ], - "path": "packages/kbn-dev-utils/src/streams.ts", - "deprecated": false, - "children": [ + }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.transformFileStream.$1", - "type": "Function", + "id": "def-server.diffStrings.$2", + "type": "string", "tags": [], - "label": "fn", + "label": "received", "description": [], "signature": [ - "(file: BufferedFile) => void | ", - "node_modules/@types/vinyl/index", - " | Promise | null" + "string" ], - "path": "packages/kbn-dev-utils/src/streams.ts", + "path": "packages/kbn-dev-utils/src/diff_strings.ts", "deprecated": false, "isRequired": true } @@ -2713,32 +515,30 @@ }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.transformFileWithBabel", + "id": "def-server.extract", "type": "Function", "tags": [], - "label": "transformFileWithBabel", + "label": "extract", "description": [ - "\nReturns a promise that resolves when the file has been\nmutated so the contents of the file are tranformed with\nbabel, include inline sourcemaps, and the filename has\nbeen updated to use .js.\n\nIf the file was previously transformed with this function\nthe promise will just resolve immediately." + "\nExtract tar and zip archives using a single function, supporting stripComponents\nfor both archive types, only tested with familiar archives we create so might not\nsupport some weird exotic zip features we don't use in our own snapshot/build tooling" ], "signature": [ - "(file: ", - "node_modules/@types/vinyl/index", - ") => Promise" + "({\n archivePath,\n targetDir,\n stripComponents = 0,\n setModifiedTimes,\n}: Options) => Promise" ], - "path": "packages/kbn-dev-utils/src/babel.ts", + "path": "packages/kbn-dev-utils/src/extract.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.transformFileWithBabel.$1", + "id": "def-server.extract.$1", "type": "Object", "tags": [], - "label": "file", + "label": "{\n archivePath,\n targetDir,\n stripComponents = 0,\n setModifiedTimes,\n}", "description": [], "signature": [ - "node_modules/@types/vinyl/index" + "Options" ], - "path": "packages/kbn-dev-utils/src/babel.ts", + "path": "packages/kbn-dev-utils/src/extract.ts", "deprecated": false, "isRequired": true } @@ -2748,131 +548,132 @@ }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.withProcRunner", + "id": "def-server.getFlags", "type": "Function", - "tags": [ - "return" - ], - "label": "withProcRunner", - "description": [ - "\n Create a ProcRunner and pass it to an async function. When\n the async function finishes the ProcRunner is torn-down\n automatically\n" - ], + "tags": [], + "label": "getFlags", + "description": [], "signature": [ - "(log: ", + "(argv: string[], flagOptions: ", { "pluginId": "@kbn/dev-utils", "scope": "server", "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.ToolingLog", - "text": "ToolingLog" + "section": "def-server.FlagOptions", + "text": "FlagOptions" }, - ", fn: (procs: ", + " | undefined, defaultLogLevel: string) => ", { "pluginId": "@kbn/dev-utils", "scope": "server", "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.ProcRunner", - "text": "ProcRunner" - }, - ") => Promise) => Promise" + "section": "def-server.Flags", + "text": "Flags" + } ], - "path": "packages/kbn-dev-utils/src/proc_runner/with_proc_runner.ts", + "path": "packages/kbn-dev-utils/src/run/flags.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.withProcRunner.$1", - "type": "Object", + "id": "def-server.getFlags.$1", + "type": "Array", "tags": [], - "label": "log", + "label": "argv", "description": [], "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.ToolingLog", - "text": "ToolingLog" - } + "string[]" ], - "path": "packages/kbn-dev-utils/src/proc_runner/with_proc_runner.ts", + "path": "packages/kbn-dev-utils/src/run/flags.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.withProcRunner.$2", - "type": "Function", + "id": "def-server.getFlags.$2", + "type": "Object", "tags": [], - "label": "fn", + "label": "flagOptions", "description": [], "signature": [ - "(procs: ", { "pluginId": "@kbn/dev-utils", "scope": "server", "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.ProcRunner", - "text": "ProcRunner" + "section": "def-server.FlagOptions", + "text": "FlagOptions" }, - ") => Promise" + " | undefined" ], - "path": "packages/kbn-dev-utils/src/proc_runner/with_proc_runner.ts", + "path": "packages/kbn-dev-utils/src/run/flags.ts", + "deprecated": false, + "isRequired": false + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.getFlags.$3", + "type": "string", + "tags": [], + "label": "defaultLogLevel", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-dev-utils/src/run/flags.ts", "deprecated": false, "isRequired": true } ], "returnComment": [], "initialIsOpen": false - } - ], - "interfaces": [ + }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.AxiosRequestError", - "type": "Interface", + "id": "def-server.isAxiosRequestError", + "type": "Function", "tags": [], - "label": "AxiosRequestError", + "label": "isAxiosRequestError", "description": [], "signature": [ + "(error: any) => error is ", { "pluginId": "@kbn/dev-utils", "scope": "server", "docId": "kibKbnDevUtilsPluginApi", "section": "def-server.AxiosRequestError", "text": "AxiosRequestError" - }, - " extends ", - "AxiosError", - "" + } ], "path": "packages/kbn-dev-utils/src/axios/errors.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.AxiosRequestError.response", - "type": "Uncategorized", + "id": "def-server.isAxiosRequestError.$1", + "type": "Any", "tags": [], - "label": "response", + "label": "error", "description": [], "signature": [ - "undefined" + "any" ], "path": "packages/kbn-dev-utils/src/axios/errors.ts", - "deprecated": false + "deprecated": false, + "isRequired": true } ], + "returnComment": [], "initialIsOpen": false }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.AxiosResponseError", - "type": "Interface", + "id": "def-server.isAxiosResponseError", + "type": "Function", "tags": [], - "label": "AxiosResponseError", + "label": "isAxiosResponseError", "description": [], "signature": [ + "(error: any) => error is ", { "pluginId": "@kbn/dev-utils", "scope": "server", @@ -2880,486 +681,479 @@ "section": "def-server.AxiosResponseError", "text": "AxiosResponseError" }, - " extends ", - "AxiosError", - "" + "" ], "path": "packages/kbn-dev-utils/src/axios/errors.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.AxiosResponseError.response", - "type": "Object", + "id": "def-server.isAxiosResponseError.$1", + "type": "Any", "tags": [], - "label": "response", + "label": "error", "description": [], "signature": [ - "AxiosResponse", - "" + "any" ], "path": "packages/kbn-dev-utils/src/axios/errors.ts", - "deprecated": false + "deprecated": false, + "isRequired": true } ], + "returnComment": [], "initialIsOpen": false }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsMetric", - "type": "Interface", + "id": "def-server.isFailError", + "type": "Function", "tags": [], - "label": "CiStatsMetric", - "description": [ - "A ci-stats metric record" + "label": "isFailError", + "description": [], + "signature": [ + "(error: any) => boolean" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "path": "packages/kbn-dev-utils/src/run/fail.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsMetric.group", - "type": "string", + "id": "def-server.isFailError.$1", + "type": "Any", "tags": [], - "label": "group", - "description": [ - "Top-level categorization for the metric, e.g. \"page load bundle size\"" + "label": "error", + "description": [], + "signature": [ + "any" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false - }, + "path": "packages/kbn-dev-utils/src/run/fail.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.mergeFlagOptions", + "type": "Function", + "tags": [], + "label": "mergeFlagOptions", + "description": [], + "signature": [ + "(global: ", { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsMetric.id", - "type": "string", - "tags": [], - "label": "id", - "description": [ - "Specific sub-set of the \"group\", e.g. \"dashboard\"" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.FlagOptions", + "text": "FlagOptions" }, + ", local: ", { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsMetric.value", - "type": "number", - "tags": [], - "label": "value", - "description": [ - "integer value recorded as the value of this metric" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.FlagOptions", + "text": "FlagOptions" }, + ") => ", { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsMetric.limit", - "type": "number", - "tags": [], - "label": "limit", - "description": [ - "optional limit which will generate an error on PRs when the metric exceeds the limit" - ], - "signature": [ - "number | undefined" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false - }, + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.FlagOptions", + "text": "FlagOptions" + } + ], + "path": "packages/kbn-dev-utils/src/run/flags.ts", + "deprecated": false, + "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsMetric.limitConfigPath", - "type": "string", + "id": "def-server.mergeFlagOptions.$1", + "type": "Object", "tags": [], - "label": "limitConfigPath", - "description": [ - "\npath, relative to the repo, where the config file contianing limits\nis kept. Linked from PR comments instructing contributors how to fix\ntheir PRs." - ], + "label": "global", + "description": [], "signature": [ - "string | undefined" + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.FlagOptions", + "text": "FlagOptions" + } ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false + "path": "packages/kbn-dev-utils/src/run/flags.ts", + "deprecated": false, + "isRequired": true }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsMetric.meta", + "id": "def-server.mergeFlagOptions.$2", "type": "Object", "tags": [], - "label": "meta", - "description": [ - "Arbitrary key-value pairs which can be used for additional filtering/reporting" - ], + "label": "local", + "description": [], "signature": [ - "CiStatsMetadata", - " | undefined" + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.FlagOptions", + "text": "FlagOptions" + } ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false + "path": "packages/kbn-dev-utils/src/run/flags.ts", + "deprecated": false, + "isRequired": true } ], + "returnComment": [], "initialIsOpen": false }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsReportTestsOptions", - "type": "Interface", + "id": "def-server.run", + "type": "Function", "tags": [], - "label": "CiStatsReportTestsOptions", - "description": [ - "Options for reporting tests to ci-stats" + "label": "run", + "description": [], + "signature": [ + "(fn: ", + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.RunFn", + "text": "RunFn" + }, + ", options: ", + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.RunOptions", + "text": "RunOptions" + }, + ") => Promise" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "path": "packages/kbn-dev-utils/src/run/run.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsReportTestsOptions.group", - "type": "Object", + "id": "def-server.run.$1", + "type": "Function", "tags": [], - "label": "group", - "description": [ - "\nInformation about the group of tests that were run" - ], + "label": "fn", + "description": [], "signature": [ { "pluginId": "@kbn/dev-utils", "scope": "server", "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.CiStatsTestGroupInfo", - "text": "CiStatsTestGroupInfo" + "section": "def-server.RunFn", + "text": "RunFn" } ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false + "path": "packages/kbn-dev-utils/src/run/run.ts", + "deprecated": false, + "isRequired": true }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsReportTestsOptions.testRuns", - "type": "Array", + "id": "def-server.run.$2", + "type": "Object", "tags": [], - "label": "testRuns", - "description": [ - "\nInformation about each test that ran, including failure information" - ], + "label": "options", + "description": [], "signature": [ { "pluginId": "@kbn/dev-utils", "scope": "server", "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.CiStatsTestRun", - "text": "CiStatsTestRun" - }, - "[]" + "section": "def-server.RunOptions", + "text": "RunOptions" + } ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false + "path": "packages/kbn-dev-utils/src/run/run.ts", + "deprecated": false, + "isRequired": true } ], + "returnComment": [], "initialIsOpen": false }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTestGroupInfo", - "type": "Interface", + "id": "def-server.runPluginListCli", + "type": "Function", + "tags": [], + "label": "runPluginListCli", + "description": [], + "signature": [ + "() => void" + ], + "path": "packages/kbn-dev-utils/src/plugin_list/run_plugin_list_cli.ts", + "deprecated": false, + "children": [], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.runUpdateVscodeConfigCli", + "type": "Function", + "tags": [], + "label": "runUpdateVscodeConfigCli", + "description": [], + "signature": [ + "() => void" + ], + "path": "packages/kbn-dev-utils/src/vscode_config/update_vscode_config_cli.ts", + "deprecated": false, + "children": [], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.shipCiStatsCli", + "type": "Function", "tags": [], - "label": "CiStatsTestGroupInfo", + "label": "shipCiStatsCli", "description": [], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_test_group_types.ts", + "signature": [ + "() => void" + ], + "path": "packages/kbn-dev-utils/src/ship_ci_stats_cli.ts", + "deprecated": false, + "children": [], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.transformFileStream", + "type": "Function", + "tags": [], + "label": "transformFileStream", + "description": [ + "\nCreate a transform stream that processes Vinyl fs streams and\ncalls a function for each file, allowing the function to either\nmutate the file, replace it with another file (return a new File\nobject), or drop it from the stream (return null)" + ], + "signature": [ + "(fn: (file: BufferedFile) => void | ", + "node_modules/@types/vinyl/index", + " | Promise | null) => ", + "Transform" + ], + "path": "packages/kbn-dev-utils/src/streams.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTestGroupInfo.startTime", - "type": "string", - "tags": [], - "label": "startTime", - "description": [ - "\nISO-8601 formatted datetime representing when the group of tests started running" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_test_group_types.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTestGroupInfo.durationMs", - "type": "number", - "tags": [], - "label": "durationMs", - "description": [ - "\nThe number of miliseconds that the tests ran for" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_test_group_types.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTestGroupInfo.type", - "type": "string", - "tags": [], - "label": "type", - "description": [ - "\nThe type of tests run in this group, any value is valid but test groups are groupped by type in the UI so use something consistent" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_test_group_types.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTestGroupInfo.name", - "type": "string", - "tags": [], - "label": "name", - "description": [ - "\nThe name of this specific group (within the \"type\")" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_test_group_types.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTestGroupInfo.meta", - "type": "Object", + "id": "def-server.transformFileStream.$1", + "type": "Function", "tags": [], - "label": "meta", - "description": [ - "\nArbitrary metadata associated with this group. We currently look for a ciGroup metadata property for highlighting that when appropriate" - ], + "label": "fn", + "description": [], "signature": [ - "CiStatsMetadata" + "(file: BufferedFile) => void | ", + "node_modules/@types/vinyl/index", + " | Promise | null" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_test_group_types.ts", - "deprecated": false + "path": "packages/kbn-dev-utils/src/streams.ts", + "deprecated": false, + "isRequired": true } ], + "returnComment": [], "initialIsOpen": false }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTestRun", - "type": "Interface", + "id": "def-server.transformFileWithBabel", + "type": "Function", "tags": [], - "label": "CiStatsTestRun", - "description": [], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_test_group_types.ts", + "label": "transformFileWithBabel", + "description": [ + "\nReturns a promise that resolves when the file has been\nmutated so the contents of the file are tranformed with\nbabel, include inline sourcemaps, and the filename has\nbeen updated to use .js.\n\nIf the file was previously transformed with this function\nthe promise will just resolve immediately." + ], + "signature": [ + "(file: ", + "node_modules/@types/vinyl/index", + ") => Promise" + ], + "path": "packages/kbn-dev-utils/src/babel.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTestRun.startTime", - "type": "string", - "tags": [], - "label": "startTime", - "description": [ - "\nISO-8601 formatted datetime representing when the tests started running" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_test_group_types.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTestRun.durationMs", - "type": "number", - "tags": [], - "label": "durationMs", - "description": [ - "\nDuration of the tests in milliseconds" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_test_group_types.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTestRun.seq", - "type": "number", - "tags": [], - "label": "seq", - "description": [ - "\nA sequence number, this is used to order the tests in a specific test run" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_test_group_types.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTestRun.type", - "type": "CompoundType", - "tags": [], - "label": "type", - "description": [ - "\nThe type of this \"test run\", usually this is just \"test\" but when reporting issues in hooks it can be set to the type of hook" - ], - "signature": [ - "\"after all hook\" | \"after each hook\" | \"before all hook\" | \"before each hook\" | \"test\"" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_test_group_types.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTestRun.result", - "type": "CompoundType", - "tags": [], - "label": "result", - "description": [ - "\n\"fail\", \"pass\" or \"skip\", the result of the tests" - ], - "signature": [ - "\"fail\" | \"pass\" | \"skip\"" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_test_group_types.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTestRun.suites", - "type": "Array", - "tags": [], - "label": "suites", - "description": [ - "\nThe list of suite names containing this test, the first being the outermost suite" - ], - "signature": [ - "string[]" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_test_group_types.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTestRun.name", - "type": "string", - "tags": [], - "label": "name", - "description": [ - "\nThe name of this specific test run" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_test_group_types.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTestRun.file", - "type": "string", + "id": "def-server.transformFileWithBabel.$1", + "type": "Object", "tags": [], "label": "file", - "description": [ - "\nRelative path from the root of the repo contianing this test" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_test_group_types.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTestRun.error", - "type": "string", - "tags": [], - "label": "error", - "description": [ - "\nError message if the test failed" - ], + "description": [], "signature": [ - "string | undefined" + "node_modules/@types/vinyl/index" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_test_group_types.ts", - "deprecated": false + "path": "packages/kbn-dev-utils/src/babel.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.withProcRunner", + "type": "Function", + "tags": [ + "return" + ], + "label": "withProcRunner", + "description": [ + "\n Create a ProcRunner and pass it to an async function. When\n the async function finishes the ProcRunner is torn-down\n automatically\n" + ], + "signature": [ + "(log: ", + "ToolingLog", + ", fn: (procs: ", + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.ProcRunner", + "text": "ProcRunner" }, + ") => Promise) => Promise" + ], + "path": "packages/kbn-dev-utils/src/proc_runner/with_proc_runner.ts", + "deprecated": false, + "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTestRun.stdout", - "type": "string", + "id": "def-server.withProcRunner.$1", + "type": "Object", "tags": [], - "label": "stdout", - "description": [ - "\nDebug output/stdout produced by the test" - ], + "label": "log", + "description": [], "signature": [ - "string | undefined" + "ToolingLog" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_test_group_types.ts", - "deprecated": false + "path": "packages/kbn-dev-utils/src/proc_runner/with_proc_runner.ts", + "deprecated": false, + "isRequired": true }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTestRun.screenshots", - "type": "Array", + "id": "def-server.withProcRunner.$2", + "type": "Function", "tags": [], - "label": "screenshots", - "description": [ - "\nScreenshots captured during the test run" - ], + "label": "fn", + "description": [], "signature": [ - "{ name: string; base64Png: string; }[] | undefined" + "(procs: ", + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.ProcRunner", + "text": "ProcRunner" + }, + ") => Promise" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_test_group_types.ts", - "deprecated": false + "path": "packages/kbn-dev-utils/src/proc_runner/with_proc_runner.ts", + "deprecated": false, + "isRequired": true } ], + "returnComment": [], "initialIsOpen": false - }, + } + ], + "interfaces": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTiming", + "id": "def-server.AxiosRequestError", "type": "Interface", "tags": [], - "label": "CiStatsTiming", - "description": [ - "A ci-stats timing event" + "label": "AxiosRequestError", + "description": [], + "signature": [ + { + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.AxiosRequestError", + "text": "AxiosRequestError" + }, + " extends ", + "AxiosError", + "" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "path": "packages/kbn-dev-utils/src/axios/errors.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTiming.group", - "type": "string", - "tags": [], - "label": "group", - "description": [ - "Top-level categorization for the timing, e.g. \"scripts/foo\", process type, etc." - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTiming.id", - "type": "string", + "id": "def-server.AxiosRequestError.response", + "type": "Uncategorized", "tags": [], - "label": "id", - "description": [ - "Specific timing (witin the \"group\" being tracked) e.g. \"total\"" + "label": "response", + "description": [], + "signature": [ + "undefined" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "path": "packages/kbn-dev-utils/src/axios/errors.ts", "deprecated": false - }, + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/dev-utils", + "id": "def-server.AxiosResponseError", + "type": "Interface", + "tags": [], + "label": "AxiosResponseError", + "description": [], + "signature": [ { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTiming.ms", - "type": "number", - "tags": [], - "label": "ms", - "description": [ - "time in milliseconds which should be recorded" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false + "pluginId": "@kbn/dev-utils", + "scope": "server", + "docId": "kibKbnDevUtilsPluginApi", + "section": "def-server.AxiosResponseError", + "text": "AxiosResponseError" }, + " extends ", + "AxiosError", + "" + ], + "path": "packages/kbn-dev-utils/src/axios/errors.ts", + "deprecated": false, + "children": [ { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTiming.meta", + "id": "def-server.AxiosResponseError.response", "type": "Object", "tags": [], - "label": "meta", - "description": [ - "hash of key-value pairs which will be stored with the timing for additional filtering and reporting" - ], + "label": "response", + "description": [], "signature": [ - "CiStatsMetadata", - " | undefined" + "AxiosResponse", + "" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "path": "packages/kbn-dev-utils/src/axios/errors.ts", "deprecated": false } ], @@ -3488,45 +1282,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.Config", - "type": "Interface", - "tags": [], - "label": "Config", - "description": [ - "\nInformation about how CiStatsReporter should talk to the ci-stats service. Normally\nit is read from a JSON environment variable using the `parseConfig()` function\nexported by this module." - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_config.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.Config.apiToken", - "type": "string", - "tags": [], - "label": "apiToken", - "description": [ - "ApiToken necessary for writing build data to ci-stats service" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_config.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.Config.buildId", - "type": "string", - "tags": [], - "label": "buildId", - "description": [ - "\nuuid which should be obtained by first creating a build with the\nci-stats service and then passing it to all subsequent steps" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_config.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "@kbn/dev-utils", "id": "def-server.FlagOptions", @@ -3687,150 +1442,47 @@ "type": "boolean", "tags": [], "label": "help", - "description": [], - "path": "packages/kbn-dev-utils/src/run/flags.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.Flags._", - "type": "Array", - "tags": [], - "label": "_", - "description": [], - "signature": [ - "string[]" - ], - "path": "packages/kbn-dev-utils/src/run/flags.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.Flags.unexpected", - "type": "Array", - "tags": [], - "label": "unexpected", - "description": [], - "signature": [ - "string[]" - ], - "path": "packages/kbn-dev-utils/src/run/flags.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.Flags.Unnamed", - "type": "IndexSignature", - "tags": [], - "label": "[key: string]: string | boolean | string[] | undefined", - "description": [], - "signature": [ - "[key: string]: string | boolean | string[] | undefined" - ], - "path": "packages/kbn-dev-utils/src/run/flags.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.Message", - "type": "Interface", - "tags": [], - "label": "Message", - "description": [ - "\nThe object shape passed to ToolingLog writers each time the log is used." - ], - "path": "packages/kbn-dev-utils/src/tooling_log/message.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.Message.type", - "type": "CompoundType", - "tags": [], - "label": "type", - "description": [ - "level/type of message" - ], - "signature": [ - "\"error\" | \"write\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"verbose\"" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/message.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.Message.indent", - "type": "number", - "tags": [], - "label": "indent", - "description": [ - "indentation intended when message written to a text log" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/message.ts", + "description": [], + "path": "packages/kbn-dev-utils/src/run/flags.ts", "deprecated": false }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.Message.source", - "type": "string", + "id": "def-server.Flags._", + "type": "Array", "tags": [], - "label": "source", - "description": [ - "type of logger this message came from" - ], + "label": "_", + "description": [], "signature": [ - "string | undefined" + "string[]" ], - "path": "packages/kbn-dev-utils/src/tooling_log/message.ts", + "path": "packages/kbn-dev-utils/src/run/flags.ts", "deprecated": false }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.Message.args", + "id": "def-server.Flags.unexpected", "type": "Array", "tags": [], - "label": "args", - "description": [ - "args passed to the logging method" - ], + "label": "unexpected", + "description": [], "signature": [ - "any[]" + "string[]" ], - "path": "packages/kbn-dev-utils/src/tooling_log/message.ts", + "path": "packages/kbn-dev-utils/src/run/flags.ts", "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.MetricsOptions", - "type": "Interface", - "tags": [], - "label": "MetricsOptions", - "description": [ - "Options for reporting metrics to ci-stats" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false, - "children": [ + }, { "parentPluginId": "@kbn/dev-utils", - "id": "def-server.MetricsOptions.defaultMeta", - "type": "Object", + "id": "def-server.Flags.Unnamed", + "type": "IndexSignature", "tags": [], - "label": "defaultMeta", - "description": [ - "Default metadata to add to each metric" - ], + "label": "[key: string]: string | boolean | string[] | undefined", + "description": [], "signature": [ - "CiStatsMetadata", - " | undefined" + "[key: string]: string | boolean | string[] | undefined" ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", + "path": "packages/kbn-dev-utils/src/run/flags.ts", "deprecated": false } ], @@ -3854,13 +1506,7 @@ "label": "log", "description": [], "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.ToolingLog", - "text": "ToolingLog" - } + "ToolingLog" ], "path": "packages/kbn-dev-utils/src/run/run.ts", "deprecated": false @@ -4007,7 +1653,7 @@ "label": "log", "description": [], "signature": [ - "{ defaultLevel?: \"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\" | undefined; } | undefined" + "{ defaultLevel?: \"error\" | \"success\" | \"warning\" | \"info\" | \"debug\" | \"silent\" | \"verbose\" | undefined; } | undefined" ], "path": "packages/kbn-dev-utils/src/run/run.ts", "deprecated": false @@ -4063,7 +1709,7 @@ "label": "log", "description": [], "signature": [ - "{ defaultLevel?: \"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\" | undefined; } | undefined" + "{ defaultLevel?: \"error\" | \"success\" | \"warning\" | \"info\" | \"debug\" | \"silent\" | \"verbose\" | undefined; } | undefined" ], "path": "packages/kbn-dev-utils/src/run/run_with_commands.ts", "deprecated": false @@ -4160,244 +1806,6 @@ } ], "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.TimingsOptions", - "type": "Interface", - "tags": [], - "label": "TimingsOptions", - "description": [ - "Options for reporting timings to ci-stats" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.TimingsOptions.timings", - "type": "Array", - "tags": [], - "label": "timings", - "description": [ - "list of timings to record" - ], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.CiStatsTiming", - "text": "CiStatsTiming" - }, - "[]" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.TimingsOptions.upstreamBranch", - "type": "string", - "tags": [], - "label": "upstreamBranch", - "description": [ - "master, 7.x, etc, automatically detected from package.json if not specified" - ], - "signature": [ - "string | undefined" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.TimingsOptions.kibanaUuid", - "type": "CompoundType", - "tags": [], - "label": "kibanaUuid", - "description": [ - "value of data/uuid, automatically loaded if not specified" - ], - "signature": [ - "string | null | undefined" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogOptions", - "type": "Interface", - "tags": [], - "label": "ToolingLogOptions", - "description": [], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogOptions.type", - "type": "string", - "tags": [], - "label": "type", - "description": [ - "\ntype name for this logger, will be assigned to the \"source\"\nproperties of messages produced by this logger" - ], - "signature": [ - "string | undefined" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogOptions.parent", - "type": "Object", - "tags": [], - "label": "parent", - "description": [ - "\nparent ToolingLog. When a ToolingLog has a parent they will both\nshare indent and writers state. Changing the indent width or\nwriters on either log will update the other too." - ], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.ToolingLog", - "text": "ToolingLog" - }, - " | undefined" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogTextWriterConfig", - "type": "Interface", - "tags": [], - "label": "ToolingLogTextWriterConfig", - "description": [], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogTextWriterConfig.level", - "type": "CompoundType", - "tags": [], - "label": "level", - "description": [ - "\nLog level, messages below this level will be ignored" - ], - "signature": [ - "\"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\"" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogTextWriterConfig.ignoreSources", - "type": "Array", - "tags": [], - "label": "ignoreSources", - "description": [ - "\nList of message sources/ToolingLog types which will be ignored. Create\na logger with `ToolingLog#withType()` to create messages with a specific\nsource. Ignored messages will be dropped without writing." - ], - "signature": [ - "string[] | undefined" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ToolingLogTextWriterConfig.writeTo", - "type": "Object", - "tags": [], - "label": "writeTo", - "description": [ - "\nTarget which will receive formatted message lines, a common value for `writeTo`\nis process.stdout" - ], - "signature": [ - "{ write(s: string): void; }" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.Writer", - "type": "Interface", - "tags": [], - "label": "Writer", - "description": [ - "\nAn object which received ToolingLog `Messages` and sends them to\nsome interface for collecting logs like stdio, or a file" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/writer.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.Writer.write", - "type": "Function", - "tags": [], - "label": "write", - "description": [ - "\nCalled with every log message, should return true if the message\nwas written and false if it was ignored." - ], - "signature": [ - "(msg: ", - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.Message", - "text": "Message" - }, - ") => boolean" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/writer.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.Writer.write.$1", - "type": "Object", - "tags": [], - "label": "msg", - "description": [ - "The log message to write" - ], - "signature": [ - { - "pluginId": "@kbn/dev-utils", - "scope": "server", - "docId": "kibKbnDevUtilsPluginApi", - "section": "def-server.Message", - "text": "Message" - } - ], - "path": "packages/kbn-dev-utils/src/tooling_log/writer.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - } - ], - "initialIsOpen": false } ], "enums": [], @@ -4413,34 +1821,6 @@ "deprecated": false, "initialIsOpen": false }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTestResult", - "type": "Type", - "tags": [], - "label": "CiStatsTestResult", - "description": [], - "signature": [ - "\"fail\" | \"pass\" | \"skip\"" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_test_group_types.ts", - "deprecated": false, - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.CiStatsTestType", - "type": "Type", - "tags": [], - "label": "CiStatsTestType", - "description": [], - "signature": [ - "\"after all hook\" | \"after each hook\" | \"before all hook\" | \"before each hook\" | \"test\"" - ], - "path": "packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_test_group_types.ts", - "deprecated": false, - "initialIsOpen": false - }, { "parentPluginId": "@kbn/dev-utils", "id": "def-server.CleanupTask", @@ -4620,34 +2000,6 @@ "deprecated": false, "initialIsOpen": false }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.LogLevel", - "type": "Type", - "tags": [], - "label": "LogLevel", - "description": [], - "signature": [ - "\"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\"" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/log_levels.ts", - "deprecated": false, - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/dev-utils", - "id": "def-server.ParsedLogLevel", - "type": "Type", - "tags": [], - "label": "ParsedLogLevel", - "description": [], - "signature": [ - "{ name: \"error\" | \"info\" | \"success\" | \"warning\" | \"debug\" | \"silent\" | \"verbose\"; flags: { error: boolean; info: boolean; success: boolean; warning: boolean; debug: boolean; silent: boolean; verbose: boolean; }; }" - ], - "path": "packages/kbn-dev-utils/src/tooling_log/log_levels.ts", - "deprecated": false, - "initialIsOpen": false - }, { "parentPluginId": "@kbn/dev-utils", "id": "def-server.RunFn", diff --git a/api_docs/kbn_dev_utils.mdx b/api_docs/kbn_dev_utils.mdx index 39d04687e47e7..66ac63e6464b6 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/dev-utils plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 277 | 3 | 199 | 1 | +| 120 | 3 | 109 | 0 | ## Server diff --git a/api_docs/kbn_doc_links.devdocs.json b/api_docs/kbn_doc_links.devdocs.json index 48d1068132518..d0d228ea60e36 100644 --- a/api_docs/kbn_doc_links.devdocs.json +++ b/api_docs/kbn_doc_links.devdocs.json @@ -261,7 +261,7 @@ "label": "appSearch", "description": [], "signature": [ - "{ readonly apiRef: string; readonly apiClients: string; readonly apiKeys: string; readonly authentication: string; readonly crawlRules: string; readonly curations: string; readonly duplicateDocuments: string; readonly entryPoints: string; readonly guide: string; readonly indexingDocuments: string; readonly indexingDocumentsSchema: string; readonly logSettings: string; readonly metaEngines: string; readonly precisionTuning: string; readonly relevanceTuning: string; readonly resultSettings: string; readonly searchUI: string; readonly security: string; readonly synonyms: string; readonly webCrawler: string; readonly webCrawlerEventLogs: string; }" + "{ readonly apiRef: string; readonly apiClients: string; readonly apiKeys: string; readonly authentication: string; readonly crawlRules: string; readonly curations: string; readonly duplicateDocuments: string; readonly elasticsearchIndexedEngines: string; readonly entryPoints: string; readonly guide: string; readonly indexingDocuments: string; readonly indexingDocumentsSchema: string; readonly logSettings: string; readonly metaEngines: string; readonly precisionTuning: string; readonly relevanceTuning: string; readonly resultSettings: string; readonly searchUI: string; readonly security: string; readonly synonyms: string; readonly webCrawler: string; readonly webCrawlerEventLogs: string; }" ], "path": "packages/kbn-doc-links/src/types.ts", "deprecated": false @@ -326,7 +326,7 @@ "label": "logstash", "description": [], "signature": [ - "{ readonly base: string; }" + "{ readonly base: string; readonly inputElasticAgent: string; }" ], "path": "packages/kbn-doc-links/src/types.ts", "deprecated": false @@ -440,7 +440,7 @@ "label": "kibana", "description": [], "signature": [ - "{ readonly guide: string; readonly autocompleteSuggestions: string; readonly xpackSecurity: string; }" + "{ readonly guide: string; readonly autocompleteSuggestions: string; readonly secureSavedObject: string; readonly xpackSecurity: string; }" ], "path": "packages/kbn-doc-links/src/types.ts", "deprecated": false @@ -489,7 +489,7 @@ "label": "siem", "description": [], "signature": [ - "{ readonly privileges: string; readonly guide: string; readonly gettingStarted: string; readonly ml: string; readonly ruleChangeLog: string; readonly detectionsReq: string; readonly networkMap: string; readonly troubleshootGaps: string; }" + "{ readonly privileges: string; readonly guide: string; readonly gettingStarted: string; readonly ml: string; readonly ruleChangeLog: string; readonly detectionsReq: string; readonly networkMap: string; readonly troubleshootGaps: string; readonly ruleApiOverview: string; }" ], "path": "packages/kbn-doc-links/src/types.ts", "deprecated": false @@ -502,7 +502,7 @@ "label": "securitySolution", "description": [], "signature": [ - "{ readonly trustedApps: string; readonly eventFilters: string; }" + "{ readonly trustedApps: string; readonly eventFilters: string; readonly blocklist: string; }" ], "path": "packages/kbn-doc-links/src/types.ts", "deprecated": false @@ -749,7 +749,7 @@ "label": "fleet", "description": [], "signature": [ - "{ readonly beatsAgentComparison: string; readonly guide: string; readonly fleetServer: string; readonly fleetServerAddFleetServer: string; readonly settings: string; readonly settingsFleetServerHostSettings: string; readonly settingsFleetServerProxySettings: string; readonly troubleshooting: string; readonly elasticAgent: string; readonly datastreams: string; readonly datastreamsILM: string; readonly datastreamsNamingScheme: string; readonly installElasticAgent: string; readonly installElasticAgentStandalone: string; readonly upgradeElasticAgent: string; readonly upgradeElasticAgent712lower: string; readonly learnMoreBlog: string; readonly apiKeysLearnMore: string; readonly onPremRegistry: string; }" + "{ readonly beatsAgentComparison: string; readonly guide: string; readonly fleetServer: string; readonly fleetServerAddFleetServer: string; readonly settings: string; readonly settingsFleetServerHostSettings: string; readonly settingsFleetServerProxySettings: string; readonly troubleshooting: string; readonly elasticAgent: string; readonly datastreams: string; readonly datastreamsILM: string; readonly datastreamsNamingScheme: string; readonly installElasticAgent: string; readonly installElasticAgentStandalone: string; readonly upgradeElasticAgent: string; readonly upgradeElasticAgent712lower: string; readonly learnMoreBlog: string; readonly apiKeysLearnMore: string; readonly onPremRegistry: string; readonly secureLogstash: string; }" ], "path": "packages/kbn-doc-links/src/types.ts", "deprecated": false @@ -805,6 +805,19 @@ ], "path": "packages/kbn-doc-links/src/types.ts", "deprecated": false + }, + { + "parentPluginId": "@kbn/doc-links", + "id": "def-server.DocLinks.kibanaUpgradeSavedObjects", + "type": "Object", + "tags": [], + "label": "kibanaUpgradeSavedObjects", + "description": [], + "signature": [ + "{ readonly resolveMigrationFailures: string; }" + ], + "path": "packages/kbn-doc-links/src/types.ts", + "deprecated": false } ], "initialIsOpen": false diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index 3f83c0371ca56..4d23bdfc99533 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/doc-links plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/doc-links'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 63 | 0 | 63 | 2 | +| 64 | 0 | 64 | 2 | ## Server diff --git a/api_docs/kbn_docs_utils.mdx b/api_docs/kbn_docs_utils.mdx index a2568bc87ea2a..3fd9067f34bae 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/docs-utils plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/docs-utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_es_archiver.mdx b/api_docs/kbn_es_archiver.mdx index 965ed6526f6a9..2372ce2f44342 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/es-archiver plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-archiver'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_es_query.mdx b/api_docs/kbn_es_query.mdx index 3c39bf2f5d09d..f51fa006128aa 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/es-query plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_eslint_plugin_imports.devdocs.json b/api_docs/kbn_eslint_plugin_imports.devdocs.json index 47400f2102348..c1b952dc57cd6 100644 --- a/api_docs/kbn_eslint_plugin_imports.devdocs.json +++ b/api_docs/kbn_eslint_plugin_imports.devdocs.json @@ -13,56 +13,34 @@ "functions": [ { "parentPluginId": "@kbn/eslint-plugin-imports", - "id": "def-server.resolveKibanaImport", + "id": "def-server.getImportResolver", "type": "Function", "tags": [], - "label": "resolveKibanaImport", + "label": "getImportResolver", "description": [ - "\nResolve an import request. All import requests in the repository should return a result, if they don't it's a bug\nwhich should be caught by the `@kbn/import/no_unresolved` rule, which should never be disabled. If you need help\nadding support for an import style please reach out to operations.\n" + "\nCreate a request resolver for ESLint, requires a PluginPackageResolver from @kbn/bazel-packages which will\nbe created and cached on contextServices automatically.\n\nAll import requests in the repository should return a result, if they don't it's a bug\nwhich should be caught by the `@kbn/import/no_unresolved` rule, which should never be disabled. If you need help\nadding support for an import style please reach out to operations." ], "signature": [ - "(req: string, dirname: string) => ", - { - "pluginId": "@kbn/eslint-plugin-imports", - "scope": "server", - "docId": "kibKbnEslintPluginImportsPluginApi", - "section": "def-server.ResolveResult", - "text": "ResolveResult" - }, - " | null" + "(context: ", + "Rule", + ".RuleContext) => ", + "ImportResolver" ], - "path": "packages/kbn-eslint-plugin-imports/src/resolve_kibana_import.ts", + "path": "packages/kbn-eslint-plugin-imports/src/get_import_resolver.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/eslint-plugin-imports", - "id": "def-server.resolveKibanaImport.$1", - "type": "string", - "tags": [], - "label": "req", - "description": [ - "Text from an import/require, like `../../src/core/public` or `@kbn/std`" - ], - "signature": [ - "string" - ], - "path": "packages/kbn-eslint-plugin-imports/src/resolve_kibana_import.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/eslint-plugin-imports", - "id": "def-server.resolveKibanaImport.$2", - "type": "string", + "id": "def-server.getImportResolver.$1", + "type": "Object", "tags": [], - "label": "dirname", - "description": [ - "The directory of the file where the req was found" - ], + "label": "context", + "description": [], "signature": [ - "string" + "Rule", + ".RuleContext" ], - "path": "packages/kbn-eslint-plugin-imports/src/resolve_kibana_import.ts", + "path": "packages/kbn-eslint-plugin-imports/src/get_import_resolver.ts", "deprecated": false, "isRequired": true } @@ -71,166 +49,9 @@ "initialIsOpen": false } ], - "interfaces": [ - { - "parentPluginId": "@kbn/eslint-plugin-imports", - "id": "def-server.FileResult", - "type": "Interface", - "tags": [], - "label": "FileResult", - "description": [ - "\nResolution result indicating that the import resolves to a specific file, possible in a nodeModule, with\nthe path of that file and the name of the nodeModule if applicable" - ], - "path": "packages/kbn-eslint-plugin-imports/src/resolve_result.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/eslint-plugin-imports", - "id": "def-server.FileResult.type", - "type": "string", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "\"file\"" - ], - "path": "packages/kbn-eslint-plugin-imports/src/resolve_result.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/eslint-plugin-imports", - "id": "def-server.FileResult.absolute", - "type": "string", - "tags": [], - "label": "absolute", - "description": [], - "path": "packages/kbn-eslint-plugin-imports/src/resolve_result.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/eslint-plugin-imports", - "id": "def-server.FileResult.nodeModule", - "type": "string", - "tags": [], - "label": "nodeModule", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "packages/kbn-eslint-plugin-imports/src/resolve_result.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/eslint-plugin-imports", - "id": "def-server.IgnoreResult", - "type": "Interface", - "tags": [], - "label": "IgnoreResult", - "description": [ - "\nResolution result indicating that the import request can't be resolved, but it shouldn't need to be\nbecause the file that is imported can't be resolved from the source alone, usually because it is explicitly\nimporting a build asset. Import requests which meet this criteria are manually added to the resolver and\ncan be trusted to exist after the build it complete or in their used location." - ], - "path": "packages/kbn-eslint-plugin-imports/src/resolve_result.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/eslint-plugin-imports", - "id": "def-server.IgnoreResult.type", - "type": "string", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "\"ignore\"" - ], - "path": "packages/kbn-eslint-plugin-imports/src/resolve_result.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/eslint-plugin-imports", - "id": "def-server.TypesResult", - "type": "Interface", - "tags": [], - "label": "TypesResult", - "description": [ - "\nResolution result indicating that the import only resolves to an @types package, including the name of\nthe @types package. We don't validate the sub-path of these import strings and assume that TS will validate\nthem, we just need to know that they don't map to actual files on the filesystem or modules which will\nend up in the build or running code." - ], - "path": "packages/kbn-eslint-plugin-imports/src/resolve_result.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/eslint-plugin-imports", - "id": "def-server.TypesResult.type", - "type": "string", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "\"@types\"" - ], - "path": "packages/kbn-eslint-plugin-imports/src/resolve_result.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/eslint-plugin-imports", - "id": "def-server.TypesResult.module", - "type": "string", - "tags": [], - "label": "module", - "description": [], - "path": "packages/kbn-eslint-plugin-imports/src/resolve_result.ts", - "deprecated": false - } - ], - "initialIsOpen": false - } - ], + "interfaces": [], "enums": [], - "misc": [ - { - "parentPluginId": "@kbn/eslint-plugin-imports", - "id": "def-server.ResolveResult", - "type": "Type", - "tags": [], - "label": "ResolveResult", - "description": [ - "\nPossible resolve result types" - ], - "signature": [ - { - "pluginId": "@kbn/eslint-plugin-imports", - "scope": "server", - "docId": "kibKbnEslintPluginImportsPluginApi", - "section": "def-server.IgnoreResult", - "text": "IgnoreResult" - }, - " | ", - { - "pluginId": "@kbn/eslint-plugin-imports", - "scope": "server", - "docId": "kibKbnEslintPluginImportsPluginApi", - "section": "def-server.TypesResult", - "text": "TypesResult" - }, - " | ", - { - "pluginId": "@kbn/eslint-plugin-imports", - "scope": "server", - "docId": "kibKbnEslintPluginImportsPluginApi", - "section": "def-server.FileResult", - "text": "FileResult" - } - ], - "path": "packages/kbn-eslint-plugin-imports/src/resolve_result.ts", - "deprecated": false, - "initialIsOpen": false - } - ], + "misc": [], "objects": [] }, "common": { diff --git a/api_docs/kbn_eslint_plugin_imports.mdx b/api_docs/kbn_eslint_plugin_imports.mdx index b1469acd5ce18..39fd23924e882 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/eslint-plugin-imports plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,16 +18,10 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 13 | 0 | 6 | 0 | +| 2 | 0 | 1 | 0 | ## Server ### Functions -### Interfaces - - -### Consts, variables and types - - diff --git a/api_docs/kbn_field_types.mdx b/api_docs/kbn_field_types.mdx index b100124a4b173..34d156709b95c 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/field-types plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_find_used_node_modules.devdocs.json b/api_docs/kbn_find_used_node_modules.devdocs.json new file mode 100644 index 0000000000000..8635fa4c975ef --- /dev/null +++ b/api_docs/kbn_find_used_node_modules.devdocs.json @@ -0,0 +1,61 @@ +{ + "id": "@kbn/find-used-node-modules", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [ + { + "parentPluginId": "@kbn/find-used-node-modules", + "id": "def-server.findUsedNodeModules", + "type": "Function", + "tags": [], + "label": "findUsedNodeModules", + "description": [ + "\nParse a list of entry paths and find the node_modules which are required by them. If the\nentry path requires/imports a non-node_module then that file is scanned too, deeply, until\nall referenced files are scanned.\n\nOptionally, we can find the used peers of the used node_modules. This will keep track of all\nthe paths we use to enter a node_module and then traverse from those points, finding the\nused modules and comparing those to the `peerDependencies` listed in the node_module's package.json\nfile. If a used dependeny is in the `peerDependencies` and is used by the node_module it will\nbe included in the results.\n\nThis was implemented mostly for `@emotion/react` which is used by @elastic/eui but only listed\nas a peerDependency. If we didn't keep it in the Kibana package.json then the package would not\nbe installed and cause an error on startup because `@emotion/react` can't be found. We used to\nsolve this by scanning the node_modules directory for all the packages which are used but that\nwas much slower and lead to extra entries in package.json." + ], + "signature": [ + "(options: Options) => Promise" + ], + "path": "packages/kbn-find-used-node-modules/src/find_used_node_modules.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/find-used-node-modules", + "id": "def-server.findUsedNodeModules.$1", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "Options" + ], + "path": "packages/kbn-find-used-node-modules/src/find_used_node_modules.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx new file mode 100644 index 0000000000000..95310ec27972b --- /dev/null +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -0,0 +1,27 @@ +--- +id: kibKbnFindUsedNodeModulesPluginApi +slug: /kibana-dev-docs/api/kbn-find-used-node-modules +title: "@kbn/find-used-node-modules" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the @kbn/find-used-node-modules plugin +date: 2022-04-26 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 2 | 0 | 0 | 0 | + +## Server + +### Functions + + diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index f678ebba804cc..891a77319d2c0 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/generate plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_i18n.mdx b/api_docs/kbn_i18n.mdx index cadd77a894b98..f1c2d35173a65 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/i18n plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_import_resolver.devdocs.json b/api_docs/kbn_import_resolver.devdocs.json new file mode 100644 index 0000000000000..50e7cdda82ff7 --- /dev/null +++ b/api_docs/kbn_import_resolver.devdocs.json @@ -0,0 +1,715 @@ +{ + "id": "@kbn/import-resolver", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [ + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.ImportResolver", + "type": "Class", + "tags": [], + "label": "ImportResolver", + "description": [], + "path": "packages/kbn-import-resolver/src/import_resolver.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.ImportResolver.create", + "type": "Function", + "tags": [], + "label": "create", + "description": [], + "signature": [ + "(repoRoot: string) => ", + { + "pluginId": "@kbn/import-resolver", + "scope": "server", + "docId": "kibKbnImportResolverPluginApi", + "section": "def-server.ImportResolver", + "text": "ImportResolver" + } + ], + "path": "packages/kbn-import-resolver/src/import_resolver.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.ImportResolver.create.$1", + "type": "string", + "tags": [], + "label": "repoRoot", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-import-resolver/src/import_resolver.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.ImportResolver.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "packages/kbn-import-resolver/src/import_resolver.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.ImportResolver.Unnamed.$1", + "type": "string", + "tags": [], + "label": "cwd", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-import-resolver/src/import_resolver.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.ImportResolver.Unnamed.$2", + "type": "Object", + "tags": [], + "label": "pkgMap", + "description": [], + "signature": [ + "PackageMap" + ], + "path": "packages/kbn-import-resolver/src/import_resolver.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.ImportResolver.Unnamed.$3", + "type": "Object", + "tags": [], + "label": "synthPkgMap", + "description": [], + "signature": [ + "PackageMap" + ], + "path": "packages/kbn-import-resolver/src/import_resolver.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.ImportResolver.getPackageIdForPath", + "type": "Function", + "tags": [], + "label": "getPackageIdForPath", + "description": [], + "signature": [ + "(path: string) => string | null" + ], + "path": "packages/kbn-import-resolver/src/import_resolver.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.ImportResolver.getPackageIdForPath.$1", + "type": "string", + "tags": [], + "label": "path", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-import-resolver/src/import_resolver.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.ImportResolver.getAbsolutePackageDir", + "type": "Function", + "tags": [], + "label": "getAbsolutePackageDir", + "description": [], + "signature": [ + "(pkgId: string) => string | null" + ], + "path": "packages/kbn-import-resolver/src/import_resolver.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.ImportResolver.getAbsolutePackageDir.$1", + "type": "string", + "tags": [], + "label": "pkgId", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-import-resolver/src/import_resolver.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.ImportResolver.isBazelPackage", + "type": "Function", + "tags": [], + "label": "isBazelPackage", + "description": [], + "signature": [ + "(pkgId: string) => boolean" + ], + "path": "packages/kbn-import-resolver/src/import_resolver.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.ImportResolver.isBazelPackage.$1", + "type": "string", + "tags": [], + "label": "pkgId", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-import-resolver/src/import_resolver.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.ImportResolver.isSyntheticPackage", + "type": "Function", + "tags": [], + "label": "isSyntheticPackage", + "description": [], + "signature": [ + "(pkgId: string) => boolean" + ], + "path": "packages/kbn-import-resolver/src/import_resolver.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.ImportResolver.isSyntheticPackage.$1", + "type": "string", + "tags": [], + "label": "pkgId", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-import-resolver/src/import_resolver.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.ImportResolver.resolve", + "type": "Function", + "tags": [], + "label": "resolve", + "description": [ + "\nResolve an import request from a file in the given dirname" + ], + "signature": [ + "(req: string, dirname: string) => ", + { + "pluginId": "@kbn/import-resolver", + "scope": "server", + "docId": "kibKbnImportResolverPluginApi", + "section": "def-server.ResolveResult", + "text": "ResolveResult" + }, + " | null" + ], + "path": "packages/kbn-import-resolver/src/import_resolver.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.ImportResolver.resolve.$1", + "type": "string", + "tags": [], + "label": "req", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-import-resolver/src/import_resolver.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.ImportResolver.resolve.$2", + "type": "string", + "tags": [], + "label": "dirname", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-import-resolver/src/import_resolver.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + } + ], + "functions": [ + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.getPackageRelativeImportReq", + "type": "Function", + "tags": [], + "label": "getPackageRelativeImportReq", + "description": [], + "signature": [ + "(options: PackageRelativeImportReqOptions) => string" + ], + "path": "packages/kbn-import-resolver/src/helpers/import_req.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.getPackageRelativeImportReq.$1", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "PackageRelativeImportReqOptions" + ], + "path": "packages/kbn-import-resolver/src/helpers/import_req.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.getRelativeImportReq", + "type": "Function", + "tags": [], + "label": "getRelativeImportReq", + "description": [], + "signature": [ + "(options: RelativeImportReqOptions) => string" + ], + "path": "packages/kbn-import-resolver/src/helpers/import_req.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.getRelativeImportReq.$1", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "RelativeImportReqOptions" + ], + "path": "packages/kbn-import-resolver/src/helpers/import_req.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.reduceImportRequest", + "type": "Function", + "tags": [], + "label": "reduceImportRequest", + "description": [], + "signature": [ + "(req: string, type: ", + { + "pluginId": "@kbn/import-resolver", + "scope": "server", + "docId": "kibKbnImportResolverPluginApi", + "section": "def-server.ImportType", + "text": "ImportType" + }, + ", original: string | undefined) => string" + ], + "path": "packages/kbn-import-resolver/src/helpers/import_req.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.reduceImportRequest.$1", + "type": "string", + "tags": [], + "label": "req", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-import-resolver/src/helpers/import_req.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.reduceImportRequest.$2", + "type": "CompoundType", + "tags": [], + "label": "type", + "description": [], + "signature": [ + { + "pluginId": "@kbn/import-resolver", + "scope": "server", + "docId": "kibKbnImportResolverPluginApi", + "section": "def-server.ImportType", + "text": "ImportType" + } + ], + "path": "packages/kbn-import-resolver/src/helpers/import_req.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.reduceImportRequest.$3", + "type": "string", + "tags": [], + "label": "original", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-import-resolver/src/helpers/import_req.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [ + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.BuiltInResult", + "type": "Interface", + "tags": [], + "label": "BuiltInResult", + "description": [ + "\nResolution result indicating that the import request resolves to a built-in node library" + ], + "path": "packages/kbn-import-resolver/src/resolve_result.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.BuiltInResult.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"built-in\"" + ], + "path": "packages/kbn-import-resolver/src/resolve_result.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.FileResult", + "type": "Interface", + "tags": [], + "label": "FileResult", + "description": [ + "\nResolution result indicating that the import resolves to a specific file, possible in a nodeModule, with\nthe path of that file and the name of the nodeModule if applicable" + ], + "path": "packages/kbn-import-resolver/src/resolve_result.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.FileResult.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"file\"" + ], + "path": "packages/kbn-import-resolver/src/resolve_result.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.FileResult.absolute", + "type": "string", + "tags": [], + "label": "absolute", + "description": [], + "path": "packages/kbn-import-resolver/src/resolve_result.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.FileResult.nodeModule", + "type": "string", + "tags": [], + "label": "nodeModule", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-import-resolver/src/resolve_result.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.FileResult.prefix", + "type": "string", + "tags": [], + "label": "prefix", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-import-resolver/src/resolve_result.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.FileResult.postfix", + "type": "string", + "tags": [], + "label": "postfix", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-import-resolver/src/resolve_result.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.IgnoreResult", + "type": "Interface", + "tags": [], + "label": "IgnoreResult", + "description": [ + "\nResolution result indicating that the import request can't be resolved, but it shouldn't need to be\nbecause the file that is imported can't be resolved from the source alone, usually because it is explicitly\nimporting a build asset. Import requests which meet this criteria are manually added to the resolver and\ncan be trusted to exist after the build it complete or in their used location." + ], + "path": "packages/kbn-import-resolver/src/resolve_result.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.IgnoreResult.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"ignore\"" + ], + "path": "packages/kbn-import-resolver/src/resolve_result.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.OptionalDepResult", + "type": "Interface", + "tags": [], + "label": "OptionalDepResult", + "description": [ + "\nResolution result indicating that the import request resolves to an npm dep which isn't\ncurrently installed so assumed to be optional" + ], + "path": "packages/kbn-import-resolver/src/resolve_result.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.OptionalDepResult.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"optional-and-missing\"" + ], + "path": "packages/kbn-import-resolver/src/resolve_result.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.TypesResult", + "type": "Interface", + "tags": [], + "label": "TypesResult", + "description": [ + "\nResolution result indicating that the import only resolves to an @types package, including the name of\nthe @types package. We don't validate the sub-path of these import strings and assume that TS will validate\nthem, we just need to know that they don't map to actual files on the filesystem or modules which will\nend up in the build or running code." + ], + "path": "packages/kbn-import-resolver/src/resolve_result.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.TypesResult.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"@types\"" + ], + "path": "packages/kbn-import-resolver/src/resolve_result.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.TypesResult.module", + "type": "string", + "tags": [], + "label": "module", + "description": [], + "path": "packages/kbn-import-resolver/src/resolve_result.ts", + "deprecated": false + } + ], + "initialIsOpen": false + } + ], + "enums": [], + "misc": [ + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.ImportType", + "type": "Type", + "tags": [], + "label": "ImportType", + "description": [], + "signature": [ + "\"esm\" | \"require\" | \"require-resolve\" | \"jest\"" + ], + "path": "packages/kbn-import-resolver/src/helpers/import_req.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/import-resolver", + "id": "def-server.ResolveResult", + "type": "Type", + "tags": [], + "label": "ResolveResult", + "description": [ + "\nPossible resolve result types" + ], + "signature": [ + { + "pluginId": "@kbn/import-resolver", + "scope": "server", + "docId": "kibKbnImportResolverPluginApi", + "section": "def-server.BuiltInResult", + "text": "BuiltInResult" + }, + " | ", + { + "pluginId": "@kbn/import-resolver", + "scope": "server", + "docId": "kibKbnImportResolverPluginApi", + "section": "def-server.IgnoreResult", + "text": "IgnoreResult" + }, + " | ", + { + "pluginId": "@kbn/import-resolver", + "scope": "server", + "docId": "kibKbnImportResolverPluginApi", + "section": "def-server.TypesResult", + "text": "TypesResult" + }, + " | ", + { + "pluginId": "@kbn/import-resolver", + "scope": "server", + "docId": "kibKbnImportResolverPluginApi", + "section": "def-server.FileResult", + "text": "FileResult" + }, + " | ", + { + "pluginId": "@kbn/import-resolver", + "scope": "server", + "docId": "kibKbnImportResolverPluginApi", + "section": "def-server.OptionalDepResult", + "text": "OptionalDepResult" + } + ], + "path": "packages/kbn-import-resolver/src/resolve_result.ts", + "deprecated": false, + "initialIsOpen": false + } + ], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_import_resolver.mdx b/api_docs/kbn_import_resolver.mdx new file mode 100644 index 0000000000000..ea7b7ff9aba1d --- /dev/null +++ b/api_docs/kbn_import_resolver.mdx @@ -0,0 +1,36 @@ +--- +id: kibKbnImportResolverPluginApi +slug: /kibana-dev-docs/api/kbn-import-resolver +title: "@kbn/import-resolver" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the @kbn/import-resolver plugin +date: 2022-04-26 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 43 | 0 | 36 | 0 | + +## Server + +### Functions + + +### Classes + + +### Interfaces + + +### Consts, variables and types + + diff --git a/api_docs/kbn_interpreter.mdx b/api_docs/kbn_interpreter.mdx index d07e5a0a44859..7a6b18efd63c5 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/interpreter plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_io_ts_utils.devdocs.json b/api_docs/kbn_io_ts_utils.devdocs.json index 6a4ae05e82231..0eac86c5269a4 100644 --- a/api_docs/kbn_io_ts_utils.devdocs.json +++ b/api_docs/kbn_io_ts_utils.devdocs.json @@ -59,10 +59,10 @@ " | ", "StringType", " | ", - "NumberType", - " | ", "BooleanType", " | ", + "NumberType", + " | ", "RecordC", "<", "Mixed", diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index 2e6530549dee3..0890c33d45907 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/io-ts-utils plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_jest_serializers.devdocs.json b/api_docs/kbn_jest_serializers.devdocs.json new file mode 100644 index 0000000000000..f4595b16f9025 --- /dev/null +++ b/api_docs/kbn_jest_serializers.devdocs.json @@ -0,0 +1,224 @@ +{ + "id": "@kbn/jest-serializers", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [ + { + "parentPluginId": "@kbn/jest-serializers", + "id": "def-server.createAbsolutePathSerializer", + "type": "Function", + "tags": [], + "label": "createAbsolutePathSerializer", + "description": [], + "signature": [ + "(rootPath: string, replacement: string) => { test: (value: any) => boolean; serialize: (value: string) => string; }" + ], + "path": "packages/kbn-jest-serializers/src/absolute_path_serializer.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/jest-serializers", + "id": "def-server.createAbsolutePathSerializer.$1", + "type": "string", + "tags": [], + "label": "rootPath", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-jest-serializers/src/absolute_path_serializer.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/jest-serializers", + "id": "def-server.createAbsolutePathSerializer.$2", + "type": "string", + "tags": [], + "label": "replacement", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-jest-serializers/src/absolute_path_serializer.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/jest-serializers", + "id": "def-server.createAnyInstanceSerializer", + "type": "Function", + "tags": [], + "label": "createAnyInstanceSerializer", + "description": [], + "signature": [ + "(Class: Function, name: string | ((instance: any) => string) | undefined) => { test: (v: any) => boolean; serialize: (v: any) => string; }" + ], + "path": "packages/kbn-jest-serializers/src/any_instance_serizlizer.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/jest-serializers", + "id": "def-server.createAnyInstanceSerializer.$1", + "type": "Object", + "tags": [], + "label": "Class", + "description": [], + "signature": [ + "Function" + ], + "path": "packages/kbn-jest-serializers/src/any_instance_serizlizer.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/jest-serializers", + "id": "def-server.createAnyInstanceSerializer.$2", + "type": "CompoundType", + "tags": [], + "label": "name", + "description": [], + "signature": [ + "string | ((instance: any) => string) | undefined" + ], + "path": "packages/kbn-jest-serializers/src/any_instance_serizlizer.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/jest-serializers", + "id": "def-server.createRecursiveSerializer", + "type": "Function", + "tags": [], + "label": "createRecursiveSerializer", + "description": [], + "signature": [ + "(test: (v: any) => boolean, print: (v: any, printRaw: (v: string) => RawPrint) => string | RawPrint) => { test: (v: any) => boolean; serialize: (v: any, ...rest: any[]) => any; }" + ], + "path": "packages/kbn-jest-serializers/src/recursive_serializer.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/jest-serializers", + "id": "def-server.createRecursiveSerializer.$1", + "type": "Function", + "tags": [], + "label": "test", + "description": [], + "signature": [ + "(v: any) => boolean" + ], + "path": "packages/kbn-jest-serializers/src/recursive_serializer.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/jest-serializers", + "id": "def-server.createRecursiveSerializer.$2", + "type": "Function", + "tags": [], + "label": "print", + "description": [], + "signature": [ + "(v: any, printRaw: (v: string) => RawPrint) => string | RawPrint" + ], + "path": "packages/kbn-jest-serializers/src/recursive_serializer.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/jest-serializers", + "id": "def-server.createReplaceSerializer", + "type": "Function", + "tags": [], + "label": "createReplaceSerializer", + "description": [], + "signature": [ + "(toReplace: string | RegExp, replaceWith: string | Replacer) => { test: (v: any) => boolean; serialize: (v: any, ...rest: any[]) => any; }" + ], + "path": "packages/kbn-jest-serializers/src/replace_serializer.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/jest-serializers", + "id": "def-server.createReplaceSerializer.$1", + "type": "CompoundType", + "tags": [], + "label": "toReplace", + "description": [], + "signature": [ + "string | RegExp" + ], + "path": "packages/kbn-jest-serializers/src/replace_serializer.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/jest-serializers", + "id": "def-server.createReplaceSerializer.$2", + "type": "CompoundType", + "tags": [], + "label": "replaceWith", + "description": [], + "signature": [ + "string | Replacer" + ], + "path": "packages/kbn-jest-serializers/src/replace_serializer.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/jest-serializers", + "id": "def-server.createStripAnsiSerializer", + "type": "Function", + "tags": [], + "label": "createStripAnsiSerializer", + "description": [], + "signature": [ + "() => { test: (v: any) => boolean; serialize: (v: any, ...rest: any[]) => any; }" + ], + "path": "packages/kbn-jest-serializers/src/strip_ansi_serializer.ts", + "deprecated": false, + "children": [], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx new file mode 100644 index 0000000000000..f9e1f71dc7804 --- /dev/null +++ b/api_docs/kbn_jest_serializers.mdx @@ -0,0 +1,27 @@ +--- +id: kibKbnJestSerializersPluginApi +slug: /kibana-dev-docs/api/kbn-jest-serializers +title: "@kbn/jest-serializers" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the @kbn/jest-serializers plugin +date: 2022-04-26 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/jest-serializers'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import kbnJestSerializersObj from './kbn_jest_serializers.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 13 | 0 | 13 | 0 | + +## Server + +### Functions + + diff --git a/api_docs/kbn_kibana_json_schema.devdocs.json b/api_docs/kbn_kibana_json_schema.devdocs.json new file mode 100644 index 0000000000000..0cc8a1e25feb5 --- /dev/null +++ b/api_docs/kbn_kibana_json_schema.devdocs.json @@ -0,0 +1,844 @@ +{ + "id": "@kbn/kibana-json-schema", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema", + "type": "Object", + "tags": [], + "label": "KibanaJsonSchema", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"object\"" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.required", + "type": "Array", + "tags": [], + "label": "required", + "description": [], + "signature": [ + "string[]" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties", + "type": "Object", + "tags": [], + "label": "properties", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.id", + "type": "Object", + "tags": [], + "label": "id", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.id.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.id.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"string\"" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.id.pattern", + "type": "string", + "tags": [], + "label": "pattern", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.version", + "type": "Object", + "tags": [], + "label": "version", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.version.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.version.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"string\"" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.version.pattern", + "type": "string", + "tags": [], + "label": "pattern", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.kibanaVersion", + "type": "Object", + "tags": [], + "label": "kibanaVersion", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.kibanaVersion.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.kibanaVersion.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"string\"" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.kibanaVersion.pattern", + "type": "string", + "tags": [], + "label": "pattern", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.type", + "type": "Object", + "tags": [], + "label": "type", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.type.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.type.enum", + "type": "Array", + "tags": [], + "label": "enum", + "description": [], + "signature": [ + "string[]" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.configPath", + "type": "Object", + "tags": [], + "label": "configPath", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.configPath.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.configPath.oneOf", + "type": "Array", + "tags": [], + "label": "oneOf", + "description": [], + "signature": [ + "({ type: \"string\"; } | { type: \"array\"; items: { type: \"string\"; }; })[]" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.requiredPlugins", + "type": "Object", + "tags": [], + "label": "requiredPlugins", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.requiredPlugins.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.requiredPlugins.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"array\"" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.requiredPlugins.items", + "type": "Object", + "tags": [], + "label": "items", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.requiredPlugins.items.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"string\"" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + } + ] + } + ] + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.optionalPlugins", + "type": "Object", + "tags": [], + "label": "optionalPlugins", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.optionalPlugins.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.optionalPlugins.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"array\"" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.optionalPlugins.items", + "type": "Object", + "tags": [], + "label": "items", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.optionalPlugins.items.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"string\"" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + } + ] + } + ] + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.requiredBundles", + "type": "Object", + "tags": [], + "label": "requiredBundles", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.requiredBundles.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.requiredBundles.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"array\"" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.requiredBundles.items", + "type": "Object", + "tags": [], + "label": "items", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.requiredBundles.items.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"string\"" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + } + ] + } + ] + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.ui", + "type": "Object", + "tags": [], + "label": "ui", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.ui.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.ui.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"boolean\"" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.server", + "type": "Object", + "tags": [], + "label": "server", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.server.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.server.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"boolean\"" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.extraPublicDirs", + "type": "Object", + "tags": [], + "label": "extraPublicDirs", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.extraPublicDirs.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.extraPublicDirs.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"array\"" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.extraPublicDirs.items", + "type": "Object", + "tags": [], + "label": "items", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.extraPublicDirs.items.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"string\"" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + } + ] + } + ] + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.serviceFolders", + "type": "Object", + "tags": [], + "label": "serviceFolders", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.serviceFolders.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.serviceFolders.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"array\"" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.serviceFolders.items", + "type": "Object", + "tags": [], + "label": "items", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.serviceFolders.items.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"string\"" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + } + ] + } + ] + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.owner", + "type": "Object", + "tags": [], + "label": "owner", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.owner.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"object\"" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.owner.required", + "type": "Array", + "tags": [], + "label": "required", + "description": [], + "signature": [ + "string[]" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.owner.properties", + "type": "Object", + "tags": [], + "label": "properties", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.owner.properties.name", + "type": "Object", + "tags": [], + "label": "name", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.owner.properties.name.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.owner.properties.name.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"string\"" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.owner.properties.githubTeam", + "type": "Object", + "tags": [], + "label": "githubTeam", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.owner.properties.githubTeam.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.owner.properties.githubTeam.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"string\"" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + } + ] + } + ] + } + ] + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.description", + "type": "Object", + "tags": [], + "label": "description", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.description.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.description.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"string\"" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.enabledOnAnonymousPages", + "type": "Object", + "tags": [], + "label": "enabledOnAnonymousPages", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.enabledOnAnonymousPages.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/kibana-json-schema", + "id": "def-server.KibanaJsonSchema.properties.enabledOnAnonymousPages.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"boolean\"" + ], + "path": "packages/kbn-kibana-json-schema/src/kibana_json_schema.ts", + "deprecated": false + } + ] + } + ] + } + ], + "initialIsOpen": false + } + ] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_kibana_json_schema.mdx b/api_docs/kbn_kibana_json_schema.mdx new file mode 100644 index 0000000000000..16776b0a20e55 --- /dev/null +++ b/api_docs/kbn_kibana_json_schema.mdx @@ -0,0 +1,27 @@ +--- +id: kibKbnKibanaJsonSchemaPluginApi +slug: /kibana-dev-docs/api/kbn-kibana-json-schema +title: "@kbn/kibana-json-schema" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the @kbn/kibana-json-schema plugin +date: 2022-04-26 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-json-schema'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import kbnKibanaJsonSchemaObj from './kbn_kibana_json_schema.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 69 | 0 | 69 | 0 | + +## Server + +### Objects + + diff --git a/api_docs/kbn_logging.devdocs.json b/api_docs/kbn_logging.devdocs.json index f9bca4daaf11f..00bfe3a5f742b 100644 --- a/api_docs/kbn_logging.devdocs.json +++ b/api_docs/kbn_logging.devdocs.json @@ -644,7 +644,7 @@ "label": "EcsEventOutcome", "description": [], "signature": [ - "\"unknown\" | \"success\" | \"failure\"" + "\"success\" | \"unknown\" | \"failure\"" ], "path": "packages/kbn-logging/src/ecs/event.ts", "deprecated": false, @@ -658,7 +658,7 @@ "label": "EcsEventType", "description": [], "signature": [ - "\"start\" | \"user\" | \"error\" | \"info\" | \"group\" | \"end\" | \"protocol\" | \"connection\" | \"access\" | \"admin\" | \"allowed\" | \"change\" | \"creation\" | \"deletion\" | \"denied\" | \"installation\"" + "\"start\" | \"error\" | \"user\" | \"info\" | \"group\" | \"end\" | \"admin\" | \"protocol\" | \"connection\" | \"access\" | \"allowed\" | \"change\" | \"creation\" | \"deletion\" | \"denied\" | \"installation\"" ], "path": "packages/kbn-logging/src/ecs/event.ts", "deprecated": false, diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index 071f96e712bb7..d1bd851ab5758 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/logging plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_logging_mocks.mdx b/api_docs/kbn_logging_mocks.mdx index 3eee38ebb640b..490414113832e 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/logging-mocks plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_mapbox_gl.devdocs.json b/api_docs/kbn_mapbox_gl.devdocs.json index e7df5d6118ad9..845de56441c91 100644 --- a/api_docs/kbn_mapbox_gl.devdocs.json +++ b/api_docs/kbn_mapbox_gl.devdocs.json @@ -12,77 +12,276 @@ "classes": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLat", + "id": "def-server.GeoJSONSource", "type": "Class", "tags": [], - "label": "LngLat", - "description": [ - "\nLngLat" - ], + "label": "GeoJSONSource", + "description": [], "signature": [ - "maplibregl.LngLat" + "maplibregl.GeoJSONSource extends maplibregl.Evented implements maplibregl.Source" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLat.lng", + "id": "def-server.GeoJSONSource.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"geojson\"" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource.minzoom", "type": "number", "tags": [], - "label": "lng", + "label": "minzoom", "description": [], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLat.lat", + "id": "def-server.GeoJSONSource.maxzoom", "type": "number", "tags": [], - "label": "lat", + "label": "maxzoom", "description": [], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLat.Unnamed", - "type": "Function", + "id": "def-server.GeoJSONSource.tileSize", + "type": "number", + "tags": [], + "label": "tileSize", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource.attribution", + "type": "string", + "tags": [], + "label": "attribution", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource.promoteId", + "type": "CompoundType", + "tags": [], + "label": "promoteId", + "description": [], + "signature": [ + "string | { [_: string]: string; }" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource.isTileClipped", + "type": "boolean", + "tags": [], + "label": "isTileClipped", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource.reparseOverscaled", + "type": "boolean", + "tags": [], + "label": "reparseOverscaled", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource._data", + "type": "CompoundType", + "tags": [], + "label": "_data", + "description": [], + "signature": [ + "string | GeoJSON.GeoJSON" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource._options", + "type": "Any", + "tags": [], + "label": "_options", + "description": [], + "signature": [ + "any" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource.workerOptions", + "type": "Any", + "tags": [], + "label": "workerOptions", + "description": [], + "signature": [ + "any" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource.map", + "type": "Object", + "tags": [], + "label": "map", + "description": [], + "signature": [ + "maplibregl.Map" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource.actor", + "type": "Object", + "tags": [], + "label": "actor", + "description": [], + "signature": [ + "maplibregl.Actor" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource._pendingLoads", + "type": "number", + "tags": [], + "label": "_pendingLoads", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource._collectResourceTiming", + "type": "boolean", + "tags": [], + "label": "_collectResourceTiming", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource._removed", + "type": "boolean", "tags": [], + "label": "_removed", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource.Unnamed", + "type": "Function", + "tags": [ + "private" + ], "label": "Constructor", "description": [], "signature": [ "any" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLat.Unnamed.$1", - "type": "number", + "id": "def-server.GeoJSONSource.Unnamed.$1", + "type": "string", "tags": [], - "label": "lng", + "label": "id", "description": [], "signature": [ - "number" + "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLat.Unnamed.$2", - "type": "number", + "id": "def-server.GeoJSONSource.Unnamed.$2", + "type": "CompoundType", "tags": [], - "label": "lat", + "label": "options", "description": [], "signature": [ - "number" + "maplibregl.GeoJSONSourceOptions" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource.Unnamed.$3", + "type": "Object", + "tags": [], + "label": "dispatcher", + "description": [], + "signature": [ + "maplibregl.Dispatcher" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource.Unnamed.$4", + "type": "Object", + "tags": [], + "label": "eventedParent", + "description": [], + "signature": [ + "maplibregl.Evented" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } @@ -91,81 +290,43 @@ }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLat.wrap", - "type": "Function", - "tags": [], - "label": "wrap", - "description": [ - "Return a new LngLat object whose longitude is wrapped to the range (-180, 180)." - ], - "signature": [ - "() => maplibregl.LngLat" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLat.toArray", - "type": "Function", - "tags": [], - "label": "toArray", - "description": [ - "Return a LngLat as an array" - ], - "signature": [ - "() => number[]" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLat.toString", + "id": "def-server.GeoJSONSource.load", "type": "Function", "tags": [], - "label": "toString", - "description": [ - "Return a LngLat as a string" - ], + "label": "load", + "description": [], "signature": [ - "() => string" + "() => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [], "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLat.distanceTo", + "id": "def-server.GeoJSONSource.onAdd", "type": "Function", "tags": [], - "label": "distanceTo", - "description": [ - "Returns the approximate distance between a pair of coordinates in meters\nUses the Haversine Formula (from R.W. Sinnott, \"Virtues of the Haversine\", Sky and Telescope, vol. 68, no. 2, 1984, p. 159)" - ], + "label": "onAdd", + "description": [], "signature": [ - "(lngLat: maplibregl.LngLat) => number" + "(map: maplibregl.Map) => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLat.distanceTo.$1", + "id": "def-server.GeoJSONSource.onAdd.$1", "type": "Object", "tags": [], - "label": "lngLat", + "label": "map", "description": [], "signature": [ - "maplibregl.LngLat" + "maplibregl.Map" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } @@ -174,206 +335,252 @@ }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLat.toBounds", + "id": "def-server.GeoJSONSource.setData", "type": "Function", "tags": [], - "label": "toBounds", - "description": [], + "label": "setData", + "description": [ + "\nSets the GeoJSON data and re-renders the map.\n" + ], "signature": [ - "(radius: number) => maplibregl.LngLatBounds" + "(data: string | GeoJSON.GeoJSON) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLat.toBounds.$1", - "type": "number", + "id": "def-server.GeoJSONSource.setData.$1", + "type": "CompoundType", "tags": [], - "label": "radius", - "description": [], + "label": "data", + "description": [ + "A GeoJSON data object or a URL to one. The latter is preferable in the case of large GeoJSON files." + ], "signature": [ - "number" + "string | GeoJSON.GeoJSON" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "this" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLat.convert", + "id": "def-server.GeoJSONSource.getClusterExpansionZoom", "type": "Function", "tags": [], - "label": "convert", - "description": [], + "label": "getClusterExpansionZoom", + "description": [ + "\nFor clustered sources, fetches the zoom at which the given cluster expands.\n" + ], "signature": [ - "(input: maplibregl.LngLatLike) => maplibregl.LngLat" + "(clusterId: number, callback: maplibregl.Callback) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLat.convert.$1", - "type": "CompoundType", + "id": "def-server.GeoJSONSource.getClusterExpansionZoom.$1", + "type": "number", "tags": [], - "label": "input", - "description": [], + "label": "clusterId", + "description": [ + "The value of the cluster's `cluster_id` property." + ], "signature": [ - "maplibregl.LngLatLike" + "number" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource.getClusterExpansionZoom.$2", + "type": "Function", + "tags": [], + "label": "callback", + "description": [ + "A callback to be called when the zoom value is retrieved (`(error, zoom) => { ... }`)." + ], + "signature": [ + "maplibregl.Callback" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } ], - "returnComment": [] - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds", - "type": "Class", - "tags": [], - "label": "LngLatBounds", - "description": [ - "\nLngLatBounds" - ], - "signature": [ - "maplibregl.LngLatBounds" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.sw", - "type": "CompoundType", - "tags": [], - "label": "sw", - "description": [], - "signature": [ - "[number, number] | maplibregl.LngLat | { lng: number; lat: number; } | { lon: number; lat: number; }" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.ne", - "type": "CompoundType", - "tags": [], - "label": "ne", - "description": [], - "signature": [ - "[number, number] | maplibregl.LngLat | { lng: number; lat: number; } | { lon: number; lat: number; }" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "returnComment": [ + "this" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.Unnamed", + "id": "def-server.GeoJSONSource.getClusterChildren", "type": "Function", "tags": [], - "label": "Constructor", - "description": [], + "label": "getClusterChildren", + "description": [ + "\nFor clustered sources, fetches the children of the given cluster on the next zoom level (as an array of GeoJSON features).\n" + ], "signature": [ - "any" + "(clusterId: number, callback: maplibregl.Callback[]>) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.Unnamed.$1", - "type": "CompoundType", + "id": "def-server.GeoJSONSource.getClusterChildren.$1", + "type": "number", "tags": [], - "label": "boundsLike", - "description": [], + "label": "clusterId", + "description": [ + "The value of the cluster's `cluster_id` property." + ], "signature": [ - "[number, number, number, number] | [maplibregl.LngLatLike, maplibregl.LngLatLike] | undefined" + "number" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": false + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource.getClusterChildren.$2", + "type": "Function", + "tags": [], + "label": "callback", + "description": [ + "A callback to be called when the features are retrieved (`(error, features) => { ... }`)." + ], + "signature": [ + "maplibregl.Callback[]>" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "this" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.Unnamed", + "id": "def-server.GeoJSONSource.getClusterLeaves", "type": "Function", "tags": [], - "label": "Constructor", - "description": [], + "label": "getClusterLeaves", + "description": [ + "\nFor clustered sources, fetches the original points that belong to the cluster (as an array of GeoJSON features).\n" + ], "signature": [ - "any" + "(clusterId: number, limit: number, offset: number, callback: maplibregl.Callback[]>) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.Unnamed.$1", - "type": "CompoundType", + "id": "def-server.GeoJSONSource.getClusterLeaves.$1", + "type": "number", "tags": [], - "label": "sw", - "description": [], + "label": "clusterId", + "description": [ + "The value of the cluster's `cluster_id` property." + ], "signature": [ - "maplibregl.LngLatLike" + "number" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.Unnamed.$2", - "type": "CompoundType", + "id": "def-server.GeoJSONSource.getClusterLeaves.$2", + "type": "number", "tags": [], - "label": "ne", - "description": [], + "label": "limit", + "description": [ + "The maximum number of features to return." + ], "signature": [ - "maplibregl.LngLatLike" + "number" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource.getClusterLeaves.$3", + "type": "number", + "tags": [], + "label": "offset", + "description": [ + "The number of features to skip (e.g. for pagination)." + ], + "signature": [ + "number" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource.getClusterLeaves.$4", + "type": "Function", + "tags": [], + "label": "callback", + "description": [ + "A callback to be called when the features are retrieved (`(error, features) => { ... }`)." + ], + "signature": [ + "maplibregl.Callback[]>" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "this" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.setNorthEast", + "id": "def-server.GeoJSONSource._updateWorkerData", "type": "Function", "tags": [], - "label": "setNorthEast", + "label": "_updateWorkerData", "description": [], "signature": [ - "(ne: maplibregl.LngLatLike) => this" + "(sourceDataType: maplibregl.MapSourceDataType) => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.setNorthEast.$1", + "id": "def-server.GeoJSONSource._updateWorkerData.$1", "type": "CompoundType", "tags": [], - "label": "ne", + "label": "sourceDataType", "description": [], "signature": [ - "maplibregl.LngLatLike" + "maplibregl.MapSourceDataType" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } @@ -382,28 +589,57 @@ }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.setSouthWest", + "id": "def-server.GeoJSONSource.loaded", "type": "Function", "tags": [], - "label": "setSouthWest", + "label": "loaded", "description": [], "signature": [ - "(sw: maplibregl.LngLatLike) => this" + "() => boolean" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource.loadTile", + "type": "Function", + "tags": [], + "label": "loadTile", + "description": [], + "signature": [ + "(tile: maplibregl.Tile, callback: maplibregl.Callback) => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.setSouthWest.$1", - "type": "CompoundType", + "id": "def-server.GeoJSONSource.loadTile.$1", + "type": "Object", "tags": [], - "label": "sw", + "label": "tile", "description": [], "signature": [ - "maplibregl.LngLatLike" + "maplibregl.Tile" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.GeoJSONSource.loadTile.$2", + "type": "Function", + "tags": [], + "label": "callback", + "description": [], + "signature": [ + "maplibregl.Callback" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } @@ -412,30 +648,28 @@ }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.contains", + "id": "def-server.GeoJSONSource.abortTile", "type": "Function", "tags": [], - "label": "contains", - "description": [ - "Check if the point is within the bounding box." - ], + "label": "abortTile", + "description": [], "signature": [ - "(lnglat: maplibregl.LngLatLike) => boolean" + "(tile: maplibregl.Tile) => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.contains.$1", - "type": "CompoundType", + "id": "def-server.GeoJSONSource.abortTile.$1", + "type": "Object", "tags": [], - "label": "lnglat", + "label": "tile", "description": [], "signature": [ - "maplibregl.LngLatLike" + "maplibregl.Tile" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } @@ -444,30 +678,28 @@ }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.extend", + "id": "def-server.GeoJSONSource.unloadTile", "type": "Function", "tags": [], - "label": "extend", - "description": [ - "Extend the bounds to include a given LngLat or LngLatBounds." - ], + "label": "unloadTile", + "description": [], "signature": [ - "(obj: [number, number] | [number, number, number, number] | maplibregl.LngLatBounds | [maplibregl.LngLatLike, maplibregl.LngLatLike] | maplibregl.LngLat | { lng: number; lat: number; } | { lon: number; lat: number; }) => this" + "(tile: maplibregl.Tile) => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.extend.$1", - "type": "CompoundType", + "id": "def-server.GeoJSONSource.unloadTile.$1", + "type": "Object", "tags": [], - "label": "obj", + "label": "tile", "description": [], "signature": [ - "[number, number] | [number, number, number, number] | maplibregl.LngLatBounds | [maplibregl.LngLatLike, maplibregl.LngLatLike] | maplibregl.LngLat | { lng: number; lat: number; } | { lon: number; lat: number; }" + "maplibregl.Tile" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } @@ -476,1942 +708,2184 @@ }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.getCenter", + "id": "def-server.GeoJSONSource.onRemove", "type": "Function", "tags": [], - "label": "getCenter", - "description": [ - "Get the point equidistant from this box's corners" - ], + "label": "onRemove", + "description": [], "signature": [ - "() => maplibregl.LngLat" + "() => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [], "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.getSouthWest", + "id": "def-server.GeoJSONSource.serialize", "type": "Function", "tags": [], - "label": "getSouthWest", - "description": [ - "Get southwest corner" - ], + "label": "serialize", + "description": [], "signature": [ - "() => maplibregl.LngLat" + "() => any" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [], "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.getNorthEast", + "id": "def-server.GeoJSONSource.hasTransition", "type": "Function", "tags": [], - "label": "getNorthEast", - "description": [ - "Get northeast corner" - ], + "label": "hasTransition", + "description": [], "signature": [ - "() => maplibregl.LngLat" + "() => boolean" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [], "returnComment": [] - }, + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.LngLat", + "type": "Class", + "tags": [], + "label": "LngLat", + "description": [], + "signature": [ + "maplibregl.LngLat" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.getNorthWest", - "type": "Function", + "id": "def-server.LngLat.lng", + "type": "number", "tags": [], - "label": "getNorthWest", - "description": [ - "Get northwest corner" - ], - "signature": [ - "() => maplibregl.LngLat" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] + "label": "lng", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.getSouthEast", - "type": "Function", + "id": "def-server.LngLat.lat", + "type": "number", "tags": [], - "label": "getSouthEast", - "description": [ - "Get southeast corner" - ], - "signature": [ - "() => maplibregl.LngLat" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] + "label": "lat", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.getWest", + "id": "def-server.LngLat.Unnamed", "type": "Function", "tags": [], - "label": "getWest", - "description": [ - "Get west edge longitude" - ], + "label": "Constructor", + "description": [], "signature": [ - "() => number" + "any" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.getSouth", - "type": "Function", - "tags": [], - "label": "getSouth", - "description": [ - "Get south edge latitude" - ], - "signature": [ - "() => number" + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.LngLat.Unnamed.$1", + "type": "number", + "tags": [], + "label": "lng", + "description": [], + "signature": [ + "number" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.LngLat.Unnamed.$2", + "type": "number", + "tags": [], + "label": "lat", + "description": [], + "signature": [ + "number" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.getEast", + "id": "def-server.LngLat.wrap", "type": "Function", "tags": [], - "label": "getEast", + "label": "wrap", "description": [ - "Get east edge longitude" + "\nReturns a new `LngLat` object whose longitude is wrapped to the range (-180, 180).\n" ], "signature": [ - "() => number" + "() => maplibregl.LngLat" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The wrapped `LngLat` object." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.getNorth", + "id": "def-server.LngLat.toArray", "type": "Function", "tags": [], - "label": "getNorth", + "label": "toArray", "description": [ - "Get north edge latitude" + "\nReturns the coordinates represented as an array of two numbers.\n" ], "signature": [ - "() => number" + "() => number[]" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The coordinates represeted as an array of longitude and latitude." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.toArray", + "id": "def-server.LngLat.toString", "type": "Function", "tags": [], - "label": "toArray", + "label": "toString", "description": [ - "Returns a LngLatBounds as an array" + "\nReturns the coordinates represent as a string.\n" ], "signature": [ - "() => number[][]" + "() => string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The coordinates represented as a string of the format `'LngLat(lng, lat)'`." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.toString", + "id": "def-server.LngLat.distanceTo", "type": "Function", "tags": [], - "label": "toString", + "label": "distanceTo", "description": [ - "Return a LngLatBounds as a string" + "\nReturns the approximate distance between a pair of coordinates in meters\nUses the Haversine Formula (from R.W. Sinnott, \"Virtues of the Haversine\", Sky and Telescope, vol. 68, no. 2, 1984, p. 159)\n" ], "signature": [ - "() => string" + "(lngLat: maplibregl.LngLat) => number" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "children": [], - "returnComment": [] + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.LngLat.distanceTo.$1", + "type": "Object", + "tags": [], + "label": "lngLat", + "description": [ + "coordinates to compute the distance to" + ], + "signature": [ + "maplibregl.LngLat" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [ + "Distance in meters between the two coordinates." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.isEmpty", + "id": "def-server.LngLat.toBounds", "type": "Function", "tags": [], - "label": "isEmpty", + "label": "toBounds", "description": [ - "Returns a boolean" + "\nReturns a `LngLatBounds` from the coordinates extended by a given `radius`. The returned `LngLatBounds` completely contains the `radius`.\n" ], "signature": [ - "() => boolean" + "(radius?: number | undefined) => maplibregl.LngLatBounds" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "children": [], - "returnComment": [] + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.LngLat.toBounds.$1", + "type": "number", + "tags": [], + "label": "radius", + "description": [ + "Distance in meters from the coordinates to extend the bounds." + ], + "signature": [ + "number | undefined" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [ + "A new `LngLatBounds` object representing the coordinates extended by the `radius`." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.convert", + "id": "def-server.LngLat.convert", "type": "Function", "tags": [], "label": "convert", "description": [ - "Convert an array to a LngLatBounds object, or return an existing LngLatBounds object unchanged." + "\nConverts an array of two numbers or an object with `lng` and `lat` or `lon` and `lat` properties\nto a `LngLat` object.\n\nIf a `LngLat` object is passed in, the function returns it unchanged.\n" ], "signature": [ - "(input: maplibregl.LngLatBoundsLike) => maplibregl.LngLatBounds" + "(input: maplibregl.LngLatLike) => maplibregl.LngLat" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.LngLatBounds.convert.$1", + "id": "def-server.LngLat.convert.$1", "type": "CompoundType", "tags": [], "label": "input", - "description": [], + "description": [ + "An array of two numbers or object to convert, or a `LngLat` object to return." + ], "signature": [ - "maplibregl.LngLatBoundsLike" + "maplibregl.LngLatLike" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "A new `LngLat` object, if a conversion occurred, or the original `LngLat` object." + ] } ], "initialIsOpen": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map", + "id": "def-server.LngLatBounds", "type": "Class", "tags": [], - "label": "Map", - "description": [ - "\nMap" - ], + "label": "LngLatBounds", + "description": [], "signature": [ - "maplibregl.Map extends maplibregl.Evented" + "maplibregl.LngLatBounds" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.Unnamed", - "type": "Function", + "id": "def-server.LngLatBounds._ne", + "type": "Object", "tags": [], - "label": "Constructor", + "label": "_ne", "description": [], "signature": [ - "any" + "maplibregl.LngLat" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.Unnamed.$1", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "signature": [ - "maplibregl.MapboxOptions | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": false - } + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.LngLatBounds._sw", + "type": "Object", + "tags": [], + "label": "_sw", + "description": [], + "signature": [ + "maplibregl.LngLat" ], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.addControl", + "id": "def-server.LngLatBounds.Unnamed", "type": "Function", "tags": [], - "label": "addControl", + "label": "Constructor", "description": [], "signature": [ - "(control: maplibregl.Control | maplibregl.IControl, position?: \"top-right\" | \"top-left\" | \"bottom-right\" | \"bottom-left\" | undefined) => this" + "any" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.addControl.$1", - "type": "CompoundType", + "id": "def-server.LngLatBounds.Unnamed.$1", + "type": "Any", "tags": [], - "label": "control", + "label": "sw", "description": [], "signature": [ - "maplibregl.Control | maplibregl.IControl" + "any" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.addControl.$2", - "type": "CompoundType", + "id": "def-server.LngLatBounds.Unnamed.$2", + "type": "Any", "tags": [], - "label": "position", + "label": "ne", "description": [], "signature": [ - "\"top-right\" | \"top-left\" | \"bottom-right\" | \"bottom-left\" | undefined" + "any" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": false + "isRequired": true } ], "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.removeControl", + "id": "def-server.LngLatBounds.setNorthEast", "type": "Function", "tags": [], - "label": "removeControl", - "description": [], + "label": "setNorthEast", + "description": [ + "\nSet the northeast corner of the bounding box\n" + ], "signature": [ - "(control: maplibregl.Control | maplibregl.IControl) => this" + "(ne: maplibregl.LngLatLike) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.removeControl.$1", + "id": "def-server.LngLatBounds.setNorthEast.$1", "type": "CompoundType", "tags": [], - "label": "control", - "description": [], + "label": "ne", + "description": [ + "a {@link LngLatLike } object describing the northeast corner of the bounding box." + ], "signature": [ - "maplibregl.Control | maplibregl.IControl" + "maplibregl.LngLatLike" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "`this`" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.hasControl", + "id": "def-server.LngLatBounds.setSouthWest", "type": "Function", "tags": [], - "label": "hasControl", + "label": "setSouthWest", "description": [ - "\nChecks if a control exists on the map.\n" + "\nSet the southwest corner of the bounding box\n" ], "signature": [ - "(control: maplibregl.IControl) => boolean" + "(sw: maplibregl.LngLatLike) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.hasControl.$1", - "type": "Object", + "id": "def-server.LngLatBounds.setSouthWest.$1", + "type": "CompoundType", "tags": [], - "label": "control", + "label": "sw", "description": [ - "The {@link IControl } to check." + "a {@link LngLatLike } object describing the southwest corner of the bounding box." ], "signature": [ - "maplibregl.IControl" + "maplibregl.LngLatLike" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } ], "returnComment": [ - "True if map contains control." + "`this`" ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.resize", + "id": "def-server.LngLatBounds.extend", "type": "Function", "tags": [], - "label": "resize", - "description": [], + "label": "extend", + "description": [ + "\nExtend the bounds to include a given LngLatLike or LngLatBoundsLike.\n" + ], "signature": [ - "(eventData?: maplibregl.EventData | undefined) => this" + "(obj: maplibregl.LngLatBoundsLike | maplibregl.LngLatLike) => any" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.resize.$1", - "type": "Object", + "id": "def-server.LngLatBounds.extend.$1", + "type": "CompoundType", "tags": [], - "label": "eventData", - "description": [], + "label": "obj", + "description": [ + "object to extend to" + ], "signature": [ - "maplibregl.EventData | undefined" + "maplibregl.LngLatBoundsLike | maplibregl.LngLatLike" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": false + "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "`this`" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getBounds", + "id": "def-server.LngLatBounds.getCenter", "type": "Function", "tags": [], - "label": "getBounds", - "description": [], + "label": "getCenter", + "description": [ + "\nReturns the geographical coordinate equidistant from the bounding box's corners.\n" + ], "signature": [ - "() => maplibregl.LngLatBounds" + "() => maplibregl.LngLat" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The bounding box's center." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getMaxBounds", + "id": "def-server.LngLatBounds.getSouthWest", "type": "Function", "tags": [], - "label": "getMaxBounds", - "description": [], + "label": "getSouthWest", + "description": [ + "\nReturns the southwest corner of the bounding box.\n" + ], "signature": [ - "() => maplibregl.LngLatBounds | null" + "() => maplibregl.LngLat" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The southwest corner of the bounding box." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setMaxBounds", + "id": "def-server.LngLatBounds.getNorthEast", "type": "Function", "tags": [], - "label": "setMaxBounds", - "description": [], + "label": "getNorthEast", + "description": [ + "\nReturns the northeast corner of the bounding box.\n" + ], "signature": [ - "(lnglatbounds?: maplibregl.LngLatBoundsLike | undefined) => this" + "() => maplibregl.LngLat" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setMaxBounds.$1", - "type": "CompoundType", - "tags": [], - "label": "lnglatbounds", - "description": [], - "signature": [ - "maplibregl.LngLatBoundsLike | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] + "children": [], + "returnComment": [ + "The northeast corner of the bounding box." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setMinZoom", + "id": "def-server.LngLatBounds.getNorthWest", "type": "Function", "tags": [], - "label": "setMinZoom", - "description": [], + "label": "getNorthWest", + "description": [ + "\nReturns the northwest corner of the bounding box.\n" + ], "signature": [ - "(minZoom?: number | null | undefined) => this" + "() => maplibregl.LngLat" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setMinZoom.$1", - "type": "CompoundType", - "tags": [], - "label": "minZoom", - "description": [], - "signature": [ - "number | null | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] + "children": [], + "returnComment": [ + "The northwest corner of the bounding box." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getMinZoom", + "id": "def-server.LngLatBounds.getSouthEast", "type": "Function", "tags": [], - "label": "getMinZoom", - "description": [], + "label": "getSouthEast", + "description": [ + "\nReturns the southeast corner of the bounding box.\n" + ], "signature": [ - "() => number" + "() => maplibregl.LngLat" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The southeast corner of the bounding box." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setMaxZoom", + "id": "def-server.LngLatBounds.getWest", "type": "Function", "tags": [], - "label": "setMaxZoom", - "description": [], + "label": "getWest", + "description": [ + "\nReturns the west edge of the bounding box.\n" + ], "signature": [ - "(maxZoom?: number | null | undefined) => this" + "() => number" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setMaxZoom.$1", - "type": "CompoundType", - "tags": [], - "label": "maxZoom", - "description": [], - "signature": [ - "number | null | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] + "children": [], + "returnComment": [ + "The west edge of the bounding box." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getMaxZoom", + "id": "def-server.LngLatBounds.getSouth", "type": "Function", "tags": [], - "label": "getMaxZoom", - "description": [], + "label": "getSouth", + "description": [ + "\nReturns the south edge of the bounding box.\n" + ], "signature": [ "() => number" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The south edge of the bounding box." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setMinPitch", + "id": "def-server.LngLatBounds.getEast", "type": "Function", "tags": [], - "label": "setMinPitch", - "description": [], + "label": "getEast", + "description": [ + "\nReturns the east edge of the bounding box.\n" + ], "signature": [ - "(minPitch?: number | null | undefined) => this" + "() => number" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setMinPitch.$1", - "type": "CompoundType", - "tags": [], - "label": "minPitch", - "description": [], - "signature": [ - "number | null | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] + "children": [], + "returnComment": [ + "The east edge of the bounding box." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getMinPitch", + "id": "def-server.LngLatBounds.getNorth", "type": "Function", "tags": [], - "label": "getMinPitch", - "description": [], + "label": "getNorth", + "description": [ + "\nReturns the north edge of the bounding box.\n" + ], "signature": [ "() => number" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The north edge of the bounding box." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setMaxPitch", + "id": "def-server.LngLatBounds.toArray", "type": "Function", "tags": [], - "label": "setMaxPitch", - "description": [], + "label": "toArray", + "description": [ + "\nReturns the bounding box represented as an array.\n" + ], "signature": [ - "(maxPitch?: number | null | undefined) => this" + "() => number[][]" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setMaxPitch.$1", - "type": "CompoundType", - "tags": [], - "label": "maxPitch", - "description": [], - "signature": [ - "number | null | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] + "children": [], + "returnComment": [ + "The bounding box represented as an array, consisting of the\nsouthwest and northeast coordinates of the bounding represented as arrays of numbers." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getMaxPitch", + "id": "def-server.LngLatBounds.toString", "type": "Function", "tags": [], - "label": "getMaxPitch", - "description": [], + "label": "toString", + "description": [ + "\nReturn the bounding box represented as a string.\n" + ], "signature": [ - "() => number" + "() => string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The bounding box represents as a string of the format\n`'LngLatBounds(LngLat(lng, lat), LngLat(lng, lat))'`." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getRenderWorldCopies", + "id": "def-server.LngLatBounds.isEmpty", "type": "Function", "tags": [], - "label": "getRenderWorldCopies", - "description": [], + "label": "isEmpty", + "description": [ + "\nCheck if the bounding box is an empty/`null`-type box.\n" + ], "signature": [ "() => boolean" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "True if bounds have been defined, otherwise false." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setRenderWorldCopies", + "id": "def-server.LngLatBounds.contains", "type": "Function", "tags": [], - "label": "setRenderWorldCopies", - "description": [], + "label": "contains", + "description": [ + "\nCheck if the point is within the bounding box.\n" + ], "signature": [ - "(renderWorldCopies?: boolean | undefined) => this" + "(lnglat: maplibregl.LngLatLike) => boolean" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setRenderWorldCopies.$1", + "id": "def-server.LngLatBounds.contains.$1", "type": "CompoundType", "tags": [], - "label": "renderWorldCopies", - "description": [], + "label": "lnglat", + "description": [ + "geographic point to check against." + ], "signature": [ - "boolean | undefined" + "maplibregl.LngLatLike" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": false + "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "True if the point is within the bounding box." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.project", + "id": "def-server.LngLatBounds.convert", "type": "Function", "tags": [], - "label": "project", - "description": [], + "label": "convert", + "description": [ + "\nConverts an array to a `LngLatBounds` object.\n\nIf a `LngLatBounds` object is passed in, the function returns it unchanged.\n\nInternally, the function calls `LngLat#convert` to convert arrays to `LngLat` values.\n" + ], "signature": [ - "(lnglat: maplibregl.LngLatLike) => maplibregl.Point" + "(input: maplibregl.LngLatBoundsLike | null) => maplibregl.LngLatBounds" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.project.$1", + "id": "def-server.LngLatBounds.convert.$1", "type": "CompoundType", "tags": [], - "label": "lnglat", - "description": [], + "label": "input", + "description": [ + "An array of two coordinates to convert, or a `LngLatBounds` object to return." + ], "signature": [ - "maplibregl.LngLatLike" + "maplibregl.LngLatBoundsLike | null" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": true + "isRequired": false } ], - "returnComment": [] - }, + "returnComment": [ + "A new `LngLatBounds` object, if a conversion occurred, or the original `LngLatBounds` object." + ] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map", + "type": "Class", + "tags": [], + "label": "Map", + "description": [], + "signature": [ + "maplibregl.Map extends Camera" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.unproject", - "type": "Function", + "id": "def-server.Map.style", + "type": "Object", "tags": [], - "label": "unproject", + "label": "style", "description": [], "signature": [ - "(point: maplibregl.PointLike) => maplibregl.LngLat" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.unproject.$1", - "type": "CompoundType", - "tags": [], - "label": "point", - "description": [], - "signature": [ - "maplibregl.PointLike" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - } + "maplibregl.Style" ], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.isMoving", - "type": "Function", + "id": "def-server.Map.painter", + "type": "Object", "tags": [], - "label": "isMoving", + "label": "painter", "description": [], "signature": [ - "() => boolean" + "maplibregl.Painter" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.isZooming", - "type": "Function", + "id": "def-server.Map.handlers", + "type": "Object", "tags": [], - "label": "isZooming", + "label": "handlers", "description": [], "signature": [ - "() => boolean" + "maplibregl.HandlerManager" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.isRotating", - "type": "Function", + "id": "def-server.Map._container", + "type": "Object", "tags": [], - "label": "isRotating", + "label": "_container", "description": [], "signature": [ - "() => boolean" + "HTMLElement" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.queryRenderedFeatures", - "type": "Function", + "id": "def-server.Map._canvasContainer", + "type": "Object", "tags": [], - "label": "queryRenderedFeatures", - "description": [ - "\nReturns an array of GeoJSON Feature objects representing visible features that satisfy the query parameters.\n\nThe properties value of each returned feature object contains the properties of its source feature. For GeoJSON sources, only string and numeric property values are supported (i.e. null, Array, and Object values are not supported).\n\nEach feature includes top-level layer, source, and sourceLayer properties. The layer property is an object representing the style layer to which the feature belongs. Layout and paint properties in this object contain values which are fully evaluated for the given zoom level and feature.\n\nOnly features that are currently rendered are included. Some features will not be included, like:\n\n- Features from layers whose visibility property is \"none\".\n- Features from layers whose zoom range excludes the current zoom level.\n- Symbol features that have been hidden due to text or icon collision.\n\nFeatures from all other layers are included, including features that may have no visible contribution to the rendered result; for example, because the layer's opacity or color alpha component is set to 0.\n\nThe topmost rendered feature appears first in the returned array, and subsequent features are sorted by descending z-order. Features that are rendered multiple times (due to wrapping across the antimeridian at low zoom levels) are returned only once (though subject to the following caveat).\n\nBecause features come from tiled vector data or GeoJSON data that is converted to tiles internally, feature geometries may be split or duplicated across tile boundaries and, as a result, features may appear multiple times in query results. For example, suppose there is a highway running through the bounding rectangle of a query. The results of the query will be those parts of the highway that lie within the map tiles covering the bounding rectangle, even if the highway extends into other tiles, and the portion of the highway within each map tile will be returned as a separate feature. Similarly, a point feature near a tile boundary may appear in multiple tiles due to tile buffering.\n" - ], + "label": "_canvasContainer", + "description": [], "signature": [ - "(pointOrBox?: maplibregl.PointLike | [maplibregl.PointLike, maplibregl.PointLike] | undefined, options?: ({ layers?: string[] | undefined; filter?: any[] | undefined; } & maplibregl.FilterOptions) | undefined) => maplibregl.MapboxGeoJSONFeature[]" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.queryRenderedFeatures.$1", - "type": "CompoundType", - "tags": [], - "label": "pointOrBox", - "description": [ - "The geometry of the query region: either a single point or southwest and northeast points describing a bounding box. Omitting this parameter (i.e. calling Map#queryRenderedFeatures with zero arguments, or with only a options argument) is equivalent to passing a bounding box encompassing the entire map viewport." - ], - "signature": [ - "maplibregl.PointLike | [maplibregl.PointLike, maplibregl.PointLike] | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.queryRenderedFeatures.$2", - "type": "CompoundType", - "tags": [], - "label": "options", - "description": [], - "signature": [ - "({ layers?: string[] | undefined; filter?: any[] | undefined; } & maplibregl.FilterOptions) | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": false - } + "HTMLElement" ], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.querySourceFeatures", - "type": "Function", + "id": "def-server.Map._controlContainer", + "type": "Object", "tags": [], - "label": "querySourceFeatures", - "description": [ - "\nReturns an array of GeoJSON Feature objects representing features within the specified vector tile or GeoJSON source that satisfy the query parameters.\n\nIn contrast to Map#queryRenderedFeatures, this function returns all features matching the query parameters, whether or not they are rendered by the current style (i.e. visible). The domain of the query includes all currently-loaded vector tiles and GeoJSON source tiles: this function does not check tiles outside the currently visible viewport.\n\nBecause features come from tiled vector data or GeoJSON data that is converted to tiles internally, feature geometries may be split or duplicated across tile boundaries and, as a result, features may appear multiple times in query results. For example, suppose there is a highway running through the bounding rectangle of a query. The results of the query will be those parts of the highway that lie within the map tiles covering the bounding rectangle, even if the highway extends into other tiles, and the portion of the highway within each map tile will be returned as a separate feature. Similarly, a point feature near a tile boundary may appear in multiple tiles due to tile buffering.\n" - ], + "label": "_controlContainer", + "description": [], "signature": [ - "(sourceID: string, parameters?: ({ sourceLayer?: string | undefined; filter?: any[] | undefined; } & maplibregl.FilterOptions) | undefined) => maplibregl.MapboxGeoJSONFeature[]" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.querySourceFeatures.$1", - "type": "string", - "tags": [], - "label": "sourceID", - "description": [ - "The ID of the vector tile or GeoJSON source to query." - ], - "signature": [ - "string" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.querySourceFeatures.$2", - "type": "CompoundType", - "tags": [], - "label": "parameters", - "description": [], - "signature": [ - "({ sourceLayer?: string | undefined; filter?: any[] | undefined; } & maplibregl.FilterOptions) | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": false - } + "HTMLElement" ], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setStyle", - "type": "Function", + "id": "def-server.Map._controlPositions", + "type": "Object", "tags": [], - "label": "setStyle", + "label": "_controlPositions", "description": [], "signature": [ - "(style: string | maplibregl.Style, options?: { diff?: boolean | undefined; localIdeographFontFamily?: string | undefined; } | undefined) => this" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setStyle.$1", - "type": "CompoundType", - "tags": [], - "label": "style", - "description": [], - "signature": [ - "string | maplibregl.Style" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setStyle.$2", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setStyle.$2.diff", - "type": "CompoundType", - "tags": [], - "label": "diff", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setStyle.$2.localIdeographFontFamily", - "type": "string", - "tags": [], - "label": "localIdeographFontFamily", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - } - ] - } + "{ [_: string]: HTMLElement; }" ], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setTransformRequest", - "type": "Function", + "id": "def-server.Map._interactive", + "type": "boolean", "tags": [], - "label": "setTransformRequest", + "label": "_interactive", "description": [], - "signature": [ - "(transformRequest: maplibregl.TransformRequestFunction) => void" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setTransformRequest.$1", - "type": "Function", - "tags": [], - "label": "transformRequest", - "description": [], - "signature": [ - "maplibregl.TransformRequestFunction" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getStyle", - "type": "Function", + "id": "def-server.Map._showTileBoundaries", + "type": "boolean", "tags": [], - "label": "getStyle", + "label": "_showTileBoundaries", "description": [], - "signature": [ - "() => maplibregl.Style" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.isStyleLoaded", - "type": "Function", + "id": "def-server.Map._showCollisionBoxes", + "type": "boolean", "tags": [], - "label": "isStyleLoaded", + "label": "_showCollisionBoxes", "description": [], - "signature": [ - "() => boolean" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.addSource", - "type": "Function", + "id": "def-server.Map._showPadding", + "type": "boolean", "tags": [], - "label": "addSource", + "label": "_showPadding", "description": [], - "signature": [ - "(id: string, source: maplibregl.AnySourceData) => this" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.addSource.$1", - "type": "string", - "tags": [], - "label": "id", - "description": [], - "signature": [ - "string" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.addSource.$2", - "type": "CompoundType", - "tags": [], - "label": "source", - "description": [], - "signature": [ - "maplibregl.AnySourceData" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.isSourceLoaded", - "type": "Function", + "id": "def-server.Map._showOverdrawInspector", + "type": "boolean", "tags": [], - "label": "isSourceLoaded", + "label": "_showOverdrawInspector", "description": [], - "signature": [ - "(id: string) => boolean" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.isSourceLoaded.$1", - "type": "string", - "tags": [], - "label": "id", - "description": [], - "signature": [ - "string" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.areTilesLoaded", - "type": "Function", + "id": "def-server.Map._repaint", + "type": "boolean", "tags": [], - "label": "areTilesLoaded", + "label": "_repaint", "description": [], - "signature": [ - "() => boolean" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.removeSource", - "type": "Function", + "id": "def-server.Map._vertices", + "type": "boolean", "tags": [], - "label": "removeSource", + "label": "_vertices", "description": [], - "signature": [ - "(id: string) => this" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.removeSource.$1", - "type": "string", - "tags": [], - "label": "id", - "description": [], - "signature": [ - "string" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getSource", - "type": "Function", + "id": "def-server.Map._canvas", + "type": "Object", "tags": [], - "label": "getSource", + "label": "_canvas", "description": [], "signature": [ - "(id: string) => maplibregl.AnySourceImpl" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getSource.$1", - "type": "string", - "tags": [], - "label": "id", - "description": [], - "signature": [ - "string" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - } + "HTMLCanvasElement" ], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.addImage", - "type": "Function", + "id": "def-server.Map._maxTileCacheSize", + "type": "number", "tags": [], - "label": "addImage", + "label": "_maxTileCacheSize", "description": [], - "signature": [ - "(name: string, image: ArrayBufferView | HTMLImageElement | { width: number; height: number; data: Uint8Array | Uint8ClampedArray; } | ImageData | ImageBitmap, options?: { pixelRatio?: number | undefined; sdf?: boolean | undefined; } | undefined) => this" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.addImage.$1", - "type": "string", - "tags": [], - "label": "name", - "description": [], - "signature": [ - "string" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.addImage.$2", - "type": "CompoundType", - "tags": [], - "label": "image", - "description": [], - "signature": [ - "ArrayBufferView | HTMLImageElement | { width: number; height: number; data: Uint8Array | Uint8ClampedArray; } | ImageData | ImageBitmap" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.addImage.$3", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.addImage.$3.pixelRatio", - "type": "number", - "tags": [], - "label": "pixelRatio", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.addImage.$3.sdf", - "type": "CompoundType", - "tags": [], - "label": "sdf", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - } - ] - } - ], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.hasImage", - "type": "Function", + "id": "def-server.Map._frame", + "type": "Object", "tags": [], - "label": "hasImage", + "label": "_frame", "description": [], "signature": [ - "(name: string) => boolean" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.hasImage.$1", - "type": "string", - "tags": [], - "label": "name", - "description": [], - "signature": [ - "string" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - } + "{ cancel: () => void; }" ], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.removeImage", - "type": "Function", + "id": "def-server.Map._styleDirty", + "type": "boolean", "tags": [], - "label": "removeImage", + "label": "_styleDirty", "description": [], - "signature": [ - "(name: string) => this" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.removeImage.$1", - "type": "string", - "tags": [], - "label": "name", - "description": [], - "signature": [ - "string" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.loadImage", - "type": "Function", + "id": "def-server.Map._sourcesDirty", + "type": "boolean", "tags": [], - "label": "loadImage", + "label": "_sourcesDirty", "description": [], - "signature": [ - "(url: string, callback: Function) => this" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.loadImage.$1", - "type": "string", - "tags": [], - "label": "url", - "description": [], - "signature": [ - "string" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.loadImage.$2", - "type": "Object", - "tags": [], - "label": "callback", - "description": [], - "signature": [ - "Function" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.listImages", - "type": "Function", + "id": "def-server.Map._placementDirty", + "type": "boolean", "tags": [], - "label": "listImages", + "label": "_placementDirty", "description": [], - "signature": [ - "() => string[]" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.addLayer", - "type": "Function", + "id": "def-server.Map._loaded", + "type": "boolean", "tags": [], - "label": "addLayer", + "label": "_loaded", "description": [], - "signature": [ - "(layer: maplibregl.AnyLayer, before?: string | undefined) => this" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._fullyLoaded", + "type": "boolean", + "tags": [], + "label": "_fullyLoaded", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._trackResize", + "type": "boolean", + "tags": [], + "label": "_trackResize", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._preserveDrawingBuffer", + "type": "boolean", + "tags": [], + "label": "_preserveDrawingBuffer", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._failIfMajorPerformanceCaveat", + "type": "boolean", + "tags": [], + "label": "_failIfMajorPerformanceCaveat", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._antialias", + "type": "boolean", + "tags": [], + "label": "_antialias", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._refreshExpiredTiles", + "type": "boolean", + "tags": [], + "label": "_refreshExpiredTiles", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._hash", + "type": "Object", + "tags": [], + "label": "_hash", + "description": [], + "signature": [ + "maplibregl.Hash" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._delegatedListeners", + "type": "Any", + "tags": [], + "label": "_delegatedListeners", + "description": [], + "signature": [ + "any" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._fadeDuration", + "type": "number", + "tags": [], + "label": "_fadeDuration", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._crossSourceCollisions", + "type": "boolean", + "tags": [], + "label": "_crossSourceCollisions", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._crossFadingFactor", + "type": "number", + "tags": [], + "label": "_crossFadingFactor", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._collectResourceTiming", + "type": "boolean", + "tags": [], + "label": "_collectResourceTiming", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._renderTaskQueue", + "type": "Object", + "tags": [], + "label": "_renderTaskQueue", + "description": [], + "signature": [ + "maplibregl.TaskQueue" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._controls", + "type": "Array", + "tags": [], + "label": "_controls", + "description": [], + "signature": [ + "maplibregl.IControl[]" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._mapId", + "type": "number", + "tags": [], + "label": "_mapId", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._localIdeographFontFamily", + "type": "string", + "tags": [], + "label": "_localIdeographFontFamily", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._requestManager", + "type": "Object", + "tags": [], + "label": "_requestManager", + "description": [], + "signature": [ + "maplibregl.RequestManager" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._locale", + "type": "Any", + "tags": [], + "label": "_locale", + "description": [], + "signature": [ + "any" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._removed", + "type": "boolean", + "tags": [], + "label": "_removed", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._clickTolerance", + "type": "number", + "tags": [], + "label": "_clickTolerance", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._pixelRatio", + "type": "number", + "tags": [], + "label": "_pixelRatio", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.scrollZoom", + "type": "Object", + "tags": [], + "label": "scrollZoom", + "description": [ + "\nThe map's {@link ScrollZoomHandler}, which implements zooming in and out with a scroll wheel or trackpad.\nFind more details and examples using `scrollZoom` in the {@link ScrollZoomHandler} section." + ], + "signature": [ + "maplibregl.ScrollZoomHandler" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.boxZoom", + "type": "Object", + "tags": [], + "label": "boxZoom", + "description": [ + "\nThe map's {@link BoxZoomHandler}, which implements zooming using a drag gesture with the Shift key pressed.\nFind more details and examples using `boxZoom` in the {@link BoxZoomHandler} section." + ], + "signature": [ + "maplibregl.BoxZoomHandler" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.dragRotate", + "type": "Object", + "tags": [], + "label": "dragRotate", + "description": [ + "\nThe map's {@link DragRotateHandler}, which implements rotating the map while dragging with the right\nmouse button or with the Control key pressed. Find more details and examples using `dragRotate`\nin the {@link DragRotateHandler} section." + ], + "signature": [ + "maplibregl.DragRotateHandler" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.dragPan", + "type": "Object", + "tags": [], + "label": "dragPan", + "description": [ + "\nThe map's {@link DragPanHandler}, which implements dragging the map with a mouse or touch gesture.\nFind more details and examples using `dragPan` in the {@link DragPanHandler} section." + ], + "signature": [ + "maplibregl.DragPanHandler" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.keyboard", + "type": "Object", + "tags": [], + "label": "keyboard", + "description": [ + "\nThe map's {@link KeyboardHandler}, which allows the user to zoom, rotate, and pan the map using keyboard\nshortcuts. Find more details and examples using `keyboard` in the {@link KeyboardHandler} section." + ], + "signature": [ + "maplibregl.KeyboardHandler" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.doubleClickZoom", + "type": "Object", + "tags": [], + "label": "doubleClickZoom", + "description": [ + "\nThe map's {@link DoubleClickZoomHandler}, which allows the user to zoom by double clicking.\nFind more details and examples using `doubleClickZoom` in the {@link DoubleClickZoomHandler} section." + ], + "signature": [ + "maplibregl.DoubleClickZoomHandler" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.touchZoomRotate", + "type": "Object", + "tags": [], + "label": "touchZoomRotate", + "description": [ + "\nThe map's {@link TouchZoomRotateHandler}, which allows the user to zoom or rotate the map with touch gestures.\nFind more details and examples using `touchZoomRotate` in the {@link TouchZoomRotateHandler} section." + ], + "signature": [ + "maplibregl.TouchZoomRotateHandler" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.touchPitch", + "type": "Object", + "tags": [], + "label": "touchPitch", + "description": [ + "\nThe map's {@link TouchPitchHandler}, which allows the user to pitch the map with touch gestures.\nFind more details and examples using `touchPitch` in the {@link TouchPitchHandler} section." + ], + "signature": [ + "maplibregl.TouchPitchHandler" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.Unnamed.$1", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "maplibregl.MapOptions" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._getMapId", + "type": "Function", + "tags": [], + "label": "_getMapId", + "description": [], + "signature": [ + "() => number" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.addControl", + "type": "Function", + "tags": [ + "see" + ], + "label": "addControl", + "description": [ + "\nAdds an {@link IControl} to the map, calling `control.onAdd(this)`.\n" + ], + "signature": [ + "(control: maplibregl.IControl, position?: maplibregl.ControlPosition | undefined) => this" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.addControl.$1", + "type": "Object", + "tags": [], + "label": "control", + "description": [ + "The {@link IControl } to add." + ], + "signature": [ + "maplibregl.IControl" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.addControl.$2", + "type": "CompoundType", + "tags": [], + "label": "position", + "description": [ + "position on the map to which the control will be added.\nValid values are `'top-left'`, `'top-right'`, `'bottom-left'`, and `'bottom-right'`. Defaults to `'top-right'`." + ], + "signature": [ + "maplibregl.ControlPosition | undefined" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [ + "`this`" + ] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.removeControl", + "type": "Function", + "tags": [], + "label": "removeControl", + "description": [ + "\nRemoves the control from the map.\n" + ], + "signature": [ + "(control: maplibregl.IControl) => this" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.removeControl.$1", + "type": "Object", + "tags": [], + "label": "control", + "description": [ + "The {@link IControl } to remove." + ], + "signature": [ + "maplibregl.IControl" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [ + "`this`" + ] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.hasControl", + "type": "Function", + "tags": [], + "label": "hasControl", + "description": [ + "\nChecks if a control exists on the map.\n" + ], + "signature": [ + "(control: maplibregl.IControl) => boolean" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.hasControl.$1", + "type": "Object", + "tags": [], + "label": "control", + "description": [ + "The {@link IControl } to check." + ], + "signature": [ + "maplibregl.IControl" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [ + "True if map contains control." + ] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.resize", + "type": "Function", + "tags": [], + "label": "resize", + "description": [ + "\nResizes the map according to the dimensions of its\n`container` element.\n\nChecks if the map container size changed and updates the map if it has changed.\nThis method must be called after the map's `container` is resized programmatically\nor when the map is shown after being initially hidden with CSS.\n" + ], + "signature": [ + "(eventData?: any) => this" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.resize.$1", + "type": "Any", + "tags": [], + "label": "eventData", + "description": [ + "Additional properties to be passed to `movestart`, `move`, `resize`, and `moveend`\nevents that get triggered as a result of resize. This can be useful for differentiating the\nsource of an event (for example, user-initiated or programmatically-triggered events)." + ], + "signature": [ + "any" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [ + "`this`" + ] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.getPixelRatio", + "type": "Function", + "tags": [], + "label": "getPixelRatio", + "description": [ + "\nReturns the map's pixel ratio." + ], + "signature": [ + "() => number" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [ + "The pixel ratio." + ] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.setPixelRatio", + "type": "Function", + "tags": [], + "label": "setPixelRatio", + "description": [ + "\nSets the map's pixel ratio. This allows to override `devicePixelRatio`.\nAfter this call, the canvas' `width` attribute will be `container.clientWidth * pixelRatio`\nand its height attribute will be `container.clientHeight * pixelRatio`." + ], + "signature": [ + "(pixelRatio: number) => void" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.setPixelRatio.$1", + "type": "number", + "tags": [], + "label": "pixelRatio", + "description": [ + "The pixel ratio." + ], + "signature": [ + "number" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.getBounds", + "type": "Function", + "tags": [], + "label": "getBounds", + "description": [ + "\nReturns the map's geographical bounds. When the bearing or pitch is non-zero, the visible region is not\nan axis-aligned rectangle, and the result is the smallest bounds that encompasses the visible region." + ], + "signature": [ + "() => maplibregl.LngLatBounds" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [ + "The geographical bounds of the map as {@link LngLatBounds }." + ] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.getMaxBounds", + "type": "Function", + "tags": [], + "label": "getMaxBounds", + "description": [ + "\nReturns the maximum geographical bounds the map is constrained to, or `null` if none set." + ], + "signature": [ + "() => maplibregl.LngLatBounds | null" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [ + "The map object." + ] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.setMaxBounds", + "type": "Function", + "tags": [], + "label": "setMaxBounds", + "description": [ + "\nSets or clears the map's geographical bounds.\n\nPan and zoom operations are constrained within these bounds.\nIf a pan or zoom is performed that would\ndisplay regions outside these bounds, the map will\ninstead display a position and zoom level\nas close as possible to the operation's request while still\nremaining within the bounds.\n" + ], + "signature": [ + "(bounds?: maplibregl.LngLatBoundsLike | null | undefined) => this" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.addLayer.$1", + "id": "def-server.Map.setMaxBounds.$1", "type": "CompoundType", "tags": [], - "label": "layer", - "description": [], - "signature": [ - "maplibregl.AnyLayer" + "label": "bounds", + "description": [ + "The maximum bounds to set. If `null` or `undefined` is provided, the function removes the map's maximum bounds." ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.addLayer.$2", - "type": "string", - "tags": [], - "label": "before", - "description": [], "signature": [ - "string | undefined" + "maplibregl.LngLatBoundsLike | null | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": false } ], - "returnComment": [] + "returnComment": [ + "`this`" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.moveLayer", + "id": "def-server.Map.setMinZoom", "type": "Function", "tags": [], - "label": "moveLayer", - "description": [], + "label": "setMinZoom", + "description": [ + "\nSets or clears the map's minimum zoom level.\nIf the map's current zoom level is lower than the new minimum,\nthe map will zoom to the new minimum.\n\nIt is not always possible to zoom out and reach the set `minZoom`.\nOther factors such as map height may restrict zooming. For example,\nif the map is 512px tall it will not be possible to zoom below zoom 0\nno matter what the `minZoom` is set to.\n" + ], "signature": [ - "(id: string, beforeId?: string | undefined) => this" + "(minZoom?: number | null | undefined) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.moveLayer.$1", - "type": "string", + "id": "def-server.Map.setMinZoom.$1", + "type": "CompoundType", "tags": [], - "label": "id", - "description": [], - "signature": [ - "string" + "label": "minZoom", + "description": [ + "The minimum zoom level to set (-2 - 24).\nIf `null` or `undefined` is provided, the function removes the current minimum zoom (i.e. sets it to -2)." ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.moveLayer.$2", - "type": "string", - "tags": [], - "label": "beforeId", - "description": [], "signature": [ - "string | undefined" + "number | null | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": false } ], - "returnComment": [] + "returnComment": [ + "`this`" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.removeLayer", + "id": "def-server.Map.getMinZoom", "type": "Function", "tags": [], - "label": "removeLayer", - "description": [], + "label": "getMinZoom", + "description": [ + "\nReturns the map's minimum allowable zoom level.\n" + ], "signature": [ - "(id: string) => this" + "() => number" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.removeLayer.$1", - "type": "string", - "tags": [], - "label": "id", - "description": [], - "signature": [ - "string" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] + "children": [], + "returnComment": [ + "minZoom" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getLayer", + "id": "def-server.Map.setMaxZoom", "type": "Function", "tags": [], - "label": "getLayer", - "description": [], + "label": "setMaxZoom", + "description": [ + "\nSets or clears the map's maximum zoom level.\nIf the map's current zoom level is higher than the new maximum,\nthe map will zoom to the new maximum.\n" + ], "signature": [ - "(id: string) => maplibregl.AnyLayer" + "(maxZoom?: number | null | undefined) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getLayer.$1", - "type": "string", + "id": "def-server.Map.setMaxZoom.$1", + "type": "CompoundType", "tags": [], - "label": "id", - "description": [], + "label": "maxZoom", + "description": [ + "The maximum zoom level to set.\nIf `null` or `undefined` is provided, the function removes the current maximum zoom (sets it to 22)." + ], "signature": [ - "string" + "number | null | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": true + "isRequired": false } ], - "returnComment": [] + "returnComment": [ + "`this`" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setFilter", + "id": "def-server.Map.getMaxZoom", "type": "Function", "tags": [], - "label": "setFilter", - "description": [], + "label": "getMaxZoom", + "description": [ + "\nReturns the map's maximum allowable zoom level.\n" + ], + "signature": [ + "() => number" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [ + "maxZoom" + ] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.setMinPitch", + "type": "Function", + "tags": [], + "label": "setMinPitch", + "description": [ + "\nSets or clears the map's minimum pitch.\nIf the map's current pitch is lower than the new minimum,\nthe map will pitch to the new minimum.\n" + ], "signature": [ - "(layer: string, filter?: boolean | any[] | null | undefined, options?: maplibregl.FilterOptions | null | undefined) => this" + "(minPitch?: number | null | undefined) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setFilter.$1", - "type": "string", - "tags": [], - "label": "layer", - "description": [], - "signature": [ - "string" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setFilter.$2", + "id": "def-server.Map.setMinPitch.$1", "type": "CompoundType", "tags": [], - "label": "filter", - "description": [], - "signature": [ - "boolean | any[] | null | undefined" + "label": "minPitch", + "description": [ + "The minimum pitch to set (0-85). Values greater than 60 degrees are experimental and may result in rendering issues. If you encounter any, please raise an issue with details in the MapLibre project.\nIf `null` or `undefined` is provided, the function removes the current minimum pitch (i.e. sets it to 0)." ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setFilter.$3", - "type": "CompoundType", - "tags": [], - "label": "options", - "description": [], "signature": [ - "maplibregl.FilterOptions | null | undefined" + "number | null | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": false } ], - "returnComment": [] + "returnComment": [ + "`this`" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setLayerZoomRange", + "id": "def-server.Map.getMinPitch", "type": "Function", "tags": [], - "label": "setLayerZoomRange", - "description": [], + "label": "getMinPitch", + "description": [ + "\nReturns the map's minimum allowable pitch.\n" + ], "signature": [ - "(layerId: string, minzoom: number, maxzoom: number) => this" + "() => number" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [ + "minPitch" + ] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.setMaxPitch", + "type": "Function", + "tags": [], + "label": "setMaxPitch", + "description": [ + "\nSets or clears the map's maximum pitch.\nIf the map's current pitch is higher than the new maximum,\nthe map will pitch to the new maximum.\n" + ], + "signature": [ + "(maxPitch?: number | null | undefined) => this" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setLayerZoomRange.$1", - "type": "string", - "tags": [], - "label": "layerId", - "description": [], - "signature": [ - "string" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setLayerZoomRange.$2", - "type": "number", + "id": "def-server.Map.setMaxPitch.$1", + "type": "CompoundType", "tags": [], - "label": "minzoom", - "description": [], - "signature": [ - "number" + "label": "maxPitch", + "description": [ + "The maximum pitch to set (0-85). Values greater than 60 degrees are experimental and may result in rendering issues. If you encounter any, please raise an issue with details in the MapLibre project.\nIf `null` or `undefined` is provided, the function removes the current maximum pitch (sets it to 60)." ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setLayerZoomRange.$3", - "type": "number", - "tags": [], - "label": "maxzoom", - "description": [], "signature": [ - "number" + "number | null | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": true + "isRequired": false } ], - "returnComment": [] + "returnComment": [ + "`this`" + ] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.getMaxPitch", + "type": "Function", + "tags": [], + "label": "getMaxPitch", + "description": [ + "\nReturns the map's maximum allowable pitch.\n" + ], + "signature": [ + "() => number" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [ + "maxPitch" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getFilter", + "id": "def-server.Map.getRenderWorldCopies", "type": "Function", - "tags": [], - "label": "getFilter", - "description": [], + "tags": [ + "see" + ], + "label": "getRenderWorldCopies", + "description": [ + "\nReturns the state of `renderWorldCopies`. If `true`, multiple copies of the world will be rendered side by side beyond -180 and 180 degrees longitude. If set to `false`:\n- When the map is zoomed out far enough that a single representation of the world does not fill the map's entire\ncontainer, there will be blank space beyond 180 and -180 degrees longitude.\n- Features that cross 180 and -180 degrees longitude will be cut in two (with one portion on the right edge of the\nmap and the other on the left edge of the map) at every zoom level." + ], "signature": [ - "(layer: string) => any[]" + "() => boolean" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getFilter.$1", - "type": "string", - "tags": [], - "label": "layer", - "description": [], - "signature": [ - "string" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] + "children": [], + "returnComment": [ + "renderWorldCopies" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setPaintProperty", + "id": "def-server.Map.setRenderWorldCopies", "type": "Function", - "tags": [], - "label": "setPaintProperty", - "description": [], + "tags": [ + "see" + ], + "label": "setRenderWorldCopies", + "description": [ + "\nSets the state of `renderWorldCopies`.\n" + ], "signature": [ - "(layer: string, name: string, value: any, klass?: string | undefined) => this" + "(renderWorldCopies?: boolean | null | undefined) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setPaintProperty.$1", - "type": "string", - "tags": [], - "label": "layer", - "description": [], - "signature": [ - "string" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setPaintProperty.$2", - "type": "string", - "tags": [], - "label": "name", - "description": [], - "signature": [ - "string" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setPaintProperty.$3", - "type": "Any", + "id": "def-server.Map.setRenderWorldCopies.$1", + "type": "CompoundType", "tags": [], - "label": "value", - "description": [], - "signature": [ - "any" + "label": "renderWorldCopies", + "description": [ + "If `true`, multiple copies of the world will be rendered side by side beyond -180 and 180 degrees longitude. If set to `false`:\n- When the map is zoomed out far enough that a single representation of the world does not fill the map's entire\ncontainer, there will be blank space beyond 180 and -180 degrees longitude.\n- Features that cross 180 and -180 degrees longitude will be cut in two (with one portion on the right edge of the\nmap and the other on the left edge of the map) at every zoom level.\n\n`undefined` is treated as `true`, `null` is treated as `false`." ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setPaintProperty.$4", - "type": "string", - "tags": [], - "label": "klass", - "description": [], "signature": [ - "string | undefined" + "boolean | null | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": false } ], - "returnComment": [] + "returnComment": [ + "`this`" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getPaintProperty", + "id": "def-server.Map.project", "type": "Function", "tags": [], - "label": "getPaintProperty", - "description": [], + "label": "project", + "description": [ + "\nReturns a [Point](https://github.com/mapbox/point-geometry) representing pixel coordinates, relative to the map's `container`,\nthat correspond to the specified geographical location.\n" + ], "signature": [ - "(layer: string, name: string) => any" + "(lnglat: maplibregl.LngLatLike) => ", + "node_modules/@types/mapbox__point-geometry/index" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getPaintProperty.$1", - "type": "string", + "id": "def-server.Map.project.$1", + "type": "CompoundType", "tags": [], - "label": "layer", - "description": [], - "signature": [ - "string" + "label": "lnglat", + "description": [ + "The geographical location to project." ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getPaintProperty.$2", - "type": "string", - "tags": [], - "label": "name", - "description": [], "signature": [ - "string" + "maplibregl.LngLatLike" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The [Point](https://github.com/mapbox/point-geometry) corresponding to `lnglat`, relative to the map's `container`." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setLayoutProperty", + "id": "def-server.Map.unproject", "type": "Function", "tags": [], - "label": "setLayoutProperty", - "description": [], + "label": "unproject", + "description": [ + "\nReturns a {@link LngLat} representing geographical coordinates that correspond\nto the specified pixel coordinates.\n" + ], "signature": [ - "(layer: string, name: string, value: any) => this" + "(point: maplibregl.PointLike) => maplibregl.LngLat" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setLayoutProperty.$1", - "type": "string", - "tags": [], - "label": "layer", - "description": [], - "signature": [ - "string" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setLayoutProperty.$2", - "type": "string", + "id": "def-server.Map.unproject.$1", + "type": "CompoundType", "tags": [], - "label": "name", - "description": [], - "signature": [ - "string" + "label": "point", + "description": [ + "The pixel coordinates to unproject." ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setLayoutProperty.$3", - "type": "Any", - "tags": [], - "label": "value", - "description": [], "signature": [ - "any" + "maplibregl.PointLike" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The {@link LngLat } corresponding to `point`." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getLayoutProperty", + "id": "def-server.Map.isMoving", "type": "Function", "tags": [], - "label": "getLayoutProperty", - "description": [], + "label": "isMoving", + "description": [ + "\nReturns true if the map is panning, zooming, rotating, or pitching due to a camera animation or user gesture." + ], "signature": [ - "(layer: string, name: string) => any" + "() => boolean" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getLayoutProperty.$1", - "type": "string", - "tags": [], - "label": "layer", - "description": [], - "signature": [ - "string" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getLayoutProperty.$2", - "type": "string", - "tags": [], - "label": "name", - "description": [], - "signature": [ - "string" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - } + "children": [], + "returnComment": [ + "True if the map is moving." + ] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.isZooming", + "type": "Function", + "tags": [], + "label": "isZooming", + "description": [ + "\nReturns true if the map is zooming due to a camera animation or user gesture." ], - "returnComment": [] + "signature": [ + "() => boolean" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [ + "True if the map is zooming." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setLight", + "id": "def-server.Map.isRotating", "type": "Function", "tags": [], - "label": "setLight", + "label": "isRotating", + "description": [ + "\nReturns true if the map is rotating due to a camera animation or user gesture." + ], + "signature": [ + "() => boolean" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [ + "True if the map is rotating." + ] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._createDelegatedListener", + "type": "Function", + "tags": [], + "label": "_createDelegatedListener", "description": [], "signature": [ - "(options: maplibregl.Light, lightOptions?: any) => this" + "(type: string, layerId: string, listener: maplibregl.Listener) => { layer: string; listener: maplibregl.Listener; delegates: { error?: ((e: any) => void) | undefined; load?: ((e: any) => void) | undefined; idle?: ((e: any) => void) | undefined; remove?: ((e: any) => void) | undefined; render?: ((e: any) => void) | undefined; resize?: ((e: any) => void) | undefined; webglcontextlost?: ((e: any) => void) | undefined; webglcontextrestored?: ((e: any) => void) | undefined; dataloading?: ((e: any) => void) | undefined; data?: ((e: any) => void) | undefined; tiledataloading?: ((e: any) => void) | undefined; sourcedataloading?: ((e: any) => void) | undefined; styledataloading?: ((e: any) => void) | undefined; sourcedata?: ((e: any) => void) | undefined; styledata?: ((e: any) => void) | undefined; styleimagemissing?: ((e: any) => void) | undefined; dataabort?: ((e: any) => void) | undefined; sourcedataabort?: ((e: any) => void) | undefined; boxzoomcancel?: ((e: any) => void) | undefined; boxzoomstart?: ((e: any) => void) | undefined; boxzoomend?: ((e: any) => void) | undefined; touchcancel?: ((e: any) => void) | undefined; touchmove?: ((e: any) => void) | undefined; touchend?: ((e: any) => void) | undefined; touchstart?: ((e: any) => void) | undefined; click?: ((e: any) => void) | undefined; contextmenu?: ((e: any) => void) | undefined; dblclick?: ((e: any) => void) | undefined; mousemove?: ((e: any) => void) | undefined; mouseup?: ((e: any) => void) | undefined; mousedown?: ((e: any) => void) | undefined; mouseout?: ((e: any) => void) | undefined; mouseover?: ((e: any) => void) | undefined; movestart?: ((e: any) => void) | undefined; move?: ((e: any) => void) | undefined; moveend?: ((e: any) => void) | undefined; zoomstart?: ((e: any) => void) | undefined; zoom?: ((e: any) => void) | undefined; zoomend?: ((e: any) => void) | undefined; rotatestart?: ((e: any) => void) | undefined; rotate?: ((e: any) => void) | undefined; rotateend?: ((e: any) => void) | undefined; dragstart?: ((e: any) => void) | undefined; drag?: ((e: any) => void) | undefined; dragend?: ((e: any) => void) | undefined; pitchstart?: ((e: any) => void) | undefined; pitch?: ((e: any) => void) | undefined; pitchend?: ((e: any) => void) | undefined; wheel?: ((e: any) => void) | undefined; }; }" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setLight.$1", - "type": "Object", + "id": "def-server.Map._createDelegatedListener.$1", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "string" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._createDelegatedListener.$2", + "type": "string", "tags": [], - "label": "options", + "label": "layerId", "description": [], "signature": [ - "maplibregl.Light" + "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setLight.$2", - "type": "Any", + "id": "def-server.Map._createDelegatedListener.$3", + "type": "Function", "tags": [], - "label": "lightOptions", + "label": "listener", "description": [], "signature": [ - "any" + "maplibregl.Listener" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } @@ -2420,98 +2894,113 @@ }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getLight", + "id": "def-server.Map.on", "type": "Function", - "tags": [], - "label": "getLight", - "description": [], - "signature": [ - "() => maplibregl.Light" + "tags": [ + "see", + "see", + "see", + "see" + ], + "label": "on", + "description": [ + "\nAdds a listener for events of a specified type, optionally limited to features in a specified style layer.\n" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setFeatureState", - "type": "Function", - "tags": [], - "label": "setFeatureState", - "description": [], "signature": [ - "(feature: maplibregl.MapboxGeoJSONFeature | maplibregl.FeatureIdentifier, state: { [key: string]: any; }) => void" + "{ (type: T, layer: string, listener: (ev: maplibregl.MapLayerEventType[T] & Object) => void): this; (type: T, listener: (ev: maplibregl.MapEventType[T] & Object) => void): this; (type: string, listener: maplibregl.Listener): this; }" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setFeatureState.$1", - "type": "CompoundType", + "id": "def-server.Map.on.$1", + "type": "Uncategorized", "tags": [], - "label": "feature", - "description": [], + "label": "type", + "description": [ + "The event type to listen for. Events compatible with the optional `layerId` parameter are triggered\nwhen the cursor enters a visible portion of the specified layer from outside that layer or outside the map canvas.\n\n| Event | Compatible with `layerId` |\n|-----------------------------------------------------------|---------------------------|\n| [`mousedown`](#map.event:mousedown) | yes |\n| [`mouseup`](#map.event:mouseup) | yes |\n| [`mouseover`](#map.event:mouseover) | yes |\n| [`mouseout`](#map.event:mouseout) | yes |\n| [`mousemove`](#map.event:mousemove) | yes |\n| [`mouseenter`](#map.event:mouseenter) | yes (required) |\n| [`mouseleave`](#map.event:mouseleave) | yes (required) |\n| [`click`](#map.event:click) | yes |\n| [`dblclick`](#map.event:dblclick) | yes |\n| [`contextmenu`](#map.event:contextmenu) | yes |\n| [`touchstart`](#map.event:touchstart) | yes |\n| [`touchend`](#map.event:touchend) | yes |\n| [`touchcancel`](#map.event:touchcancel) | yes |\n| [`wheel`](#map.event:wheel) | |\n| [`resize`](#map.event:resize) | |\n| [`remove`](#map.event:remove) | |\n| [`touchmove`](#map.event:touchmove) | |\n| [`movestart`](#map.event:movestart) | |\n| [`move`](#map.event:move) | |\n| [`moveend`](#map.event:moveend) | |\n| [`dragstart`](#map.event:dragstart) | |\n| [`drag`](#map.event:drag) | |\n| [`dragend`](#map.event:dragend) | |\n| [`zoomstart`](#map.event:zoomstart) | |\n| [`zoom`](#map.event:zoom) | |\n| [`zoomend`](#map.event:zoomend) | |\n| [`rotatestart`](#map.event:rotatestart) | |\n| [`rotate`](#map.event:rotate) | |\n| [`rotateend`](#map.event:rotateend) | |\n| [`pitchstart`](#map.event:pitchstart) | |\n| [`pitch`](#map.event:pitch) | |\n| [`pitchend`](#map.event:pitchend) | |\n| [`boxzoomstart`](#map.event:boxzoomstart) | |\n| [`boxzoomend`](#map.event:boxzoomend) | |\n| [`boxzoomcancel`](#map.event:boxzoomcancel) | |\n| [`webglcontextlost`](#map.event:webglcontextlost) | |\n| [`webglcontextrestored`](#map.event:webglcontextrestored) | |\n| [`load`](#map.event:load) | |\n| [`render`](#map.event:render) | |\n| [`idle`](#map.event:idle) | |\n| [`error`](#map.event:error) | |\n| [`data`](#map.event:data) | |\n| [`styledata`](#map.event:styledata) | |\n| [`sourcedata`](#map.event:sourcedata) | |\n| [`dataloading`](#map.event:dataloading) | |\n| [`styledataloading`](#map.event:styledataloading) | |\n| [`sourcedataloading`](#map.event:sourcedataloading) | |\n| [`styleimagemissing`](#map.event:styleimagemissing) | |\n| [`dataabort`](#map.event:dataabort) | |\n| [`sourcedataabort`](#map.event:sourcedataabort) | |" + ], "signature": [ - "maplibregl.MapboxGeoJSONFeature | maplibregl.FeatureIdentifier" + "T" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setFeatureState.$2", - "type": "Object", + "id": "def-server.Map.on.$2", + "type": "string", "tags": [], - "label": "state", + "label": "layer", "description": [], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setFeatureState.$2.Unnamed", - "type": "IndexSignature", - "tags": [], - "label": "[key: string]: any", - "description": [], - "signature": [ - "[key: string]: any" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - } - ] + "signature": [ + "string" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.on.$3", + "type": "Function", + "tags": [], + "label": "listener", + "description": [ + "The function to be called when the event is fired." + ], + "signature": [ + "(ev: maplibregl.MapLayerEventType[T] & Object) => void" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "`this`" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getFeatureState", + "id": "def-server.Map.on", "type": "Function", "tags": [], - "label": "getFeatureState", + "label": "on", "description": [], "signature": [ - "(feature: maplibregl.MapboxGeoJSONFeature | maplibregl.FeatureIdentifier) => { [key: string]: any; }" + "{ (type: T, layer: string, listener: (ev: maplibregl.MapLayerEventType[T] & Object) => void): this; (type: T, listener: (ev: maplibregl.MapEventType[T] & Object) => void): this; (type: string, listener: maplibregl.Listener): this; }" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getFeatureState.$1", - "type": "CompoundType", + "id": "def-server.Map.on.$1", + "type": "Uncategorized", "tags": [], - "label": "feature", + "label": "type", + "description": [], + "signature": [ + "T" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.on.$2", + "type": "Function", + "tags": [], + "label": "listener", "description": [], "signature": [ - "maplibregl.MapboxGeoJSONFeature | maplibregl.FeatureIdentifier" + "(ev: maplibregl.MapEventType[T] & Object) => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } @@ -2520,618 +3009,628 @@ }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.removeFeatureState", + "id": "def-server.Map.on", "type": "Function", "tags": [], - "label": "removeFeatureState", + "label": "on", "description": [], "signature": [ - "(target: maplibregl.MapboxGeoJSONFeature | maplibregl.FeatureIdentifier, key?: string | undefined) => void" + "{ (type: T, layer: string, listener: (ev: maplibregl.MapLayerEventType[T] & Object) => void): this; (type: T, listener: (ev: maplibregl.MapEventType[T] & Object) => void): this; (type: string, listener: maplibregl.Listener): this; }" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.removeFeatureState.$1", - "type": "CompoundType", + "id": "def-server.Map.on.$1", + "type": "string", "tags": [], - "label": "target", + "label": "type", "description": [], "signature": [ - "maplibregl.MapboxGeoJSONFeature | maplibregl.FeatureIdentifier" + "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.removeFeatureState.$2", - "type": "string", + "id": "def-server.Map.on.$2", + "type": "Function", "tags": [], - "label": "key", + "label": "listener", "description": [], "signature": [ - "string | undefined" + "maplibregl.Listener" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": false + "isRequired": true } ], "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getContainer", - "type": "Function", - "tags": [], - "label": "getContainer", - "description": [], - "signature": [ - "() => HTMLElement" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getCanvasContainer", - "type": "Function", - "tags": [], - "label": "getCanvasContainer", - "description": [], - "signature": [ - "() => HTMLElement" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getCanvas", - "type": "Function", - "tags": [], - "label": "getCanvas", - "description": [], - "signature": [ - "() => HTMLCanvasElement" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.loaded", - "type": "Function", - "tags": [], - "label": "loaded", - "description": [], - "signature": [ - "() => boolean" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.remove", - "type": "Function", - "tags": [], - "label": "remove", - "description": [], - "signature": [ - "() => void" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.triggerRepaint", + "id": "def-server.Map.once", "type": "Function", - "tags": [], - "label": "triggerRepaint", - "description": [], - "signature": [ - "() => void" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.showTileBoundaries", - "type": "boolean", - "tags": [], - "label": "showTileBoundaries", - "description": [], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.showCollisionBoxes", - "type": "boolean", - "tags": [], - "label": "showCollisionBoxes", - "description": [], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.showPadding", - "type": "boolean", "tags": [ + "method", "name", - "type", - "instance", - "memberof" + "memberof", + "instance" ], - "label": "showPadding", + "label": "once", "description": [ - "\nGets and sets a Boolean indicating whether the map will visualize\nthe padding offsets.\n" + "\nAdds a listener that will be called only once to a specified event type.\n\n\nAdds a listener that will be called only once to a specified event type occurring on features in a specified style layer.\n" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.repaint", - "type": "boolean", - "tags": [], - "label": "repaint", - "description": [], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getCenter", - "type": "Function", - "tags": [], - "label": "getCenter", - "description": [], "signature": [ - "() => maplibregl.LngLat" + "{ (type: T, layer: string, listener: (ev: maplibregl.MapLayerEventType[T] & Object) => void): this; (type: T, listener: (ev: maplibregl.MapEventType[T] & Object) => void): this; (type: string, listener: maplibregl.Listener): this; }" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.once.$1", + "type": "Uncategorized", + "tags": [], + "label": "type", + "description": [ + "The event type to add a listener for." + ], + "signature": [ + "T" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.once.$2", + "type": "string", + "tags": [], + "label": "layer", + "description": [], + "signature": [ + "string" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.once.$3", + "type": "Function", + "tags": [], + "label": "listener", + "description": [ + "The function to be called when the event is fired.\nThe listener function is called with the data object passed to `fire`,\nextended with `target` and `type` properties." + ], + "signature": [ + "(ev: maplibregl.MapLayerEventType[T] & Object) => void" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] + "returnComment": [ + "`this`" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setCenter", + "id": "def-server.Map.once", "type": "Function", "tags": [], - "label": "setCenter", + "label": "once", "description": [], "signature": [ - "(center: maplibregl.LngLatLike, eventData?: maplibregl.EventData | undefined) => this" + "{ (type: T, layer: string, listener: (ev: maplibregl.MapLayerEventType[T] & Object) => void): this; (type: T, listener: (ev: maplibregl.MapEventType[T] & Object) => void): this; (type: string, listener: maplibregl.Listener): this; }" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setCenter.$1", - "type": "CompoundType", + "id": "def-server.Map.once.$1", + "type": "Uncategorized", "tags": [], - "label": "center", + "label": "type", "description": [], "signature": [ - "maplibregl.LngLatLike" + "T" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setCenter.$2", - "type": "Object", + "id": "def-server.Map.once.$2", + "type": "Function", "tags": [], - "label": "eventData", + "label": "listener", "description": [], "signature": [ - "maplibregl.EventData | undefined" + "(ev: maplibregl.MapEventType[T] & Object) => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": false + "isRequired": true } ], "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.panBy", + "id": "def-server.Map.once", "type": "Function", "tags": [], - "label": "panBy", + "label": "once", "description": [], "signature": [ - "(offset: maplibregl.PointLike, options?: maplibregl.AnimationOptions | undefined, eventData?: maplibregl.EventData | undefined) => this" + "{ (type: T, layer: string, listener: (ev: maplibregl.MapLayerEventType[T] & Object) => void): this; (type: T, listener: (ev: maplibregl.MapEventType[T] & Object) => void): this; (type: string, listener: maplibregl.Listener): this; }" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.panBy.$1", - "type": "CompoundType", + "id": "def-server.Map.once.$1", + "type": "string", "tags": [], - "label": "offset", + "label": "type", "description": [], "signature": [ - "maplibregl.PointLike" + "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.panBy.$2", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "signature": [ - "maplibregl.AnimationOptions | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.panBy.$3", - "type": "Object", + "id": "def-server.Map.once.$2", + "type": "Function", "tags": [], - "label": "eventData", + "label": "listener", "description": [], "signature": [ - "maplibregl.EventData | undefined" + "maplibregl.Listener" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": false + "isRequired": true } ], "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.panTo", + "id": "def-server.Map.off", "type": "Function", - "tags": [], - "label": "panTo", - "description": [], + "tags": [ + "method", + "name", + "memberof", + "instance" + ], + "label": "off", + "description": [ + "\nRemoves an event listener previously added with `Map#on`.\n\n\nRemoves an event listener for layer-specific events previously added with `Map#on`.\n" + ], "signature": [ - "(lnglat: maplibregl.LngLatLike, options?: maplibregl.AnimationOptions | undefined, eventdata?: maplibregl.EventData | undefined) => this" + "{ (type: T, layer: string, listener: (ev: maplibregl.MapLayerEventType[T] & Object) => void): this; (type: T, listener: (ev: maplibregl.MapEventType[T] & Object) => void): this; (type: string, listener: maplibregl.Listener): this; }" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.panTo.$1", - "type": "CompoundType", + "id": "def-server.Map.off.$1", + "type": "Uncategorized", "tags": [], - "label": "lnglat", - "description": [], + "label": "type", + "description": [ + "The event type previously used to install the listener." + ], "signature": [ - "maplibregl.LngLatLike" + "T" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.panTo.$2", - "type": "Object", + "id": "def-server.Map.off.$2", + "type": "string", "tags": [], - "label": "options", + "label": "layer", "description": [], "signature": [ - "maplibregl.AnimationOptions | undefined" + "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": false + "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.panTo.$3", - "type": "Object", + "id": "def-server.Map.off.$3", + "type": "Function", "tags": [], - "label": "eventdata", - "description": [], + "label": "listener", + "description": [ + "The function previously installed as a listener." + ], "signature": [ - "maplibregl.EventData | undefined" + "(ev: maplibregl.MapLayerEventType[T] & Object) => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": false + "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "`this`" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getZoom", + "id": "def-server.Map.off", "type": "Function", "tags": [], - "label": "getZoom", + "label": "off", "description": [], "signature": [ - "() => number" + "{ (type: T, layer: string, listener: (ev: maplibregl.MapLayerEventType[T] & Object) => void): this; (type: T, listener: (ev: maplibregl.MapEventType[T] & Object) => void): this; (type: string, listener: maplibregl.Listener): this; }" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "children": [], + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.off.$1", + "type": "Uncategorized", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "T" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.off.$2", + "type": "Function", + "tags": [], + "label": "listener", + "description": [], + "signature": [ + "(ev: maplibregl.MapEventType[T] & Object) => void" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setZoom", + "id": "def-server.Map.off", "type": "Function", "tags": [], - "label": "setZoom", + "label": "off", "description": [], "signature": [ - "(zoom: number, eventData?: maplibregl.EventData | undefined) => this" + "{ (type: T, layer: string, listener: (ev: maplibregl.MapLayerEventType[T] & Object) => void): this; (type: T, listener: (ev: maplibregl.MapEventType[T] & Object) => void): this; (type: string, listener: maplibregl.Listener): this; }" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setZoom.$1", - "type": "number", + "id": "def-server.Map.off.$1", + "type": "string", "tags": [], - "label": "zoom", + "label": "type", "description": [], "signature": [ - "number" + "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setZoom.$2", - "type": "Object", + "id": "def-server.Map.off.$2", + "type": "Function", "tags": [], - "label": "eventData", + "label": "listener", "description": [], "signature": [ - "maplibregl.EventData | undefined" + "maplibregl.Listener" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": false + "isRequired": true } ], "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.zoomTo", + "id": "def-server.Map.queryRenderedFeatures", "type": "Function", - "tags": [], - "label": "zoomTo", - "description": [], + "tags": [ + "see" + ], + "label": "queryRenderedFeatures", + "description": [ + "\nReturns an array of MapGeoJSONFeature objects\nrepresenting visible features that satisfy the query parameters.\n" + ], "signature": [ - "(zoom: number, options?: maplibregl.AnimationOptions | undefined, eventData?: maplibregl.EventData | undefined) => this" + "(geometry?: maplibregl.PointLike | [maplibregl.PointLike, maplibregl.PointLike] | undefined, options?: any) => maplibregl.MapGeoJSONFeature[]" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.zoomTo.$1", - "type": "number", + "id": "def-server.Map.queryRenderedFeatures.$1", + "type": "CompoundType", "tags": [], - "label": "zoom", - "description": [], + "label": "geometry", + "description": [ + "- The geometry of the query region:\neither a single point or southwest and northeast points describing a bounding box.\nOmitting this parameter (i.e. calling {@link MapqueryRenderedFeatures } with zero arguments,\nor with only a `options` argument) is equivalent to passing a bounding box encompassing the entire\nmap viewport." + ], "signature": [ - "number" + "maplibregl.PointLike | [maplibregl.PointLike, maplibregl.PointLike] | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": true + "isRequired": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.zoomTo.$2", - "type": "Object", + "id": "def-server.Map.queryRenderedFeatures.$2", + "type": "Any", "tags": [], "label": "options", - "description": [], + "description": [ + "Options object." + ], "signature": [ - "maplibregl.AnimationOptions | undefined" + "any" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": false + "isRequired": true + } + ], + "returnComment": [ + "An array of MapGeoJSONFeature objects.\n\nThe `properties` value of each returned feature object contains the properties of its source feature. For GeoJSON sources, only\nstring and numeric property values are supported (i.e. `null`, `Array`, and `Object` values are not supported).\n\nEach feature includes top-level `layer`, `source`, and `sourceLayer` properties. The `layer` property is an object\nrepresenting the style layer to which the feature belongs. Layout and paint properties in this object contain values\nwhich are fully evaluated for the given zoom level and feature.\n\nOnly features that are currently rendered are included. Some features will **not** be included, like:\n\n- Features from layers whose `visibility` property is `\"none\"`.\n- Features from layers whose zoom range excludes the current zoom level.\n- Symbol features that have been hidden due to text or icon collision.\n\nFeatures from all other layers are included, including features that may have no visible\ncontribution to the rendered result; for example, because the layer's opacity or color alpha component is set to\n0.\n\nThe topmost rendered feature appears first in the returned array, and subsequent features are sorted by\ndescending z-order. Features that are rendered multiple times (due to wrapping across the antimeridian at low\nzoom levels) are returned only once (though subject to the following caveat).\n\nBecause features come from tiled vector data or GeoJSON data that is converted to tiles internally, feature\ngeometries may be split or duplicated across tile boundaries and, as a result, features may appear multiple\ntimes in query results. For example, suppose there is a highway running through the bounding rectangle of a query.\nThe results of the query will be those parts of the highway that lie within the map tiles covering the bounding\nrectangle, even if the highway extends into other tiles, and the portion of the highway within each map tile\nwill be returned as a separate feature. Similarly, a point feature near a tile boundary may appear in multiple\ntiles due to tile buffering." + ] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.querySourceFeatures", + "type": "Function", + "tags": [], + "label": "querySourceFeatures", + "description": [ + "\nReturns an array of MapGeoJSONFeature objects\nrepresenting features within the specified vector tile or GeoJSON source that satisfy the query parameters.\n" + ], + "signature": [ + "(sourceId: string, parameters?: { sourceLayer: string; filter: any[]; validate?: boolean | undefined; } | null | undefined) => maplibregl.MapGeoJSONFeature[]" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.querySourceFeatures.$1", + "type": "string", + "tags": [], + "label": "sourceId", + "description": [ + "The ID of the vector tile or GeoJSON source to query." + ], + "signature": [ + "string" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.zoomTo.$3", - "type": "Object", + "id": "def-server.Map.querySourceFeatures.$2", + "type": "CompoundType", "tags": [], - "label": "eventData", - "description": [], + "label": "parameters", + "description": [ + "Options object." + ], "signature": [ - "maplibregl.EventData | undefined" + "{ sourceLayer: string; filter: any[]; validate?: boolean | undefined; } | null | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": false } ], - "returnComment": [] + "returnComment": [ + "An array of MapGeoJSONFeature objects.\n\nIn contrast to {@link MapqueryRenderedFeatures }, this function returns all features matching the query parameters,\nwhether or not they are rendered by the current style (i.e. visible). The domain of the query includes all currently-loaded\nvector tiles and GeoJSON source tiles: this function does not check tiles outside the currently\nvisible viewport.\n\nBecause features come from tiled vector data or GeoJSON data that is converted to tiles internally, feature\ngeometries may be split or duplicated across tile boundaries and, as a result, features may appear multiple\ntimes in query results. For example, suppose there is a highway running through the bounding rectangle of a query.\nThe results of the query will be those parts of the highway that lie within the map tiles covering the bounding\nrectangle, even if the highway extends into other tiles, and the portion of the highway within each map tile\nwill be returned as a separate feature. Similarly, a point feature near a tile boundary may appear in multiple\ntiles due to tile buffering." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.zoomIn", + "id": "def-server.Map.setStyle", "type": "Function", "tags": [], - "label": "zoomIn", - "description": [], + "label": "setStyle", + "description": [ + "\nUpdates the map's MapLibre style object with a new value.\n\nIf a style is already set when this is used and options.diff is set to true, the map renderer will attempt to compare the given style\nagainst the map's current state and perform only the changes necessary to make the map style match the desired state. Changes in sprites\n(images used for icons and patterns) and glyphs (fonts for label text) **cannot** be diffed. If the sprites or fonts used in the current\nstyle and the given style are different in any way, the map renderer will force a full update, removing the current style and building\nthe given one from scratch.\n\n" + ], "signature": [ - "(options?: maplibregl.AnimationOptions | undefined, eventData?: maplibregl.EventData | undefined) => this" + "(style: string | maplibregl.StyleSpecification | null, options?: ({ diff?: boolean | undefined; } & maplibregl.StyleOptions) | undefined) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.zoomIn.$1", - "type": "Object", + "id": "def-server.Map.setStyle.$1", + "type": "CompoundType", "tags": [], - "label": "options", - "description": [], + "label": "style", + "description": [ + "A JSON object conforming to the schema described in the\n[MapLibre Style Specification](https://maplibre.org/maplibre-gl-js-docs/style-spec/), or a URL to such JSON." + ], "signature": [ - "maplibregl.AnimationOptions | undefined" + "string | maplibregl.StyleSpecification | null" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.zoomIn.$2", - "type": "Object", - "tags": [], - "label": "eventData", - "description": [], + "id": "def-server.Map.setStyle.$2", + "type": "CompoundType", + "tags": [], + "label": "options", + "description": [ + "Options object." + ], "signature": [ - "maplibregl.EventData | undefined" + "({ diff?: boolean | undefined; } & maplibregl.StyleOptions) | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": false } ], - "returnComment": [] + "returnComment": [ + "`this`" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.zoomOut", + "id": "def-server.Map.setTransformRequest", "type": "Function", "tags": [], - "label": "zoomOut", - "description": [], + "label": "setTransformRequest", + "description": [ + "\n Updates the requestManager's transform request with a new function\n" + ], "signature": [ - "(options?: maplibregl.AnimationOptions | undefined, eventData?: maplibregl.EventData | undefined) => this" + "(transformRequest: maplibregl.RequestTransformFunction) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.zoomOut.$1", - "type": "Object", + "id": "def-server.Map.setTransformRequest.$1", + "type": "Function", "tags": [], - "label": "options", - "description": [], - "signature": [ - "maplibregl.AnimationOptions | undefined" + "label": "transformRequest", + "description": [ + "A callback run before the Map makes a request for an external URL. The callback can be used to modify the url, set headers, or set the credentials property for cross-origin requests.\nExpected to return an object with a `url` property and optionally `headers` and `credentials` properties" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.zoomOut.$2", - "type": "Object", - "tags": [], - "label": "eventData", - "description": [], "signature": [ - "maplibregl.EventData | undefined" + "maplibregl.RequestTransformFunction" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": false + "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "`this`" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getBearing", + "id": "def-server.Map._getUIString", "type": "Function", "tags": [], - "label": "getBearing", + "label": "_getUIString", "description": [], "signature": [ - "() => number" + "(key: string) => any" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "children": [], + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._getUIString.$1", + "type": "string", + "tags": [], + "label": "key", + "description": [], + "signature": [ + "string" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setBearing", + "id": "def-server.Map._updateStyle", "type": "Function", "tags": [], - "label": "setBearing", + "label": "_updateStyle", "description": [], "signature": [ - "(bearing: number, eventData?: maplibregl.EventData | undefined) => this" + "(style: string | maplibregl.StyleSpecification | null, options?: ({ diff?: boolean | undefined; } & maplibregl.StyleOptions) | undefined) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setBearing.$1", - "type": "number", + "id": "def-server.Map._updateStyle.$1", + "type": "CompoundType", "tags": [], - "label": "bearing", + "label": "style", "description": [], "signature": [ - "number" + "string | maplibregl.StyleSpecification | null" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": true + "isRequired": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setBearing.$2", - "type": "Object", + "id": "def-server.Map._updateStyle.$2", + "type": "CompoundType", "tags": [], - "label": "eventData", + "label": "options", "description": [], "signature": [ - "maplibregl.EventData | undefined" + "({ diff?: boolean | undefined; } & maplibregl.StyleOptions) | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": false } @@ -3140,133 +3639,101 @@ }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getPadding", + "id": "def-server.Map._lazyInitEmptyStyle", "type": "Function", - "tags": [ - "memberof" - ], - "label": "getPadding", - "description": [ - "\nReturns the current padding applied around the map viewport.\n" - ], + "tags": [], + "label": "_lazyInitEmptyStyle", + "description": [], "signature": [ - "() => maplibregl.PaddingOptions" + "() => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [], - "returnComment": [ - "The current padding around the map viewport." - ] + "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setPadding", + "id": "def-server.Map._diffStyle", "type": "Function", - "tags": [ - "memberof", - "fires", - "fires" - ], - "label": "setPadding", - "description": [ - "\nSets the padding in pixels around the viewport.\n\nEquivalent to `jumpTo({padding: padding})`.\n" - ], + "tags": [], + "label": "_diffStyle", + "description": [], "signature": [ - "(padding: maplibregl.RequireAtLeastOne, eventData?: maplibregl.EventData | undefined) => this" + "(style: string | maplibregl.StyleSpecification, options?: ({ diff?: boolean | undefined; } & maplibregl.StyleOptions) | undefined) => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setPadding.$1", + "id": "def-server.Map._diffStyle.$1", "type": "CompoundType", "tags": [], - "label": "padding", - "description": [ - "The desired padding. Format: { left: number, right: number, top: number, bottom: number }" - ], + "label": "style", + "description": [], "signature": [ - "maplibregl.RequireAtLeastOne" + "string | maplibregl.StyleSpecification" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setPadding.$2", - "type": "Object", + "id": "def-server.Map._diffStyle.$2", + "type": "CompoundType", "tags": [], - "label": "eventData", - "description": [ - "Additional properties to be added to event objects of events triggered by this method." - ], + "label": "options", + "description": [], "signature": [ - "maplibregl.EventData | undefined" + "({ diff?: boolean | undefined; } & maplibregl.StyleOptions) | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": false } ], - "returnComment": [ - "`this`" - ] + "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.rotateTo", + "id": "def-server.Map._updateDiff", "type": "Function", "tags": [], - "label": "rotateTo", + "label": "_updateDiff", "description": [], "signature": [ - "(bearing: number, options?: maplibregl.AnimationOptions | undefined, eventData?: maplibregl.EventData | undefined) => this" + "(style: maplibregl.StyleSpecification, options?: ({ diff?: boolean | undefined; } & maplibregl.StyleOptions) | undefined) => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.rotateTo.$1", - "type": "number", + "id": "def-server.Map._updateDiff.$1", + "type": "Object", "tags": [], - "label": "bearing", + "label": "style", "description": [], "signature": [ - "number" + "maplibregl.StyleSpecification" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.rotateTo.$2", - "type": "Object", + "id": "def-server.Map._updateDiff.$2", + "type": "CompoundType", "tags": [], "label": "options", "description": [], "signature": [ - "maplibregl.AnimationOptions | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.rotateTo.$3", - "type": "Object", - "tags": [], - "label": "eventData", - "description": [], - "signature": [ - "maplibregl.EventData | undefined" + "({ diff?: boolean | undefined; } & maplibregl.StyleOptions) | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": false } @@ -3275,377 +3742,357 @@ }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.resetNorth", + "id": "def-server.Map.getStyle", "type": "Function", "tags": [], - "label": "resetNorth", - "description": [], + "label": "getStyle", + "description": [ + "\nReturns the map's MapLibre style object, a JSON object which can be used to recreate the map's style.\n" + ], "signature": [ - "(options?: maplibregl.AnimationOptions | undefined, eventData?: maplibregl.EventData | undefined) => this" + "() => maplibregl.StyleSpecification" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.resetNorth.$1", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "signature": [ - "maplibregl.AnimationOptions | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.resetNorth.$2", - "type": "Object", - "tags": [], - "label": "eventData", - "description": [], - "signature": [ - "maplibregl.EventData | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] + "children": [], + "returnComment": [ + "The map's style JSON object." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.resetNorthPitch", + "id": "def-server.Map.isStyleLoaded", "type": "Function", "tags": [], - "label": "resetNorthPitch", - "description": [], + "label": "isStyleLoaded", + "description": [ + "\nReturns a Boolean indicating whether the map's style is fully loaded.\n" + ], + "signature": [ + "() => boolean | void" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [ + "A Boolean indicating whether the style is fully loaded." + ] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.addSource", + "type": "Function", + "tags": [ + "fires", + "see" + ], + "label": "addSource", + "description": [ + "\nAdds a source to the map's style.\n" + ], "signature": [ - "(options?: maplibregl.AnimationOptions | null | undefined, eventData?: maplibregl.EventData | null | undefined) => this" + "(id: string, source: maplibregl.SourceSpecification) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.resetNorthPitch.$1", - "type": "CompoundType", + "id": "def-server.Map.addSource.$1", + "type": "string", "tags": [], - "label": "options", - "description": [], + "label": "id", + "description": [ + "The ID of the source to add. Must not conflict with existing sources." + ], "signature": [ - "maplibregl.AnimationOptions | null | undefined" + "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": false + "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.resetNorthPitch.$2", + "id": "def-server.Map.addSource.$2", "type": "CompoundType", "tags": [], - "label": "eventData", - "description": [], + "label": "source", + "description": [ + "The source object, conforming to the\nMapLibre Style Specification's [source definition](https://maplibre.org/maplibre-gl-js-docs/style-spec/#sources) or\n{@link CanvasSourceOptions }." + ], "signature": [ - "maplibregl.EventData | null | undefined" + "maplibregl.SourceSpecification" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": false + "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "`this`" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.snapToNorth", + "id": "def-server.Map.isSourceLoaded", "type": "Function", "tags": [], - "label": "snapToNorth", - "description": [], + "label": "isSourceLoaded", + "description": [ + "\nReturns a Boolean indicating whether the source is loaded. Returns `true` if the source with\nthe given ID in the map's style has no outstanding network requests, otherwise `false`.\n" + ], "signature": [ - "(options?: maplibregl.AnimationOptions | undefined, eventData?: maplibregl.EventData | undefined) => this" + "(id: string) => boolean" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.snapToNorth.$1", - "type": "Object", + "id": "def-server.Map.isSourceLoaded.$1", + "type": "string", "tags": [], - "label": "options", - "description": [], - "signature": [ - "maplibregl.AnimationOptions | undefined" + "label": "id", + "description": [ + "The ID of the source to be checked." ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.snapToNorth.$2", - "type": "Object", - "tags": [], - "label": "eventData", - "description": [], "signature": [ - "maplibregl.EventData | undefined" + "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": false + "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "A Boolean indicating whether the source is loaded." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.getPitch", + "id": "def-server.Map.areTilesLoaded", "type": "Function", "tags": [], - "label": "getPitch", - "description": [], + "label": "areTilesLoaded", + "description": [ + "\nReturns a Boolean indicating whether all tiles in the viewport from all sources on\nthe style are loaded.\n" + ], "signature": [ - "() => number" + "() => boolean" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "A Boolean indicating whether all tiles are loaded." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setPitch", + "id": "def-server.Map.addSourceType", "type": "Function", - "tags": [], - "label": "setPitch", - "description": [], + "tags": [ + "private" + ], + "label": "addSourceType", + "description": [ + "\nAdds a [custom source type](#Custom Sources), making it available for use with\n{@link Map#addSource}." + ], "signature": [ - "(pitch: number, eventData?: maplibregl.EventData | undefined) => this" + "(name: string, SourceType: any, callback: maplibregl.Callback) => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setPitch.$1", - "type": "number", + "id": "def-server.Map.addSourceType.$1", + "type": "string", "tags": [], - "label": "pitch", - "description": [], + "label": "name", + "description": [ + "The name of the source type; source definition objects use this name in the `{type: ...}` field." + ], "signature": [ - "number" + "string" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.addSourceType.$2", + "type": "Any", + "tags": [], + "label": "SourceType", + "description": [ + "A {@link Source } constructor." + ], + "signature": [ + "any" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.setPitch.$2", - "type": "Object", + "id": "def-server.Map.addSourceType.$3", + "type": "Function", "tags": [], - "label": "eventData", - "description": [], + "label": "callback", + "description": [ + "Called when the source type is ready or with an error argument if there is an error." + ], "signature": [ - "maplibregl.EventData | undefined" + "maplibregl.Callback" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": false + "isRequired": true } ], "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.cameraForBounds", + "id": "def-server.Map.removeSource", "type": "Function", "tags": [], - "label": "cameraForBounds", - "description": [], + "label": "removeSource", + "description": [ + "\nRemoves a source from the map's style.\n" + ], "signature": [ - "(bounds: maplibregl.LngLatBoundsLike, options?: maplibregl.CameraForBoundsOptions | undefined) => maplibregl.CameraForBoundsResult | undefined" + "(id: string) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.cameraForBounds.$1", - "type": "CompoundType", + "id": "def-server.Map.removeSource.$1", + "type": "string", "tags": [], - "label": "bounds", - "description": [], - "signature": [ - "maplibregl.LngLatBoundsLike" + "label": "id", + "description": [ + "The ID of the source to remove." ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.cameraForBounds.$2", - "type": "Object", - "tags": [], - "label": "options", - "description": [], "signature": [ - "maplibregl.CameraForBoundsOptions | undefined" + "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": false + "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "`this`" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.fitBounds", + "id": "def-server.Map.getSource", "type": "Function", - "tags": [], - "label": "fitBounds", - "description": [], + "tags": [ + "see", + "see", + "see" + ], + "label": "getSource", + "description": [ + "\nReturns the source with the specified ID in the map's style.\n\nThis method is often used to update a source using the instance members for the relevant\nsource type as defined in [Sources](#sources).\nFor example, setting the `data` for a GeoJSON source or updating the `url` and `coordinates`\nof an image source.\n" + ], "signature": [ - "(bounds: maplibregl.LngLatBoundsLike, options?: maplibregl.FitBoundsOptions | undefined, eventData?: maplibregl.EventData | undefined) => this" + "(id: string) => maplibregl.Source | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.fitBounds.$1", - "type": "CompoundType", - "tags": [], - "label": "bounds", - "description": [], - "signature": [ - "maplibregl.LngLatBoundsLike" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.fitBounds.$2", - "type": "Object", + "id": "def-server.Map.getSource.$1", + "type": "string", "tags": [], - "label": "options", - "description": [], - "signature": [ - "maplibregl.FitBoundsOptions | undefined" + "label": "id", + "description": [ + "The ID of the source to get." ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.fitBounds.$3", - "type": "Object", - "tags": [], - "label": "eventData", - "description": [], "signature": [ - "maplibregl.EventData | undefined" + "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": false + "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The style source with the specified ID or `undefined` if the ID\ncorresponds to no existing sources.\nThe shape of the object varies by source type.\nA list of options for each source type is available on the MapLibre Style Specification's\n[Sources](https://maplibre.org/maplibre-gl-js-docs/style-spec/sources/) page." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.fitScreenCoordinates", + "id": "def-server.Map.addImage", "type": "Function", - "tags": [], - "label": "fitScreenCoordinates", - "description": [], + "tags": [ + "see", + "see" + ], + "label": "addImage", + "description": [ + "\nAdd an image to the style. This image can be displayed on the map like any other icon in the style's\nsprite using the image's ID with\n[`icon-image`](https://maplibre.org/maplibre-gl-js-docs/style-spec/#layout-symbol-icon-image),\n[`background-pattern`](https://maplibre.org/maplibre-gl-js-docs/style-spec/#paint-background-background-pattern),\n[`fill-pattern`](https://maplibre.org/maplibre-gl-js-docs/style-spec/#paint-fill-fill-pattern),\nor [`line-pattern`](https://maplibre.org/maplibre-gl-js-docs/style-spec/#paint-line-line-pattern).\nA {@link Map.event:error} event will be fired if there is not enough space in the sprite to add this image.\n" + ], "signature": [ - "(p0: maplibregl.PointLike, p1: maplibregl.PointLike, bearing: number, options?: (maplibregl.AnimationOptions & maplibregl.CameraOptions) | undefined, eventData?: maplibregl.EventData | undefined) => this" + "(id: string, image: HTMLImageElement | ImageBitmap | ImageData | { width: number; height: number; data: Uint8Array | Uint8ClampedArray; } | maplibregl.StyleImageInterface, { pixelRatio, sdf, stretchX, stretchY, content }?: Partial | undefined) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.fitScreenCoordinates.$1", - "type": "CompoundType", + "id": "def-server.Map.addImage.$1", + "type": "string", "tags": [], - "label": "p0", - "description": [], + "label": "id", + "description": [ + "The ID of the image." + ], "signature": [ - "maplibregl.PointLike" + "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.fitScreenCoordinates.$2", + "id": "def-server.Map.addImage.$2", "type": "CompoundType", "tags": [], - "label": "p1", - "description": [], - "signature": [ - "maplibregl.PointLike" + "label": "image", + "description": [ + "The image as an `HTMLImageElement`, `ImageData`, `ImageBitmap` or object with `width`, `height`, and `data`\nproperties with the same format as `ImageData`." ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.fitScreenCoordinates.$3", - "type": "number", - "tags": [], - "label": "bearing", - "description": [], "signature": [ - "number" + "HTMLImageElement | ImageBitmap | ImageData | { width: number; height: number; data: Uint8Array | Uint8ClampedArray; } | maplibregl.StyleImageInterface" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.fitScreenCoordinates.$4", - "type": "CompoundType", - "tags": [], - "label": "options", - "description": [], - "signature": [ - "(maplibregl.AnimationOptions & maplibregl.CameraOptions) | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.fitScreenCoordinates.$5", + "id": "def-server.Map.addImage.$3", "type": "Object", "tags": [], - "label": "eventData", + "label": "{ pixelRatio, sdf, stretchX, stretchY, content }", "description": [], "signature": [ - "maplibregl.EventData | undefined" + "Partial | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": false } @@ -3654,218 +4101,170 @@ }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.jumpTo", + "id": "def-server.Map.updateImage", "type": "Function", "tags": [], - "label": "jumpTo", - "description": [], + "label": "updateImage", + "description": [ + "\nUpdate an existing image in a style. This image can be displayed on the map like any other icon in the style's\nsprite using the image's ID with\n[`icon-image`](https://maplibre.org/maplibre-gl-js-docs/style-spec/#layout-symbol-icon-image),\n[`background-pattern`](https://maplibre.org/maplibre-gl-js-docs/style-spec/#paint-background-background-pattern),\n[`fill-pattern`](https://maplibre.org/maplibre-gl-js-docs/style-spec/#paint-fill-fill-pattern),\nor [`line-pattern`](https://maplibre.org/maplibre-gl-js-docs/style-spec/#paint-line-line-pattern).\n" + ], "signature": [ - "(options: maplibregl.CameraOptions, eventData?: maplibregl.EventData | undefined) => this" + "(id: string, image: HTMLImageElement | ImageBitmap | ImageData | maplibregl.StyleImageInterface | { width: number; height: number; data: Uint8Array | Uint8ClampedArray; }) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.jumpTo.$1", - "type": "Object", + "id": "def-server.Map.updateImage.$1", + "type": "string", "tags": [], - "label": "options", - "description": [], + "label": "id", + "description": [ + "The ID of the image." + ], "signature": [ - "maplibregl.CameraOptions" + "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.jumpTo.$2", - "type": "Object", + "id": "def-server.Map.updateImage.$2", + "type": "CompoundType", "tags": [], - "label": "eventData", - "description": [], + "label": "image", + "description": [ + "The image as an `HTMLImageElement`, `ImageData`, `ImageBitmap` or object with `width`, `height`, and `data`\nproperties with the same format as `ImageData`." + ], "signature": [ - "maplibregl.EventData | undefined" + "HTMLImageElement | ImageBitmap | ImageData | maplibregl.StyleImageInterface | { width: number; height: number; data: Uint8Array | Uint8ClampedArray; }" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": false + "isRequired": true } ], "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.easeTo", + "id": "def-server.Map.hasImage", "type": "Function", "tags": [], - "label": "easeTo", - "description": [], + "label": "hasImage", + "description": [ + "\nCheck whether or not an image with a specific ID exists in the style. This checks both images\nin the style's original sprite and any images\nthat have been added at runtime using {@link Map#addImage}.\n" + ], "signature": [ - "(options: maplibregl.EaseToOptions, eventData?: maplibregl.EventData | undefined) => this" + "(id: string) => boolean" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.easeTo.$1", - "type": "Object", + "id": "def-server.Map.hasImage.$1", + "type": "string", "tags": [], - "label": "options", - "description": [], - "signature": [ - "maplibregl.EaseToOptions" + "label": "id", + "description": [ + "The ID of the image." ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.easeTo.$2", - "type": "Object", - "tags": [], - "label": "eventData", - "description": [], "signature": [ - "maplibregl.EventData | undefined" + "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": false + "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "A Boolean indicating whether the image exists." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.flyTo", + "id": "def-server.Map.removeImage", "type": "Function", "tags": [], - "label": "flyTo", - "description": [], + "label": "removeImage", + "description": [ + "\nRemove an image from a style. This can be an image from the style's original\nsprite or any images\nthat have been added at runtime using {@link Map#addImage}.\n" + ], "signature": [ - "(options: maplibregl.FlyToOptions, eventData?: maplibregl.EventData | undefined) => this" + "(id: string) => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.flyTo.$1", - "type": "Object", + "id": "def-server.Map.removeImage.$1", + "type": "string", "tags": [], - "label": "options", - "description": [], - "signature": [ - "maplibregl.FlyToOptions" + "label": "id", + "description": [ + "The ID of the image." ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.flyTo.$2", - "type": "Object", - "tags": [], - "label": "eventData", - "description": [], "signature": [ - "maplibregl.EventData | undefined" + "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": false + "isRequired": true } ], "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.isEasing", + "id": "def-server.Map.loadImage", "type": "Function", - "tags": [], - "label": "isEasing", - "description": [], - "signature": [ - "() => boolean" + "tags": [ + "see" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.stop", - "type": "Function", - "tags": [], - "label": "stop", - "description": [], - "signature": [ - "() => this" + "label": "loadImage", + "description": [ + "\nLoad an image from an external URL to be used with {@link Map#addImage}. External\ndomains must support [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS).\n" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.on", - "type": "Function", - "tags": [], - "label": "on", - "description": [], "signature": [ - "{ (type: T, layer: string, listener: (ev: maplibregl.MapLayerEventType[T] & maplibregl.EventData) => void): this; (type: T, listener: (ev: maplibregl.MapEventType[T] & maplibregl.EventData) => void): this; (type: string, listener: (ev: any) => void): this; }" + "(url: string, callback: maplibregl.GetImageCallback) => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.on.$1", - "type": "Uncategorized", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "T" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.on.$2", + "id": "def-server.Map.loadImage.$1", "type": "string", "tags": [], - "label": "layer", - "description": [], + "label": "url", + "description": [ + "The URL of the image file. Image file must be in png, webp, or jpg format." + ], "signature": [ "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.on.$3", + "id": "def-server.Map.loadImage.$2", "type": "Function", "tags": [], - "label": "listener", - "description": [], + "label": "callback", + "description": [ + "Expecting `callback(error, data)`. Called when the image has loaded or with an error argument if there is an error." + ], "signature": [ - "(ev: maplibregl.MapLayerEventType[T] & maplibregl.EventData) => void" + "maplibregl.GetImageCallback" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } @@ -3874,144 +4273,161 @@ }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.on", + "id": "def-server.Map.listImages", "type": "Function", "tags": [], - "label": "on", - "description": [], + "label": "listImages", + "description": [ + "\nReturns an Array of strings containing the IDs of all images currently available in the map.\nThis includes both images from the style's original sprite\nand any images that have been added at runtime using {@link Map#addImage}.\n" + ], + "signature": [ + "() => string[]" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [ + "An Array of strings containing the names of all sprites/images currently available in the map." + ] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.addLayer", + "type": "Function", + "tags": [ + "see", + "see", + "see" + ], + "label": "addLayer", + "description": [ + "\nAdds a [MapLibre style layer](https://maplibre.org/maplibre-gl-js-docs/style-spec/#layers)\nto the map's style.\n\nA layer defines how data from a specified source will be styled. Read more about layer types\nand available paint and layout properties in the [MapLibre Style Specification](https://maplibre.org/maplibre-gl-js-docs/style-spec/#layers).\n" + ], "signature": [ - "{ (type: T, layer: string, listener: (ev: maplibregl.MapLayerEventType[T] & maplibregl.EventData) => void): this; (type: T, listener: (ev: maplibregl.MapEventType[T] & maplibregl.EventData) => void): this; (type: string, listener: (ev: any) => void): this; }" + "(layer: maplibregl.LayerSpecification | maplibregl.CustomLayerInterface, beforeId?: string | undefined) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.on.$1", - "type": "Uncategorized", + "id": "def-server.Map.addLayer.$1", + "type": "CompoundType", "tags": [], - "label": "type", - "description": [], + "label": "layer", + "description": [ + "The layer to add, conforming to either the MapLibre Style Specification's [layer definition](https://maplibre.org/maplibre-gl-js-docs/style-spec/#layers) or, less commonly, the {@link CustomLayerInterface } specification.\nThe MapLibre Style Specification's layer definition is appropriate for most layers." + ], "signature": [ - "T" + "maplibregl.LayerSpecification | maplibregl.CustomLayerInterface" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.on.$2", - "type": "Function", + "id": "def-server.Map.addLayer.$2", + "type": "string", "tags": [], - "label": "listener", - "description": [], + "label": "beforeId", + "description": [ + "The ID of an existing layer to insert the new layer before,\nresulting in the new layer appearing visually beneath the existing layer.\nIf this argument is not specified, the layer will be appended to the end of the layers array\nand appear visually above all other layers." + ], "signature": [ - "(ev: maplibregl.MapEventType[T] & maplibregl.EventData) => void" + "string | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": true + "isRequired": false } ], - "returnComment": [] + "returnComment": [ + "`this`" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.on", + "id": "def-server.Map.moveLayer", "type": "Function", "tags": [], - "label": "on", - "description": [], + "label": "moveLayer", + "description": [ + "\nMoves a layer to a different z-position.\n" + ], "signature": [ - "{ (type: T, layer: string, listener: (ev: maplibregl.MapLayerEventType[T] & maplibregl.EventData) => void): this; (type: T, listener: (ev: maplibregl.MapEventType[T] & maplibregl.EventData) => void): this; (type: string, listener: (ev: any) => void): this; }" + "(id: string, beforeId?: string | undefined) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.on.$1", + "id": "def-server.Map.moveLayer.$1", "type": "string", "tags": [], - "label": "type", - "description": [], + "label": "id", + "description": [ + "The ID of the layer to move." + ], "signature": [ "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.on.$2", - "type": "Function", + "id": "def-server.Map.moveLayer.$2", + "type": "string", "tags": [], - "label": "listener", - "description": [], + "label": "beforeId", + "description": [ + "The ID of an existing layer to insert the new layer before. When viewing the map, the `id` layer will appear beneath the `beforeId` layer. If `beforeId` is omitted, the layer will be appended to the end of the layers array and appear above all other layers on the map." + ], "signature": [ - "(ev: any) => void" + "string | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": true + "isRequired": false } ], - "returnComment": [] + "returnComment": [ + "`this`" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.once", + "id": "def-server.Map.removeLayer", "type": "Function", - "tags": [], - "label": "once", - "description": [], + "tags": [ + "fires" + ], + "label": "removeLayer", + "description": [ + "\nRemoves the layer with the given ID from the map's style.\n\nIf no such layer exists, an `error` event is fired.\n" + ], "signature": [ - "{ (type: T, layer: string, listener: (ev: maplibregl.MapLayerEventType[T] & maplibregl.EventData) => void): this; (type: T, listener: (ev: maplibregl.MapEventType[T] & maplibregl.EventData) => void): this; (type: string, listener: (ev: any) => void): this; }" + "(id: string) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.once.$1", - "type": "Uncategorized", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "T" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.once.$2", + "id": "def-server.Map.removeLayer.$1", "type": "string", "tags": [], - "label": "layer", - "description": [], - "signature": [ - "string" + "label": "id", + "description": [ + "id of the layer to remove" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.once.$3", - "type": "Function", - "tags": [], - "label": "listener", - "description": [], "signature": [ - "(ev: maplibregl.MapLayerEventType[T] & maplibregl.EventData) => void" + "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } @@ -4020,633 +4436,609 @@ }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.once", + "id": "def-server.Map.getLayer", "type": "Function", - "tags": [], - "label": "once", - "description": [], + "tags": [ + "see", + "see" + ], + "label": "getLayer", + "description": [ + "\nReturns the layer with the specified ID in the map's style.\n" + ], "signature": [ - "{ (type: T, layer: string, listener: (ev: maplibregl.MapLayerEventType[T] & maplibregl.EventData) => void): this; (type: T, listener: (ev: maplibregl.MapEventType[T] & maplibregl.EventData) => void): this; (type: string, listener: (ev: any) => void): this; }" + "(id: string) => StyleLayer" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.once.$1", - "type": "Uncategorized", + "id": "def-server.Map.getLayer.$1", + "type": "string", "tags": [], - "label": "type", - "description": [], - "signature": [ - "T" + "label": "id", + "description": [ + "The ID of the layer to get." ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.once.$2", - "type": "Function", - "tags": [], - "label": "listener", - "description": [], "signature": [ - "(ev: maplibregl.MapEventType[T] & maplibregl.EventData) => void" + "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The layer with the specified ID, or `undefined`\nif the ID corresponds to no existing layers." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.once", + "id": "def-server.Map.setLayerZoomRange", "type": "Function", "tags": [], - "label": "once", - "description": [], + "label": "setLayerZoomRange", + "description": [ + "\nSets the zoom extent for the specified style layer. The zoom extent includes the\n[minimum zoom level](https://maplibre.org/maplibre-gl-js-docs/style-spec/#layer-minzoom)\nand [maximum zoom level](https://maplibre.org/maplibre-gl-js-docs/style-spec/#layer-maxzoom))\nat which the layer will be rendered.\n\nNote: For style layers using vector sources, style layers cannot be rendered at zoom levels lower than the\nminimum zoom level of the _source layer_ because the data does not exist at those zoom levels. If the minimum\nzoom level of the source layer is higher than the minimum zoom level defined in the style layer, the style\nlayer will not be rendered at all zoom levels in the zoom range.\n" + ], "signature": [ - "{ (type: T, layer: string, listener: (ev: maplibregl.MapLayerEventType[T] & maplibregl.EventData) => void): this; (type: T, listener: (ev: maplibregl.MapEventType[T] & maplibregl.EventData) => void): this; (type: string, listener: (ev: any) => void): this; }" + "(layerId: string, minzoom: number, maxzoom: number) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.once.$1", + "id": "def-server.Map.setLayerZoomRange.$1", "type": "string", "tags": [], - "label": "type", - "description": [], + "label": "layerId", + "description": [ + "The ID of the layer to which the zoom extent will be applied." + ], "signature": [ "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.once.$2", - "type": "Function", + "id": "def-server.Map.setLayerZoomRange.$2", + "type": "number", "tags": [], - "label": "listener", - "description": [], + "label": "minzoom", + "description": [ + "The minimum zoom to set (0-24)." + ], + "signature": [ + "number" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.setLayerZoomRange.$3", + "type": "number", + "tags": [], + "label": "maxzoom", + "description": [ + "The maximum zoom to set (0-24)." + ], "signature": [ - "(ev: any) => void" + "number" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "`this`" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.off", + "id": "def-server.Map.setFilter", "type": "Function", - "tags": [], - "label": "off", - "description": [], + "tags": [ + "see" + ], + "label": "setFilter", + "description": [ + "\nSets the filter for the specified style layer.\n\nFilters control which features a style layer renders from its source.\nAny feature for which the filter expression evaluates to `true` will be\nrendered on the map. Those that are false will be hidden.\n\nUse `setFilter` to show a subset of your source data.\n\nTo clear the filter, pass `null` or `undefined` as the second parameter.\n" + ], "signature": [ - "{ (type: T, layer: string, listener: (ev: maplibregl.MapLayerEventType[T] & maplibregl.EventData) => void): this; (type: T, listener: (ev: maplibregl.MapEventType[T] & maplibregl.EventData) => void): this; (type: string, listener: (ev: any) => void): this; }" + "(layerId: string, filter?: maplibregl.FilterSpecification | null | undefined, options?: maplibregl.StyleSetterOptions | undefined) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.off.$1", - "type": "Uncategorized", + "id": "def-server.Map.setFilter.$1", + "type": "string", "tags": [], - "label": "type", - "description": [], + "label": "layerId", + "description": [ + "The ID of the layer to which the filter will be applied." + ], "signature": [ - "T" + "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.off.$2", - "type": "string", + "id": "def-server.Map.setFilter.$2", + "type": "CompoundType", "tags": [], - "label": "layer", - "description": [], + "label": "filter", + "description": [ + "The filter, conforming to the MapLibre Style Specification's\n[filter definition](https://maplibre.org/maplibre-gl-js-docs/style-spec/layers/#filter). If `null` or `undefined` is provided, the function removes any existing filter from the layer." + ], "signature": [ - "string" + "maplibregl.FilterSpecification | null | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": true + "isRequired": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.off.$3", - "type": "Function", + "id": "def-server.Map.setFilter.$3", + "type": "Object", "tags": [], - "label": "listener", - "description": [], + "label": "options", + "description": [ + "Options object." + ], "signature": [ - "(ev: maplibregl.MapLayerEventType[T] & maplibregl.EventData) => void" + "maplibregl.StyleSetterOptions | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": true + "isRequired": false } ], - "returnComment": [] + "returnComment": [ + "`this`" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.off", + "id": "def-server.Map.getFilter", "type": "Function", - "tags": [], - "label": "off", - "description": [], + "tags": [], + "label": "getFilter", + "description": [ + "\nReturns the filter applied to the specified style layer.\n" + ], "signature": [ - "{ (type: T, layer: string, listener: (ev: maplibregl.MapLayerEventType[T] & maplibregl.EventData) => void): this; (type: T, listener: (ev: maplibregl.MapEventType[T] & maplibregl.EventData) => void): this; (type: string, listener: (ev: any) => void): this; }" + "(layerId: string) => void | maplibregl.FilterSpecification" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.off.$1", - "type": "Uncategorized", + "id": "def-server.Map.getFilter.$1", + "type": "string", "tags": [], - "label": "type", - "description": [], - "signature": [ - "T" + "label": "layerId", + "description": [ + "The ID of the style layer whose filter to get." ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.off.$2", - "type": "Function", - "tags": [], - "label": "listener", - "description": [], "signature": [ - "(ev: maplibregl.MapEventType[T] & maplibregl.EventData) => void" + "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The layer's filter." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.off", + "id": "def-server.Map.setPaintProperty", "type": "Function", - "tags": [], - "label": "off", - "description": [], + "tags": [ + "see", + "see" + ], + "label": "setPaintProperty", + "description": [ + "\nSets the value of a paint property in the specified style layer.\n" + ], "signature": [ - "{ (type: T, layer: string, listener: (ev: maplibregl.MapLayerEventType[T] & maplibregl.EventData) => void): this; (type: T, listener: (ev: maplibregl.MapEventType[T] & maplibregl.EventData) => void): this; (type: string, listener: (ev: any) => void): this; }" + "(layerId: string, name: string, value: any, options?: maplibregl.StyleSetterOptions | undefined) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.off.$1", + "id": "def-server.Map.setPaintProperty.$1", "type": "string", "tags": [], - "label": "type", - "description": [], + "label": "layerId", + "description": [ + "The ID of the layer to set the paint property in." + ], "signature": [ "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.off.$2", - "type": "Function", + "id": "def-server.Map.setPaintProperty.$2", + "type": "string", "tags": [], - "label": "listener", - "description": [], + "label": "name", + "description": [ + "The name of the paint property to set." + ], "signature": [ - "(ev: any) => void" + "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.scrollZoom", - "type": "Object", - "tags": [], - "label": "scrollZoom", - "description": [], - "signature": [ - "maplibregl.ScrollZoomHandler" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.boxZoom", - "type": "Object", - "tags": [], - "label": "boxZoom", - "description": [], - "signature": [ - "maplibregl.BoxZoomHandler" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.dragRotate", - "type": "Object", - "tags": [], - "label": "dragRotate", - "description": [], - "signature": [ - "maplibregl.DragRotateHandler" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.dragPan", - "type": "Object", - "tags": [], - "label": "dragPan", - "description": [], - "signature": [ - "maplibregl.DragPanHandler" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.keyboard", - "type": "Object", - "tags": [], - "label": "keyboard", - "description": [], - "signature": [ - "maplibregl.KeyboardHandler" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.doubleClickZoom", - "type": "Object", - "tags": [], - "label": "doubleClickZoom", - "description": [], - "signature": [ - "maplibregl.DoubleClickZoomHandler" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.touchZoomRotate", - "type": "Object", - "tags": [], - "label": "touchZoomRotate", - "description": [], - "signature": [ - "maplibregl.TouchZoomRotateHandler" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Map.touchPitch", - "type": "Object", - "tags": [], - "label": "touchPitch", - "description": [], - "signature": [ - "maplibregl.TouchPitchHandler" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapMouseEvent", - "type": "Class", - "tags": [], - "label": "MapMouseEvent", - "description": [], - "signature": [ - "maplibregl.MapMouseEvent extends maplibregl.MapboxEvent" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapMouseEvent.type", - "type": "CompoundType", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "\"click\" | \"dblclick\" | \"mousedown\" | \"mouseup\" | \"mousemove\" | \"mouseenter\" | \"mouseleave\" | \"mouseover\" | \"mouseout\" | \"contextmenu\"" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapMouseEvent.point", - "type": "Object", - "tags": [], - "label": "point", - "description": [], - "signature": [ - "maplibregl.Point" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapMouseEvent.lngLat", - "type": "Object", - "tags": [], - "label": "lngLat", - "description": [], - "signature": [ - "maplibregl.LngLat" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapMouseEvent.preventDefault", - "type": "Function", - "tags": [], - "label": "preventDefault", - "description": [], - "signature": [ - "() => void" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapMouseEvent.defaultPrevented", - "type": "boolean", - "tags": [], - "label": "defaultPrevented", - "description": [], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point", - "type": "Class", - "tags": [], - "label": "Point", - "description": [ - "\nPoint" - ], - "signature": [ - "maplibregl.Point" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.x", - "type": "number", - "tags": [], - "label": "x", - "description": [], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.y", - "type": "number", - "tags": [], - "label": "y", - "description": [], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.setPaintProperty.$3", + "type": "Any", + "tags": [], + "label": "value", + "description": [ + "The value of the paint property to set.\nMust be of a type appropriate for the property, as defined in the [MapLibre Style Specification](https://maplibre.org/maplibre-gl-js-docs/style-spec/)." + ], + "signature": [ + "any" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.setPaintProperty.$4", + "type": "Object", + "tags": [], + "label": "options", + "description": [ + "Options object." + ], + "signature": [ + "maplibregl.StyleSetterOptions | undefined" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [ + "`this`" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.Unnamed", + "id": "def-server.Map.getPaintProperty", "type": "Function", "tags": [], - "label": "Constructor", - "description": [], + "label": "getPaintProperty", + "description": [ + "\nReturns the value of a paint property in the specified style layer.\n" + ], "signature": [ - "any" + "(layerId: string, name: string) => unknown" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.Unnamed.$1", - "type": "number", + "id": "def-server.Map.getPaintProperty.$1", + "type": "string", "tags": [], - "label": "x", - "description": [], + "label": "layerId", + "description": [ + "The ID of the layer to get the paint property from." + ], "signature": [ - "number" + "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.Unnamed.$2", - "type": "number", + "id": "def-server.Map.getPaintProperty.$2", + "type": "string", "tags": [], - "label": "y", - "description": [], + "label": "name", + "description": [ + "The name of a paint property to get." + ], "signature": [ - "number" + "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The value of the specified paint property." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.clone", + "id": "def-server.Map.setLayoutProperty", "type": "Function", "tags": [], - "label": "clone", - "description": [], - "signature": [ - "() => maplibregl.Point" + "label": "setLayoutProperty", + "description": [ + "\nSets the value of a layout property in the specified style layer.\n" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.add", - "type": "Function", - "tags": [], - "label": "add", - "description": [], "signature": [ - "(p: maplibregl.Point) => maplibregl.Point" + "(layerId: string, name: string, value: any, options?: maplibregl.StyleSetterOptions | undefined) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.add.$1", - "type": "Object", + "id": "def-server.Map.setLayoutProperty.$1", + "type": "string", "tags": [], - "label": "p", - "description": [], + "label": "layerId", + "description": [ + "The ID of the layer to set the layout property in." + ], + "signature": [ + "string" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.setLayoutProperty.$2", + "type": "string", + "tags": [], + "label": "name", + "description": [ + "The name of the layout property to set." + ], + "signature": [ + "string" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.setLayoutProperty.$3", + "type": "Any", + "tags": [], + "label": "value", + "description": [ + "The value of the layout property. Must be of a type appropriate for the property, as defined in the [MapLibre Style Specification](https://maplibre.org/maplibre-gl-js-docs/style-spec/)." + ], "signature": [ - "maplibregl.Point" + "any" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.setLayoutProperty.$4", + "type": "Object", + "tags": [], + "label": "options", + "description": [ + "Options object." + ], + "signature": [ + "maplibregl.StyleSetterOptions | undefined" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": false } ], - "returnComment": [] + "returnComment": [ + "`this`" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.sub", + "id": "def-server.Map.getLayoutProperty", "type": "Function", "tags": [], - "label": "sub", - "description": [], + "label": "getLayoutProperty", + "description": [ + "\nReturns the value of a layout property in the specified style layer.\n" + ], "signature": [ - "(p: maplibregl.Point) => maplibregl.Point" + "(layerId: string, name: string) => any" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.sub.$1", - "type": "Object", + "id": "def-server.Map.getLayoutProperty.$1", + "type": "string", "tags": [], - "label": "p", - "description": [], + "label": "layerId", + "description": [ + "The ID of the layer to get the layout property from." + ], + "signature": [ + "string" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.getLayoutProperty.$2", + "type": "string", + "tags": [], + "label": "name", + "description": [ + "The name of the layout property to get." + ], "signature": [ - "maplibregl.Point" + "string" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The value of the specified layout property." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.mult", + "id": "def-server.Map.setLight", "type": "Function", "tags": [], - "label": "mult", - "description": [], + "label": "setLight", + "description": [ + "\nSets the any combination of light values.\n" + ], "signature": [ - "(k: number) => maplibregl.Point" + "(light: maplibregl.LightSpecification, options?: maplibregl.StyleSetterOptions | undefined) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.mult.$1", - "type": "number", + "id": "def-server.Map.setLight.$1", + "type": "Object", "tags": [], - "label": "k", - "description": [], + "label": "light", + "description": [ + "Light properties to set. Must conform to the [MapLibre Style Specification](https://maplibre.org/maplibre-gl-js-docs/style-spec/#light)." + ], "signature": [ - "number" + "maplibregl.LightSpecification" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.setLight.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [ + "Options object." + ], + "signature": [ + "maplibregl.StyleSetterOptions | undefined" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": false } ], - "returnComment": [] + "returnComment": [ + "`this`" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.div", + "id": "def-server.Map.getLight", "type": "Function", "tags": [], - "label": "div", - "description": [], + "label": "getLight", + "description": [ + "\nReturns the value of the light object.\n" + ], + "signature": [ + "() => any" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [ + "light Light properties of the style." + ] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.setFeatureState", + "type": "Function", + "tags": [ + "see" + ], + "label": "setFeatureState", + "description": [ + "\nSets the `state` of a feature.\nA feature's `state` is a set of user-defined key-value pairs that are assigned to a feature at runtime.\nWhen using this method, the `state` object is merged with any existing key-value pairs in the feature's state.\nFeatures are identified by their `feature.id` attribute, which can be any number or string.\n\nThis method can only be used with sources that have a `feature.id` attribute. The `feature.id` attribute can be defined in three ways:\n- For vector or GeoJSON sources, including an `id` attribute in the original data file.\n- For vector or GeoJSON sources, using the [`promoteId`](https://maplibre.org/maplibre-gl-js-docs/style-spec/sources/#vector-promoteId) option at the time the source is defined.\n- For GeoJSON sources, using the [`generateId`](https://maplibre.org/maplibre-gl-js-docs/style-spec/sources/#geojson-generateId) option to auto-assign an `id` based on the feature's index in the source data. If you change feature data using `map.getSource('some id').setData(..)`, you may need to re-apply state taking into account updated `id` values.\n\n_Note: You can use the [`feature-state` expression](https://maplibre.org/maplibre-gl-js-docs/style-spec/expressions/#feature-state) to access the values in a feature's state object for the purposes of styling._\n" + ], "signature": [ - "(k: number) => maplibregl.Point" + "(feature: maplibregl.FeatureIdentifier, state: any) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.div.$1", - "type": "number", + "id": "def-server.Map.setFeatureState.$1", + "type": "Object", "tags": [], - "label": "k", - "description": [], + "label": "feature", + "description": [ + "Feature identifier. Feature objects returned from\n{@link MapqueryRenderedFeatures } or event handlers can be used as feature identifiers." + ], "signature": [ - "number" + "maplibregl.FeatureIdentifier" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.setFeatureState.$2", + "type": "Any", + "tags": [], + "label": "state", + "description": [ + "A set of key-value pairs. The values should be valid JSON types." + ], + "signature": [ + "any" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } @@ -4655,208 +5047,235 @@ }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.rotate", + "id": "def-server.Map.removeFeatureState", "type": "Function", "tags": [], - "label": "rotate", - "description": [], + "label": "removeFeatureState", + "description": [ + "\nRemoves the `state` of a feature, setting it back to the default behavior.\nIf only a `target.source` is specified, it will remove the state for all features from that source.\nIf `target.id` is also specified, it will remove all keys for that feature's state.\nIf `key` is also specified, it removes only that key from that feature's state.\nFeatures are identified by their `feature.id` attribute, which can be any number or string.\n" + ], "signature": [ - "(a: number) => maplibregl.Point" + "(target: maplibregl.FeatureIdentifier, key?: string | undefined) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.rotate.$1", - "type": "number", + "id": "def-server.Map.removeFeatureState.$1", + "type": "Object", "tags": [], - "label": "a", - "description": [], + "label": "target", + "description": [ + "Identifier of where to remove state. It can be a source, a feature, or a specific key of feature.\nFeature objects returned from {@link MapqueryRenderedFeatures } or event handlers can be used as feature identifiers." + ], "signature": [ - "number" + "maplibregl.FeatureIdentifier" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.removeFeatureState.$2", + "type": "string", + "tags": [], + "label": "key", + "description": [ + "(optional) The key in the feature state to reset." + ], + "signature": [ + "string | undefined" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": false } ], "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.matMult", + "id": "def-server.Map.getFeatureState", "type": "Function", "tags": [], - "label": "matMult", - "description": [], + "label": "getFeatureState", + "description": [ + "\nGets the `state` of a feature.\nA feature's `state` is a set of user-defined key-value pairs that are assigned to a feature at runtime.\nFeatures are identified by their `feature.id` attribute, which can be any number or string.\n\n_Note: To access the values in a feature's state object for the purposes of styling the feature, use the [`feature-state` expression](https://maplibre.org/maplibre-gl-js-docs/style-spec/expressions/#feature-state)._\n" + ], "signature": [ - "(m: number) => maplibregl.Point" + "(feature: maplibregl.FeatureIdentifier) => any" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.matMult.$1", - "type": "number", + "id": "def-server.Map.getFeatureState.$1", + "type": "Object", "tags": [], - "label": "m", - "description": [], + "label": "feature", + "description": [ + "Feature identifier. Feature objects returned from\n{@link MapqueryRenderedFeatures } or event handlers can be used as feature identifiers." + ], "signature": [ - "number" + "maplibregl.FeatureIdentifier" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The state of the feature: a set of key-value pairs that was assigned to the feature at runtime." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.unit", + "id": "def-server.Map.getContainer", "type": "Function", "tags": [], - "label": "unit", - "description": [], + "label": "getContainer", + "description": [ + "\nReturns the map's containing HTML element.\n" + ], "signature": [ - "() => maplibregl.Point" + "() => HTMLElement" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The map's container." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.perp", + "id": "def-server.Map.getCanvasContainer", "type": "Function", - "tags": [], - "label": "perp", - "description": [], + "tags": [ + "see" + ], + "label": "getCanvasContainer", + "description": [ + "\nReturns the HTML element containing the map's `` element.\n\nIf you want to add non-GL overlays to the map, you should append them to this element.\n\nThis is the element to which event bindings for map interactivity (such as panning and zooming) are\nattached. It will receive bubbled events from child elements such as the ``, but not from\nmap controls.\n" + ], "signature": [ - "() => maplibregl.Point" + "() => HTMLElement" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The container of the map's ``." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.round", + "id": "def-server.Map.getCanvas", + "type": "Function", + "tags": [ + "see", + "see", + "see" + ], + "label": "getCanvas", + "description": [ + "\nReturns the map's `` element.\n" + ], + "signature": [ + "() => HTMLCanvasElement" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [ + "The map's `` element." + ] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._containerDimensions", "type": "Function", "tags": [], - "label": "round", + "label": "_containerDimensions", "description": [], "signature": [ - "() => maplibregl.Point" + "() => number[]" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [], "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.mag", + "id": "def-server.Map._setupContainer", "type": "Function", "tags": [], - "label": "mag", + "label": "_setupContainer", "description": [], "signature": [ - "() => number" + "() => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [], "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.equals", + "id": "def-server.Map._resizeCanvas", "type": "Function", "tags": [], - "label": "equals", + "label": "_resizeCanvas", "description": [], "signature": [ - "(p: maplibregl.Point) => boolean" + "(width: number, height: number, pixelRatio: number) => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.equals.$1", - "type": "Object", + "id": "def-server.Map._resizeCanvas.$1", + "type": "number", "tags": [], - "label": "p", + "label": "width", "description": [], "signature": [ - "maplibregl.Point" + "number" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.dist", - "type": "Function", - "tags": [], - "label": "dist", - "description": [], - "signature": [ - "(p: maplibregl.Point) => number" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ + }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.dist.$1", - "type": "Object", + "id": "def-server.Map._resizeCanvas.$2", + "type": "number", "tags": [], - "label": "p", + "label": "height", "description": [], "signature": [ - "maplibregl.Point" + "number" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.distSqr", - "type": "Function", - "tags": [], - "label": "distSqr", - "description": [], - "signature": [ - "(p: maplibregl.Point) => number" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ + }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.distSqr.$1", - "type": "Object", + "id": "def-server.Map._resizeCanvas.$3", + "type": "number", "tags": [], - "label": "p", + "label": "pixelRatio", "description": [], "signature": [ - "maplibregl.Point" + "number" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } @@ -4865,73 +5284,43 @@ }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.angle", + "id": "def-server.Map._setupPainter", "type": "Function", "tags": [], - "label": "angle", + "label": "_setupPainter", "description": [], "signature": [ - "() => number" + "() => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [], "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.angleTo", - "type": "Function", - "tags": [], - "label": "angleTo", - "description": [], - "signature": [ - "(p: maplibregl.Point) => number" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.angleTo.$1", - "type": "Object", - "tags": [], - "label": "p", - "description": [], - "signature": [ - "maplibregl.Point" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.angleWidth", + "id": "def-server.Map._contextLost", "type": "Function", "tags": [], - "label": "angleWidth", + "label": "_contextLost", "description": [], "signature": [ - "(p: maplibregl.Point) => number" + "(event: any) => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.angleWidth.$1", - "type": "Object", + "id": "def-server.Map._contextLost.$1", + "type": "Any", "tags": [], - "label": "p", + "label": "event", "description": [], "signature": [ - "maplibregl.Point" + "any" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } @@ -4940,42 +5329,28 @@ }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.angleWithSep", + "id": "def-server.Map._contextRestored", "type": "Function", "tags": [], - "label": "angleWithSep", + "label": "_contextRestored", "description": [], "signature": [ - "(x: number, y: number) => number" + "(event: any) => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.angleWithSep.$1", - "type": "number", - "tags": [], - "label": "x", - "description": [], - "signature": [ - "number" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.angleWithSep.$2", - "type": "number", + "id": "def-server.Map._contextRestored.$1", + "type": "Any", "tags": [], - "label": "y", + "label": "event", "description": [], "signature": [ - "number" + "any" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } @@ -4984,235 +5359,151 @@ }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.convert", + "id": "def-server.Map._onMapScroll", "type": "Function", "tags": [], - "label": "convert", + "label": "_onMapScroll", "description": [], "signature": [ - "(a: maplibregl.PointLike) => maplibregl.Point" + "(event: any) => boolean" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Point.convert.$1", - "type": "CompoundType", + "id": "def-server.Map._onMapScroll.$1", + "type": "Any", "tags": [], - "label": "a", + "label": "event", "description": [], "signature": [ - "maplibregl.PointLike" + "any" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } ], "returnComment": [] - } - ], - "initialIsOpen": false - } - ], - "functions": [], - "interfaces": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.CustomLayerInterface", - "type": "Interface", - "tags": [], - "label": "CustomLayerInterface", - "description": [], - "signature": [ - "maplibregl.CustomLayerInterface" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.CustomLayerInterface.id", - "type": "string", - "tags": [], - "label": "id", - "description": [ - "A unique layer id." - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.CustomLayerInterface.type", - "type": "string", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "\"custom\"" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.CustomLayerInterface.renderingMode", - "type": "CompoundType", - "tags": [], - "label": "renderingMode", - "description": [], - "signature": [ - "\"2d\" | \"3d\" | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.CustomLayerInterface.onRemove", + "id": "def-server.Map.loaded", "type": "Function", "tags": [], - "label": "onRemove", + "label": "loaded", "description": [ - "\nOptional method called when the layer has been removed from the Map with Map#removeLayer.\nThis gives the layer a chance to clean up gl resources and event listeners." + "\nReturns a Boolean indicating whether the map is fully loaded.\n\nReturns `false` if the style is not yet fully loaded,\nor if there has been a change to the sources or style that\nhas not yet fully loaded.\n" ], "signature": [ - "((map: maplibregl.Map, gl: WebGLRenderingContext) => void) | undefined" + "() => boolean" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.CustomLayerInterface.onRemove.$1", - "type": "Object", - "tags": [], - "label": "map", - "description": [ - "The Map this custom layer was just added to." - ], - "signature": [ - "maplibregl.Map" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.CustomLayerInterface.onRemove.$2", - "type": "Object", - "tags": [], - "label": "gl", - "description": [ - "The gl context for the map." - ], - "signature": [ - "WebGLRenderingContext" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] + "children": [], + "returnComment": [ + "A Boolean indicating whether the map is fully loaded." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.CustomLayerInterface.onAdd", + "id": "def-server.Map._update", "type": "Function", - "tags": [], - "label": "onAdd", + "tags": [ + "private" + ], + "label": "_update", "description": [ - "\nOptional method called when the layer has been added to the Map with Map#addLayer.\nThis gives the layer a chance to initialize gl resources and register event listeners." + "\nUpdate this map's style and sources, and re-render the map.\n" ], "signature": [ - "((map: maplibregl.Map, gl: WebGLRenderingContext) => void) | undefined" + "(updateStyle?: boolean | undefined) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.CustomLayerInterface.onAdd.$1", - "type": "Object", - "tags": [], - "label": "map", - "description": [ - "The Map this custom layer was just added to." - ], - "signature": [ - "maplibregl.Map" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.CustomLayerInterface.onAdd.$2", - "type": "Object", + "id": "def-server.Map._update.$1", + "type": "CompoundType", "tags": [], - "label": "gl", + "label": "updateStyle", "description": [ - "The gl context for the map." + "mark the map's style for reprocessing as\nwell as its sources" ], "signature": [ - "WebGLRenderingContext" + "boolean | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, - "isRequired": true + "isRequired": false } ], - "returnComment": [] + "returnComment": [ + "this" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.CustomLayerInterface.prerender", + "id": "def-server.Map._requestRenderFrame", "type": "Function", - "tags": [], - "label": "prerender", + "tags": [ + "private" + ], + "label": "_requestRenderFrame", "description": [ - "\nOptional method called during a render frame to allow a layer to prepare resources\nor render into a texture.\n\nThe layer cannot make any assumptions about the current GL state and must bind a framebuffer\nbefore rendering." + "\nRequest that the given callback be executed during the next render\nframe. Schedule a render frame if one is not already scheduled." ], "signature": [ - "((gl: WebGLRenderingContext, matrix: number[]) => void) | undefined" + "(callback: () => void) => number" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.CustomLayerInterface.prerender.$1", - "type": "Object", + "id": "def-server.Map._requestRenderFrame.$1", + "type": "Function", "tags": [], - "label": "gl", - "description": [ - "The map's gl context." - ], + "label": "callback", + "description": [], "signature": [ - "WebGLRenderingContext" + "() => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true - }, + } + ], + "returnComment": [ + "An id that can be used to cancel the callback" + ] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._cancelRenderFrame", + "type": "Function", + "tags": [], + "label": "_cancelRenderFrame", + "description": [], + "signature": [ + "(id: number) => void" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.CustomLayerInterface.prerender.$2", - "type": "Array", + "id": "def-server.Map._cancelRenderFrame.$1", + "type": "number", "tags": [], - "label": "matrix", - "description": [ - "The map's camera matrix. It projects spherical mercator coordinates to gl\ncoordinates. The mercator coordinate [0, 0] represents the top left corner of\nthe mercator world and [1, 1] represents the bottom right corner. When the\nrenderingMode is \"3d\" , the z coordinate is conformal. A box with identical\nx, y, and z lengths in mercator units would be rendered as a cube.\nMercatorCoordinate .fromLatLng can be used to project a LngLat to a mercator\ncoordinate." - ], + "label": "id", + "description": [], "signature": [ - "number[]" + "number" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } @@ -5221,283 +5512,307 @@ }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.CustomLayerInterface.render", + "id": "def-server.Map._render", "type": "Function", - "tags": [], - "label": "render", + "tags": [ + "private" + ], + "label": "_render", "description": [ - "\nCalled during a render frame allowing the layer to draw into the GL context.\n\nThe layer can assume blending and depth state is set to allow the layer to properly blend\nand clip other layers. The layer cannot make any other assumptions about the current GL state.\n\nIf the layer needs to render to a texture, it should implement the prerender method to do this\nand only use the render method for drawing directly into the main framebuffer.\n\nThe blend function is set to gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA). This expects\ncolors to be provided in premultiplied alpha form where the r, g and b values are already\nmultiplied by the a value. If you are unable to provide colors in premultiplied form you may\nwant to change the blend function to\ngl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA).\n" + "\nCall when a (re-)render of the map is required:\n- The style has changed (`setPaintProperty()`, etc.)\n- Source data has changed (e.g. tiles have finished loading)\n- The map has is moving (or just finished moving)\n- A transition is in progress\n" ], "signature": [ - "(gl: WebGLRenderingContext, matrix: number[]) => void" + "(paintStartTimeStamp: number) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.CustomLayerInterface.render.$1", - "type": "Object", + "id": "def-server.Map._render.$1", + "type": "number", "tags": [], - "label": "gl", + "label": "paintStartTimeStamp", "description": [ - "The map's gl context." + "The time when the animation frame began executing." ], "signature": [ - "WebGLRenderingContext" + "number" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true - }, + } + ], + "returnComment": [ + "this" + ] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.redraw", + "type": "Function", + "tags": [], + "label": "redraw", + "description": [ + "\nForce a synchronous redraw of the map." + ], + "signature": [ + "() => maplibregl.Map" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [ + "`this`" + ] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.remove", + "type": "Function", + "tags": [], + "label": "remove", + "description": [ + "\nClean up and release all internal resources associated with this map.\n\nThis includes DOM elements, event bindings, web workers, and WebGL resources.\n\nUse this method when you are done using the map and wish to ensure that it no\nlonger consumes browser resources. Afterwards, you must not call any other\nmethods on the map." + ], + "signature": [ + "() => void" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.triggerRepaint", + "type": "Function", + "tags": [ + "see", + "see" + ], + "label": "triggerRepaint", + "description": [ + "\nTrigger the rendering of a single frame. Use this method with custom layers to\nrepaint the map when the layer changes. Calling this multiple times before the\nnext frame is rendered will still result in only a single frame being rendered." + ], + "signature": [ + "() => void" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._onWindowOnline", + "type": "Function", + "tags": [], + "label": "_onWindowOnline", + "description": [], + "signature": [ + "() => void" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map._onWindowResize", + "type": "Function", + "tags": [], + "label": "_onWindowResize", + "description": [], + "signature": [ + "(event: maplibregl.Event) => void" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.CustomLayerInterface.render.$2", - "type": "Array", + "id": "def-server.Map._onWindowResize.$1", + "type": "Object", "tags": [], - "label": "matrix", - "description": [ - "The map's camera matrix. It projects spherical mercator coordinates to gl\ncoordinates. The mercator coordinate [0, 0] represents the top left corner of\nthe mercator world and [1, 1] represents the bottom right corner. When the\nrenderingMode is \"3d\" , the z coordinate is conformal. A box with identical\nx, y, and z lengths in mercator units would be rendered as a cube.\nMercatorCoordinate .fromLatLng can be used to project a LngLat to a mercator\ncoordinate." - ], + "label": "event", + "description": [], "signature": [ - "number[]" + "maplibregl.Event" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } ], "returnComment": [] - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.FeatureIdentifier", - "type": "Interface", - "tags": [], - "label": "FeatureIdentifier", - "description": [], - "signature": [ - "maplibregl.FeatureIdentifier" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ + }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.FeatureIdentifier.id", - "type": "CompoundType", + "id": "def-server.Map.showTileBoundaries", + "type": "boolean", + "tags": [ + "name", + "type", + "instance", + "memberof" + ], + "label": "showTileBoundaries", + "description": [ + "\nGets and sets a Boolean indicating whether the map will render an outline\naround each tile and the tile ID. These tile boundaries are useful for\ndebugging.\n\nThe uncompressed file size of the first vector source is drawn in the top left\ncorner of each tile, next to the tile ID.\n" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.showTileBoundaries", + "type": "boolean", "tags": [], - "label": "id", + "label": "showTileBoundaries", "description": [], - "signature": [ - "string | number | undefined" + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.showPadding", + "type": "boolean", + "tags": [ + "name", + "type", + "instance", + "memberof" + ], + "label": "showPadding", + "description": [ + "\nGets and sets a Boolean indicating whether the map will visualize\nthe padding offsets.\n" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.FeatureIdentifier.source", - "type": "string", + "id": "def-server.Map.showPadding", + "type": "boolean", "tags": [], - "label": "source", + "label": "showPadding", "description": [], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.FeatureIdentifier.sourceLayer", - "type": "string", + "id": "def-server.Map.showCollisionBoxes", + "type": "boolean", + "tags": [ + "name", + "type", + "instance", + "memberof" + ], + "label": "showCollisionBoxes", + "description": [ + "\nGets and sets a Boolean indicating whether the map will render boxes\naround all symbols in the data source, revealing which symbols\nwere rendered or which were hidden due to collisions.\nThis information is useful for debugging.\n" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.showCollisionBoxes", + "type": "boolean", "tags": [], - "label": "sourceLayer", + "label": "showCollisionBoxes", "description": [], - "signature": [ - "string | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.GeoJSONSource", - "type": "Interface", - "tags": [], - "label": "GeoJSONSource", - "description": [], - "signature": [ - "maplibregl.GeoJSONSource extends maplibregl.GeoJSONSourceRaw" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ + }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.GeoJSONSource.type", - "type": "string", + "id": "def-server.Map.showOverdrawInspector", + "type": "boolean", "tags": [], - "label": "type", + "label": "showOverdrawInspector", "description": [], - "signature": [ - "\"geojson\"" + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.showOverdrawInspector", + "type": "boolean", + "tags": [], + "label": "showOverdrawInspector", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Map.repaint", + "type": "boolean", + "tags": [ + "name", + "type", + "instance", + "memberof" + ], + "label": "repaint", + "description": [ + "\nGets and sets a Boolean indicating whether the map will\ncontinuously repaint. This information is useful for analyzing performance.\n" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.GeoJSONSource.setData", - "type": "Function", + "id": "def-server.Map.repaint", + "type": "boolean", "tags": [], - "label": "setData", + "label": "repaint", "description": [], - "signature": [ - "(data: String | GeoJSON.FeatureCollection | GeoJSON.Feature) => this" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.GeoJSONSource.setData.$1", - "type": "CompoundType", - "tags": [], - "label": "data", - "description": [], - "signature": [ - "String | GeoJSON.FeatureCollection | GeoJSON.Feature" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.GeoJSONSource.getClusterExpansionZoom", - "type": "Function", + "id": "def-server.Map.vertices", + "type": "boolean", "tags": [], - "label": "getClusterExpansionZoom", + "label": "vertices", "description": [], - "signature": [ - "(clusterId: number, callback: (error: any, zoom: number) => void) => this" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.GeoJSONSource.getClusterExpansionZoom.$1", - "type": "number", - "tags": [], - "label": "clusterId", - "description": [], - "signature": [ - "number" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.GeoJSONSource.getClusterExpansionZoom.$2", - "type": "Function", - "tags": [], - "label": "callback", - "description": [], - "signature": [ - "(error: any, zoom: number) => void" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.GeoJSONSource.getClusterChildren", - "type": "Function", + "id": "def-server.Map.vertices", + "type": "boolean", "tags": [], - "label": "getClusterChildren", + "label": "vertices", "description": [], - "signature": [ - "(clusterId: number, callback: (error: any, features: GeoJSON.Feature[]) => void) => this" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.GeoJSONSource.getClusterChildren.$1", - "type": "number", - "tags": [], - "label": "clusterId", - "description": [], - "signature": [ - "number" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.GeoJSONSource.getClusterChildren.$2", - "type": "Function", - "tags": [], - "label": "callback", - "description": [], - "signature": [ - "(error: any, features: GeoJSON.Feature[]) => void" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.GeoJSONSource.getClusterLeaves", + "id": "def-server.Map._setCacheLimits", "type": "Function", "tags": [], - "label": "getClusterLeaves", + "label": "_setCacheLimits", "description": [], "signature": [ - "(cluserId: number, limit: number, offset: number, callback: (error: any, features: GeoJSON.Feature[]) => void) => this" + "(limit: number, checkThreshold: number) => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.GeoJSONSource.getClusterLeaves.$1", - "type": "number", - "tags": [], - "label": "cluserId", - "description": [], - "signature": [ - "number" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.GeoJSONSource.getClusterLeaves.$2", + "id": "def-server.Map._setCacheLimits.$1", "type": "number", "tags": [], "label": "limit", @@ -5505,35 +5820,21 @@ "signature": [ "number" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.GeoJSONSource.getClusterLeaves.$3", + "id": "def-server.Map._setCacheLimits.$2", "type": "number", "tags": [], - "label": "offset", + "label": "checkThreshold", "description": [], "signature": [ "number" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.GeoJSONSource.getClusterLeaves.$4", - "type": "Function", - "tags": [], - "label": "callback", - "description": [], - "signature": [ - "(error: any, features: GeoJSON.Feature[]) => void" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "isRequired": true } @@ -5545,851 +5846,1102 @@ }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Layer", - "type": "Interface", + "id": "def-server.MapMouseEvent", + "type": "Class", "tags": [], - "label": "Layer", + "label": "MapMouseEvent", "description": [], "signature": [ - "maplibregl.Layer" + "maplibregl.MapMouseEvent extends maplibregl.Event implements maplibregl.MapLibreEvent" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Layer.id", - "type": "string", - "tags": [], - "label": "id", - "description": [], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Layer.type", - "type": "string", + "id": "def-server.MapMouseEvent.type", + "type": "CompoundType", "tags": [], "label": "type", - "description": [], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Layer.metadata", - "type": "Any", - "tags": [], - "label": "metadata", - "description": [], - "signature": [ - "any" + "description": [ + "\nThe event type (one of {@link Map.event:mousedown},\n{@link Map.event:mouseup},\n{@link Map.event:click},\n{@link Map.event:dblclick},\n{@link Map.event:mousemove},\n{@link Map.event:mouseover},\n{@link Map.event:mouseenter},\n{@link Map.event:mouseleave},\n{@link Map.event:mouseout},\n{@link Map.event:contextmenu})." ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Layer.ref", - "type": "string", - "tags": [], - "label": "ref", - "description": [], "signature": [ - "string | undefined" + "\"mousedown\" | \"mouseup\" | \"mouseover\" | \"mousemove\" | \"click\" | \"dblclick\" | \"mouseenter\" | \"mouseleave\" | \"mouseout\" | \"contextmenu\"" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Layer.source", - "type": "CompoundType", + "id": "def-server.MapMouseEvent.target", + "type": "Object", "tags": [], - "label": "source", - "description": [], + "label": "target", + "description": [ + "\nThe `Map` object that fired the event." + ], "signature": [ - "string | maplibregl.AnySourceData | undefined" + "maplibregl.Map" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Layer.sourcelayer", - "type": "string", + "id": "def-server.MapMouseEvent.originalEvent", + "type": "Object", "tags": [], - "label": "'source-layer'", - "description": [], + "label": "originalEvent", + "description": [ + "\nThe DOM event which caused the map event." + ], "signature": [ - "string | undefined" + "MouseEvent" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Layer.minzoom", - "type": "number", + "id": "def-server.MapMouseEvent.point", + "type": "Object", "tags": [], - "label": "minzoom", - "description": [], + "label": "point", + "description": [ + "\nThe pixel coordinates of the mouse cursor, relative to the map and measured from the top left corner." + ], "signature": [ - "number | undefined" + "node_modules/@types/mapbox__point-geometry/index" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Layer.maxzoom", - "type": "number", + "id": "def-server.MapMouseEvent.lngLat", + "type": "Object", "tags": [], - "label": "maxzoom", - "description": [], + "label": "lngLat", + "description": [ + "\nThe geographic location on the map of the mouse cursor." + ], "signature": [ - "number | undefined" + "maplibregl.LngLat" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Layer.interactive", - "type": "CompoundType", + "id": "def-server.MapMouseEvent.preventDefault", + "type": "Function", "tags": [], - "label": "interactive", - "description": [], + "label": "preventDefault", + "description": [ + "\nPrevents subsequent default processing of the event by the map.\n\nCalling this method will prevent the following default map behaviors:\n\n * On `mousedown` events, the behavior of {@link DragPanHandler}\n * On `mousedown` events, the behavior of {@link DragRotateHandler}\n * On `mousedown` events, the behavior of {@link BoxZoomHandler}\n * On `dblclick` events, the behavior of {@link DoubleClickZoomHandler}\n" + ], "signature": [ - "boolean | undefined" + "() => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Layer.filter", - "type": "Array", - "tags": [], - "label": "filter", - "description": [], - "signature": [ - "any[] | undefined" + "id": "def-server.MapMouseEvent.defaultPrevented", + "type": "boolean", + "tags": [ + "private" + ], + "label": "defaultPrevented", + "description": [ + "\n`true` if `preventDefault` has been called." ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Layer.layout", - "type": "Object", + "id": "def-server.MapMouseEvent._defaultPrevented", + "type": "boolean", "tags": [], - "label": "layout", + "label": "_defaultPrevented", "description": [], - "signature": [ - "maplibregl.Layout | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Layer.paint", - "type": "Uncategorized", - "tags": [], - "label": "paint", + "id": "def-server.MapMouseEvent.Unnamed", + "type": "Function", + "tags": [ + "private" + ], + "label": "Constructor", "description": [], "signature": [ - "object | undefined" + "any" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.MapMouseEvent.Unnamed.$1", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "string" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.MapMouseEvent.Unnamed.$2", + "type": "Object", + "tags": [], + "label": "map", + "description": [], + "signature": [ + "maplibregl.Map" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.MapMouseEvent.Unnamed.$3", + "type": "Object", + "tags": [], + "label": "originalEvent", + "description": [], + "signature": [ + "MouseEvent" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.MapMouseEvent.Unnamed.$4", + "type": "Any", + "tags": [], + "label": "data", + "description": [], + "signature": [ + "any" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "returnComment": [] } ], "initialIsOpen": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions", - "type": "Interface", + "id": "def-server.VectorTileSource", + "type": "Class", "tags": [], - "label": "MapboxOptions", + "label": "VectorTileSource", "description": [], "signature": [ - "maplibregl.MapboxOptions" + "maplibregl.VectorTileSource extends maplibregl.Evented implements maplibregl.Source" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.antialias", - "type": "CompoundType", + "id": "def-server.VectorTileSource.type", + "type": "string", "tags": [], - "label": "antialias", - "description": [ - "\nIf true, the gl context will be created with MSA antialiasing, which can be useful for antialiasing custom layers.\nThis is false by default as a performance optimization." - ], + "label": "type", + "description": [], "signature": [ - "boolean | undefined" + "\"vector\"" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.attributionControl", - "type": "CompoundType", + "id": "def-server.VectorTileSource.id", + "type": "string", "tags": [], - "label": "attributionControl", - "description": [ - "If true, an attribution control will be added to the map." - ], - "signature": [ - "boolean | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "label": "id", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.bearing", + "id": "def-server.VectorTileSource.minzoom", "type": "number", "tags": [], - "label": "bearing", + "label": "minzoom", "description": [], - "signature": [ - "number | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.bearingSnap", + "id": "def-server.VectorTileSource.maxzoom", "type": "number", "tags": [], - "label": "bearingSnap", - "description": [ - "Snap to north threshold in degrees." - ], - "signature": [ - "number | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.bounds", - "type": "CompoundType", - "tags": [], - "label": "bounds", - "description": [ - "The initial bounds of the map. If bounds is specified, it overrides center and zoom constructor options." - ], - "signature": [ - "maplibregl.LngLatBoundsLike | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "label": "maxzoom", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.boxZoom", - "type": "CompoundType", + "id": "def-server.VectorTileSource.url", + "type": "string", "tags": [], - "label": "boxZoom", - "description": [ - "If true, enable the \"box zoom\" interaction (see BoxZoomHandler)" - ], - "signature": [ - "boolean | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "label": "url", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.center", - "type": "CompoundType", + "id": "def-server.VectorTileSource.scheme", + "type": "string", "tags": [], - "label": "center", - "description": [ - "initial map center" - ], - "signature": [ - "maplibregl.LngLatLike | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "label": "scheme", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.clickTolerance", + "id": "def-server.VectorTileSource.tileSize", "type": "number", - "tags": [ - "default" - ], - "label": "clickTolerance", - "description": [ - "\nThe max number of pixels a user can shift the mouse pointer during a click for it to be\nconsidered a valid click (as opposed to a mouse drag).\n" - ], - "signature": [ - "number | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.collectResourceTiming", - "type": "CompoundType", - "tags": [ - "default" - ], - "label": "collectResourceTiming", - "description": [ - "\nIf `true`, Resource Timing API information will be collected for requests made by GeoJSON\nand Vector Tile web workers (this information is normally inaccessible from the main\nJavascript thread). Information will be returned in a `resourceTiming` property of\nrelevant `data` events.\n" - ], - "signature": [ - "boolean | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "tags": [], + "label": "tileSize", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.crossSourceCollisions", + "id": "def-server.VectorTileSource.promoteId", "type": "CompoundType", - "tags": [ - "default" - ], - "label": "crossSourceCollisions", - "description": [ - "\nIf `true`, symbols from multiple sources can collide with each other during collision\ndetection. If `false`, collision detection is run separately for the symbols in each source.\n" - ], + "tags": [], + "label": "promoteId", + "description": [], "signature": [ - "boolean | undefined" + "string | { [_: string]: string; }" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.container", - "type": "CompoundType", + "id": "def-server.VectorTileSource._options", + "type": "Object", "tags": [], - "label": "container", - "description": [ - "ID of the container element" - ], + "label": "_options", + "description": [], "signature": [ - "string | HTMLElement" + "{ type: \"vector\"; url?: string | undefined; tiles?: string[] | undefined; bounds?: [number, number, number, number] | undefined; scheme?: \"xyz\" | \"tms\" | undefined; minzoom?: number | undefined; maxzoom?: number | undefined; attribution?: string | undefined; promoteId?: maplibregl.PromoteIdSpecification | undefined; volatile?: boolean | undefined; }" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.customAttribution", - "type": "CompoundType", + "id": "def-server.VectorTileSource._collectResourceTiming", + "type": "boolean", "tags": [], - "label": "customAttribution", - "description": [ - "String or strings to show in an AttributionControl.\nOnly applicable if options.attributionControl is `true`." - ], - "signature": [ - "string | string[] | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "label": "_collectResourceTiming", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.dragPan", - "type": "CompoundType", + "id": "def-server.VectorTileSource.dispatcher", + "type": "Object", "tags": [], - "label": "dragPan", - "description": [ - "If true, enable the \"drag to pan\" interaction (see DragPanHandler)." - ], + "label": "dispatcher", + "description": [], "signature": [ - "boolean | undefined" + "maplibregl.Dispatcher" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.dragRotate", - "type": "CompoundType", + "id": "def-server.VectorTileSource.map", + "type": "Object", "tags": [], - "label": "dragRotate", - "description": [ - "If true, enable the \"drag to rotate\" interaction (see DragRotateHandler)." - ], + "label": "map", + "description": [], "signature": [ - "boolean | undefined" + "maplibregl.Map" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.doubleClickZoom", - "type": "CompoundType", + "id": "def-server.VectorTileSource.bounds", + "type": "Object", "tags": [], - "label": "doubleClickZoom", - "description": [ - "If true, enable the \"double click to zoom\" interaction (see DoubleClickZoomHandler)." - ], + "label": "bounds", + "description": [], "signature": [ - "boolean | undefined" + "[number, number, number, number]" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.hash", - "type": "CompoundType", + "id": "def-server.VectorTileSource.tiles", + "type": "Array", "tags": [], - "label": "hash", - "description": [ - "If `true`, the map's position (zoom, center latitude, center longitude, bearing, and pitch) will be synced with the hash fragment of the page's URL.\nFor example, `http://path/to/my/page.html#2.59/39.26/53.07/-24.1/60`.\nAn additional string may optionally be provided to indicate a parameter-styled hash,\ne.g. http://path/to/my/page.html#map=2.59/39.26/53.07/-24.1/60&foo=bar, where foo\nis a custom parameter and bar is an arbitrary hash distinct from the map hash." - ], + "label": "tiles", + "description": [], "signature": [ - "string | boolean | undefined" + "string[]" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.fadeDuration", - "type": "number", - "tags": [ - "default" - ], - "label": "fadeDuration", - "description": [ - "\nControls the duration of the fade-in/fade-out animation for label collisions, in milliseconds.\nThis setting affects all symbol layers. This setting does not affect the duration of runtime\nstyling transitions or raster tile cross-fading.\n" - ], + "id": "def-server.VectorTileSource.tileBounds", + "type": "Object", + "tags": [], + "label": "tileBounds", + "description": [], "signature": [ - "number | undefined" + "maplibregl.TileBounds" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.failIfMajorPerformanceCaveat", - "type": "CompoundType", + "id": "def-server.VectorTileSource.reparseOverscaled", + "type": "boolean", "tags": [], - "label": "failIfMajorPerformanceCaveat", - "description": [ - "If true, map creation will fail if the implementation determines that the performance of the created WebGL context would be dramatically lower than expected." - ], - "signature": [ - "boolean | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "label": "reparseOverscaled", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.fitBoundsOptions", - "type": "Object", + "id": "def-server.VectorTileSource.isTileClipped", + "type": "boolean", "tags": [], - "label": "fitBoundsOptions", - "description": [ - "A fitBounds options object to use only when setting the bounds option." - ], - "signature": [ - "maplibregl.FitBoundsOptions | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "label": "isTileClipped", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.interactive", - "type": "CompoundType", + "id": "def-server.VectorTileSource._tileJSONRequest", + "type": "Object", "tags": [], - "label": "interactive", - "description": [ - "If false, no mouse, touch, or keyboard listeners are attached to the map, so it will not respond to input" - ], + "label": "_tileJSONRequest", + "description": [], "signature": [ - "boolean | undefined" + "{ cancel: () => void; }" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.keyboard", - "type": "CompoundType", + "id": "def-server.VectorTileSource._loaded", + "type": "boolean", "tags": [], - "label": "keyboard", - "description": [ - "If true, enable keyboard shortcuts (see KeyboardHandler)." - ], - "signature": [ - "boolean | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "label": "_loaded", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.locale", - "type": "Object", + "id": "def-server.VectorTileSource.Unnamed", + "type": "Function", "tags": [], - "label": "locale", - "description": [ - "A patch to apply to the default localization table for UI strings, e.g. control tooltips.\nThe `locale` object maps namespaced UI string IDs to translated strings in the target language;\nsee `src/ui/default_locale.js` for an example with all supported string IDs.\nThe object may specify all UI strings (thereby adding support for a new translation) or\nonly a subset of strings (thereby patching the default translation table)." - ], + "label": "Constructor", + "description": [], "signature": [ - "{ [key: string]: string; } | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.localIdeographFontFamily", - "type": "string", - "tags": [ - "default" - ], - "label": "localIdeographFontFamily", - "description": [ - "\nIf specified, defines a CSS font-family for locally overriding generation of glyphs in the\n'CJK Unified Ideographs' and 'Hangul Syllables' ranges. In these ranges, font settings from\nthe map's style will be ignored, except for font-weight keywords (light/regular/medium/bold).\nThe purpose of this option is to avoid bandwidth-intensive glyph server requests.\n" + "any" ], - "signature": [ - "string | undefined" + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.VectorTileSource.Unnamed.$1", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "signature": [ + "string" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.VectorTileSource.Unnamed.$2", + "type": "CompoundType", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "maplibregl.VectorSourceSpecification & { collectResourceTiming: boolean; }" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.VectorTileSource.Unnamed.$3", + "type": "Object", + "tags": [], + "label": "dispatcher", + "description": [], + "signature": [ + "maplibregl.Dispatcher" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.VectorTileSource.Unnamed.$4", + "type": "Object", + "tags": [], + "label": "eventedParent", + "description": [], + "signature": [ + "maplibregl.Evented" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.logoPosition", - "type": "CompoundType", - "tags": [ - "default" - ], - "label": "logoPosition", - "description": [ - "\nA string representing the position of the Mapbox wordmark on the map.\n" - ], + "id": "def-server.VectorTileSource.load", + "type": "Function", + "tags": [], + "label": "load", + "description": [], "signature": [ - "\"top-right\" | \"top-left\" | \"bottom-right\" | \"bottom-left\" | undefined" + "() => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.maxBounds", - "type": "CompoundType", + "id": "def-server.VectorTileSource.loaded", + "type": "Function", "tags": [], - "label": "maxBounds", - "description": [ - "If set, the map is constrained to the given bounds." - ], + "label": "loaded", + "description": [], "signature": [ - "maplibregl.LngLatBoundsLike | undefined" + "() => boolean" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.maxPitch", - "type": "number", + "id": "def-server.VectorTileSource.hasTile", + "type": "Function", "tags": [], - "label": "maxPitch", - "description": [ - "Maximum pitch of the map." - ], + "label": "hasTile", + "description": [], "signature": [ - "number | undefined" + "(tileID: maplibregl.OverscaledTileID) => boolean" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.VectorTileSource.hasTile.$1", + "type": "Object", + "tags": [], + "label": "tileID", + "description": [], + "signature": [ + "maplibregl.OverscaledTileID" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.maxZoom", - "type": "number", + "id": "def-server.VectorTileSource.onAdd", + "type": "Function", "tags": [], - "label": "maxZoom", - "description": [ - "Maximum zoom of the map." - ], + "label": "onAdd", + "description": [], "signature": [ - "number | undefined" + "(map: maplibregl.Map) => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.VectorTileSource.onAdd.$1", + "type": "Object", + "tags": [], + "label": "map", + "description": [], + "signature": [ + "maplibregl.Map" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.minPitch", - "type": "number", + "id": "def-server.VectorTileSource.setSourceProperty", + "type": "Function", "tags": [], - "label": "minPitch", - "description": [ - "Minimum pitch of the map." - ], + "label": "setSourceProperty", + "description": [], "signature": [ - "number | undefined" + "(callback: Function) => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.VectorTileSource.setSourceProperty.$1", + "type": "Object", + "tags": [], + "label": "callback", + "description": [], + "signature": [ + "Function" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.minZoom", - "type": "number", + "id": "def-server.VectorTileSource.setTiles", + "type": "Function", "tags": [], - "label": "minZoom", + "label": "setTiles", "description": [ - "Minimum zoom of the map." + "\nSets the source `tiles` property and re-renders the map.\n" ], "signature": [ - "number | undefined" + "(tiles: string[]) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.VectorTileSource.setTiles.$1", + "type": "Array", + "tags": [], + "label": "tiles", + "description": [ + "An array of one or more tile source URLs, as in the TileJSON spec." + ], + "signature": [ + "string[]" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [ + "this" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.preserveDrawingBuffer", - "type": "CompoundType", + "id": "def-server.VectorTileSource.setUrl", + "type": "Function", "tags": [], - "label": "preserveDrawingBuffer", + "label": "setUrl", "description": [ - "If true, The maps canvas can be exported to a PNG using map.getCanvas().toDataURL();. This is false by default as a performance optimization." + "\nSets the source `url` property and re-renders the map.\n" ], "signature": [ - "boolean | undefined" + "(url: string) => this" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.VectorTileSource.setUrl.$1", + "type": "string", + "tags": [], + "label": "url", + "description": [ + "A URL to a TileJSON resource. Supported protocols are `http:` and `https:`." + ], + "signature": [ + "string" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [ + "this" + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.pitch", - "type": "number", - "tags": [ - "default" - ], - "label": "pitch", - "description": [ - "\nThe initial pitch (tilt) of the map, measured in degrees away from the plane of the\nscreen (0-60).\n" - ], + "id": "def-server.VectorTileSource.onRemove", + "type": "Function", + "tags": [], + "label": "onRemove", + "description": [], "signature": [ - "number | undefined" + "() => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.pitchWithRotate", - "type": "CompoundType", - "tags": [ - "default" - ], - "label": "pitchWithRotate", - "description": [ - "\nIf `false`, the map's pitch (tilt) control with \"drag to rotate\" interaction will be disabled.\n" - ], + "id": "def-server.VectorTileSource.serialize", + "type": "Function", + "tags": [], + "label": "serialize", + "description": [], "signature": [ - "boolean | undefined" + "() => any" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.refreshExpiredTiles", - "type": "CompoundType", - "tags": [ - "default" - ], - "label": "refreshExpiredTiles", - "description": [ - "\nIf `false`, the map won't attempt to re-request tiles once they expire per their HTTP\n`cacheControl`/`expires` headers.\n" - ], + "id": "def-server.VectorTileSource.loadTile", + "type": "Function", + "tags": [], + "label": "loadTile", + "description": [], "signature": [ - "boolean | undefined" + "(tile: maplibregl.Tile, callback: maplibregl.Callback) => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.VectorTileSource.loadTile.$1", + "type": "Object", + "tags": [], + "label": "tile", + "description": [], + "signature": [ + "maplibregl.Tile" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.VectorTileSource.loadTile.$2", + "type": "Function", + "tags": [], + "label": "callback", + "description": [], + "signature": [ + "maplibregl.Callback" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.renderWorldCopies", - "type": "CompoundType", - "tags": [ - "default" + "id": "def-server.VectorTileSource.abortTile", + "type": "Function", + "tags": [], + "label": "abortTile", + "description": [], + "signature": [ + "(tile: maplibregl.Tile) => void" ], - "label": "renderWorldCopies", - "description": [ - "\nIf `true`, multiple copies of the world will be rendered, when zoomed out.\n" + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.VectorTileSource.abortTile.$1", + "type": "Object", + "tags": [], + "label": "tile", + "description": [], + "signature": [ + "maplibregl.Tile" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.VectorTileSource.unloadTile", + "type": "Function", + "tags": [], + "label": "unloadTile", + "description": [], "signature": [ - "boolean | undefined" + "(tile: maplibregl.Tile) => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.VectorTileSource.unloadTile.$1", + "type": "Object", + "tags": [], + "label": "tile", + "description": [], + "signature": [ + "maplibregl.Tile" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.scrollZoom", - "type": "CompoundType", + "id": "def-server.VectorTileSource.hasTransition", + "type": "Function", "tags": [], - "label": "scrollZoom", - "description": [ - "If true, enable the \"scroll to zoom\" interaction" - ], + "label": "hasTransition", + "description": [], "signature": [ - "boolean | undefined" + "() => boolean" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [] + } + ], + "initialIsOpen": false + } + ], + "functions": [], + "interfaces": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.CustomLayerInterface", + "type": "Interface", + "tags": [ + "interface" + ], + "label": "CustomLayerInterface", + "description": [ + "\nInterface for custom style layers. This is a specification for\nimplementers to model: it is not an exported method or class.\n\nCustom layers allow a user to render directly into the map's GL context using the map's camera.\nThese layers can be added between any regular layers using {@link Map#addLayer}.\n\nCustom layers must have a unique `id` and must have the `type` of `\"custom\"`.\nThey must implement `render` and may implement `prerender`, `onAdd` and `onRemove`.\nThey can trigger rendering using {@link Map#triggerRepaint}\nand they should appropriately handle {@link Map.event:webglcontextlost} and\n{@link Map.event:webglcontextrestored}.\n\nThe `renderingMode` property controls whether the layer is treated as a `\"2d\"` or `\"3d\"` map layer. Use:\n- `\"renderingMode\": \"3d\"` to use the depth buffer and share it with other layers\n- `\"renderingMode\": \"2d\"` to add a layer with no depth. If you need to use the depth buffer for a `\"2d\"` layer you must use an offscreen\n framebuffer and {@link CustomLayerInterface#prerender}\n" + ], + "signature": [ + "maplibregl.CustomLayerInterface" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.CustomLayerInterface.id", + "type": "string", + "tags": [ + "property" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "label": "id", + "description": [], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.style", - "type": "CompoundType", - "tags": [], - "label": "style", - "description": [ - "stylesheet location" + "id": "def-server.CustomLayerInterface.type", + "type": "string", + "tags": [ + "property" ], + "label": "type", + "description": [], "signature": [ - "string | maplibregl.Style | undefined" + "\"custom\"" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.trackResize", + "id": "def-server.CustomLayerInterface.renderingMode", "type": "CompoundType", - "tags": [], - "label": "trackResize", - "description": [ - "If true, the map will automatically resize when the browser window resizes" + "tags": [ + "property" ], + "label": "renderingMode", + "description": [], "signature": [ - "boolean | undefined" + "\"2d\" | \"3d\" | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.transformRequest", + "id": "def-server.CustomLayerInterface.render", "type": "Function", "tags": [ - "default" - ], - "label": "transformRequest", - "description": [ - "\nA callback run before the Map makes a request for an external URL. The callback can be\nused to modify the url, set headers, or set the credentials property for cross-origin requests.\n" - ], - "signature": [ - "maplibregl.TransformRequestFunction | undefined" + "function", + "memberof", + "instance", + "name" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.touchZoomRotate", - "type": "CompoundType", - "tags": [], - "label": "touchZoomRotate", + "label": "render", "description": [ - "If true, enable the \"pinch to rotate and zoom\" interaction (see TouchZoomRotateHandler)." + "\nCalled during a render frame allowing the layer to draw into the GL context.\n\nThe layer can assume blending and depth state is set to allow the layer to properly\nblend and clip other layers. The layer cannot make any other assumptions about the\ncurrent GL state.\n\nIf the layer needs to render to a texture, it should implement the `prerender` method\nto do this and only use the `render` method for drawing directly into the main framebuffer.\n\nThe blend function is set to `gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)`. This expects\ncolors to be provided in premultiplied alpha form where the `r`, `g` and `b` values are already\nmultiplied by the `a` value. If you are unable to provide colors in premultiplied form you\nmay want to change the blend function to\n`gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA)`.\n" ], "signature": [ - "boolean | undefined" + "(gl: WebGLRenderingContext, matrix: ", + "mat4", + ") => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.CustomLayerInterface.render.$1", + "type": "Object", + "tags": [], + "label": "gl", + "description": [ + "The map's gl context." + ], + "signature": [ + "WebGLRenderingContext" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.CustomLayerInterface.render.$2", + "type": "CompoundType", + "tags": [], + "label": "matrix", + "description": [ + "The map's camera matrix. It projects spherical mercator\ncoordinates to gl coordinates. The spherical mercator coordinate `[0, 0]` represents the\ntop left corner of the mercator world and `[1, 1]` represents the bottom right corner. When\nthe `renderingMode` is `\"3d\"`, the z coordinate is conformal. A box with identical x, y, and z\nlengths in mercator units would be rendered as a cube. {@link MercatorCoordinate }.fromLngLat\ncan be used to project a `LngLat` to a mercator coordinate." + ], + "signature": [ + "Float32Array | [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number]" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false + } + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.touchPitch", - "type": "CompoundType", - "tags": [], - "label": "touchPitch", - "description": [ - "If true, the \"drag to pitch\" interaction is enabled" - ], - "signature": [ - "boolean | undefined" + "id": "def-server.CustomLayerInterface.prerender", + "type": "Function", + "tags": [ + "function", + "memberof", + "instance", + "name" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.zoom", - "type": "number", - "tags": [], - "label": "zoom", + "label": "prerender", "description": [ - "Initial zoom level" + "\nOptional method called during a render frame to allow a layer to prepare resources or render into a texture.\n\nThe layer cannot make any assumptions about the current GL state and must bind a framebuffer before rendering.\n" ], "signature": [ - "number | undefined" + "maplibregl.CustomRenderMethod | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.maxTileCacheSize", - "type": "number", + "id": "def-server.CustomLayerInterface.onAdd", + "type": "Function", "tags": [ - "default" + "function", + "memberof", + "instance", + "name" ], - "label": "maxTileCacheSize", + "label": "onAdd", "description": [ - "\nThe maximum number of tiles stored in the tile cache for a given source. If omitted, the\ncache will be dynamically sized based on the current viewport.\n" + "\nOptional method called when the layer has been added to the Map with {@link Map#addLayer}. This\ngives the layer a chance to initialize gl resources and register event listeners.\n" ], "signature": [ - "number | undefined" + "((map: maplibregl.Map, gl: WebGLRenderingContext) => void) | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.CustomLayerInterface.onAdd.$1", + "type": "Object", + "tags": [], + "label": "map", + "description": [ + "The Map this custom layer was just added to." + ], + "signature": [ + "maplibregl.Map" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.CustomLayerInterface.onAdd.$2", + "type": "Object", + "tags": [], + "label": "gl", + "description": [ + "The gl context for the map." + ], + "signature": [ + "WebGLRenderingContext" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxOptions.accessToken", - "type": "string", + "id": "def-server.CustomLayerInterface.onRemove", + "type": "Function", "tags": [ - "default" + "function", + "memberof", + "instance", + "name" ], - "label": "accessToken", + "label": "onRemove", "description": [ - "\nIf specified, map will use this token instead of the one defined in maplibregl.accessToken.\n" + "\nOptional method called when the layer has been removed from the Map with {@link Map#removeLayer}. This\ngives the layer a chance to clean up gl resources and event listeners.\n" ], "signature": [ - "string | undefined" + "((map: maplibregl.Map, gl: WebGLRenderingContext) => void) | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.CustomLayerInterface.onRemove.$1", + "type": "Object", + "tags": [], + "label": "map", + "description": [ + "The Map this custom layer was just added to." + ], + "signature": [ + "maplibregl.Map" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.CustomLayerInterface.onRemove.$2", + "type": "Object", + "tags": [], + "label": "gl", + "description": [ + "The gl context for the map." + ], + "signature": [ + "WebGLRenderingContext" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] } ], "initialIsOpen": false @@ -6402,9 +6954,9 @@ "label": "MapSourceDataEvent", "description": [], "signature": [ - "maplibregl.MapSourceDataEvent extends maplibregl.MapboxEvent" + "maplibregl.MapSourceDataEvent extends maplibregl.MapLibreEvent" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { @@ -6417,7 +6969,7 @@ "signature": [ "\"source\"" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { @@ -6427,20 +6979,20 @@ "tags": [], "label": "isSourceLoaded", "description": [], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", "id": "def-server.MapSourceDataEvent.source", - "type": "Object", + "type": "CompoundType", "tags": [], "label": "source", "description": [], "signature": [ - "maplibregl.Source" + "maplibregl.VectorSourceSpecification | maplibregl.RasterSourceSpecification | maplibregl.RasterDEMSourceSpecification | maplibregl.GeoJSONSourceSpecification | maplibregl.VideoSourceSpecification | maplibregl.ImageSourceSpecification" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { @@ -6450,7 +7002,7 @@ "tags": [], "label": "sourceId", "description": [], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { @@ -6463,7 +7015,7 @@ "signature": [ "\"metadata\" | \"content\"" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { @@ -6476,20 +7028,7 @@ "signature": [ "any" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapSourceDataEvent.coord", - "type": "Object", - "tags": [], - "label": "coord", - "description": [], - "signature": [ - "maplibregl.Coordinate" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false } ], @@ -6497,315 +7036,471 @@ }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Style", + "id": "def-server.Source", "type": "Interface", - "tags": [], - "label": "Style", - "description": [], + "tags": [ + "private", + "fires", + "property", + "property", + "property", + "property", + "property", + "property" + ], + "label": "Source", + "description": [ + "\nThe `Source` interface must be implemented by each source type, including \"core\" types (`vector`, `raster`,\n`video`, etc.) and all custom, third-party types.\n" + ], "signature": [ - "maplibregl.Style" + "maplibregl.Source" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "children": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Style.bearing", - "type": "number", + "id": "def-server.Source.type", + "type": "string", "tags": [], - "label": "bearing", + "label": "type", "description": [], - "signature": [ - "number | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Style.center", - "type": "Array", + "id": "def-server.Source.id", + "type": "string", "tags": [], - "label": "center", + "label": "id", "description": [], - "signature": [ - "number[] | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Style.glyphs", - "type": "string", + "id": "def-server.Source.minzoom", + "type": "number", "tags": [], - "label": "glyphs", + "label": "minzoom", "description": [], - "signature": [ - "string | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Style.layers", - "type": "Array", + "id": "def-server.Source.maxzoom", + "type": "number", "tags": [], - "label": "layers", + "label": "maxzoom", "description": [], - "signature": [ - "maplibregl.AnyLayer[] | undefined" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Style.metadata", - "type": "Any", + "id": "def-server.Source.tileSize", + "type": "number", "tags": [], - "label": "metadata", + "label": "tileSize", "description": [], - "signature": [ - "any" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Style.name", + "id": "def-server.Source.attribution", "type": "string", "tags": [], - "label": "name", + "label": "attribution", "description": [], "signature": [ "string | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Style.pitch", - "type": "number", + "id": "def-server.Source.roundZoom", + "type": "CompoundType", "tags": [], - "label": "pitch", + "label": "roundZoom", "description": [], "signature": [ - "number | undefined" + "boolean | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Style.light", - "type": "Object", + "id": "def-server.Source.isTileClipped", + "type": "CompoundType", "tags": [], - "label": "light", + "label": "isTileClipped", "description": [], "signature": [ - "maplibregl.Light | undefined" + "boolean | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Style.sources", + "id": "def-server.Source.tileID", "type": "Object", "tags": [], - "label": "sources", + "label": "tileID", "description": [], "signature": [ - "maplibregl.Sources | undefined" + "maplibregl.CanonicalTileID | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Style.sprite", - "type": "string", + "id": "def-server.Source.reparseOverscaled", + "type": "CompoundType", "tags": [], - "label": "sprite", + "label": "reparseOverscaled", "description": [], "signature": [ - "string | undefined" + "boolean | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Style.transition", - "type": "Object", + "id": "def-server.Source.vectorLayerIds", + "type": "Array", "tags": [], - "label": "transition", + "label": "vectorLayerIds", "description": [], "signature": [ - "maplibregl.Transition | undefined" + "string[] | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Style.version", - "type": "number", + "id": "def-server.Source.hasTransition", + "type": "Function", "tags": [], - "label": "version", + "label": "hasTransition", "description": [], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "signature": [ + "() => boolean" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.Style.zoom", - "type": "number", + "id": "def-server.Source.loaded", + "type": "Function", "tags": [], - "label": "zoom", + "label": "loaded", "description": [], "signature": [ - "number | undefined" + "() => boolean" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.VectorSource", - "type": "Interface", - "tags": [], - "label": "VectorSource", - "description": [], - "signature": [ - "maplibregl.VectorSource extends maplibregl.Source" - ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false, - "children": [ + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.VectorSource.type", - "type": "string", + "id": "def-server.Source.fire", + "type": "Function", "tags": [], - "label": "type", + "label": "fire", "description": [], "signature": [ - "\"vector\"" + "(event: maplibregl.Event) => unknown" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Source.fire.$1", + "type": "Object", + "tags": [], + "label": "event", + "description": [], + "signature": [ + "maplibregl.Event" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.VectorSource.url", - "type": "string", + "id": "def-server.Source.onAdd", + "type": "Function", "tags": [], - "label": "url", + "label": "onAdd", "description": [], "signature": [ - "string | undefined" + "((map: maplibregl.Map) => void) | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Source.onAdd.$1", + "type": "Object", + "tags": [], + "label": "map", + "description": [], + "signature": [ + "maplibregl.Map" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.VectorSource.tiles", - "type": "Array", + "id": "def-server.Source.onRemove", + "type": "Function", "tags": [], - "label": "tiles", + "label": "onRemove", "description": [], "signature": [ - "string[] | undefined" + "((map: maplibregl.Map) => void) | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Source.onRemove.$1", + "type": "Object", + "tags": [], + "label": "map", + "description": [], + "signature": [ + "maplibregl.Map" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.VectorSource.bounds", - "type": "Array", + "id": "def-server.Source.loadTile", + "type": "Function", "tags": [], - "label": "bounds", + "label": "loadTile", "description": [], "signature": [ - "number[] | undefined" + "(tile: maplibregl.Tile, callback: maplibregl.Callback) => void" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Source.loadTile.$1", + "type": "Object", + "tags": [], + "label": "tile", + "description": [], + "signature": [ + "maplibregl.Tile" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Source.loadTile.$2", + "type": "Function", + "tags": [], + "label": "callback", + "description": [], + "signature": [ + "maplibregl.Callback" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.VectorSource.scheme", - "type": "CompoundType", + "id": "def-server.Source.hasTile", + "type": "Function", "tags": [], - "label": "scheme", + "label": "hasTile", "description": [], "signature": [ - "\"xyz\" | \"tms\" | undefined" + "((tileID: maplibregl.OverscaledTileID) => boolean) | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Source.hasTile.$1", + "type": "Object", + "tags": [], + "label": "tileID", + "description": [], + "signature": [ + "maplibregl.OverscaledTileID" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.VectorSource.minzoom", - "type": "number", + "id": "def-server.Source.abortTile", + "type": "Function", "tags": [], - "label": "minzoom", + "label": "abortTile", "description": [], "signature": [ - "number | undefined" + "((tile: maplibregl.Tile, callback: maplibregl.Callback) => void) | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Source.abortTile.$1", + "type": "Object", + "tags": [], + "label": "tile", + "description": [], + "signature": [ + "maplibregl.Tile" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Source.abortTile.$2", + "type": "Function", + "tags": [], + "label": "callback", + "description": [], + "signature": [ + "maplibregl.Callback" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.VectorSource.maxzoom", - "type": "number", + "id": "def-server.Source.unloadTile", + "type": "Function", "tags": [], - "label": "maxzoom", + "label": "unloadTile", "description": [], "signature": [ - "number | undefined" + "((tile: maplibregl.Tile, callback: maplibregl.Callback) => void) | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Source.unloadTile.$1", + "type": "Object", + "tags": [], + "label": "tile", + "description": [], + "signature": [ + "maplibregl.Tile" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Source.unloadTile.$2", + "type": "Function", + "tags": [], + "label": "callback", + "description": [], + "signature": [ + "maplibregl.Callback" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.VectorSource.attribution", - "type": "string", - "tags": [], - "label": "attribution", + "id": "def-server.Source.serialize", + "type": "Function", + "tags": [ + "private" + ], + "label": "serialize", "description": [], "signature": [ - "string | undefined" + "() => any" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [ + "A plain (stringifiable) JS object representing the current state of the source.\nCreating a source using the returned object as the `options` should result in a Source that is\nequivalent to this one." + ] }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.VectorSource.promoteId", - "type": "CompoundType", + "id": "def-server.Source.prepare", + "type": "Function", "tags": [], - "label": "promoteId", + "label": "prepare", "description": [], "signature": [ - "maplibregl.PromoteIdSpecification | undefined" + "(() => void) | undefined" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", - "deprecated": false + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "children": [], + "returnComment": [] } ], "initialIsOpen": false @@ -6815,38 +7510,80 @@ "misc": [ { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.AnyLayer", + "id": "def-server.FeatureIdentifier", + "type": "Type", + "tags": [], + "label": "FeatureIdentifier", + "description": [], + "signature": [ + "{ id?: string | number | undefined; source: string; sourceLayer?: string | undefined; }" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.FilterSpecification", + "type": "Type", + "tags": [], + "label": "FilterSpecification", + "description": [], + "signature": [ + "[\"at\", number, (string | number)[]] | [\"get\", string, (Record | undefined)?] | [\"has\", string, (Record | undefined)?] | [\"in\", ...maplibregl.FilterSpecificationInputType[], maplibregl.FilterSpecificationInputType | maplibregl.FilterSpecificationInputType[]] | [\"index-of\", maplibregl.FilterSpecificationInputType, maplibregl.FilterSpecificationInputType | maplibregl.FilterSpecificationInputType[]] | [\"length\", string | string[]] | [\"slice\", string | string[], number] | [\"!\", maplibregl.FilterSpecification] | [\"!=\", string | maplibregl.FilterSpecification, maplibregl.FilterSpecificationInputType] | [\"<\", string | maplibregl.FilterSpecification, maplibregl.FilterSpecificationInputType] | [\"<=\", string | maplibregl.FilterSpecification, maplibregl.FilterSpecificationInputType] | [\"==\", string | maplibregl.FilterSpecification, maplibregl.FilterSpecificationInputType] | [\">\", string | maplibregl.FilterSpecification, maplibregl.FilterSpecificationInputType] | [\">=\", string | maplibregl.FilterSpecification, maplibregl.FilterSpecificationInputType] | [\"all\", ...maplibregl.FilterSpecification[], maplibregl.FilterSpecificationInputType] | [\"any\", ...maplibregl.FilterSpecification[], maplibregl.FilterSpecificationInputType] | [\"case\", ...maplibregl.FilterSpecification[], maplibregl.FilterSpecificationInputType] | [\"coalesce\", ...maplibregl.FilterSpecification[], maplibregl.FilterSpecificationInputType] | [\"match\", ...maplibregl.FilterSpecification[], maplibregl.FilterSpecificationInputType] | [\"within\", ...maplibregl.FilterSpecification[], maplibregl.FilterSpecificationInputType] | [\"!in\", ...maplibregl.FilterSpecification[], maplibregl.FilterSpecificationInputType] | [\"!has\", ...maplibregl.FilterSpecification[], maplibregl.FilterSpecificationInputType] | [\"none\", ...maplibregl.FilterSpecification[], maplibregl.FilterSpecificationInputType] | (string | maplibregl.FilterSpecification)[]" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.LayerSpecification", + "type": "Type", + "tags": [], + "label": "LayerSpecification", + "description": [], + "signature": [ + "maplibregl.FillLayerSpecification | maplibregl.LineLayerSpecification | maplibregl.SymbolLayerSpecification | maplibregl.CircleLayerSpecification | maplibregl.HeatmapLayerSpecification | maplibregl.FillExtrusionLayerSpecification | maplibregl.RasterLayerSpecification | maplibregl.HillshadeLayerSpecification | maplibregl.BackgroundLayerSpecification" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.MapEvent", "type": "Type", "tags": [], - "label": "AnyLayer", + "label": "MapEvent", "description": [], "signature": [ - "maplibregl.BackgroundLayer | maplibregl.CircleLayer | maplibregl.FillExtrusionLayer | maplibregl.FillLayer | maplibregl.HeatmapLayer | maplibregl.HillshadeLayer | maplibregl.LineLayer | maplibregl.RasterLayer | maplibregl.SymbolLayer | maplibregl.CustomLayerInterface" + "\"remove\" | \"error\" | \"data\" | \"render\" | \"move\" | \"rotate\" | \"idle\" | \"resize\" | \"zoom\" | \"mousedown\" | \"mouseup\" | \"mouseover\" | \"mousemove\" | \"click\" | \"dblclick\" | \"mouseenter\" | \"mouseleave\" | \"mouseout\" | \"contextmenu\" | \"wheel\" | \"touchstart\" | \"touchend\" | \"touchmove\" | \"touchcancel\" | \"movestart\" | \"moveend\" | \"dragstart\" | \"drag\" | \"dragend\" | \"zoomstart\" | \"zoomend\" | \"rotatestart\" | \"rotateend\" | \"pitchstart\" | \"pitch\" | \"pitchend\" | \"boxzoomstart\" | \"boxzoomend\" | \"boxzoomcancel\" | \"webglcontextlost\" | \"webglcontextrestored\" | \"load\" | \"styledata\" | \"sourcedata\" | \"dataloading\" | \"styledataloading\" | \"sourcedataloading\" | \"styleimagemissing\" | \"style.load\" | \"dataabort\" | \"sourcedataabort\"" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "initialIsOpen": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.MapboxGeoJSONFeature", + "id": "def-server.MapGeoJSONFeature", "type": "Type", "tags": [], - "label": "MapboxGeoJSONFeature", + "label": "MapGeoJSONFeature", "description": [], "signature": [ - "GeoJSON.Feature & { layer: maplibregl.Layer; source: string; sourceLayer: string; state: { [key: string]: any; }; }" + "maplibregl.GeoJSONFeature & { layer: Omit & { source: string; }; source: string; sourceLayer?: string | undefined; state: { [key: string]: any; }; }" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "initialIsOpen": false }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.mapboxgl", + "id": "def-server.maplibregl", "type": "Any", "tags": [], - "label": "mapboxgl", + "label": "maplibregl", "description": [], "signature": [ "any" @@ -6857,15 +7594,62 @@ }, { "parentPluginId": "@kbn/mapbox-gl", - "id": "def-server.PointLike", + "id": "def-server.MapOptions", "type": "Type", "tags": [], + "label": "MapOptions", + "description": [], + "signature": [ + "{ hash?: string | boolean | undefined; interactive?: boolean | undefined; container: string | HTMLElement; bearingSnap?: number | undefined; attributionControl?: boolean | undefined; customAttribution?: string | string[] | undefined; maplibreLogo?: boolean | undefined; logoPosition?: maplibregl.ControlPosition | undefined; failIfMajorPerformanceCaveat?: boolean | undefined; preserveDrawingBuffer?: boolean | undefined; antialias?: boolean | undefined; refreshExpiredTiles?: boolean | undefined; maxBounds?: maplibregl.LngLatBoundsLike | undefined; scrollZoom?: boolean | undefined; minZoom?: number | null | undefined; maxZoom?: number | null | undefined; minPitch?: number | null | undefined; maxPitch?: number | null | undefined; boxZoom?: boolean | undefined; dragRotate?: boolean | undefined; dragPan?: boolean | maplibregl.DragPanOptions | undefined; keyboard?: boolean | undefined; doubleClickZoom?: boolean | undefined; touchZoomRotate?: boolean | undefined; touchPitch?: boolean | undefined; trackResize?: boolean | undefined; center?: maplibregl.LngLatLike | undefined; zoom?: number | undefined; bearing?: number | undefined; pitch?: number | undefined; renderWorldCopies?: boolean | undefined; maxTileCacheSize?: number | undefined; transformRequest?: maplibregl.RequestTransformFunction | undefined; locale?: any; fadeDuration?: number | undefined; crossSourceCollisions?: boolean | undefined; collectResourceTiming?: boolean | undefined; clickTolerance?: number | undefined; bounds?: maplibregl.LngLatBoundsLike | undefined; fitBoundsOptions?: Object | undefined; localIdeographFontFamily?: string | undefined; style: string | maplibregl.StyleSpecification; pitchWithRotate?: boolean | undefined; pixelRatio?: number | undefined; }" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.Point2D", + "type": "Type", + "tags": [], + "label": "Point2D", + "description": [], + "signature": [ + "{ x: number; y: number; }" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.PointLike", + "type": "Type", + "tags": [ + "typedef" + ], "label": "PointLike", + "description": [ + "\nA [Point](https://github.com/mapbox/point-geometry) or an array of two numbers representing `x` and `y` screen coordinates in pixels.\n" + ], + "signature": [ + "[number, number] | ", + "node_modules/@types/mapbox__point-geometry/index" + ], + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/mapbox-gl", + "id": "def-server.StyleSpecification", + "type": "Type", + "tags": [], + "label": "StyleSpecification", "description": [], "signature": [ - "[number, number] | maplibregl.Point" + "{ version: 8; name?: string | undefined; metadata?: unknown; center?: number[] | undefined; zoom?: number | undefined; bearing?: number | undefined; pitch?: number | undefined; light?: maplibregl.LightSpecification | undefined; sources: { [_: string]: maplibregl.SourceSpecification; }; sprite?: string | undefined; glyphs?: string | undefined; transition?: maplibregl.TransitionSpecification | undefined; layers: maplibregl.LayerSpecification[]; }" ], - "path": "node_modules/maplibre-gl/src/index.d.ts", + "path": "node_modules/maplibre-gl/dist/maplibre-gl.d.ts", "deprecated": false, "initialIsOpen": false } diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index 53aa377e5c7a7..98e67f9b8208e 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/mapbox-gl plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 466 | 1 | 1 | 0 | +| 494 | 1 | 1 | 0 | ## Server diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index 71a68c280f4c4..e0dbc611af5a0 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/monaco plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/monaco'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index 2a473e955b4f0..589a60a957724 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/optimizer plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_plugin_discovery.devdocs.json b/api_docs/kbn_plugin_discovery.devdocs.json index f3e8e676b568f..331ea07e1db83 100644 --- a/api_docs/kbn_plugin_discovery.devdocs.json +++ b/api_docs/kbn_plugin_discovery.devdocs.json @@ -19,7 +19,7 @@ "label": "getPluginSearchPaths", "description": [], "signature": [ - "({ rootDir, oss, examples }: ", + "({ rootDir, oss, examples, testPlugins }: ", { "pluginId": "@kbn/plugin-discovery", "scope": "server", @@ -37,7 +37,7 @@ "id": "def-server.getPluginSearchPaths.$1", "type": "Object", "tags": [], - "label": "{ rootDir, oss, examples }", + "label": "{ rootDir, oss, examples, testPlugins }", "description": [], "signature": [ { @@ -289,6 +289,19 @@ "path": "packages/kbn-plugin-discovery/src/parse_kibana_platform_plugin.ts", "deprecated": false }, + { + "parentPluginId": "@kbn/plugin-discovery", + "id": "def-server.KibanaPlatformPluginManifest.enabledOnAnonymousPages", + "type": "CompoundType", + "tags": [], + "label": "enabledOnAnonymousPages", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "packages/kbn-plugin-discovery/src/parse_kibana_platform_plugin.ts", + "deprecated": false + }, { "parentPluginId": "@kbn/plugin-discovery", "id": "def-server.KibanaPlatformPluginManifest.serviceFolders", @@ -396,6 +409,19 @@ "description": [], "path": "packages/kbn-plugin-discovery/src/plugin_search_paths.ts", "deprecated": false + }, + { + "parentPluginId": "@kbn/plugin-discovery", + "id": "def-server.SearchOptions.testPlugins", + "type": "CompoundType", + "tags": [], + "label": "testPlugins", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "packages/kbn-plugin-discovery/src/plugin_search_paths.ts", + "deprecated": false } ], "initialIsOpen": false diff --git a/api_docs/kbn_plugin_discovery.mdx b/api_docs/kbn_plugin_discovery.mdx index 0bdfc493aa7d4..1e30d398d906c 100644 --- a/api_docs/kbn_plugin_discovery.mdx +++ b/api_docs/kbn_plugin_discovery.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-discovery title: "@kbn/plugin-discovery" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/plugin-discovery plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-discovery'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 28 | 0 | 27 | 0 | +| 30 | 0 | 29 | 0 | ## Server diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index 6803a60cd1d81..85a2f9ace93de 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/plugin-generator plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-generator'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_plugin_helpers.mdx b/api_docs/kbn_plugin_helpers.mdx index b549f24fa74fa..abcb0613f1d31 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/plugin-helpers plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_pm.devdocs.json b/api_docs/kbn_pm.devdocs.json index ec66a824a63a3..d43dd55273e42 100644 --- a/api_docs/kbn_pm.devdocs.json +++ b/api_docs/kbn_pm.devdocs.json @@ -328,23 +328,6 @@ "children": [], "returnComment": [] }, - { - "parentPluginId": "@kbn/pm", - "id": "def-server.Project.getIntermediateBuildDirectory", - "type": "Function", - "tags": [], - "label": "getIntermediateBuildDirectory", - "description": [ - "\nReturns the directory that should be copied into the Kibana build artifact.\nThis config can be specified to only include the project's build artifacts\ninstead of everything located in the project directory." - ], - "signature": [ - "() => string" - ], - "path": "packages/kbn-pm/src/utils/project.ts", - "deprecated": false, - "children": [], - "returnComment": [] - }, { "parentPluginId": "@kbn/pm", "id": "def-server.Project.getCleanConfig", @@ -578,177 +561,12 @@ "deprecated": false, "children": [], "returnComment": [] - }, - { - "parentPluginId": "@kbn/pm", - "id": "def-server.Project.installDependencies", - "type": "Function", - "tags": [], - "label": "installDependencies", - "description": [], - "signature": [ - "(options?: { extraArgs?: string[] | undefined; }) => Promise" - ], - "path": "packages/kbn-pm/src/utils/project.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/pm", - "id": "def-server.Project.installDependencies.$1", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "path": "packages/kbn-pm/src/utils/project.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/pm", - "id": "def-server.Project.installDependencies.$1.extraArgs", - "type": "Array", - "tags": [], - "label": "extraArgs", - "description": [], - "signature": [ - "string[] | undefined" - ], - "path": "packages/kbn-pm/src/utils/project.ts", - "deprecated": false - } - ] - } - ], - "returnComment": [] } ], "initialIsOpen": false } ], "functions": [ - { - "parentPluginId": "@kbn/pm", - "id": "def-server.buildBazelProductionProjects", - "type": "Function", - "tags": [], - "label": "buildBazelProductionProjects", - "description": [], - "signature": [ - "({\n kibanaRoot,\n buildRoot,\n onlyOSS,\n}: { kibanaRoot: string; buildRoot: string; onlyOSS?: boolean | undefined; }) => Promise" - ], - "path": "packages/kbn-pm/src/production/build_bazel_production_projects.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/pm", - "id": "def-server.buildBazelProductionProjects.$1", - "type": "Object", - "tags": [], - "label": "{\n kibanaRoot,\n buildRoot,\n onlyOSS,\n}", - "description": [], - "path": "packages/kbn-pm/src/production/build_bazel_production_projects.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/pm", - "id": "def-server.buildBazelProductionProjects.$1.kibanaRoot", - "type": "string", - "tags": [], - "label": "kibanaRoot", - "description": [], - "path": "packages/kbn-pm/src/production/build_bazel_production_projects.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/pm", - "id": "def-server.buildBazelProductionProjects.$1.buildRoot", - "type": "string", - "tags": [], - "label": "buildRoot", - "description": [], - "path": "packages/kbn-pm/src/production/build_bazel_production_projects.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/pm", - "id": "def-server.buildBazelProductionProjects.$1.onlyOSS", - "type": "CompoundType", - "tags": [], - "label": "onlyOSS", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "packages/kbn-pm/src/production/build_bazel_production_projects.ts", - "deprecated": false - } - ] - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/pm", - "id": "def-server.buildNonBazelProductionProjects", - "type": "Function", - "tags": [], - "label": "buildNonBazelProductionProjects", - "description": [], - "signature": [ - "({\n kibanaRoot,\n buildRoot,\n onlyOSS,\n}: { kibanaRoot: string; buildRoot: string; onlyOSS?: boolean | undefined; }) => Promise" - ], - "path": "packages/kbn-pm/src/production/build_non_bazel_production_projects.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/pm", - "id": "def-server.buildNonBazelProductionProjects.$1", - "type": "Object", - "tags": [], - "label": "{\n kibanaRoot,\n buildRoot,\n onlyOSS,\n}", - "description": [], - "path": "packages/kbn-pm/src/production/build_non_bazel_production_projects.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/pm", - "id": "def-server.buildNonBazelProductionProjects.$1.kibanaRoot", - "type": "string", - "tags": [], - "label": "kibanaRoot", - "description": [], - "path": "packages/kbn-pm/src/production/build_non_bazel_production_projects.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/pm", - "id": "def-server.buildNonBazelProductionProjects.$1.buildRoot", - "type": "string", - "tags": [], - "label": "buildRoot", - "description": [], - "path": "packages/kbn-pm/src/production/build_non_bazel_production_projects.ts", - "deprecated": false - }, - { - "parentPluginId": "@kbn/pm", - "id": "def-server.buildNonBazelProductionProjects.$1.onlyOSS", - "type": "CompoundType", - "tags": [], - "label": "onlyOSS", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "packages/kbn-pm/src/production/build_non_bazel_production_projects.ts", - "deprecated": false - } - ] - } - ], - "returnComment": [], - "initialIsOpen": false - }, { "parentPluginId": "@kbn/pm", "id": "def-server.getProjectPaths", @@ -889,42 +707,6 @@ ], "returnComment": [], "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/pm", - "id": "def-server.transformDependencies", - "type": "Function", - "tags": [], - "label": "transformDependencies", - "description": [ - "\nReplaces `link:` dependencies with `file:` dependencies. When installing\ndependencies, these `file:` dependencies will be copied into `node_modules`\ninstead of being symlinked.\n\nThis will allow us to copy packages into the build and run `yarn`, which\nwill then _copy_ the `file:` dependencies into `node_modules` instead of\nsymlinking like we do in development.\n\nAdditionally it also taken care of replacing `link:bazel-bin/` with\n`file:` so we can also support the copy of the Bazel packages dist already into\nbuild/packages to be copied into the node_modules" - ], - "signature": [ - "(dependencies: ", - "IPackageDependencies", - ") => ", - "IPackageDependencies" - ], - "path": "packages/kbn-pm/src/utils/package_json.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/pm", - "id": "def-server.transformDependencies.$1", - "type": "Object", - "tags": [], - "label": "dependencies", - "description": [], - "signature": [ - "IPackageDependencies" - ], - "path": "packages/kbn-pm/src/utils/package_json.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false } ], "interfaces": [], diff --git a/api_docs/kbn_pm.mdx b/api_docs/kbn_pm.mdx index c71a8c2a1e351..b720c9ac68580 100644 --- a/api_docs/kbn_pm.mdx +++ b/api_docs/kbn_pm.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-pm title: "@kbn/pm" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/pm plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/pm'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 63 | 0 | 49 | 5 | +| 47 | 0 | 35 | 5 | ## Server diff --git a/api_docs/kbn_react_field.mdx b/api_docs/kbn_react_field.mdx index 5ada92c6138c5..6253496021689 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/react-field plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index 13068a7957a81..94645ec075d4d 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/rule-data-utils plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rule-data-utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_autocomplete.devdocs.json b/api_docs/kbn_securitysolution_autocomplete.devdocs.json index ee08de8665996..3c23bf9f43822 100644 --- a/api_docs/kbn_securitysolution_autocomplete.devdocs.json +++ b/api_docs/kbn_securitysolution_autocomplete.devdocs.json @@ -305,9 +305,9 @@ "\nGiven an array of lists and optionally a field this will return all\nthe lists that match against the field based on the types from the field\n\nNOTE: That we support one additional property from \"FieldSpec\" located here:\nsrc/plugins/data/common/index_patterns/fields/types.ts\nThis type property is esTypes. If it exists and is on there we will read off the esTypes." ], "signature": [ - "(lists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }[], field?: (", + "(lists: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }[], field?: (", "DataViewFieldBase", - " & { esTypes?: string[] | undefined; }) | undefined) => { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }[]" + " & { esTypes?: string[] | undefined; }) | undefined) => { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }[]" ], "path": "packages/kbn-securitysolution-autocomplete/src/filter_field_to_list/index.ts", "deprecated": false, @@ -322,7 +322,7 @@ "The lists to match against the field" ], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }[]" + "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }[]" ], "path": "packages/kbn-securitysolution-autocomplete/src/filter_field_to_list/index.ts", "deprecated": false, diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index c2866fcd43b3f..e007783b67ee3 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_es_utils.mdx b/api_docs/kbn_securitysolution_es_utils.mdx index ed7d867290493..4662dfc9e1a4e 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-es-utils plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-es-utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index 41a05b8d05265..4894eb915413e 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-hook-utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx index bb61fa2b22770..f0e0356561dd8 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-alerting-types'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.devdocs.json b/api_docs/kbn_securitysolution_io_ts_list_types.devdocs.json index f3b10dd30d340..333ab73f958fc 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.devdocs.json +++ b/api_docs/kbn_securitysolution_io_ts_list_types.devdocs.json @@ -27,7 +27,7 @@ "label": "updateExceptionListItemValidate", "description": [], "signature": [ - "(schema: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => string[]" + "(schema: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => string[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_validation/index.ts", "deprecated": false, @@ -40,7 +40,7 @@ "label": "schema", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_validation/index.ts", "deprecated": false, @@ -58,7 +58,7 @@ "label": "validateComments", "description": [], "signature": [ - "(item: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => string[]" + "(item: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => string[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_validation/index.ts", "deprecated": false, @@ -71,7 +71,7 @@ "label": "item", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_validation/index.ts", "deprecated": false, @@ -153,7 +153,7 @@ "label": "listItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts", "deprecated": false @@ -1216,7 +1216,7 @@ "label": "listItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts", "deprecated": false @@ -1307,7 +1307,7 @@ "label": "exceptions", "description": [], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts", "deprecated": false @@ -1897,7 +1897,7 @@ "label": "CreateEndpointListItemSchemaDecoded", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; comments: { comment: string; }[] | undefined; item_id: string | undefined; meta: object | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"os_types\"> & { comments: { comment: string; }[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Omit<{ description: string; entries: ({ field: string; operator: \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; comments: { comment: string; }[] | undefined; item_id: string | undefined; meta: object | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"os_types\"> & { comments: { comment: string; }[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_endpoint_list_item_schema/index.ts", "deprecated": false, @@ -1925,7 +1925,7 @@ "label": "CreateExceptionListItemSchema", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_exception_list_item_schema/index.ts", "deprecated": false, @@ -1939,7 +1939,7 @@ "label": "CreateExceptionListItemSchemaDecoded", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; comments: { comment: string; }[] | undefined; item_id: string | undefined; meta: object | undefined; namespace_type: \"single\" | \"agnostic\" | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"namespace_type\"> & { comments: { comment: string; }[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; comments: { comment: string; }[] | undefined; item_id: string | undefined; meta: object | undefined; namespace_type: \"single\" | \"agnostic\" | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"namespace_type\"> & { comments: { comment: string; }[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_exception_list_item_schema/index.ts", "deprecated": false, @@ -2009,7 +2009,7 @@ "label": "CreateListSchema", "description": [], "signature": [ - "{ description: string; name: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; } & { deserializer?: string | undefined; id?: string | undefined; meta?: object | undefined; serializer?: string | undefined; version?: number | undefined; }" + "{ description: string; name: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; } & { deserializer?: string | undefined; id?: string | undefined; meta?: object | undefined; serializer?: string | undefined; version?: number | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_list_schema/index.ts", "deprecated": false, @@ -2023,7 +2023,7 @@ "label": "CreateListSchemaDecoded", "description": [], "signature": [ - "{ type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; id: string | undefined; description: string; name: string; meta: object | undefined; serializer: string | undefined; deserializer: string | undefined; } & { version: number; }" + "{ id: string | undefined; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; description: string; name: string; meta: object | undefined; serializer: string | undefined; deserializer: string | undefined; } & { version: number; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/create_list_schema/index.ts", "deprecated": false, @@ -2317,7 +2317,7 @@ "label": "EntriesArray", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/entries/index.ts", "deprecated": false, @@ -2331,7 +2331,7 @@ "label": "EntriesArrayOrUndefined", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[] | undefined" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[] | undefined" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/entries/index.ts", "deprecated": false, @@ -2345,7 +2345,7 @@ "label": "Entry", "description": [], "signature": [ - "{ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }" + "{ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/entries/index.ts", "deprecated": false, @@ -2373,7 +2373,7 @@ "label": "EntryList", "description": [], "signature": [ - "{ field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; }" + "{ field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/entries_list/index.ts", "deprecated": false, @@ -2443,7 +2443,7 @@ "label": "ExceptionListItemSchema", "description": [], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/exception_list_item_schema/index.ts", "deprecated": false, @@ -2765,7 +2765,7 @@ "label": "FoundExceptionListItemSchema", "description": [], "signature": [ - "{ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }" + "{ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/found_exception_list_item_schema/index.ts", "deprecated": false, @@ -2793,7 +2793,7 @@ "label": "FoundListItemSchema", "description": [], "signature": [ - "{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; }[]; page: number; per_page: number; total: number; }" + "{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; }[]; page: number; per_page: number; total: number; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/found_list_item_schema/index.ts", "deprecated": false, @@ -2807,7 +2807,7 @@ "label": "FoundListSchema", "description": [], "signature": [ - "{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }" + "{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/found_list_schema/index.ts", "deprecated": false, @@ -2919,7 +2919,7 @@ "label": "ImportExceptionListItemSchema", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; item_id: string; list_id: string; name: string; type: \"simple\"; } & { id?: string | undefined; comments?: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[] | undefined; created_at?: string | undefined; updated_at?: string | undefined; created_by?: string | undefined; updated_by?: string | undefined; _version?: string | undefined; tie_breaker_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; item_id: string; list_id: string; name: string; type: \"simple\"; } & { id?: string | undefined; comments?: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[] | undefined; created_at?: string | undefined; updated_at?: string | undefined; created_by?: string | undefined; updated_by?: string | undefined; _version?: string | undefined; tie_breaker_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/import_exception_item_schema/index.ts", "deprecated": false, @@ -2933,7 +2933,7 @@ "label": "ImportExceptionListItemSchemaDecoded", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; item_id: string; list_id: string; name: string; type: \"simple\"; } & { id?: string | undefined; comments?: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[] | undefined; created_at?: string | undefined; updated_at?: string | undefined; created_by?: string | undefined; updated_by?: string | undefined; _version?: string | undefined; tie_breaker_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"namespace_type\"> & { comments: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; item_id: string; list_id: string; name: string; type: \"simple\"; } & { id?: string | undefined; comments?: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[] | undefined; created_at?: string | undefined; updated_at?: string | undefined; created_by?: string | undefined; updated_by?: string | undefined; _version?: string | undefined; tie_breaker_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"item_id\" | \"namespace_type\"> & { comments: (({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; }) | { comment: string; })[]; tags: string[]; item_id: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/import_exception_item_schema/index.ts", "deprecated": false, @@ -2989,7 +2989,7 @@ "label": "ImportListItemQuerySchema", "description": [], "signature": [ - "{ deserializer: string | undefined; list_id: string | undefined; serializer: string | undefined; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\" | undefined; }" + "{ deserializer: string | undefined; list_id: string | undefined; serializer: string | undefined; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\" | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/import_list_item_query_schema/index.ts", "deprecated": false, @@ -3003,7 +3003,7 @@ "label": "ImportListItemQuerySchemaEncoded", "description": [], "signature": [ - "{ deserializer?: string | undefined; list_id?: string | undefined; serializer?: string | undefined; type?: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\" | undefined; }" + "{ deserializer?: string | undefined; list_id?: string | undefined; serializer?: string | undefined; type?: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\" | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/import_list_item_query_schema/index.ts", "deprecated": false, @@ -3115,7 +3115,7 @@ "label": "ListArraySchema", "description": [], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }[]" + "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/list_schema/index.ts", "deprecated": false, @@ -3157,7 +3157,7 @@ "label": "ListItemArraySchema", "description": [], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; }[]" + "{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; }[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/list_item_schema/index.ts", "deprecated": false, @@ -3185,7 +3185,7 @@ "label": "ListItemSchema", "description": [], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; }" + "{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/list_item_schema/index.ts", "deprecated": false, @@ -3213,7 +3213,7 @@ "label": "ListSchema", "description": [], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }" + "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/list_schema/index.ts", "deprecated": false, @@ -3423,7 +3423,7 @@ "label": "NonEmptyEntriesArray", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/non_empty_entries_array/index.ts", "deprecated": false, @@ -3437,7 +3437,7 @@ "label": "NonEmptyEntriesArrayDecoded", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/non_empty_entries_array/index.ts", "deprecated": false, @@ -3829,7 +3829,7 @@ "label": "SearchListItemArraySchema", "description": [], "signature": [ - "{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }[]" + "{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }[]" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/search_list_item_schema/index.ts", "deprecated": false, @@ -3843,7 +3843,7 @@ "label": "SearchListItemSchema", "description": [], "signature": [ - "{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }" + "{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/response/search_list_item_schema/index.ts", "deprecated": false, @@ -3983,7 +3983,7 @@ "label": "Type", "description": [], "signature": [ - "\"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"" + "\"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/type/index.ts", "deprecated": false, @@ -3997,7 +3997,7 @@ "label": "TypeOrUndefined", "description": [], "signature": [ - "\"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\" | undefined" + "\"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\" | undefined" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/type/index.ts", "deprecated": false, @@ -4053,7 +4053,7 @@ "label": "UpdateEndpointListItemSchema", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_endpoint_list_item_schema/index.ts", "deprecated": false, @@ -4067,7 +4067,7 @@ "label": "UpdateEndpointListItemSchemaDecoded", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; _version: string | undefined; comments: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id: string | undefined; item_id: string | undefined; meta: object | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\"> & { comments: ({ comment: string; } & { id?: string | undefined; })[]; tags: string[]; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; _version: string | undefined; comments: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id: string | undefined; item_id: string | undefined; meta: object | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\"> & { comments: ({ comment: string; } & { id?: string | undefined; })[]; tags: string[]; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_endpoint_list_item_schema/index.ts", "deprecated": false, @@ -4081,7 +4081,7 @@ "label": "UpdateExceptionListItemSchema", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_schema/index.ts", "deprecated": false, @@ -4095,7 +4095,7 @@ "label": "UpdateExceptionListItemSchemaDecoded", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; _version: string | undefined; comments: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id: string | undefined; item_id: string | undefined; meta: object | undefined; namespace_type: \"single\" | \"agnostic\" | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"namespace_type\" | \"os_types\"> & { comments: ({ comment: string; } & { id?: string | undefined; })[]; tags: string[]; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" + "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; _version: string | undefined; comments: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id: string | undefined; item_id: string | undefined; meta: object | undefined; namespace_type: \"single\" | \"agnostic\" | undefined; os_types: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags: string[] | undefined; }, \"tags\" | \"entries\" | \"comments\" | \"namespace_type\" | \"os_types\"> & { comments: ({ comment: string; } & { id?: string | undefined; })[]; tags: string[]; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[]; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; }" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/request/update_exception_list_item_schema/index.ts", "deprecated": false, @@ -4628,7 +4628,7 @@ "StringC", "; entries: ", "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>; list_id: ", + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>; list_id: ", "Type", "; name: ", "StringC", @@ -6914,7 +6914,7 @@ "StringC", "; entries: ", "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>; item_id: ", + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>; item_id: ", "Type", "; list_id: ", "Type", @@ -7847,7 +7847,7 @@ ], "signature": [ "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>" + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>" ], "path": "packages/kbn-securitysolution-io-ts-list-types/src/common/non_empty_entries_array/index.ts", "deprecated": false, @@ -8780,7 +8780,7 @@ "StringC", "; entries: ", "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>; name: ", + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>; name: ", "StringC", "; type: ", "KeyofC", @@ -8833,7 +8833,7 @@ "StringC", "; entries: ", "Type", - "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>; name: ", + "<({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; })[]; field: string; type: \"nested\"; })[], unknown>; name: ", "StringC", "; type: ", "KeyofC", diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.mdx b/api_docs/kbn_securitysolution_io_ts_list_types.mdx index dd8f1bf8648d9..22b0760147191 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-list-types'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_io_ts_types.mdx b/api_docs/kbn_securitysolution_io_ts_types.mdx index 65d532fec19e4..40ecac1736349 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-types'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_io_ts_utils.mdx b/api_docs/kbn_securitysolution_io_ts_utils.mdx index a5c39ba338990..04e891298a380 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_list_api.devdocs.json b/api_docs/kbn_securitysolution_list_api.devdocs.json index 816e93b590a41..8c92d4257224a 100644 --- a/api_docs/kbn_securitysolution_list_api.devdocs.json +++ b/api_docs/kbn_securitysolution_list_api.devdocs.json @@ -62,7 +62,7 @@ "signature": [ "({ http, listItem, signal, }: ", "AddExceptionListItemProps", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-api/src/api/index.ts", "deprecated": false, @@ -206,7 +206,7 @@ "signature": [ "({ http, id, namespaceType, signal, }: ", "ApiCallByIdProps", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-api/src/api/index.ts", "deprecated": false, @@ -245,7 +245,7 @@ "section": "def-common.DeleteListParams", "text": "DeleteListParams" }, - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "packages/kbn-securitysolution-list-api/src/list_api/index.ts", "deprecated": false, @@ -399,7 +399,7 @@ "signature": [ "({ http, id, namespaceType, signal, }: ", "ApiCallByIdProps", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-api/src/api/index.ts", "deprecated": false, @@ -432,7 +432,7 @@ "signature": [ "({ filterOptions, http, listIds, namespaceTypes, pagination, signal, }: ", "ApiCallByListIdProps", - ") => Promise<{ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }>" + ") => Promise<{ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }>" ], "path": "packages/kbn-securitysolution-list-api/src/api/index.ts", "deprecated": false, @@ -504,7 +504,7 @@ "section": "def-common.FindListsParams", "text": "FindListsParams" }, - ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" + ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" ], "path": "packages/kbn-securitysolution-list-api/src/list_api/index.ts", "deprecated": false, @@ -549,7 +549,7 @@ "section": "def-common.ImportListParams", "text": "ImportListParams" }, - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "packages/kbn-securitysolution-list-api/src/list_api/index.ts", "deprecated": false, @@ -743,7 +743,7 @@ "signature": [ "({ http, listItem, signal, }: ", "UpdateExceptionListItemProps", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-api/src/api/index.ts", "deprecated": false, @@ -1076,7 +1076,7 @@ "label": "type", "description": [], "signature": [ - "\"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\" | undefined" + "\"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\" | undefined" ], "path": "packages/kbn-securitysolution-list-api/src/list_api/types.ts", "deprecated": false diff --git a/api_docs/kbn_securitysolution_list_api.mdx b/api_docs/kbn_securitysolution_list_api.mdx index 0f81fc34f3478..8b6b8cf07c15a 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-list-api plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-api'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_list_constants.mdx b/api_docs/kbn_securitysolution_list_constants.mdx index 698ac13af76d0..6615bac9efb38 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-list-constants plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-constants'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_list_hooks.devdocs.json b/api_docs/kbn_securitysolution_list_hooks.devdocs.json index 248881607be2d..48a866f37b9f3 100644 --- a/api_docs/kbn_securitysolution_list_hooks.devdocs.json +++ b/api_docs/kbn_securitysolution_list_hooks.devdocs.json @@ -29,7 +29,7 @@ "\nThis adds an id to the incoming exception item entries as ReactJS prefers to have\nan id added to them for use as a stable id. Later if we decide to change the data\nmodel to have id's within the array then this code should be removed. If not, then\nthis code should stay as an adapter for ReactJS.\n\nThis does break the type system slightly as we are lying a bit to the type system as we return\nthe same exceptionItem as we have previously but are augmenting the arrays with an id which TypeScript\ndoesn't mind us doing here. However, downstream you will notice that you have an id when the type\ndoes not indicate it. In that case use (ExceptionItem & { id: string }) temporarily if you're using the id. If you're not,\nyou can ignore the id and just use the normal TypeScript with ReactJS.\n" ], "signature": [ - "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -44,7 +44,7 @@ "The exceptionItem to add an id to the threat matches." ], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -66,7 +66,7 @@ "\nThis removes an id from the exceptionItem entries as ReactJS prefers to have\nan id added to them for use as a stable id. Later if we decide to change the data\nmodel to have id's within the array then this code should be removed. If not, then\nthis code should stay as an adapter for ReactJS.\n" ], "signature": [ - "(exceptionItem: T) => T" + "(exceptionItem: T) => T" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -103,7 +103,7 @@ "\nTransforms the output of rules to compensate for technical debt or UI concerns such as\nReactJS preferences for having ids within arrays if the data is not modeled that way.\n\nIf you add a new transform of the input called \"myNewTransform\" do it\nin the form of:\nflow(addIdToExceptionItemEntries, myNewTransform)(exceptionItem)\n" ], "signature": [ - "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -118,7 +118,7 @@ "The exceptionItem to transform the output of" ], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -138,7 +138,7 @@ "label": "transformNewItemOutput", "description": [], "signature": [ - "(exceptionItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "(exceptionItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) => { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -151,7 +151,7 @@ "label": "exceptionItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -171,7 +171,7 @@ "\nTransforms the output of exception items to compensate for technical debt or UI concerns such as\nReactJS preferences for having ids within arrays if the data is not modeled that way.\n\nIf you add a new transform of the output called \"myNewTransform\" do it\nin the form of:\nflow(removeIdFromExceptionItemsEntries, myNewTransform)(exceptionItem)\n" ], "signature": [ - "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" + "(exceptionItem: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })) => { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -186,7 +186,7 @@ "The exceptionItem to transform the output of" ], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; })" ], "path": "packages/kbn-securitysolution-list-hooks/src/transforms/index.ts", "deprecated": false, @@ -317,7 +317,7 @@ "OptionalSignalArgs", "<", "DeleteListParams", - ">], { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }>" + ">], { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_delete_list/index.ts", "deprecated": false, @@ -445,7 +445,7 @@ "OptionalSignalArgs", "<", "FindListsParams", - ">], { cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" + ">], { cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_find_lists/index.ts", "deprecated": false, @@ -467,7 +467,7 @@ "OptionalSignalArgs", "<", "ImportListParams", - ">], { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }>" + ">], { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_import_list/index.ts", "deprecated": false, @@ -623,7 +623,7 @@ "label": "addExceptionListItem", "description": [], "signature": [ - "(arg: { listItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }; }) => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + "(arg: { listItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }; }) => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false, @@ -646,7 +646,7 @@ "label": "listItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false @@ -664,7 +664,7 @@ "label": "updateExceptionListItem", "description": [], "signature": [ - "(arg: { listItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }; }) => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + "(arg: { listItem: { description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }; }) => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false, @@ -687,7 +687,7 @@ "label": "listItem", "description": [], "signature": [ - "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" + "{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false @@ -771,7 +771,7 @@ "signature": [ "(arg: ", "ApiCallMemoProps", - " & { onSuccess: (arg: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => void; }) => Promise" + " & { onSuccess: (arg: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => void; }) => Promise" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false, @@ -785,7 +785,7 @@ "description": [], "signature": [ "ApiCallMemoProps", - " & { onSuccess: (arg: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => void; }" + " & { onSuccess: (arg: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }) => void; }" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_api/index.ts", "deprecated": false, @@ -954,7 +954,7 @@ "label": "ReturnExceptionListAndItems", "description": [], "signature": [ - "[boolean, { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[], ", + "[boolean, { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[], ", "Pagination", ", Func | null]" ], @@ -996,7 +996,7 @@ "label": "ReturnPersistExceptionItem", "description": [], "signature": [ - "[PersistReturnExceptionItem, React.Dispatch<({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) | null>]" + "[PersistReturnExceptionItem, React.Dispatch<({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; name: string; type: \"simple\"; } & { _version?: string | undefined; comments?: ({ comment: string; } & { id?: string | undefined; })[] | undefined; id?: string | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }) | null>]" ], "path": "packages/kbn-securitysolution-list-hooks/src/use_persist_exception_item/index.ts", "deprecated": false, diff --git a/api_docs/kbn_securitysolution_list_hooks.mdx b/api_docs/kbn_securitysolution_list_hooks.mdx index db34eab6092e6..70e03cbfed95c 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-hooks'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_list_utils.devdocs.json b/api_docs/kbn_securitysolution_list_utils.devdocs.json index e10ed1097e954..89f36219cbe6b 100644 --- a/api_docs/kbn_securitysolution_list_utils.devdocs.json +++ b/api_docs/kbn_securitysolution_list_utils.devdocs.json @@ -27,7 +27,7 @@ "label": "addIdToEntries", "description": [], "signature": [ - "(entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]) => ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "(entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]) => ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "packages/kbn-securitysolution-list-utils/src/helpers/index.ts", "deprecated": false, @@ -40,7 +40,7 @@ "label": "entries", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "packages/kbn-securitysolution-list-utils/src/helpers/index.ts", "deprecated": false, @@ -58,7 +58,7 @@ "label": "buildExceptionFilter", "description": [], "signature": [ - "({ lists, excludeExceptions, chunkSize, alias, }: { lists: ({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]; excludeExceptions: boolean; chunkSize: number; alias: string | null; }) => ", + "({ lists, excludeExceptions, chunkSize, alias, }: { lists: ({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]; excludeExceptions: boolean; chunkSize: number; alias: string | null; }) => ", "Filter", " | undefined" ], @@ -83,7 +83,7 @@ "label": "lists", "description": [], "signature": [ - "({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]" + "({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]" ], "path": "packages/kbn-securitysolution-list-utils/src/build_exception_filter/index.ts", "deprecated": false @@ -703,7 +703,7 @@ "section": "def-common.ExceptionsBuilderExceptionItem", "text": "ExceptionsBuilderExceptionItem" }, - "[]) => ({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]" + "[]) => ({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]" ], "path": "packages/kbn-securitysolution-list-utils/src/helpers/index.ts", "deprecated": false, @@ -957,7 +957,7 @@ "section": "def-common.FormattedBuilderEntry", "text": "FormattedBuilderEntry" }, - ") => ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }) & { id?: string | undefined; }" + ") => ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }) & { id?: string | undefined; }" ], "path": "packages/kbn-securitysolution-list-utils/src/helpers/index.ts", "deprecated": false, @@ -1099,7 +1099,7 @@ "section": "def-common.FormattedBuilderEntry", "text": "FormattedBuilderEntry" }, - ", newField: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }) => { index: number; updatedEntry: ", + ", newField: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }) => { index: number; updatedEntry: ", { "pluginId": "@kbn/securitysolution-list-utils", "scope": "common", @@ -1144,7 +1144,7 @@ "- newly selected list" ], "signature": [ - "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }" + "{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }" ], "path": "packages/kbn-securitysolution-list-utils/src/helpers/index.ts", "deprecated": false, @@ -2529,7 +2529,7 @@ "label": "hasLargeValueList", "description": [], "signature": [ - "(entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]) => boolean" + "(entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]) => boolean" ], "path": "packages/kbn-securitysolution-list-utils/src/has_large_value_list/index.ts", "deprecated": false, @@ -2542,7 +2542,7 @@ "label": "entries", "description": [], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "packages/kbn-securitysolution-list-utils/src/has_large_value_list/index.ts", "deprecated": false, @@ -3170,7 +3170,7 @@ "label": "BuilderEntry", "description": [], "signature": [ - "(({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }) & { id?: string | undefined; }) | ", + "(({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; }) & { id?: string | undefined; }) | ", { "pluginId": "@kbn/securitysolution-list-utils", "scope": "common", @@ -3229,7 +3229,7 @@ "label": "CreateExceptionListItemBuilderSchema", "description": [], "signature": [ - "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }, \"meta\" | \"entries\"> & { meta: { temporaryUuid: string; }; entries: ", + "Omit<{ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }, \"meta\" | \"entries\"> & { meta: { temporaryUuid: string; }; entries: ", { "pluginId": "@kbn/securitysolution-list-utils", "scope": "common", @@ -3363,7 +3363,7 @@ "label": "ExceptionListItemBuilderSchema", "description": [], "signature": [ - "Omit<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }, \"entries\"> & { entries: ", + "Omit<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }, \"entries\"> & { entries: ", { "pluginId": "@kbn/securitysolution-list-utils", "scope": "common", diff --git a/api_docs/kbn_securitysolution_list_utils.mdx b/api_docs/kbn_securitysolution_list_utils.mdx index 935139d5e2871..39b7d58043270 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-list-utils plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_rules.mdx b/api_docs/kbn_securitysolution_rules.mdx index 8063a4d5dd5fa..e0a298ed33ecc 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-rules plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-rules'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_t_grid.mdx b/api_docs/kbn_securitysolution_t_grid.mdx index 6b5ef155d35b4..269196aeeda43 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-t-grid plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-t-grid'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_utils.mdx b/api_docs/kbn_securitysolution_utils.mdx index d9c6d570aa91b..f89634ac45a1b 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-utils plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_server_http_tools.mdx b/api_docs/kbn_server_http_tools.mdx index 5947022a02051..b7177420222a4 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/server-http-tools plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-http-tools'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_server_route_repository.mdx b/api_docs/kbn_server_route_repository.mdx index 59f1273b9499f..b4ded054b09ea 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/server-route-repository plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen.devdocs.json b/api_docs/kbn_shared_ux_button_exit_full_screen.devdocs.json new file mode 100644 index 0000000000000..bec75a657ccc1 --- /dev/null +++ b/api_docs/kbn_shared_ux_button_exit_full_screen.devdocs.json @@ -0,0 +1,242 @@ +{ + "id": "@kbn/shared-ux-button-exit-full-screen", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [ + { + "parentPluginId": "@kbn/shared-ux-button-exit-full-screen", + "id": "def-common.ExitFullScreenButton", + "type": "Function", + "tags": [], + "label": "ExitFullScreenButton", + "description": [ + "\nA component that can be used to exit full screen mode in Kibana. Requires a Provider for\nrelevant services." + ], + "signature": [ + "React.ForwardRefExoticComponent<", + "Props", + " & React.RefAttributes<{}>>" + ], + "path": "packages/shared-ux/button/exit_full_screen/src/index.ts", + "deprecated": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "@kbn/shared-ux-button-exit-full-screen", + "id": "def-common.ExitFullScreenButton.$1", + "type": "Uncategorized", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "P" + ], + "path": "node_modules/@types/react/index.d.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-button-exit-full-screen", + "id": "def-common.ExitFullScreenButtonComponent", + "type": "Function", + "tags": [], + "label": "ExitFullScreenButtonComponent", + "description": [ + "\nA pure component that resembles a button to exit full screen mode." + ], + "signature": [ + "React.ForwardRefExoticComponent<", + "Props", + " & React.RefAttributes<{}>>" + ], + "path": "packages/shared-ux/button/exit_full_screen/src/index.ts", + "deprecated": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "@kbn/shared-ux-button-exit-full-screen", + "id": "def-common.ExitFullScreenButtonComponent.$1", + "type": "Uncategorized", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "P" + ], + "path": "node_modules/@types/react/index.d.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-button-exit-full-screen", + "id": "def-common.ExitFullScreenButtonKibanaProvider", + "type": "Function", + "tags": [], + "label": "ExitFullScreenButtonKibanaProvider", + "description": [ + "\nKibana-specific Provider that maps to known dependency types." + ], + "signature": [ + "({ children, ...services }: React.PropsWithChildren<", + "KibanaServices", + ">) => JSX.Element" + ], + "path": "packages/shared-ux/button/exit_full_screen/src/services.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-button-exit-full-screen", + "id": "def-common.ExitFullScreenButtonKibanaProvider.$1", + "type": "CompoundType", + "tags": [], + "label": "{\n children,\n ...services\n}", + "description": [], + "signature": [ + "React.PropsWithChildren<", + "KibanaServices", + ">" + ], + "path": "packages/shared-ux/button/exit_full_screen/src/services.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-button-exit-full-screen", + "id": "def-common.ExitFullScreenButtonProvider", + "type": "Function", + "tags": [], + "label": "ExitFullScreenButtonProvider", + "description": [ + "\nAbstract external service Provider." + ], + "signature": [ + "({ children, ...services }: React.PropsWithChildren<", + "Services", + ">) => JSX.Element" + ], + "path": "packages/shared-ux/button/exit_full_screen/src/services.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-button-exit-full-screen", + "id": "def-common.ExitFullScreenButtonProvider.$1", + "type": "CompoundType", + "tags": [], + "label": "{ children, ...services }", + "description": [], + "signature": [ + "React.PropsWithChildren<", + "Services", + ">" + ], + "path": "packages/shared-ux/button/exit_full_screen/src/services.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-button-exit-full-screen", + "id": "def-common.LazyExitFullScreenButton", + "type": "Function", + "tags": [], + "label": "LazyExitFullScreenButton", + "description": [ + "\nLazy-loaded connected component. Must be wrapped in `React.Suspense` and a Provider." + ], + "signature": [ + "React.ExoticComponent<", + "Props", + "> & { readonly _result: ({ onExit, toggleChrome }: ", + "Props", + ") => JSX.Element; }" + ], + "path": "packages/shared-ux/button/exit_full_screen/src/index.ts", + "deprecated": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "@kbn/shared-ux-button-exit-full-screen", + "id": "def-common.LazyExitFullScreenButton.$1", + "type": "Uncategorized", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "P" + ], + "path": "node_modules/@types/react/index.d.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-button-exit-full-screen", + "id": "def-common.LazyExitFullScreenButtonComponent", + "type": "Function", + "tags": [], + "label": "LazyExitFullScreenButtonComponent", + "description": [ + "\nLazy-loaded pure component. Must be wrapped in `React.Suspense`." + ], + "signature": [ + "React.ExoticComponent<", + "Props", + "> & { readonly _result: ({ onClick, className }: ", + "Props", + ") => JSX.Element; }" + ], + "path": "packages/shared-ux/button/exit_full_screen/src/index.ts", + "deprecated": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "@kbn/shared-ux-button-exit-full-screen", + "id": "def-common.LazyExitFullScreenButtonComponent.$1", + "type": "Uncategorized", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "P" + ], + "path": "node_modules/@types/react/index.d.ts", + "deprecated": false + } + ], + "initialIsOpen": false + } + ], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx new file mode 100644 index 0000000000000..16c76cd894f90 --- /dev/null +++ b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx @@ -0,0 +1,27 @@ +--- +id: kibKbnSharedUxButtonExitFullScreenPluginApi +slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen +title: "@kbn/shared-ux-button-exit-full-screen" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the @kbn/shared-ux-button-exit-full-screen plugin +date: 2022-04-26 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import kbnSharedUxButtonExitFullScreenObj from './kbn_shared_ux_button_exit_full_screen.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 12 | 0 | 2 | 3 | + +## Common + +### Functions + + diff --git a/api_docs/kbn_shared_ux_components.devdocs.json b/api_docs/kbn_shared_ux_components.devdocs.json index 77f778bb3f118..fd3d022aeaef2 100644 --- a/api_docs/kbn_shared_ux_components.devdocs.json +++ b/api_docs/kbn_shared_ux_components.devdocs.json @@ -54,12 +54,12 @@ }, { "parentPluginId": "@kbn/shared-ux-components", - "id": "def-common.ExitFullScreenButton", + "id": "def-common.IconButtonGroup", "type": "Function", "tags": [], - "label": "ExitFullScreenButton", + "label": "IconButtonGroup", "description": [ - "\nA `ExitFullScreenButton` component that is wrapped by the `withSuspense` HOC. This component can\nbe used directly by consumers and will load the `LazyExitFullScreenButton` component lazily with\na predefined fallback and error boundary." + "\nThe IconButtonGroup component that is wrapped by the `withSuspence` HOC." ], "signature": [ "React.ForwardRefExoticComponent<", @@ -72,7 +72,7 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-components", - "id": "def-common.ExitFullScreenButton.$1", + "id": "def-common.IconButtonGroup.$1", "type": "Uncategorized", "tags": [], "label": "props", @@ -88,17 +88,35 @@ }, { "parentPluginId": "@kbn/shared-ux-components", - "id": "def-common.IconButtonGroup", + "id": "def-common.KibanaPageTemplate", "type": "Function", "tags": [], - "label": "IconButtonGroup", + "label": "KibanaPageTemplate", "description": [ - "\nThe IconButtonGroup component that is wrapped by the `withSuspence` HOC." + "\nA `KibanaPageTemplate` component that is wrapped by the `withSuspense` HOC. This component can\nbe used directly by consumers and will load the `KibanaPageTemplateLazy` component lazily with\na predefined fallback and error boundary." ], "signature": [ - "React.ForwardRefExoticComponent<", - "Props", - " & React.RefAttributes<{}>>" + "React.ForwardRefExoticComponent & { template?: \"default\" | \"empty\" | \"centeredBody\" | \"centeredContent\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; pageSideBar?: React.ReactNode; pageSideBarProps?: ", + "EuiPageSideBarProps", + " | undefined; pageHeader?: ", + "EuiPageHeaderProps", + " | undefined; pageBodyProps?: ", + "EuiPageBodyProps", + "<\"main\"> | undefined; pageContentProps?: ", + "EuiPageContentProps", + " | undefined; pageContentBodyProps?: ", + "EuiPageContentBodyProps", + " | undefined; bottomBar?: React.ReactNode; bottomBarProps?: ", + "EuiBottomBarProps", + " | undefined; fullHeight?: boolean | \"noscroll\" | undefined; minHeight?: ", + "MinHeightProperty", + " | undefined; } & { isEmptyState?: boolean | undefined; solutionNav?: ", + "KibanaPageTemplateSolutionNavProps", + " | undefined; noDataConfig?: ", + "NoDataPageProps", + " | undefined; } & React.RefAttributes<{}>>" ], "path": "packages/kbn-shared-ux-components/src/index.ts", "deprecated": false, @@ -106,7 +124,61 @@ "children": [ { "parentPluginId": "@kbn/shared-ux-components", - "id": "def-common.IconButtonGroup.$1", + "id": "def-common.KibanaPageTemplate.$1", + "type": "Uncategorized", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "P" + ], + "path": "node_modules/@types/react/index.d.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-components", + "id": "def-common.KibanaPageTemplateLazy", + "type": "Function", + "tags": [], + "label": "KibanaPageTemplateLazy", + "description": [ + "\nThe lazily loaded `KibanaPageTemplate` component that is wrapped by the `withSuspense` HOC. Consumers should use\n`React.Suspense` or `withSuspense` HOC to load this component." + ], + "signature": [ + "React.ExoticComponent & { template?: \"default\" | \"empty\" | \"centeredBody\" | \"centeredContent\" | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"l\" | undefined; pageSideBar?: React.ReactNode; pageSideBarProps?: ", + "EuiPageSideBarProps", + " | undefined; pageHeader?: ", + "EuiPageHeaderProps", + " | undefined; pageBodyProps?: ", + "EuiPageBodyProps", + "<\"main\"> | undefined; pageContentProps?: ", + "EuiPageContentProps", + " | undefined; pageContentBodyProps?: ", + "EuiPageContentBodyProps", + " | undefined; bottomBar?: React.ReactNode; bottomBarProps?: ", + "EuiBottomBarProps", + " | undefined; fullHeight?: boolean | \"noscroll\" | undefined; minHeight?: ", + "MinHeightProperty", + " | undefined; } & { isEmptyState?: boolean | undefined; solutionNav?: ", + "KibanaPageTemplateSolutionNavProps", + " | undefined; noDataConfig?: ", + "NoDataPageProps", + " | undefined; } & { children?: React.ReactNode; }> & { readonly _result: React.FunctionComponent<", + "KibanaPageTemplateProps", + ">; }" + ], + "path": "packages/kbn-shared-ux-components/src/index.ts", + "deprecated": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "@kbn/shared-ux-components", + "id": "def-common.KibanaPageTemplateLazy.$1", "type": "Uncategorized", "tags": [], "label": "props", @@ -280,42 +352,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "@kbn/shared-ux-components", - "id": "def-common.LazyExitFullScreenButton", - "type": "Function", - "tags": [], - "label": "LazyExitFullScreenButton", - "description": [ - "\nThe Lazily-loaded `ExitFullScreenButton` component. Consumers should use `React.Suspennse` or the\n`withSuspense` HOC to load this component." - ], - "signature": [ - "React.ExoticComponent<", - "Props", - "> & { readonly _result: ({ onExit, toggleChrome }: ", - "Props", - ") => JSX.Element; }" - ], - "path": "packages/kbn-shared-ux-components/src/index.ts", - "deprecated": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "@kbn/shared-ux-components", - "id": "def-common.LazyExitFullScreenButton.$1", - "type": "Uncategorized", - "tags": [], - "label": "props", - "description": [], - "signature": [ - "P" - ], - "path": "node_modules/@types/react/index.d.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "@kbn/shared-ux-components", "id": "def-common.LazyIconButtonGroup", @@ -323,7 +359,7 @@ "tags": [], "label": "LazyIconButtonGroup", "description": [ - "\nThe Lazily-loaded `IconButtonGroup` component. Consumers should use `React.Suspennse` or the\n`withSuspense` HOC to load this component." + "\nThe Lazily-loaded `IconButtonGroup` component. Consumers should use `React.Suspense` or the\n`withSuspense` HOC to load this component." ], "signature": [ "React.ExoticComponent<", @@ -359,7 +395,7 @@ "tags": [], "label": "LazyNoDataViews", "description": [ - "\nThe Lazily-loaded `NoDataViews` component. Consumers should use `React.Suspennse` or the\n`withSuspense` HOC to load this component." + "\nThe Lazily-loaded `NoDataViews` component. Consumers should use `React.Suspense` or the\n`withSuspense` HOC to load this component." ], "signature": [ "React.ExoticComponent<", @@ -395,7 +431,7 @@ "tags": [], "label": "LazyNoDataViewsComponent", "description": [ - "\nA pure `NoDataViews` component, with no services hooks. Consumers should use `React.Suspennse` or the\n`withSuspense` HOC to load this component." + "\nA pure `NoDataViews` component, with no services hooks. Consumers should use `React.Suspense` or the\n`withSuspense` HOC to load this component." ], "signature": [ "React.ExoticComponent<", @@ -434,7 +470,7 @@ "signature": [ "React.ExoticComponent<", "Props", - "> & { readonly _result: ({ label, ...rest }: ", + "> & { readonly _result: ({ label, iconSide, ...rest }: ", "Props", ") => JSX.Element; }" ], @@ -536,7 +572,7 @@ "signature": [ "React.ExoticComponent & { ref?: React.RefObject | ((instance: HTMLDivElement | null) => void) | null | undefined; }> & { readonly _result: React.FC<", + " & { children?: React.ReactNode; }, \"children\" | \"color\" | \"className\" | \"title\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"key\" | \"id\" | \"css\" | \"security\" | \"defaultValue\" | \"hidden\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"currentAppId$\" | \"navigateToUrl\"> & { ref?: React.RefObject | ((instance: HTMLDivElement | null) => void) | null | undefined; }> & { readonly _result: React.FC<", "RedirectAppLinksProps", ">; }" ], @@ -593,6 +629,39 @@ } ], "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/shared-ux-components", + "id": "def-common.ToolbarPopover", + "type": "Function", + "tags": [], + "label": "ToolbarPopover", + "description": [], + "signature": [ + "({ label, iconType, children, iconSide, ...popover }: ", + "Props", + ") => JSX.Element" + ], + "path": "packages/kbn-shared-ux-components/src/toolbar/popovers/popover.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/shared-ux-components", + "id": "def-common.ToolbarPopover.$1", + "type": "CompoundType", + "tags": [], + "label": "{ label, iconType, children, iconSide, ...popover }", + "description": [], + "signature": [ + "Props" + ], + "path": "packages/kbn-shared-ux-components/src/toolbar/popovers/popover.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false } ], "interfaces": [], diff --git a/api_docs/kbn_shared_ux_components.mdx b/api_docs/kbn_shared_ux_components.mdx index f5b118c1b36d2..41704c6d85694 100644 --- a/api_docs/kbn_shared_ux_components.mdx +++ b/api_docs/kbn_shared_ux_components.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-components title: "@kbn/shared-ux-components" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/shared-ux-components plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-components'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 32 | 0 | 4 | 4 | +| 34 | 0 | 6 | 6 | ## Common diff --git a/api_docs/kbn_shared_ux_services.mdx b/api_docs/kbn_shared_ux_services.mdx index e2cb765ac7161..98fc062b43b0b 100644 --- a/api_docs/kbn_shared_ux_services.mdx +++ b/api_docs/kbn_shared_ux_services.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-services title: "@kbn/shared-ux-services" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/shared-ux-services plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-services'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_shared_ux_storybook.mdx b/api_docs/kbn_shared_ux_storybook.mdx index 7643af3cf9f90..2ce78307c21c8 100644 --- a/api_docs/kbn_shared_ux_storybook.mdx +++ b/api_docs/kbn_shared_ux_storybook.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook title: "@kbn/shared-ux-storybook" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/shared-ux-storybook plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index 31ccc6897e4cb..5d8a6344b7906 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/shared-ux-utility plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-utility'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_sort_package_json.devdocs.json b/api_docs/kbn_sort_package_json.devdocs.json new file mode 100644 index 0000000000000..1c3fb56277e17 --- /dev/null +++ b/api_docs/kbn_sort_package_json.devdocs.json @@ -0,0 +1,59 @@ +{ + "id": "@kbn/sort-package-json", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [ + { + "parentPluginId": "@kbn/sort-package-json", + "id": "def-server.sortPackageJson", + "type": "Function", + "tags": [], + "label": "sortPackageJson", + "description": [], + "signature": [ + "(json: string) => string" + ], + "path": "packages/kbn-sort-package-json/src/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/sort-package-json", + "id": "def-server.sortPackageJson.$1", + "type": "string", + "tags": [], + "label": "json", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-sort-package-json/src/index.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_sort_package_json.mdx b/api_docs/kbn_sort_package_json.mdx new file mode 100644 index 0000000000000..de6879b4cef66 --- /dev/null +++ b/api_docs/kbn_sort_package_json.mdx @@ -0,0 +1,27 @@ +--- +id: kibKbnSortPackageJsonPluginApi +slug: /kibana-dev-docs/api/kbn-sort-package-json +title: "@kbn/sort-package-json" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the @kbn/sort-package-json plugin +date: 2022-04-26 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sort-package-json'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import kbnSortPackageJsonObj from './kbn_sort_package_json.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 2 | 0 | 2 | 0 | + +## Server + +### Functions + + diff --git a/api_docs/kbn_std.devdocs.json b/api_docs/kbn_std.devdocs.json index 3c7b5119d2b21..95993490eec8d 100644 --- a/api_docs/kbn_std.devdocs.json +++ b/api_docs/kbn_std.devdocs.json @@ -55,7 +55,7 @@ ], "signature": [ "(iterable: ", - "IterableInput", + "ObservableInput", ", fn: ", "AsyncMapFn", ") => Promise" @@ -73,7 +73,7 @@ "Items to iterate" ], "signature": [ - "IterableInput", + "ObservableInput", "" ], "path": "packages/kbn-std/src/iteration/for_each.ts", @@ -112,7 +112,7 @@ ], "signature": [ "(iterable: ", - "IterableInput", + "ObservableInput", ", limit: number, fn: ", "AsyncMapFn", ") => Promise" @@ -130,7 +130,7 @@ "Items to iterate" ], "signature": [ - "IterableInput", + "ObservableInput", "" ], "path": "packages/kbn-std/src/iteration/for_each.ts", @@ -185,7 +185,7 @@ ], "signature": [ "(iterable: ", - "IterableInput", + "ObservableInput", ", fn: ", "AsyncMapFn", ") => Promise" @@ -203,7 +203,7 @@ "Items to iterate" ], "signature": [ - "IterableInput", + "ObservableInput", "" ], "path": "packages/kbn-std/src/iteration/map.ts", @@ -242,7 +242,7 @@ ], "signature": [ "(iterable: ", - "IterableInput", + "ObservableInput", ", limit: number, fn: ", "AsyncMapFn", ") => Promise" @@ -260,7 +260,7 @@ "Items to iterate" ], "signature": [ - "IterableInput", + "ObservableInput", "" ], "path": "packages/kbn-std/src/iteration/map.ts", @@ -370,40 +370,6 @@ "returnComment": [], "initialIsOpen": false }, - { - "parentPluginId": "@kbn/std", - "id": "def-server.firstValueFrom", - "type": "Function", - "tags": [], - "label": "firstValueFrom", - "description": [], - "signature": [ - "(source: ", - "Observable", - ") => Promise" - ], - "path": "packages/kbn-std/src/rxjs_7.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/std", - "id": "def-server.firstValueFrom.$1", - "type": "Object", - "tags": [], - "label": "source", - "description": [], - "signature": [ - "Observable", - "" - ], - "path": "packages/kbn-std/src/rxjs_7.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, { "parentPluginId": "@kbn/std", "id": "def-server.get", @@ -806,40 +772,6 @@ "returnComment": [], "initialIsOpen": false }, - { - "parentPluginId": "@kbn/std", - "id": "def-server.lastValueFrom", - "type": "Function", - "tags": [], - "label": "lastValueFrom", - "description": [], - "signature": [ - "(source: ", - "Observable", - ") => Promise" - ], - "path": "packages/kbn-std/src/rxjs_7.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@kbn/std", - "id": "def-server.lastValueFrom.$1", - "type": "Object", - "tags": [], - "label": "source", - "description": [], - "signature": [ - "Observable", - "" - ], - "path": "packages/kbn-std/src/rxjs_7.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, { "parentPluginId": "@kbn/std", "id": "def-server.map$", @@ -851,7 +783,7 @@ ], "signature": [ "(iterable: ", - "IterableInput", + "ObservableInput", ", fn: ", "AsyncMapFn", ") => ", @@ -871,7 +803,7 @@ "Items to iterate" ], "signature": [ - "IterableInput", + "ObservableInput", "" ], "path": "packages/kbn-std/src/iteration/observable.ts", @@ -941,7 +873,7 @@ ], "signature": [ "(iterable: ", - "IterableInput", + "ObservableInput", ", limit: number, fn: ", "AsyncMapFn", ") => ", @@ -961,7 +893,7 @@ "Items to iterate" ], "signature": [ - "IterableInput", + "ObservableInput", "" ], "path": "packages/kbn-std/src/iteration/observable.ts", diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index ad1559fa9ea9d..f998a00c60e83 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/std plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/std'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 96 | 1 | 63 | 2 | +| 92 | 1 | 59 | 1 | ## Server diff --git a/api_docs/kbn_stdio_dev_helpers.devdocs.json b/api_docs/kbn_stdio_dev_helpers.devdocs.json new file mode 100644 index 0000000000000..478b3ea7c54e8 --- /dev/null +++ b/api_docs/kbn_stdio_dev_helpers.devdocs.json @@ -0,0 +1,104 @@ +{ + "id": "@kbn/stdio-dev-helpers", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [ + { + "parentPluginId": "@kbn/stdio-dev-helpers", + "id": "def-server.observeLines", + "type": "Function", + "tags": [ + "return" + ], + "label": "observeLines", + "description": [ + "\n Creates an Observable from a Readable Stream that:\n - splits data from `readable` into lines\n - completes when `readable` emits \"end\"\n - fails if `readable` emits \"errors\"\n" + ], + "signature": [ + "(readable: ", + "Readable", + ") => ", + "Observable", + "" + ], + "path": "packages/kbn-stdio-dev-helpers/src/observe_lines.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/stdio-dev-helpers", + "id": "def-server.observeLines.$1", + "type": "Object", + "tags": [], + "label": "readable", + "description": [], + "signature": [ + "Readable" + ], + "path": "packages/kbn-stdio-dev-helpers/src/observe_lines.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/stdio-dev-helpers", + "id": "def-server.observeReadable", + "type": "Function", + "tags": [], + "label": "observeReadable", + "description": [ + "\n Produces an Observable from a ReadableSteam that:\n - completes on the first \"end\" event\n - fails on the first \"error\" event" + ], + "signature": [ + "(readable: ", + "Readable", + ") => ", + "Observable", + "" + ], + "path": "packages/kbn-stdio-dev-helpers/src/observe_readable.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/stdio-dev-helpers", + "id": "def-server.observeReadable.$1", + "type": "Object", + "tags": [], + "label": "readable", + "description": [], + "signature": [ + "Readable" + ], + "path": "packages/kbn-stdio-dev-helpers/src/observe_readable.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_stdio_dev_helpers.mdx b/api_docs/kbn_stdio_dev_helpers.mdx new file mode 100644 index 0000000000000..0397b21fa5d78 --- /dev/null +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -0,0 +1,27 @@ +--- +id: kibKbnStdioDevHelpersPluginApi +slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers +title: "@kbn/stdio-dev-helpers" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the @kbn/stdio-dev-helpers plugin +date: 2022-04-26 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/stdio-dev-helpers'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import kbnStdioDevHelpersObj from './kbn_stdio_dev_helpers.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 4 | 0 | 2 | 0 | + +## Server + +### Functions + + diff --git a/api_docs/kbn_storybook.mdx b/api_docs/kbn_storybook.mdx index 98453e30ef707..c44717161b692 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/storybook plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index 0e9beedb79fde..e925254e723ee 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/telemetry-tools plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/telemetry-tools'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_test.mdx b/api_docs/kbn_test.mdx index f44a7d8a0b889..5edb2515010a2 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/test plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index 4c9edbd805851..0f711e998f1c7 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/test-jest-helpers plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_tooling_log.devdocs.json b/api_docs/kbn_tooling_log.devdocs.json new file mode 100644 index 0000000000000..6442d3feca9f3 --- /dev/null +++ b/api_docs/kbn_tooling_log.devdocs.json @@ -0,0 +1,1251 @@ +{ + "id": "@kbn/tooling-log", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog", + "type": "Class", + "tags": [], + "label": "ToolingLog", + "description": [], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.Unnamed.$1", + "type": "Object", + "tags": [], + "label": "writerConfig", + "description": [], + "signature": [ + { + "pluginId": "@kbn/tooling-log", + "scope": "server", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-server.ToolingLogTextWriterConfig", + "text": "ToolingLogTextWriterConfig" + }, + " | undefined" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "isRequired": false + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.Unnamed.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + { + "pluginId": "@kbn/tooling-log", + "scope": "server", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-server.ToolingLogOptions", + "text": "ToolingLogOptions" + }, + " | undefined" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.getIndent", + "type": "Function", + "tags": [], + "label": "getIndent", + "description": [ + "\nGet the current indentation level of the ToolingLog" + ], + "signature": [ + "() => number" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.indent", + "type": "Function", + "tags": [], + "label": "indent", + "description": [], + "signature": [ + "{ (delta: number): void; (delta: number, block: () => Promise): Promise; (delta: number, block: () => T): T; }" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.indent.$1", + "type": "number", + "tags": [], + "label": "delta", + "description": [], + "signature": [ + "number" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.indent.$2", + "type": "Function", + "tags": [], + "label": "block", + "description": [], + "signature": [ + "(() => T | Promise) | undefined" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.verbose", + "type": "Function", + "tags": [], + "label": "verbose", + "description": [], + "signature": [ + "(...args: any[]) => void" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.verbose.$1", + "type": "Array", + "tags": [], + "label": "args", + "description": [], + "signature": [ + "any[]" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.debug", + "type": "Function", + "tags": [], + "label": "debug", + "description": [], + "signature": [ + "(...args: any[]) => void" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.debug.$1", + "type": "Array", + "tags": [], + "label": "args", + "description": [], + "signature": [ + "any[]" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.info", + "type": "Function", + "tags": [], + "label": "info", + "description": [], + "signature": [ + "(...args: any[]) => void" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.info.$1", + "type": "Array", + "tags": [], + "label": "args", + "description": [], + "signature": [ + "any[]" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.success", + "type": "Function", + "tags": [], + "label": "success", + "description": [], + "signature": [ + "(...args: any[]) => void" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.success.$1", + "type": "Array", + "tags": [], + "label": "args", + "description": [], + "signature": [ + "any[]" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.warning", + "type": "Function", + "tags": [], + "label": "warning", + "description": [], + "signature": [ + "(...args: any[]) => void" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.warning.$1", + "type": "Array", + "tags": [], + "label": "args", + "description": [], + "signature": [ + "any[]" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.error", + "type": "Function", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "(error: string | Error) => void" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.error.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "string | Error" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.write", + "type": "Function", + "tags": [], + "label": "write", + "description": [], + "signature": [ + "(...args: any[]) => void" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.write.$1", + "type": "Array", + "tags": [], + "label": "args", + "description": [], + "signature": [ + "any[]" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.getWriters", + "type": "Function", + "tags": [], + "label": "getWriters", + "description": [], + "signature": [ + "() => ", + { + "pluginId": "@kbn/tooling-log", + "scope": "server", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-server.Writer", + "text": "Writer" + }, + "[]" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.setWriters", + "type": "Function", + "tags": [], + "label": "setWriters", + "description": [], + "signature": [ + "(writers: ", + { + "pluginId": "@kbn/tooling-log", + "scope": "server", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-server.Writer", + "text": "Writer" + }, + "[]) => void" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.setWriters.$1", + "type": "Array", + "tags": [], + "label": "writers", + "description": [], + "signature": [ + { + "pluginId": "@kbn/tooling-log", + "scope": "server", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-server.Writer", + "text": "Writer" + }, + "[]" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.getWritten$", + "type": "Function", + "tags": [], + "label": "getWritten$", + "description": [], + "signature": [ + "() => ", + "Observable", + "<", + { + "pluginId": "@kbn/tooling-log", + "scope": "server", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-server.Message", + "text": "Message" + }, + ">" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.withType", + "type": "Function", + "tags": [], + "label": "withType", + "description": [ + "\nCreate a new ToolingLog which sets a different \"type\", allowing messages to be filtered out by \"source\"" + ], + "signature": [ + "(type: string) => ", + { + "pluginId": "@kbn/tooling-log", + "scope": "server", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-server.ToolingLog", + "text": "ToolingLog" + } + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLog.withType.$1", + "type": "string", + "tags": [], + "label": "type", + "description": [ + "A string that will be passed along with messages from this logger which can be used to filter messages with `ignoreSources`" + ], + "signature": [ + "string" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogCollectingWriter", + "type": "Class", + "tags": [], + "label": "ToolingLogCollectingWriter", + "description": [], + "signature": [ + { + "pluginId": "@kbn/tooling-log", + "scope": "server", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-server.ToolingLogCollectingWriter", + "text": "ToolingLogCollectingWriter" + }, + " extends ", + { + "pluginId": "@kbn/tooling-log", + "scope": "server", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-server.ToolingLogTextWriter", + "text": "ToolingLogTextWriter" + } + ], + "path": "packages/kbn-tooling-log/src/tooling_log_collecting_writer.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogCollectingWriter.messages", + "type": "Array", + "tags": [], + "label": "messages", + "description": [], + "signature": [ + "string[]" + ], + "path": "packages/kbn-tooling-log/src/tooling_log_collecting_writer.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogCollectingWriter.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "packages/kbn-tooling-log/src/tooling_log_collecting_writer.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogCollectingWriter.Unnamed.$1", + "type": "CompoundType", + "tags": [], + "label": "level", + "description": [], + "signature": [ + "\"error\" | \"success\" | \"warning\" | \"info\" | \"debug\" | \"silent\" | \"verbose\"" + ], + "path": "packages/kbn-tooling-log/src/tooling_log_collecting_writer.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogCollectingWriter.write", + "type": "Function", + "tags": [], + "label": "write", + "description": [ + "\nCalled by ToolingLog, extends messages with the source if message includes one." + ], + "signature": [ + "(msg: ", + { + "pluginId": "@kbn/tooling-log", + "scope": "server", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-server.Message", + "text": "Message" + }, + ") => boolean" + ], + "path": "packages/kbn-tooling-log/src/tooling_log_collecting_writer.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogCollectingWriter.write.$1", + "type": "Object", + "tags": [], + "label": "msg", + "description": [], + "signature": [ + { + "pluginId": "@kbn/tooling-log", + "scope": "server", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-server.Message", + "text": "Message" + } + ], + "path": "packages/kbn-tooling-log/src/tooling_log_collecting_writer.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogTextWriter", + "type": "Class", + "tags": [], + "label": "ToolingLogTextWriter", + "description": [], + "signature": [ + { + "pluginId": "@kbn/tooling-log", + "scope": "server", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-server.ToolingLogTextWriter", + "text": "ToolingLogTextWriter" + }, + " implements ", + { + "pluginId": "@kbn/tooling-log", + "scope": "server", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-server.Writer", + "text": "Writer" + } + ], + "path": "packages/kbn-tooling-log/src/tooling_log_text_writer.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogTextWriter.level", + "type": "Object", + "tags": [], + "label": "level", + "description": [], + "signature": [ + "{ name: \"error\" | \"success\" | \"warning\" | \"info\" | \"debug\" | \"silent\" | \"verbose\"; flags: { error: boolean; success: boolean; warning: boolean; info: boolean; debug: boolean; silent: boolean; verbose: boolean; }; }" + ], + "path": "packages/kbn-tooling-log/src/tooling_log_text_writer.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogTextWriter.writeTo", + "type": "Object", + "tags": [], + "label": "writeTo", + "description": [], + "signature": [ + "{ write(msg: string): void; }" + ], + "path": "packages/kbn-tooling-log/src/tooling_log_text_writer.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogTextWriter.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "packages/kbn-tooling-log/src/tooling_log_text_writer.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogTextWriter.Unnamed.$1", + "type": "Object", + "tags": [], + "label": "config", + "description": [], + "signature": [ + { + "pluginId": "@kbn/tooling-log", + "scope": "server", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-server.ToolingLogTextWriterConfig", + "text": "ToolingLogTextWriterConfig" + } + ], + "path": "packages/kbn-tooling-log/src/tooling_log_text_writer.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogTextWriter.write", + "type": "Function", + "tags": [], + "label": "write", + "description": [], + "signature": [ + "(msg: ", + { + "pluginId": "@kbn/tooling-log", + "scope": "server", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-server.Message", + "text": "Message" + }, + ") => boolean" + ], + "path": "packages/kbn-tooling-log/src/tooling_log_text_writer.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogTextWriter.write.$1", + "type": "Object", + "tags": [], + "label": "msg", + "description": [], + "signature": [ + { + "pluginId": "@kbn/tooling-log", + "scope": "server", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-server.Message", + "text": "Message" + } + ], + "path": "packages/kbn-tooling-log/src/tooling_log_text_writer.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogTextWriter.write", + "type": "Function", + "tags": [], + "label": "write", + "description": [], + "signature": [ + "(writeTo: { write(msg: string): void; }, prefix: string, msg: ", + { + "pluginId": "@kbn/tooling-log", + "scope": "server", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-server.Message", + "text": "Message" + }, + ") => void" + ], + "path": "packages/kbn-tooling-log/src/tooling_log_text_writer.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogTextWriter.write.$1", + "type": "Object", + "tags": [], + "label": "writeTo", + "description": [], + "signature": [ + "{ write(msg: string): void; }" + ], + "path": "packages/kbn-tooling-log/src/tooling_log_text_writer.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogTextWriter.write.$2", + "type": "string", + "tags": [], + "label": "prefix", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-tooling-log/src/tooling_log_text_writer.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogTextWriter.write.$3", + "type": "Object", + "tags": [], + "label": "msg", + "description": [], + "signature": [ + { + "pluginId": "@kbn/tooling-log", + "scope": "server", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-server.Message", + "text": "Message" + } + ], + "path": "packages/kbn-tooling-log/src/tooling_log_text_writer.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + } + ], + "functions": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.getLogLevelFlagsHelp", + "type": "Function", + "tags": [], + "label": "getLogLevelFlagsHelp", + "description": [], + "signature": [ + "(defaultLogLevel: string) => string" + ], + "path": "packages/kbn-tooling-log/src/log_levels.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.getLogLevelFlagsHelp.$1", + "type": "string", + "tags": [], + "label": "defaultLogLevel", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-tooling-log/src/log_levels.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.parseLogLevel", + "type": "Function", + "tags": [], + "label": "parseLogLevel", + "description": [], + "signature": [ + "(name: \"error\" | \"success\" | \"warning\" | \"info\" | \"debug\" | \"silent\" | \"verbose\") => { name: \"error\" | \"success\" | \"warning\" | \"info\" | \"debug\" | \"silent\" | \"verbose\"; flags: { error: boolean; success: boolean; warning: boolean; info: boolean; debug: boolean; silent: boolean; verbose: boolean; }; }" + ], + "path": "packages/kbn-tooling-log/src/log_levels.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.parseLogLevel.$1", + "type": "CompoundType", + "tags": [], + "label": "name", + "description": [], + "signature": [ + "\"error\" | \"success\" | \"warning\" | \"info\" | \"debug\" | \"silent\" | \"verbose\"" + ], + "path": "packages/kbn-tooling-log/src/log_levels.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.pickLevelFromFlags", + "type": "Function", + "tags": [], + "label": "pickLevelFromFlags", + "description": [], + "signature": [ + "(flags: Record, options: { default?: \"error\" | \"success\" | \"warning\" | \"info\" | \"debug\" | \"silent\" | \"verbose\" | undefined; }) => \"error\" | \"success\" | \"warning\" | \"info\" | \"debug\" | \"silent\" | \"verbose\"" + ], + "path": "packages/kbn-tooling-log/src/log_levels.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.pickLevelFromFlags.$1", + "type": "Object", + "tags": [], + "label": "flags", + "description": [], + "signature": [ + "Record" + ], + "path": "packages/kbn-tooling-log/src/log_levels.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.pickLevelFromFlags.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "path": "packages/kbn-tooling-log/src/log_levels.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.pickLevelFromFlags.$2.default", + "type": "CompoundType", + "tags": [], + "label": "default", + "description": [], + "signature": [ + "\"error\" | \"success\" | \"warning\" | \"info\" | \"debug\" | \"silent\" | \"verbose\" | undefined" + ], + "path": "packages/kbn-tooling-log/src/log_levels.ts", + "deprecated": false + } + ] + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.Message", + "type": "Interface", + "tags": [], + "label": "Message", + "description": [ + "\nThe object shape passed to ToolingLog writers each time the log is used." + ], + "path": "packages/kbn-tooling-log/src/message.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.Message.type", + "type": "CompoundType", + "tags": [], + "label": "type", + "description": [ + "level/type of message" + ], + "signature": [ + "\"error\" | \"success\" | \"warning\" | \"write\" | \"info\" | \"debug\" | \"verbose\"" + ], + "path": "packages/kbn-tooling-log/src/message.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.Message.indent", + "type": "number", + "tags": [], + "label": "indent", + "description": [ + "indentation intended when message written to a text log" + ], + "path": "packages/kbn-tooling-log/src/message.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.Message.source", + "type": "string", + "tags": [], + "label": "source", + "description": [ + "type of logger this message came from" + ], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-tooling-log/src/message.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.Message.args", + "type": "Array", + "tags": [], + "label": "args", + "description": [ + "args passed to the logging method" + ], + "signature": [ + "any[]" + ], + "path": "packages/kbn-tooling-log/src/message.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogOptions", + "type": "Interface", + "tags": [], + "label": "ToolingLogOptions", + "description": [], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogOptions.type", + "type": "string", + "tags": [], + "label": "type", + "description": [ + "\ntype name for this logger, will be assigned to the \"source\"\nproperties of messages produced by this logger" + ], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogOptions.parent", + "type": "Object", + "tags": [], + "label": "parent", + "description": [ + "\nparent ToolingLog. When a ToolingLog has a parent they will both\nshare indent and writers state. Changing the indent width or\nwriters on either log will update the other too." + ], + "signature": [ + { + "pluginId": "@kbn/tooling-log", + "scope": "server", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-server.ToolingLog", + "text": "ToolingLog" + }, + " | undefined" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogTextWriterConfig", + "type": "Interface", + "tags": [], + "label": "ToolingLogTextWriterConfig", + "description": [], + "path": "packages/kbn-tooling-log/src/tooling_log_text_writer.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogTextWriterConfig.level", + "type": "CompoundType", + "tags": [], + "label": "level", + "description": [ + "\nLog level, messages below this level will be ignored" + ], + "signature": [ + "\"error\" | \"success\" | \"warning\" | \"info\" | \"debug\" | \"silent\" | \"verbose\"" + ], + "path": "packages/kbn-tooling-log/src/tooling_log_text_writer.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogTextWriterConfig.ignoreSources", + "type": "Array", + "tags": [], + "label": "ignoreSources", + "description": [ + "\nList of message sources/ToolingLog types which will be ignored. Create\na logger with `ToolingLog#withType()` to create messages with a specific\nsource. Ignored messages will be dropped without writing." + ], + "signature": [ + "string[] | undefined" + ], + "path": "packages/kbn-tooling-log/src/tooling_log_text_writer.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ToolingLogTextWriterConfig.writeTo", + "type": "Object", + "tags": [], + "label": "writeTo", + "description": [ + "\nTarget which will receive formatted message lines, a common value for `writeTo`\nis process.stdout" + ], + "signature": [ + "{ write(s: string): void; }" + ], + "path": "packages/kbn-tooling-log/src/tooling_log_text_writer.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.Writer", + "type": "Interface", + "tags": [], + "label": "Writer", + "description": [ + "\nAn object which received ToolingLog `Messages` and sends them to\nsome interface for collecting logs like stdio, or a file" + ], + "path": "packages/kbn-tooling-log/src/writer.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.Writer.write", + "type": "Function", + "tags": [], + "label": "write", + "description": [ + "\nCalled with every log message, should return true if the message\nwas written and false if it was ignored." + ], + "signature": [ + "(msg: ", + { + "pluginId": "@kbn/tooling-log", + "scope": "server", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-server.Message", + "text": "Message" + }, + ") => boolean" + ], + "path": "packages/kbn-tooling-log/src/writer.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.Writer.write.$1", + "type": "Object", + "tags": [], + "label": "msg", + "description": [ + "The log message to write" + ], + "signature": [ + { + "pluginId": "@kbn/tooling-log", + "scope": "server", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-server.Message", + "text": "Message" + } + ], + "path": "packages/kbn-tooling-log/src/writer.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + } + ], + "enums": [], + "misc": [ + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.DEFAULT_LOG_LEVEL", + "type": "string", + "tags": [], + "label": "DEFAULT_LOG_LEVEL", + "description": [], + "signature": [ + "\"info\"" + ], + "path": "packages/kbn-tooling-log/src/log_levels.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.LOG_LEVEL_FLAGS", + "type": "Array", + "tags": [], + "label": "LOG_LEVEL_FLAGS", + "description": [], + "signature": [ + "{ name: string; help: string; }[]" + ], + "path": "packages/kbn-tooling-log/src/log_levels.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.LogLevel", + "type": "Type", + "tags": [], + "label": "LogLevel", + "description": [], + "signature": [ + "\"error\" | \"success\" | \"warning\" | \"info\" | \"debug\" | \"silent\" | \"verbose\"" + ], + "path": "packages/kbn-tooling-log/src/log_levels.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/tooling-log", + "id": "def-server.ParsedLogLevel", + "type": "Type", + "tags": [], + "label": "ParsedLogLevel", + "description": [], + "signature": [ + "{ name: \"error\" | \"success\" | \"warning\" | \"info\" | \"debug\" | \"silent\" | \"verbose\"; flags: { error: boolean; success: boolean; warning: boolean; info: boolean; debug: boolean; silent: boolean; verbose: boolean; }; }" + ], + "path": "packages/kbn-tooling-log/src/log_levels.ts", + "deprecated": false, + "initialIsOpen": false + } + ], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx new file mode 100644 index 0000000000000..7dcb0b67415cb --- /dev/null +++ b/api_docs/kbn_tooling_log.mdx @@ -0,0 +1,36 @@ +--- +id: kibKbnToolingLogPluginApi +slug: /kibana-dev-docs/api/kbn-tooling-log +title: "@kbn/tooling-log" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the @kbn/tooling-log plugin +date: 2022-04-26 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 72 | 0 | 55 | 0 | + +## Server + +### Functions + + +### Classes + + +### Interfaces + + +### Consts, variables and types + + diff --git a/api_docs/kbn_type_summarizer.mdx b/api_docs/kbn_type_summarizer.mdx index 385d3c755dfe2..c715205758b5e 100644 --- a/api_docs/kbn_type_summarizer.mdx +++ b/api_docs/kbn_type_summarizer.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-type-summarizer title: "@kbn/type-summarizer" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/type-summarizer plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/type-summarizer'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index 02f14ac7a325b..66d08cdf52378 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/typed-react-router-config plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_ui_theme.devdocs.json b/api_docs/kbn_ui_theme.devdocs.json index c4272d206e8bd..bcfd5d506638a 100644 --- a/api_docs/kbn_ui_theme.devdocs.json +++ b/api_docs/kbn_ui_theme.devdocs.json @@ -52,7 +52,7 @@ "label": "Theme", "description": [], "signature": [ - "{ paddingSizes: { xs: string; s: string; m: string; l: string; xl: string; }; avatarSizing: { s: { size: string; 'font-size': string; }; m: { size: string; 'font-size': string; }; l: { size: string; 'font-size': string; }; xl: { size: string; 'font-size': string; }; }; euiBadgeGroupGutterTypes: { gutterExtraSmall: string; gutterSmall: string; }; euiBreadcrumbSpacing: string; euiBreadcrumbTruncateWidth: string; euiButtonEmptyTypes: { primary: string; danger: string; disabled: string; ghost: string; text: string; success: string; warning: string; }; euiCallOutTypes: { primary: string; success: string; warning: string; danger: string; }; euiCardSpacing: string; euiCardBottomNodeHeight: string; euiCardSelectButtonBorders: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardSelectButtonBackgrounds: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCheckableCardPadding: string; euiCodeBlockPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCollapsibleNavGroupLightBackgroundColor: string; euiCollapsibleNavGroupDarkBackgroundColor: string; euiCollapsibleNavGroupDarkHighContrastColor: string; euiColorPickerValueRange0: string; euiColorPickerValueRange1: string; euiColorPickerSaturationRange0: string; euiColorPickerSaturationRange1: string; euiColorPickerIndicatorSize: string; euiColorPickerWidth: string; euiColorPaletteDisplaySizes: { sizeExtraSmall: string; sizeSmall: string; sizeMedium: string; }; euiContextMenuWidth: string; euiControlBarBackground: string; euiControlBarText: string; euiControlBarBorderColor: string; euiControlBarInitialHeight: string; euiControlBarMaxHeight: string; euiControlBarHeights: { s: string; m: string; l: string; }; euiDataGridPrefix: string; euiDataGridStyles: string; euiZDataGrid: number; euiZHeaderBelowDataGrid: number; euiZDataGridCellPopover: number; euiDataGridColumnResizerWidth: string; euiDataGridPopoverMaxHeight: string; euiDataGridCellPaddingS: string; euiDataGridCellPaddingM: string; euiDataGridCellPaddingL: string; euiDataGridVerticalBorder: string; euiSuperDatePickerWidth: string; euiSuperDatePickerButtonWidth: string; euiDragAndDropSpacing: { s: string; m: string; l: string; }; euiExpressionColors: { subdued: string; primary: string; success: string; warning: string; danger: string; accent: string; }; euiFacetGutterSizes: { gutterNone: number; gutterSmall: string; gutterMedium: string; gutterLarge: string; }; gutterTypes: { gutterExtraSmall: string; gutterSmall: string; gutterMedium: string; gutterLarge: string; gutterExtraLarge: string; }; fractions: { fourths: { percentage: string; count: number; }; thirds: { percentage: string; count: number; }; halves: { percentage: string; count: number; }; single: { percentage: string; count: number; }; }; flyoutSizes: { small: { min: string; width: string; max: string; }; medium: { min: string; width: string; max: string; }; large: { min: string; width: string; max: string; }; }; euiFlyoutBorder: string; euiFlyoutPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiFilePickerTallHeight: string; euiRangeLevelColors: { primary: string; success: string; warning: string; danger: string; }; textareaResizing: { vertical: string; horizontal: string; both: string; none: string; }; euiHeaderLinksGutterSizes: { gutterXS: string; gutterS: string; gutterM: string; gutterL: string; }; ruleMargins: { marginXSmall: string; marginSmall: string; marginMedium: string; marginLarge: string; marginXLarge: string; marginXXLarge: string; }; euiIconLoadingOpacity: number; euiIconColors: { accent: string; danger: string; ghost: string; primary: string; success: string; subdued: string; text: string; warning: string; inherit: string; }; euiIconSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiKeyPadMenuSize: string; euiKeyPadMenuMarginSize: string; euiLinkColors: { subdued: string; primary: string; success: string; accent: string; warning: string; danger: string; text: string; ghost: string; }; euiListGroupItemHoverBackground: string; euiListGroupItemHoverBackgroundGhost: string; euiListGroupGutterTypes: { gutterSmall: string; gutterMedium: string; }; euiListGroupItemColorTypes: { primary: string; text: string; subdued: string; ghost: string; }; euiListGroupItemSizeTypes: { xSmall: string; small: string; medium: string; large: string; }; euiGradientStartStop: string; euiGradientMiddle: string; euiLoadingSpinnerSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiMarkdownEditorMinHeight: string; euiPopoverArrowSize: string; euiPopoverTranslateDistance: string; euiProgressSizes: { xs: string; s: string; m: string; l: string; }; euiProgressColors: { primary: string; success: string; warning: string; danger: string; accent: string; subdued: string; vis0: string; vis1: string; vis2: string; vis3: string; vis4: string; vis5: string; vis6: string; vis7: string; vis8: string; vis9: string; customColor: string; }; euiResizableButtonTransitionSpeed: string; euiResizableButtonSize: string; euiSelectableListItemBorder: string; euiSelectableListItemPadding: string; euiSelectableTemplateSitewideTypes: { application: { color: string; 'font-weight': number; }; deployment: { color: string; 'font-weight': number; }; article: { color: string; 'font-weight': number; }; case: { color: string; 'font-weight': number; }; platform: { color: string; 'font-weight': number; }; }; euiSideNavEmphasizedBackgroundColor: string; euiSideNavRootTextcolor: string; euiSideNavBranchTextcolor: string; euiSideNavSelectedTextcolor: string; euiSideNavDisabledTextcolor: string; spacerSizes: { xs: string; s: string; m: string; l: string; xl: string; xxl: string; }; euiStepNumberSize: string; euiStepNumberSmallSize: string; euiStepNumberMargin: string; euiStepStatusColorsToFade: { warning: string; danger: string; disabled: string; incomplete: string; }; euiSuggestItemColors: { tint0: string; tint1: string; tint2: string; tint3: string; tint4: string; tint5: string; tint6: string; tint7: string; tint8: string; tint9: string; tint10: string; }; euiTableCellContentPadding: string; euiTableCellContentPaddingCompressed: string; euiTableCellCheckboxWidth: string; euiTableActionsAreaWidth: string; euiTableHoverColor: string; euiTableSelectedColor: string; euiTableHoverSelectedColor: string; euiTableActionsBorderColor: string; euiTableHoverClickableColor: string; euiTableFocusClickableColor: string; euiTextColors: { default: string; subdued: string; success: string; accent: string; warning: string; danger: string; ghost: string; inherit: string; }; euiTextConstrainedMaxWidth: string; euiToastWidth: string; euiToastTypes: { primary: string; success: string; warning: string; danger: string; }; euiTokenGrayColor: string; euiTokenTypes: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; gray: { graphic: string; behindText: string; }; }; euiTokenTypeKeys: string; euiContrastRatioText: number; euiContrastRatioGraphic: number; euiContrastRatioDisabled: number; euiAnimSlightBounce: string; euiAnimSlightResistance: string; euiAnimSpeedExtraFast: string; euiAnimSpeedFast: string; euiAnimSpeedNormal: string; euiAnimSpeedSlow: string; euiAnimSpeedExtraSlow: string; euiBorderWidthThin: string; euiBorderWidthThick: string; euiBorderColor: string; euiBorderRadius: string; euiBorderRadiusSmall: string; euiBorderThick: string; euiBorderThin: string; euiBorderEditable: string; euiButtonHeight: string; euiButtonHeightSmall: string; euiButtonHeightXSmall: string; euiButtonColorDisabled: string; euiButtonColorDisabledText: string; euiButtonColorGhostDisabled: string; euiButtonTypes: { primary: string; accent: string; success: string; warning: string; danger: string; subdued: string; ghost: string; text: string; }; euiCodeBlockBackgroundColor: string; euiCodeBlockColor: string; euiCodeBlockSelectedBackgroundColor: string; euiCodeBlockCommentColor: string; euiCodeBlockSelectorTagColor: string; euiCodeBlockStringColor: string; euiCodeBlockTagColor: string; euiCodeBlockNameColor: string; euiCodeBlockNumberColor: string; euiCodeBlockKeywordColor: string; euiCodeBlockFunctionTitleColor: string; euiCodeBlockTypeColor: string; euiCodeBlockAttributeColor: string; euiCodeBlockSymbolColor: string; euiCodeBlockParamsColor: string; euiCodeBlockMetaColor: string; euiCodeBlockTitleColor: string; euiCodeBlockSectionColor: string; euiCodeBlockAdditionColor: string; euiCodeBlockDeletionColor: string; euiCodeBlockSelectorClassColor: string; euiCodeBlockSelectorIdColor: string; euiPaletteColorBlind: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; }; euiPaletteColorBlindKeys: string; euiColorVis0: string; euiColorVis1: string; euiColorVis2: string; euiColorVis3: string; euiColorVis4: string; euiColorVis5: string; euiColorVis6: string; euiColorVis7: string; euiColorVis8: string; euiColorVis9: string; euiColorVis0_behindText: string; euiColorVis1_behindText: string; euiColorVis2_behindText: string; euiColorVis3_behindText: string; euiColorVis4_behindText: string; euiColorVis5_behindText: string; euiColorVis6_behindText: string; euiColorVis7_behindText: string; euiColorVis8_behindText: string; euiColorVis9_behindText: string; euiFontWeightLight: number; euiFontWeightRegular: number; euiFontWeightMedium: number; euiFontWeightSemiBold: number; euiFontWeightBold: number; euiCodeFontWeightRegular: number; euiCodeFontWeightBold: number; euiFormMaxWidth: string; euiFormControlHeight: string; euiFormControlCompressedHeight: string; euiFormControlPadding: string; euiFormControlCompressedPadding: string; euiFormControlBorderRadius: string; euiFormControlCompressedBorderRadius: string; euiRadioSize: string; euiCheckBoxSize: string; euiCheckboxBorderRadius: string; euiSwitchHeight: string; euiSwitchWidth: string; euiSwitchThumbSize: string; euiSwitchIconHeight: string; euiSwitchHeightCompressed: string; euiSwitchWidthCompressed: string; euiSwitchThumbSizeCompressed: string; euiSwitchHeightMini: string; euiSwitchWidthMini: string; euiSwitchThumbSizeMini: string; euiFormBackgroundColor: string; euiFormBackgroundDisabledColor: string; euiFormBackgroundReadOnlyColor: string; euiFormBorderOpaqueColor: string; euiFormBorderColor: string; euiFormBorderDisabledColor: string; euiFormCustomControlDisabledIconColor: string; euiFormCustomControlBorderColor: string; euiFormControlDisabledColor: string; euiFormControlBoxShadow: string; euiFormControlPlaceholderText: string; euiFormInputGroupLabelBackground: string; euiFormInputGroupBorder: string; euiSwitchOffColor: string; euiFormControlLayoutGroupInputHeight: string; euiFormControlLayoutGroupInputCompressedHeight: string; euiFormControlLayoutGroupInputCompressedBorderRadius: string; euiRangeTrackColor: string; euiRangeThumbRadius: string; euiRangeThumbHeight: string; euiRangeThumbWidth: string; euiRangeThumbBorderColor: string; euiRangeTrackWidth: string; euiRangeTrackHeight: string; euiRangeTrackBorderWidth: number; euiRangeTrackBorderColor: string; euiRangeTrackRadius: string; euiRangeDisabledOpacity: number; euiRangeHighlightHeight: string; euiHeaderBackgroundColor: string; euiHeaderDarkBackgroundColor: string; euiHeaderBorderColor: string; euiHeaderBreadcrumbColor: string; euiHeaderHeight: string; euiHeaderChildSize: string; euiHeaderHeightCompensation: string; euiPageDefaultMaxWidth: string; euiPageSidebarMinWidth: string; euiPanelPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiPanelBorderRadiusModifiers: { borderRadiusNone: number; borderRadiusMedium: string; }; euiPanelBackgroundColorModifiers: { transparent: string; plain: string; subdued: string; accent: string; primary: string; success: string; warning: string; danger: string; }; euiBreakpoints: { xs: number; s: string; m: string; l: string; xl: string; }; euiBreakpointKeys: string; euiShadowColor: string; euiShadowColorLarge: string; euiSize: string; euiSizeXS: string; euiSizeS: string; euiSizeM: string; euiSizeL: string; euiSizeXL: string; euiSizeXXL: string; euiButtonMinWidth: string; euiScrollBar: string; euiScrollBarCorner: string; euiScrollBarCornerThin: string; euiFocusRingColor: string; euiFocusRingAnimStartColor: string; euiFocusRingAnimStartSize: string; euiFocusRingAnimStartSizeLarge: string; euiFocusRingSizeLarge: string; euiFocusRingSize: string; euiFocusTransparency: number; euiFocusTransparencyPercent: string; euiFocusBackgroundColor: string; euiTooltipBackgroundColor: string; euiTooltipBorderColor: string; euiTooltipAnimations: { top: string; left: string; bottom: string; right: string; }; euiFontFamily: string; euiCodeFontFamily: string; euiFontFeatureSettings: string; euiTextScale: string; euiFontSize: string; euiFontSizeXS: string; euiFontSizeS: string; euiFontSizeM: string; euiFontSizeL: string; euiFontSizeXL: string; euiFontSizeXXL: string; euiLineHeight: number; euiBodyLineHeight: number; euiTitles: { xxxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; s: { 'font-size': string; 'line-height': string; 'font-weight': number; }; m: { 'font-size': string; 'line-height': string; 'font-weight': number; }; l: { 'font-size': string; 'line-height': string; 'font-weight': number; }; }; euiZLevel0: number; euiZLevel1: number; euiZLevel2: number; euiZLevel3: number; euiZLevel4: number; euiZLevel5: number; euiZLevel6: number; euiZLevel7: number; euiZLevel8: number; euiZLevel9: number; euiZToastList: number; euiZModal: number; euiZMask: number; euiZNavigation: number; euiZContentMenu: number; euiZHeader: number; euiZFlyout: number; euiZMaskBelowHeader: number; euiZContent: number; euiColorGhost: string; euiColorInk: string; euiColorPrimary: string; euiColorAccent: string; euiColorSuccess: string; euiColorWarning: string; euiColorDanger: string; euiColorEmptyShade: string; euiColorLightestShade: string; euiColorLightShade: string; euiColorMediumShade: string; euiColorDarkShade: string; euiColorDarkestShade: string; euiColorFullShade: string; euiPageBackgroundColor: string; euiColorHighlight: string; euiTextColor: string; euiTitleColor: string; euiTextSubduedColor: string; euiColorDisabled: string; euiColorPrimaryText: string; euiColorSuccessText: string; euiColorAccentText: string; euiColorWarningText: string; euiColorDangerText: string; euiColorDisabledText: string; euiLinkColor: string; euiColorChartLines: string; euiColorChartBand: string; euiDatePickerCalendarWidth: string; euiDatePickerPadding: string; euiDatePickerGap: string; euiDatePickerCalendarColumns: number; euiDatePickerButtonSize: string; euiDatePickerMinControlWidth: string; euiDatePickerMaxControlWidth: string; euiButtonDefaultTransparency: number; euiButtonFontWeight: number; euiRangeHighlightColor: string; euiRangeThumbBackgroundColor: string; euiRangeTrackCompressedHeight: string; euiRangeHighlightCompressedHeight: string; euiRangeHeight: string; euiRangeCompressedHeight: string; euiStepStatusColors: { default: string; complete: string; warning: string; danger: string; }; }" + "{ paddingSizes: { xs: string; s: string; m: string; l: string; xl: string; }; euiBadgeGroupGutterTypes: { gutterExtraSmall: string; gutterSmall: string; }; euiBreadcrumbSpacing: string; euiBreadcrumbTruncateWidth: string; euiButtonEmptyTypes: { primary: string; danger: string; disabled: string; ghost: string; text: string; success: string; warning: string; }; euiCallOutTypes: { primary: string; success: string; warning: string; danger: string; }; euiCardSpacing: string; euiCardBottomNodeHeight: string; euiCardSelectButtonBorders: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardSelectButtonBackgrounds: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCheckableCardPadding: string; euiCodeBlockPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCollapsibleNavGroupLightBackgroundColor: string; euiCollapsibleNavGroupDarkBackgroundColor: string; euiCollapsibleNavGroupDarkHighContrastColor: string; euiColorPickerValueRange0: string; euiColorPickerValueRange1: string; euiColorPickerSaturationRange0: string; euiColorPickerSaturationRange1: string; euiColorPickerIndicatorSize: string; euiColorPickerWidth: string; euiColorPaletteDisplaySizes: { sizeExtraSmall: string; sizeSmall: string; sizeMedium: string; }; euiContextMenuWidth: string; euiControlBarBackground: string; euiControlBarText: string; euiControlBarBorderColor: string; euiControlBarInitialHeight: string; euiControlBarMaxHeight: string; euiControlBarHeights: { s: string; m: string; l: string; }; euiDataGridPrefix: string; euiDataGridStyles: string; euiZDataGrid: number; euiZHeaderBelowDataGrid: number; euiZDataGridCellPopover: number; euiDataGridColumnResizerWidth: string; euiDataGridPopoverMaxHeight: string; euiDataGridCellPaddingS: string; euiDataGridCellPaddingM: string; euiDataGridCellPaddingL: string; euiDataGridVerticalBorder: string; euiSuperDatePickerWidth: string; euiSuperDatePickerButtonWidth: string; euiDragAndDropSpacing: { s: string; m: string; l: string; }; euiExpressionColors: { subdued: string; primary: string; success: string; warning: string; danger: string; accent: string; }; euiFacetGutterSizes: { gutterNone: number; gutterSmall: string; gutterMedium: string; gutterLarge: string; }; gutterTypes: { gutterExtraSmall: string; gutterSmall: string; gutterMedium: string; gutterLarge: string; gutterExtraLarge: string; }; fractions: { fourths: { percentage: string; count: number; }; thirds: { percentage: string; count: number; }; halves: { percentage: string; count: number; }; single: { percentage: string; count: number; }; }; flyoutSizes: { small: { min: string; width: string; max: string; }; medium: { min: string; width: string; max: string; }; large: { min: string; width: string; max: string; }; }; euiFlyoutBorder: string; euiFlyoutPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiFilePickerTallHeight: string; euiRangeLevelColors: { primary: string; success: string; warning: string; danger: string; }; textareaResizing: { vertical: string; horizontal: string; both: string; none: string; }; euiHeaderLinksGutterSizes: { gutterXS: string; gutterS: string; gutterM: string; gutterL: string; }; ruleMargins: { marginXSmall: string; marginSmall: string; marginMedium: string; marginLarge: string; marginXLarge: string; marginXXLarge: string; }; euiIconLoadingOpacity: number; euiIconColors: { accent: string; danger: string; ghost: string; primary: string; success: string; subdued: string; text: string; warning: string; inherit: string; }; euiIconSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiKeyPadMenuSize: string; euiKeyPadMenuMarginSize: string; euiLinkColors: { subdued: string; primary: string; success: string; accent: string; warning: string; danger: string; text: string; ghost: string; }; euiListGroupItemHoverBackground: string; euiListGroupItemHoverBackgroundGhost: string; euiListGroupGutterTypes: { gutterSmall: string; gutterMedium: string; }; euiListGroupItemColorTypes: { primary: string; text: string; subdued: string; ghost: string; }; euiListGroupItemSizeTypes: { xSmall: string; small: string; medium: string; large: string; }; euiGradientStartStop: string; euiGradientMiddle: string; euiLoadingSpinnerSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiMarkdownEditorMinHeight: string; euiPopoverArrowSize: string; euiPopoverTranslateDistance: string; euiProgressSizes: { xs: string; s: string; m: string; l: string; }; euiProgressColors: { primary: string; success: string; warning: string; danger: string; accent: string; subdued: string; vis0: string; vis1: string; vis2: string; vis3: string; vis4: string; vis5: string; vis6: string; vis7: string; vis8: string; vis9: string; customColor: string; }; euiResizableButtonTransitionSpeed: string; euiResizableButtonSize: string; euiSelectableListItemBorder: string; euiSelectableListItemPadding: string; euiSelectableTemplateSitewideTypes: { application: { color: string; 'font-weight': number; }; deployment: { color: string; 'font-weight': number; }; article: { color: string; 'font-weight': number; }; case: { color: string; 'font-weight': number; }; platform: { color: string; 'font-weight': number; }; }; euiSideNavEmphasizedBackgroundColor: string; euiSideNavRootTextcolor: string; euiSideNavBranchTextcolor: string; euiSideNavSelectedTextcolor: string; euiSideNavDisabledTextcolor: string; spacerSizes: { xs: string; s: string; m: string; l: string; xl: string; xxl: string; }; euiStepNumberSize: string; euiStepNumberSmallSize: string; euiStepNumberMargin: string; euiStepStatusColorsToFade: { warning: string; danger: string; disabled: string; incomplete: string; }; euiSuggestItemColors: { tint0: string; tint1: string; tint2: string; tint3: string; tint4: string; tint5: string; tint6: string; tint7: string; tint8: string; tint9: string; tint10: string; }; euiTableCellContentPadding: string; euiTableCellContentPaddingCompressed: string; euiTableCellCheckboxWidth: string; euiTableActionsAreaWidth: string; euiTableHoverColor: string; euiTableSelectedColor: string; euiTableHoverSelectedColor: string; euiTableActionsBorderColor: string; euiTableHoverClickableColor: string; euiTableFocusClickableColor: string; euiTextColors: { default: string; subdued: string; success: string; accent: string; warning: string; danger: string; ghost: string; inherit: string; }; euiTextConstrainedMaxWidth: string; euiToastWidth: string; euiToastTypes: { primary: string; success: string; warning: string; danger: string; }; euiTokenGrayColor: string; euiTokenTypes: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; gray: { graphic: string; behindText: string; }; }; euiTokenTypeKeys: string; euiContrastRatioText: number; euiContrastRatioGraphic: number; euiContrastRatioDisabled: number; euiAnimSlightBounce: string; euiAnimSlightResistance: string; euiAnimSpeedExtraFast: string; euiAnimSpeedFast: string; euiAnimSpeedNormal: string; euiAnimSpeedSlow: string; euiAnimSpeedExtraSlow: string; euiBorderWidthThin: string; euiBorderWidthThick: string; euiBorderColor: string; euiBorderRadius: string; euiBorderRadiusSmall: string; euiBorderThick: string; euiBorderThin: string; euiBorderEditable: string; euiButtonHeight: string; euiButtonHeightSmall: string; euiButtonHeightXSmall: string; euiButtonColorDisabled: string; euiButtonColorDisabledText: string; euiButtonColorGhostDisabled: string; euiButtonTypes: { primary: string; accent: string; success: string; warning: string; danger: string; subdued: string; ghost: string; text: string; }; euiCodeBlockBackgroundColor: string; euiCodeBlockColor: string; euiCodeBlockSelectedBackgroundColor: string; euiCodeBlockCommentColor: string; euiCodeBlockSelectorTagColor: string; euiCodeBlockStringColor: string; euiCodeBlockTagColor: string; euiCodeBlockNameColor: string; euiCodeBlockNumberColor: string; euiCodeBlockKeywordColor: string; euiCodeBlockFunctionTitleColor: string; euiCodeBlockTypeColor: string; euiCodeBlockAttributeColor: string; euiCodeBlockSymbolColor: string; euiCodeBlockParamsColor: string; euiCodeBlockMetaColor: string; euiCodeBlockTitleColor: string; euiCodeBlockSectionColor: string; euiCodeBlockAdditionColor: string; euiCodeBlockDeletionColor: string; euiCodeBlockSelectorClassColor: string; euiCodeBlockSelectorIdColor: string; euiPaletteColorBlind: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; }; euiPaletteColorBlindKeys: string; euiColorVis0: string; euiColorVis1: string; euiColorVis2: string; euiColorVis3: string; euiColorVis4: string; euiColorVis5: string; euiColorVis6: string; euiColorVis7: string; euiColorVis8: string; euiColorVis9: string; euiColorVis0_behindText: string; euiColorVis1_behindText: string; euiColorVis2_behindText: string; euiColorVis3_behindText: string; euiColorVis4_behindText: string; euiColorVis5_behindText: string; euiColorVis6_behindText: string; euiColorVis7_behindText: string; euiColorVis8_behindText: string; euiColorVis9_behindText: string; euiFontWeightLight: number; euiFontWeightRegular: number; euiFontWeightMedium: number; euiFontWeightSemiBold: number; euiFontWeightBold: number; euiCodeFontWeightRegular: number; euiCodeFontWeightBold: number; euiFormMaxWidth: string; euiFormControlHeight: string; euiFormControlCompressedHeight: string; euiFormControlPadding: string; euiFormControlCompressedPadding: string; euiFormControlBorderRadius: string; euiFormControlCompressedBorderRadius: string; euiRadioSize: string; euiCheckBoxSize: string; euiCheckboxBorderRadius: string; euiSwitchHeight: string; euiSwitchWidth: string; euiSwitchThumbSize: string; euiSwitchIconHeight: string; euiSwitchHeightCompressed: string; euiSwitchWidthCompressed: string; euiSwitchThumbSizeCompressed: string; euiSwitchHeightMini: string; euiSwitchWidthMini: string; euiSwitchThumbSizeMini: string; euiFormBackgroundColor: string; euiFormBackgroundDisabledColor: string; euiFormBackgroundReadOnlyColor: string; euiFormBorderOpaqueColor: string; euiFormBorderColor: string; euiFormBorderDisabledColor: string; euiFormCustomControlDisabledIconColor: string; euiFormCustomControlBorderColor: string; euiFormControlDisabledColor: string; euiFormControlBoxShadow: string; euiFormControlPlaceholderText: string; euiFormInputGroupLabelBackground: string; euiFormInputGroupBorder: string; euiSwitchOffColor: string; euiFormControlLayoutGroupInputHeight: string; euiFormControlLayoutGroupInputCompressedHeight: string; euiFormControlLayoutGroupInputCompressedBorderRadius: string; euiRangeTrackColor: string; euiRangeThumbRadius: string; euiRangeThumbHeight: string; euiRangeThumbWidth: string; euiRangeThumbBorderColor: string; euiRangeTrackWidth: string; euiRangeTrackHeight: string; euiRangeTrackBorderWidth: number; euiRangeTrackBorderColor: string; euiRangeTrackRadius: string; euiRangeDisabledOpacity: number; euiRangeHighlightHeight: string; euiHeaderBackgroundColor: string; euiHeaderDarkBackgroundColor: string; euiHeaderBorderColor: string; euiHeaderBreadcrumbColor: string; euiHeaderHeight: string; euiHeaderChildSize: string; euiHeaderHeightCompensation: string; euiPageDefaultMaxWidth: string; euiPageSidebarMinWidth: string; euiPanelPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiPanelBorderRadiusModifiers: { borderRadiusNone: number; borderRadiusMedium: string; }; euiPanelBackgroundColorModifiers: { transparent: string; plain: string; subdued: string; accent: string; primary: string; success: string; warning: string; danger: string; }; euiBreakpoints: { xs: number; s: string; m: string; l: string; xl: string; }; euiBreakpointKeys: string; euiShadowColor: string; euiShadowColorLarge: string; euiSize: string; euiSizeXS: string; euiSizeS: string; euiSizeM: string; euiSizeL: string; euiSizeXL: string; euiSizeXXL: string; euiButtonMinWidth: string; euiScrollBar: string; euiScrollBarCorner: string; euiScrollBarCornerThin: string; euiFocusRingColor: string; euiFocusRingAnimStartColor: string; euiFocusRingAnimStartSize: string; euiFocusRingAnimStartSizeLarge: string; euiFocusRingSizeLarge: string; euiFocusRingSize: string; euiFocusTransparency: number; euiFocusTransparencyPercent: string; euiFocusBackgroundColor: string; euiTooltipBackgroundColor: string; euiTooltipBorderColor: string; euiTooltipAnimations: { top: string; left: string; bottom: string; right: string; }; euiFontFamily: string; euiCodeFontFamily: string; euiFontFeatureSettings: string; euiTextScale: string; euiFontSize: string; euiFontSizeXS: string; euiFontSizeS: string; euiFontSizeM: string; euiFontSizeL: string; euiFontSizeXL: string; euiFontSizeXXL: string; euiLineHeight: number; euiBodyLineHeight: number; euiTitles: { xxxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; s: { 'font-size': string; 'line-height': string; 'font-weight': number; }; m: { 'font-size': string; 'line-height': string; 'font-weight': number; }; l: { 'font-size': string; 'line-height': string; 'font-weight': number; }; }; euiZLevel0: number; euiZLevel1: number; euiZLevel2: number; euiZLevel3: number; euiZLevel4: number; euiZLevel5: number; euiZLevel6: number; euiZLevel7: number; euiZLevel8: number; euiZLevel9: number; euiZToastList: number; euiZModal: number; euiZMask: number; euiZNavigation: number; euiZContentMenu: number; euiZHeader: number; euiZFlyout: number; euiZMaskBelowHeader: number; euiZContent: number; euiColorGhost: string; euiColorInk: string; euiColorPrimary: string; euiColorAccent: string; euiColorSuccess: string; euiColorWarning: string; euiColorDanger: string; euiColorEmptyShade: string; euiColorLightestShade: string; euiColorLightShade: string; euiColorMediumShade: string; euiColorDarkShade: string; euiColorDarkestShade: string; euiColorFullShade: string; euiPageBackgroundColor: string; euiColorHighlight: string; euiTextColor: string; euiTitleColor: string; euiTextSubduedColor: string; euiColorDisabled: string; euiColorPrimaryText: string; euiColorSuccessText: string; euiColorAccentText: string; euiColorWarningText: string; euiColorDangerText: string; euiColorDisabledText: string; euiLinkColor: string; euiColorChartLines: string; euiColorChartBand: string; euiDatePickerCalendarWidth: string; euiDatePickerPadding: string; euiDatePickerGap: string; euiDatePickerCalendarColumns: number; euiDatePickerButtonSize: string; euiDatePickerMinControlWidth: string; euiDatePickerMaxControlWidth: string; euiButtonDefaultTransparency: number; euiButtonFontWeight: number; euiRangeHighlightColor: string; euiRangeThumbBackgroundColor: string; euiRangeTrackCompressedHeight: string; euiRangeHighlightCompressedHeight: string; euiRangeHeight: string; euiRangeCompressedHeight: string; euiStepStatusColors: { default: string; complete: string; warning: string; danger: string; }; }" ], "path": "packages/kbn-ui-theme/src/theme.ts", "deprecated": false, @@ -82,7 +82,7 @@ "label": "euiDarkVars", "description": [], "signature": [ - "{ paddingSizes: { xs: string; s: string; m: string; l: string; xl: string; }; avatarSizing: { s: { size: string; 'font-size': string; }; m: { size: string; 'font-size': string; }; l: { size: string; 'font-size': string; }; xl: { size: string; 'font-size': string; }; }; euiBadgeGroupGutterTypes: { gutterExtraSmall: string; gutterSmall: string; }; euiBreadcrumbSpacing: string; euiBreadcrumbTruncateWidth: string; euiButtonEmptyTypes: { primary: string; danger: string; disabled: string; ghost: string; text: string; success: string; warning: string; }; euiCallOutTypes: { primary: string; success: string; warning: string; danger: string; }; euiCardSpacing: string; euiCardBottomNodeHeight: string; euiCardSelectButtonBorders: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardSelectButtonBackgrounds: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCheckableCardPadding: string; euiCodeBlockPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCollapsibleNavGroupLightBackgroundColor: string; euiCollapsibleNavGroupDarkBackgroundColor: string; euiCollapsibleNavGroupDarkHighContrastColor: string; euiColorPickerValueRange0: string; euiColorPickerValueRange1: string; euiColorPickerSaturationRange0: string; euiColorPickerSaturationRange1: string; euiColorPickerIndicatorSize: string; euiColorPickerWidth: string; euiColorPaletteDisplaySizes: { sizeExtraSmall: string; sizeSmall: string; sizeMedium: string; }; euiContextMenuWidth: string; euiControlBarBackground: string; euiControlBarText: string; euiControlBarBorderColor: string; euiControlBarInitialHeight: string; euiControlBarMaxHeight: string; euiControlBarHeights: { s: string; m: string; l: string; }; euiDataGridPrefix: string; euiDataGridStyles: string; euiZDataGrid: number; euiZHeaderBelowDataGrid: number; euiZDataGridCellPopover: number; euiDataGridColumnResizerWidth: string; euiDataGridPopoverMaxHeight: string; euiDataGridCellPaddingS: string; euiDataGridCellPaddingM: string; euiDataGridCellPaddingL: string; euiDataGridVerticalBorder: string; euiSuperDatePickerWidth: string; euiSuperDatePickerButtonWidth: string; euiDragAndDropSpacing: { s: string; m: string; l: string; }; euiExpressionColors: { subdued: string; primary: string; success: string; warning: string; danger: string; accent: string; }; euiFacetGutterSizes: { gutterNone: number; gutterSmall: string; gutterMedium: string; gutterLarge: string; }; gutterTypes: { gutterExtraSmall: string; gutterSmall: string; gutterMedium: string; gutterLarge: string; gutterExtraLarge: string; }; fractions: { fourths: { percentage: string; count: number; }; thirds: { percentage: string; count: number; }; halves: { percentage: string; count: number; }; single: { percentage: string; count: number; }; }; flyoutSizes: { small: { min: string; width: string; max: string; }; medium: { min: string; width: string; max: string; }; large: { min: string; width: string; max: string; }; }; euiFlyoutBorder: string; euiFlyoutPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiFilePickerTallHeight: string; euiRangeLevelColors: { primary: string; success: string; warning: string; danger: string; }; textareaResizing: { vertical: string; horizontal: string; both: string; none: string; }; euiHeaderLinksGutterSizes: { gutterXS: string; gutterS: string; gutterM: string; gutterL: string; }; ruleMargins: { marginXSmall: string; marginSmall: string; marginMedium: string; marginLarge: string; marginXLarge: string; marginXXLarge: string; }; euiIconLoadingOpacity: number; euiIconColors: { accent: string; danger: string; ghost: string; primary: string; success: string; subdued: string; text: string; warning: string; inherit: string; }; euiIconSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiKeyPadMenuSize: string; euiKeyPadMenuMarginSize: string; euiLinkColors: { subdued: string; primary: string; success: string; accent: string; warning: string; danger: string; text: string; ghost: string; }; euiListGroupItemHoverBackground: string; euiListGroupItemHoverBackgroundGhost: string; euiListGroupGutterTypes: { gutterSmall: string; gutterMedium: string; }; euiListGroupItemColorTypes: { primary: string; text: string; subdued: string; ghost: string; }; euiListGroupItemSizeTypes: { xSmall: string; small: string; medium: string; large: string; }; euiGradientStartStop: string; euiGradientMiddle: string; euiLoadingSpinnerSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiMarkdownEditorMinHeight: string; euiPopoverArrowSize: string; euiPopoverTranslateDistance: string; euiProgressSizes: { xs: string; s: string; m: string; l: string; }; euiProgressColors: { primary: string; success: string; warning: string; danger: string; accent: string; subdued: string; vis0: string; vis1: string; vis2: string; vis3: string; vis4: string; vis5: string; vis6: string; vis7: string; vis8: string; vis9: string; customColor: string; }; euiResizableButtonTransitionSpeed: string; euiResizableButtonSize: string; euiSelectableListItemBorder: string; euiSelectableListItemPadding: string; euiSelectableTemplateSitewideTypes: { application: { color: string; 'font-weight': number; }; deployment: { color: string; 'font-weight': number; }; article: { color: string; 'font-weight': number; }; case: { color: string; 'font-weight': number; }; platform: { color: string; 'font-weight': number; }; }; euiSideNavEmphasizedBackgroundColor: string; euiSideNavRootTextcolor: string; euiSideNavBranchTextcolor: string; euiSideNavSelectedTextcolor: string; euiSideNavDisabledTextcolor: string; spacerSizes: { xs: string; s: string; m: string; l: string; xl: string; xxl: string; }; euiStepNumberSize: string; euiStepNumberSmallSize: string; euiStepNumberMargin: string; euiStepStatusColorsToFade: { warning: string; danger: string; disabled: string; incomplete: string; }; euiSuggestItemColors: { tint0: string; tint1: string; tint2: string; tint3: string; tint4: string; tint5: string; tint6: string; tint7: string; tint8: string; tint9: string; tint10: string; }; euiTableCellContentPadding: string; euiTableCellContentPaddingCompressed: string; euiTableCellCheckboxWidth: string; euiTableActionsAreaWidth: string; euiTableHoverColor: string; euiTableSelectedColor: string; euiTableHoverSelectedColor: string; euiTableActionsBorderColor: string; euiTableHoverClickableColor: string; euiTableFocusClickableColor: string; euiTextColors: { default: string; subdued: string; success: string; accent: string; warning: string; danger: string; ghost: string; inherit: string; }; euiTextConstrainedMaxWidth: string; euiToastWidth: string; euiToastTypes: { primary: string; success: string; warning: string; danger: string; }; euiTokenGrayColor: string; euiTokenTypes: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; gray: { graphic: string; behindText: string; }; }; euiTokenTypeKeys: string; euiContrastRatioText: number; euiContrastRatioGraphic: number; euiContrastRatioDisabled: number; euiAnimSlightBounce: string; euiAnimSlightResistance: string; euiAnimSpeedExtraFast: string; euiAnimSpeedFast: string; euiAnimSpeedNormal: string; euiAnimSpeedSlow: string; euiAnimSpeedExtraSlow: string; euiBorderWidthThin: string; euiBorderWidthThick: string; euiBorderColor: string; euiBorderRadius: string; euiBorderRadiusSmall: string; euiBorderThick: string; euiBorderThin: string; euiBorderEditable: string; euiButtonHeight: string; euiButtonHeightSmall: string; euiButtonHeightXSmall: string; euiButtonColorDisabled: string; euiButtonColorDisabledText: string; euiButtonColorGhostDisabled: string; euiButtonTypes: { primary: string; accent: string; success: string; warning: string; danger: string; subdued: string; ghost: string; text: string; }; euiCodeBlockBackgroundColor: string; euiCodeBlockColor: string; euiCodeBlockSelectedBackgroundColor: string; euiCodeBlockCommentColor: string; euiCodeBlockSelectorTagColor: string; euiCodeBlockStringColor: string; euiCodeBlockTagColor: string; euiCodeBlockNameColor: string; euiCodeBlockNumberColor: string; euiCodeBlockKeywordColor: string; euiCodeBlockFunctionTitleColor: string; euiCodeBlockTypeColor: string; euiCodeBlockAttributeColor: string; euiCodeBlockSymbolColor: string; euiCodeBlockParamsColor: string; euiCodeBlockMetaColor: string; euiCodeBlockTitleColor: string; euiCodeBlockSectionColor: string; euiCodeBlockAdditionColor: string; euiCodeBlockDeletionColor: string; euiCodeBlockSelectorClassColor: string; euiCodeBlockSelectorIdColor: string; euiPaletteColorBlind: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; }; euiPaletteColorBlindKeys: string; euiColorVis0: string; euiColorVis1: string; euiColorVis2: string; euiColorVis3: string; euiColorVis4: string; euiColorVis5: string; euiColorVis6: string; euiColorVis7: string; euiColorVis8: string; euiColorVis9: string; euiColorVis0_behindText: string; euiColorVis1_behindText: string; euiColorVis2_behindText: string; euiColorVis3_behindText: string; euiColorVis4_behindText: string; euiColorVis5_behindText: string; euiColorVis6_behindText: string; euiColorVis7_behindText: string; euiColorVis8_behindText: string; euiColorVis9_behindText: string; euiFontWeightLight: number; euiFontWeightRegular: number; euiFontWeightMedium: number; euiFontWeightSemiBold: number; euiFontWeightBold: number; euiCodeFontWeightRegular: number; euiCodeFontWeightBold: number; euiFormMaxWidth: string; euiFormControlHeight: string; euiFormControlCompressedHeight: string; euiFormControlPadding: string; euiFormControlCompressedPadding: string; euiFormControlBorderRadius: string; euiFormControlCompressedBorderRadius: string; euiRadioSize: string; euiCheckBoxSize: string; euiCheckboxBorderRadius: string; euiSwitchHeight: string; euiSwitchWidth: string; euiSwitchThumbSize: string; euiSwitchIconHeight: string; euiSwitchHeightCompressed: string; euiSwitchWidthCompressed: string; euiSwitchThumbSizeCompressed: string; euiSwitchHeightMini: string; euiSwitchWidthMini: string; euiSwitchThumbSizeMini: string; euiFormBackgroundColor: string; euiFormBackgroundDisabledColor: string; euiFormBackgroundReadOnlyColor: string; euiFormBorderOpaqueColor: string; euiFormBorderColor: string; euiFormBorderDisabledColor: string; euiFormCustomControlDisabledIconColor: string; euiFormCustomControlBorderColor: string; euiFormControlDisabledColor: string; euiFormControlBoxShadow: string; euiFormControlPlaceholderText: string; euiFormInputGroupLabelBackground: string; euiFormInputGroupBorder: string; euiSwitchOffColor: string; euiFormControlLayoutGroupInputHeight: string; euiFormControlLayoutGroupInputCompressedHeight: string; euiFormControlLayoutGroupInputCompressedBorderRadius: string; euiRangeTrackColor: string; euiRangeThumbRadius: string; euiRangeThumbHeight: string; euiRangeThumbWidth: string; euiRangeThumbBorderColor: string; euiRangeTrackWidth: string; euiRangeTrackHeight: string; euiRangeTrackBorderWidth: number; euiRangeTrackBorderColor: string; euiRangeTrackRadius: string; euiRangeDisabledOpacity: number; euiRangeHighlightHeight: string; euiHeaderBackgroundColor: string; euiHeaderDarkBackgroundColor: string; euiHeaderBorderColor: string; euiHeaderBreadcrumbColor: string; euiHeaderHeight: string; euiHeaderChildSize: string; euiHeaderHeightCompensation: string; euiPageDefaultMaxWidth: string; euiPageSidebarMinWidth: string; euiPanelPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiPanelBorderRadiusModifiers: { borderRadiusNone: number; borderRadiusMedium: string; }; euiPanelBackgroundColorModifiers: { transparent: string; plain: string; subdued: string; accent: string; primary: string; success: string; warning: string; danger: string; }; euiBreakpoints: { xs: number; s: string; m: string; l: string; xl: string; }; euiBreakpointKeys: string; euiShadowColor: string; euiShadowColorLarge: string; euiSize: string; euiSizeXS: string; euiSizeS: string; euiSizeM: string; euiSizeL: string; euiSizeXL: string; euiSizeXXL: string; euiButtonMinWidth: string; euiScrollBar: string; euiScrollBarCorner: string; euiScrollBarCornerThin: string; euiFocusRingColor: string; euiFocusRingAnimStartColor: string; euiFocusRingAnimStartSize: string; euiFocusRingAnimStartSizeLarge: string; euiFocusRingSizeLarge: string; euiFocusRingSize: string; euiFocusTransparency: number; euiFocusTransparencyPercent: string; euiFocusBackgroundColor: string; euiTooltipBackgroundColor: string; euiTooltipBorderColor: string; euiTooltipAnimations: { top: string; left: string; bottom: string; right: string; }; euiFontFamily: string; euiCodeFontFamily: string; euiFontFeatureSettings: string; euiTextScale: string; euiFontSize: string; euiFontSizeXS: string; euiFontSizeS: string; euiFontSizeM: string; euiFontSizeL: string; euiFontSizeXL: string; euiFontSizeXXL: string; euiLineHeight: number; euiBodyLineHeight: number; euiTitles: { xxxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; s: { 'font-size': string; 'line-height': string; 'font-weight': number; }; m: { 'font-size': string; 'line-height': string; 'font-weight': number; }; l: { 'font-size': string; 'line-height': string; 'font-weight': number; }; }; euiZLevel0: number; euiZLevel1: number; euiZLevel2: number; euiZLevel3: number; euiZLevel4: number; euiZLevel5: number; euiZLevel6: number; euiZLevel7: number; euiZLevel8: number; euiZLevel9: number; euiZToastList: number; euiZModal: number; euiZMask: number; euiZNavigation: number; euiZContentMenu: number; euiZHeader: number; euiZFlyout: number; euiZMaskBelowHeader: number; euiZContent: number; euiColorGhost: string; euiColorInk: string; euiColorPrimary: string; euiColorAccent: string; euiColorSuccess: string; euiColorWarning: string; euiColorDanger: string; euiColorEmptyShade: string; euiColorLightestShade: string; euiColorLightShade: string; euiColorMediumShade: string; euiColorDarkShade: string; euiColorDarkestShade: string; euiColorFullShade: string; euiPageBackgroundColor: string; euiColorHighlight: string; euiTextColor: string; euiTitleColor: string; euiTextSubduedColor: string; euiColorDisabled: string; euiColorPrimaryText: string; euiColorSuccessText: string; euiColorAccentText: string; euiColorWarningText: string; euiColorDangerText: string; euiColorDisabledText: string; euiLinkColor: string; euiColorChartLines: string; euiColorChartBand: string; euiDatePickerCalendarWidth: string; euiDatePickerPadding: string; euiDatePickerGap: string; euiDatePickerCalendarColumns: number; euiDatePickerButtonSize: string; euiDatePickerMinControlWidth: string; euiDatePickerMaxControlWidth: string; euiButtonDefaultTransparency: number; euiButtonFontWeight: number; euiRangeHighlightColor: string; euiRangeThumbBackgroundColor: string; euiRangeTrackCompressedHeight: string; euiRangeHighlightCompressedHeight: string; euiRangeHeight: string; euiRangeCompressedHeight: string; euiStepStatusColors: { default: string; complete: string; warning: string; danger: string; }; }" + "{ paddingSizes: { xs: string; s: string; m: string; l: string; xl: string; }; euiBadgeGroupGutterTypes: { gutterExtraSmall: string; gutterSmall: string; }; euiBreadcrumbSpacing: string; euiBreadcrumbTruncateWidth: string; euiButtonEmptyTypes: { primary: string; danger: string; disabled: string; ghost: string; text: string; success: string; warning: string; }; euiCallOutTypes: { primary: string; success: string; warning: string; danger: string; }; euiCardSpacing: string; euiCardBottomNodeHeight: string; euiCardSelectButtonBorders: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardSelectButtonBackgrounds: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCheckableCardPadding: string; euiCodeBlockPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCollapsibleNavGroupLightBackgroundColor: string; euiCollapsibleNavGroupDarkBackgroundColor: string; euiCollapsibleNavGroupDarkHighContrastColor: string; euiColorPickerValueRange0: string; euiColorPickerValueRange1: string; euiColorPickerSaturationRange0: string; euiColorPickerSaturationRange1: string; euiColorPickerIndicatorSize: string; euiColorPickerWidth: string; euiColorPaletteDisplaySizes: { sizeExtraSmall: string; sizeSmall: string; sizeMedium: string; }; euiContextMenuWidth: string; euiControlBarBackground: string; euiControlBarText: string; euiControlBarBorderColor: string; euiControlBarInitialHeight: string; euiControlBarMaxHeight: string; euiControlBarHeights: { s: string; m: string; l: string; }; euiDataGridPrefix: string; euiDataGridStyles: string; euiZDataGrid: number; euiZHeaderBelowDataGrid: number; euiZDataGridCellPopover: number; euiDataGridColumnResizerWidth: string; euiDataGridPopoverMaxHeight: string; euiDataGridCellPaddingS: string; euiDataGridCellPaddingM: string; euiDataGridCellPaddingL: string; euiDataGridVerticalBorder: string; euiSuperDatePickerWidth: string; euiSuperDatePickerButtonWidth: string; euiDragAndDropSpacing: { s: string; m: string; l: string; }; euiExpressionColors: { subdued: string; primary: string; success: string; warning: string; danger: string; accent: string; }; euiFacetGutterSizes: { gutterNone: number; gutterSmall: string; gutterMedium: string; gutterLarge: string; }; gutterTypes: { gutterExtraSmall: string; gutterSmall: string; gutterMedium: string; gutterLarge: string; gutterExtraLarge: string; }; fractions: { fourths: { percentage: string; count: number; }; thirds: { percentage: string; count: number; }; halves: { percentage: string; count: number; }; single: { percentage: string; count: number; }; }; flyoutSizes: { small: { min: string; width: string; max: string; }; medium: { min: string; width: string; max: string; }; large: { min: string; width: string; max: string; }; }; euiFlyoutBorder: string; euiFlyoutPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiFilePickerTallHeight: string; euiRangeLevelColors: { primary: string; success: string; warning: string; danger: string; }; textareaResizing: { vertical: string; horizontal: string; both: string; none: string; }; euiHeaderLinksGutterSizes: { gutterXS: string; gutterS: string; gutterM: string; gutterL: string; }; ruleMargins: { marginXSmall: string; marginSmall: string; marginMedium: string; marginLarge: string; marginXLarge: string; marginXXLarge: string; }; euiIconLoadingOpacity: number; euiIconColors: { accent: string; danger: string; ghost: string; primary: string; success: string; subdued: string; text: string; warning: string; inherit: string; }; euiIconSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiKeyPadMenuSize: string; euiKeyPadMenuMarginSize: string; euiLinkColors: { subdued: string; primary: string; success: string; accent: string; warning: string; danger: string; text: string; ghost: string; }; euiListGroupItemHoverBackground: string; euiListGroupItemHoverBackgroundGhost: string; euiListGroupGutterTypes: { gutterSmall: string; gutterMedium: string; }; euiListGroupItemColorTypes: { primary: string; text: string; subdued: string; ghost: string; }; euiListGroupItemSizeTypes: { xSmall: string; small: string; medium: string; large: string; }; euiGradientStartStop: string; euiGradientMiddle: string; euiLoadingSpinnerSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiMarkdownEditorMinHeight: string; euiPopoverArrowSize: string; euiPopoverTranslateDistance: string; euiProgressSizes: { xs: string; s: string; m: string; l: string; }; euiProgressColors: { primary: string; success: string; warning: string; danger: string; accent: string; subdued: string; vis0: string; vis1: string; vis2: string; vis3: string; vis4: string; vis5: string; vis6: string; vis7: string; vis8: string; vis9: string; customColor: string; }; euiResizableButtonTransitionSpeed: string; euiResizableButtonSize: string; euiSelectableListItemBorder: string; euiSelectableListItemPadding: string; euiSelectableTemplateSitewideTypes: { application: { color: string; 'font-weight': number; }; deployment: { color: string; 'font-weight': number; }; article: { color: string; 'font-weight': number; }; case: { color: string; 'font-weight': number; }; platform: { color: string; 'font-weight': number; }; }; euiSideNavEmphasizedBackgroundColor: string; euiSideNavRootTextcolor: string; euiSideNavBranchTextcolor: string; euiSideNavSelectedTextcolor: string; euiSideNavDisabledTextcolor: string; spacerSizes: { xs: string; s: string; m: string; l: string; xl: string; xxl: string; }; euiStepNumberSize: string; euiStepNumberSmallSize: string; euiStepNumberMargin: string; euiStepStatusColorsToFade: { warning: string; danger: string; disabled: string; incomplete: string; }; euiSuggestItemColors: { tint0: string; tint1: string; tint2: string; tint3: string; tint4: string; tint5: string; tint6: string; tint7: string; tint8: string; tint9: string; tint10: string; }; euiTableCellContentPadding: string; euiTableCellContentPaddingCompressed: string; euiTableCellCheckboxWidth: string; euiTableActionsAreaWidth: string; euiTableHoverColor: string; euiTableSelectedColor: string; euiTableHoverSelectedColor: string; euiTableActionsBorderColor: string; euiTableHoverClickableColor: string; euiTableFocusClickableColor: string; euiTextColors: { default: string; subdued: string; success: string; accent: string; warning: string; danger: string; ghost: string; inherit: string; }; euiTextConstrainedMaxWidth: string; euiToastWidth: string; euiToastTypes: { primary: string; success: string; warning: string; danger: string; }; euiTokenGrayColor: string; euiTokenTypes: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; gray: { graphic: string; behindText: string; }; }; euiTokenTypeKeys: string; euiContrastRatioText: number; euiContrastRatioGraphic: number; euiContrastRatioDisabled: number; euiAnimSlightBounce: string; euiAnimSlightResistance: string; euiAnimSpeedExtraFast: string; euiAnimSpeedFast: string; euiAnimSpeedNormal: string; euiAnimSpeedSlow: string; euiAnimSpeedExtraSlow: string; euiBorderWidthThin: string; euiBorderWidthThick: string; euiBorderColor: string; euiBorderRadius: string; euiBorderRadiusSmall: string; euiBorderThick: string; euiBorderThin: string; euiBorderEditable: string; euiButtonHeight: string; euiButtonHeightSmall: string; euiButtonHeightXSmall: string; euiButtonColorDisabled: string; euiButtonColorDisabledText: string; euiButtonColorGhostDisabled: string; euiButtonTypes: { primary: string; accent: string; success: string; warning: string; danger: string; subdued: string; ghost: string; text: string; }; euiCodeBlockBackgroundColor: string; euiCodeBlockColor: string; euiCodeBlockSelectedBackgroundColor: string; euiCodeBlockCommentColor: string; euiCodeBlockSelectorTagColor: string; euiCodeBlockStringColor: string; euiCodeBlockTagColor: string; euiCodeBlockNameColor: string; euiCodeBlockNumberColor: string; euiCodeBlockKeywordColor: string; euiCodeBlockFunctionTitleColor: string; euiCodeBlockTypeColor: string; euiCodeBlockAttributeColor: string; euiCodeBlockSymbolColor: string; euiCodeBlockParamsColor: string; euiCodeBlockMetaColor: string; euiCodeBlockTitleColor: string; euiCodeBlockSectionColor: string; euiCodeBlockAdditionColor: string; euiCodeBlockDeletionColor: string; euiCodeBlockSelectorClassColor: string; euiCodeBlockSelectorIdColor: string; euiPaletteColorBlind: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; }; euiPaletteColorBlindKeys: string; euiColorVis0: string; euiColorVis1: string; euiColorVis2: string; euiColorVis3: string; euiColorVis4: string; euiColorVis5: string; euiColorVis6: string; euiColorVis7: string; euiColorVis8: string; euiColorVis9: string; euiColorVis0_behindText: string; euiColorVis1_behindText: string; euiColorVis2_behindText: string; euiColorVis3_behindText: string; euiColorVis4_behindText: string; euiColorVis5_behindText: string; euiColorVis6_behindText: string; euiColorVis7_behindText: string; euiColorVis8_behindText: string; euiColorVis9_behindText: string; euiFontWeightLight: number; euiFontWeightRegular: number; euiFontWeightMedium: number; euiFontWeightSemiBold: number; euiFontWeightBold: number; euiCodeFontWeightRegular: number; euiCodeFontWeightBold: number; euiFormMaxWidth: string; euiFormControlHeight: string; euiFormControlCompressedHeight: string; euiFormControlPadding: string; euiFormControlCompressedPadding: string; euiFormControlBorderRadius: string; euiFormControlCompressedBorderRadius: string; euiRadioSize: string; euiCheckBoxSize: string; euiCheckboxBorderRadius: string; euiSwitchHeight: string; euiSwitchWidth: string; euiSwitchThumbSize: string; euiSwitchIconHeight: string; euiSwitchHeightCompressed: string; euiSwitchWidthCompressed: string; euiSwitchThumbSizeCompressed: string; euiSwitchHeightMini: string; euiSwitchWidthMini: string; euiSwitchThumbSizeMini: string; euiFormBackgroundColor: string; euiFormBackgroundDisabledColor: string; euiFormBackgroundReadOnlyColor: string; euiFormBorderOpaqueColor: string; euiFormBorderColor: string; euiFormBorderDisabledColor: string; euiFormCustomControlDisabledIconColor: string; euiFormCustomControlBorderColor: string; euiFormControlDisabledColor: string; euiFormControlBoxShadow: string; euiFormControlPlaceholderText: string; euiFormInputGroupLabelBackground: string; euiFormInputGroupBorder: string; euiSwitchOffColor: string; euiFormControlLayoutGroupInputHeight: string; euiFormControlLayoutGroupInputCompressedHeight: string; euiFormControlLayoutGroupInputCompressedBorderRadius: string; euiRangeTrackColor: string; euiRangeThumbRadius: string; euiRangeThumbHeight: string; euiRangeThumbWidth: string; euiRangeThumbBorderColor: string; euiRangeTrackWidth: string; euiRangeTrackHeight: string; euiRangeTrackBorderWidth: number; euiRangeTrackBorderColor: string; euiRangeTrackRadius: string; euiRangeDisabledOpacity: number; euiRangeHighlightHeight: string; euiHeaderBackgroundColor: string; euiHeaderDarkBackgroundColor: string; euiHeaderBorderColor: string; euiHeaderBreadcrumbColor: string; euiHeaderHeight: string; euiHeaderChildSize: string; euiHeaderHeightCompensation: string; euiPageDefaultMaxWidth: string; euiPageSidebarMinWidth: string; euiPanelPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiPanelBorderRadiusModifiers: { borderRadiusNone: number; borderRadiusMedium: string; }; euiPanelBackgroundColorModifiers: { transparent: string; plain: string; subdued: string; accent: string; primary: string; success: string; warning: string; danger: string; }; euiBreakpoints: { xs: number; s: string; m: string; l: string; xl: string; }; euiBreakpointKeys: string; euiShadowColor: string; euiShadowColorLarge: string; euiSize: string; euiSizeXS: string; euiSizeS: string; euiSizeM: string; euiSizeL: string; euiSizeXL: string; euiSizeXXL: string; euiButtonMinWidth: string; euiScrollBar: string; euiScrollBarCorner: string; euiScrollBarCornerThin: string; euiFocusRingColor: string; euiFocusRingAnimStartColor: string; euiFocusRingAnimStartSize: string; euiFocusRingAnimStartSizeLarge: string; euiFocusRingSizeLarge: string; euiFocusRingSize: string; euiFocusTransparency: number; euiFocusTransparencyPercent: string; euiFocusBackgroundColor: string; euiTooltipBackgroundColor: string; euiTooltipBorderColor: string; euiTooltipAnimations: { top: string; left: string; bottom: string; right: string; }; euiFontFamily: string; euiCodeFontFamily: string; euiFontFeatureSettings: string; euiTextScale: string; euiFontSize: string; euiFontSizeXS: string; euiFontSizeS: string; euiFontSizeM: string; euiFontSizeL: string; euiFontSizeXL: string; euiFontSizeXXL: string; euiLineHeight: number; euiBodyLineHeight: number; euiTitles: { xxxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; s: { 'font-size': string; 'line-height': string; 'font-weight': number; }; m: { 'font-size': string; 'line-height': string; 'font-weight': number; }; l: { 'font-size': string; 'line-height': string; 'font-weight': number; }; }; euiZLevel0: number; euiZLevel1: number; euiZLevel2: number; euiZLevel3: number; euiZLevel4: number; euiZLevel5: number; euiZLevel6: number; euiZLevel7: number; euiZLevel8: number; euiZLevel9: number; euiZToastList: number; euiZModal: number; euiZMask: number; euiZNavigation: number; euiZContentMenu: number; euiZHeader: number; euiZFlyout: number; euiZMaskBelowHeader: number; euiZContent: number; euiColorGhost: string; euiColorInk: string; euiColorPrimary: string; euiColorAccent: string; euiColorSuccess: string; euiColorWarning: string; euiColorDanger: string; euiColorEmptyShade: string; euiColorLightestShade: string; euiColorLightShade: string; euiColorMediumShade: string; euiColorDarkShade: string; euiColorDarkestShade: string; euiColorFullShade: string; euiPageBackgroundColor: string; euiColorHighlight: string; euiTextColor: string; euiTitleColor: string; euiTextSubduedColor: string; euiColorDisabled: string; euiColorPrimaryText: string; euiColorSuccessText: string; euiColorAccentText: string; euiColorWarningText: string; euiColorDangerText: string; euiColorDisabledText: string; euiLinkColor: string; euiColorChartLines: string; euiColorChartBand: string; euiDatePickerCalendarWidth: string; euiDatePickerPadding: string; euiDatePickerGap: string; euiDatePickerCalendarColumns: number; euiDatePickerButtonSize: string; euiDatePickerMinControlWidth: string; euiDatePickerMaxControlWidth: string; euiButtonDefaultTransparency: number; euiButtonFontWeight: number; euiRangeHighlightColor: string; euiRangeThumbBackgroundColor: string; euiRangeTrackCompressedHeight: string; euiRangeHighlightCompressedHeight: string; euiRangeHeight: string; euiRangeCompressedHeight: string; euiStepStatusColors: { default: string; complete: string; warning: string; danger: string; }; }" ], "path": "packages/kbn-ui-theme/src/theme.ts", "deprecated": false, @@ -96,7 +96,7 @@ "label": "euiLightVars", "description": [], "signature": [ - "{ paddingSizes: { xs: string; s: string; m: string; l: string; xl: string; }; avatarSizing: { s: { size: string; 'font-size': string; }; m: { size: string; 'font-size': string; }; l: { size: string; 'font-size': string; }; xl: { size: string; 'font-size': string; }; }; euiBadgeGroupGutterTypes: { gutterExtraSmall: string; gutterSmall: string; }; euiBreadcrumbSpacing: string; euiBreadcrumbTruncateWidth: string; euiButtonEmptyTypes: { primary: string; danger: string; disabled: string; ghost: string; text: string; success: string; warning: string; }; euiCallOutTypes: { primary: string; success: string; warning: string; danger: string; }; euiCardSpacing: string; euiCardBottomNodeHeight: string; euiCardSelectButtonBorders: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardSelectButtonBackgrounds: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCheckableCardPadding: string; euiCodeBlockPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCollapsibleNavGroupLightBackgroundColor: string; euiCollapsibleNavGroupDarkBackgroundColor: string; euiCollapsibleNavGroupDarkHighContrastColor: string; euiColorPickerValueRange0: string; euiColorPickerValueRange1: string; euiColorPickerSaturationRange0: string; euiColorPickerSaturationRange1: string; euiColorPickerIndicatorSize: string; euiColorPickerWidth: string; euiColorPaletteDisplaySizes: { sizeExtraSmall: string; sizeSmall: string; sizeMedium: string; }; euiContextMenuWidth: string; euiControlBarBackground: string; euiControlBarText: string; euiControlBarBorderColor: string; euiControlBarInitialHeight: string; euiControlBarMaxHeight: string; euiControlBarHeights: { s: string; m: string; l: string; }; euiDataGridPrefix: string; euiDataGridStyles: string; euiZDataGrid: number; euiZHeaderBelowDataGrid: number; euiZDataGridCellPopover: number; euiDataGridColumnResizerWidth: string; euiDataGridPopoverMaxHeight: string; euiDataGridCellPaddingS: string; euiDataGridCellPaddingM: string; euiDataGridCellPaddingL: string; euiDataGridVerticalBorder: string; euiSuperDatePickerWidth: string; euiSuperDatePickerButtonWidth: string; euiDragAndDropSpacing: { s: string; m: string; l: string; }; euiExpressionColors: { subdued: string; primary: string; success: string; warning: string; danger: string; accent: string; }; euiFacetGutterSizes: { gutterNone: number; gutterSmall: string; gutterMedium: string; gutterLarge: string; }; gutterTypes: { gutterExtraSmall: string; gutterSmall: string; gutterMedium: string; gutterLarge: string; gutterExtraLarge: string; }; fractions: { fourths: { percentage: string; count: number; }; thirds: { percentage: string; count: number; }; halves: { percentage: string; count: number; }; single: { percentage: string; count: number; }; }; flyoutSizes: { small: { min: string; width: string; max: string; }; medium: { min: string; width: string; max: string; }; large: { min: string; width: string; max: string; }; }; euiFlyoutBorder: string; euiFlyoutPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiFilePickerTallHeight: string; euiRangeLevelColors: { primary: string; success: string; warning: string; danger: string; }; textareaResizing: { vertical: string; horizontal: string; both: string; none: string; }; euiHeaderLinksGutterSizes: { gutterXS: string; gutterS: string; gutterM: string; gutterL: string; }; ruleMargins: { marginXSmall: string; marginSmall: string; marginMedium: string; marginLarge: string; marginXLarge: string; marginXXLarge: string; }; euiIconLoadingOpacity: number; euiIconColors: { accent: string; danger: string; ghost: string; primary: string; success: string; subdued: string; text: string; warning: string; inherit: string; }; euiIconSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiKeyPadMenuSize: string; euiKeyPadMenuMarginSize: string; euiLinkColors: { subdued: string; primary: string; success: string; accent: string; warning: string; danger: string; text: string; ghost: string; }; euiListGroupItemHoverBackground: string; euiListGroupItemHoverBackgroundGhost: string; euiListGroupGutterTypes: { gutterSmall: string; gutterMedium: string; }; euiListGroupItemColorTypes: { primary: string; text: string; subdued: string; ghost: string; }; euiListGroupItemSizeTypes: { xSmall: string; small: string; medium: string; large: string; }; euiGradientStartStop: string; euiGradientMiddle: string; euiLoadingSpinnerSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiMarkdownEditorMinHeight: string; euiPopoverArrowSize: string; euiPopoverTranslateDistance: string; euiProgressSizes: { xs: string; s: string; m: string; l: string; }; euiProgressColors: { primary: string; success: string; warning: string; danger: string; accent: string; subdued: string; vis0: string; vis1: string; vis2: string; vis3: string; vis4: string; vis5: string; vis6: string; vis7: string; vis8: string; vis9: string; customColor: string; }; euiResizableButtonTransitionSpeed: string; euiResizableButtonSize: string; euiSelectableListItemBorder: string; euiSelectableListItemPadding: string; euiSelectableTemplateSitewideTypes: { application: { color: string; 'font-weight': number; }; deployment: { color: string; 'font-weight': number; }; article: { color: string; 'font-weight': number; }; case: { color: string; 'font-weight': number; }; platform: { color: string; 'font-weight': number; }; }; euiSideNavEmphasizedBackgroundColor: string; euiSideNavRootTextcolor: string; euiSideNavBranchTextcolor: string; euiSideNavSelectedTextcolor: string; euiSideNavDisabledTextcolor: string; spacerSizes: { xs: string; s: string; m: string; l: string; xl: string; xxl: string; }; euiStepNumberSize: string; euiStepNumberSmallSize: string; euiStepNumberMargin: string; euiStepStatusColorsToFade: { warning: string; danger: string; disabled: string; incomplete: string; }; euiSuggestItemColors: { tint0: string; tint1: string; tint2: string; tint3: string; tint4: string; tint5: string; tint6: string; tint7: string; tint8: string; tint9: string; tint10: string; }; euiTableCellContentPadding: string; euiTableCellContentPaddingCompressed: string; euiTableCellCheckboxWidth: string; euiTableActionsAreaWidth: string; euiTableHoverColor: string; euiTableSelectedColor: string; euiTableHoverSelectedColor: string; euiTableActionsBorderColor: string; euiTableHoverClickableColor: string; euiTableFocusClickableColor: string; euiTextColors: { default: string; subdued: string; success: string; accent: string; warning: string; danger: string; ghost: string; inherit: string; }; euiTextConstrainedMaxWidth: string; euiToastWidth: string; euiToastTypes: { primary: string; success: string; warning: string; danger: string; }; euiTokenGrayColor: string; euiTokenTypes: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; gray: { graphic: string; behindText: string; }; }; euiTokenTypeKeys: string; euiContrastRatioText: number; euiContrastRatioGraphic: number; euiContrastRatioDisabled: number; euiAnimSlightBounce: string; euiAnimSlightResistance: string; euiAnimSpeedExtraFast: string; euiAnimSpeedFast: string; euiAnimSpeedNormal: string; euiAnimSpeedSlow: string; euiAnimSpeedExtraSlow: string; euiBorderWidthThin: string; euiBorderWidthThick: string; euiBorderColor: string; euiBorderRadius: string; euiBorderRadiusSmall: string; euiBorderThick: string; euiBorderThin: string; euiBorderEditable: string; euiButtonHeight: string; euiButtonHeightSmall: string; euiButtonHeightXSmall: string; euiButtonColorDisabled: string; euiButtonColorDisabledText: string; euiButtonColorGhostDisabled: string; euiButtonTypes: { primary: string; accent: string; success: string; warning: string; danger: string; subdued: string; ghost: string; text: string; }; euiCodeBlockBackgroundColor: string; euiCodeBlockColor: string; euiCodeBlockSelectedBackgroundColor: string; euiCodeBlockCommentColor: string; euiCodeBlockSelectorTagColor: string; euiCodeBlockStringColor: string; euiCodeBlockTagColor: string; euiCodeBlockNameColor: string; euiCodeBlockNumberColor: string; euiCodeBlockKeywordColor: string; euiCodeBlockFunctionTitleColor: string; euiCodeBlockTypeColor: string; euiCodeBlockAttributeColor: string; euiCodeBlockSymbolColor: string; euiCodeBlockParamsColor: string; euiCodeBlockMetaColor: string; euiCodeBlockTitleColor: string; euiCodeBlockSectionColor: string; euiCodeBlockAdditionColor: string; euiCodeBlockDeletionColor: string; euiCodeBlockSelectorClassColor: string; euiCodeBlockSelectorIdColor: string; euiPaletteColorBlind: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; }; euiPaletteColorBlindKeys: string; euiColorVis0: string; euiColorVis1: string; euiColorVis2: string; euiColorVis3: string; euiColorVis4: string; euiColorVis5: string; euiColorVis6: string; euiColorVis7: string; euiColorVis8: string; euiColorVis9: string; euiColorVis0_behindText: string; euiColorVis1_behindText: string; euiColorVis2_behindText: string; euiColorVis3_behindText: string; euiColorVis4_behindText: string; euiColorVis5_behindText: string; euiColorVis6_behindText: string; euiColorVis7_behindText: string; euiColorVis8_behindText: string; euiColorVis9_behindText: string; euiFontWeightLight: number; euiFontWeightRegular: number; euiFontWeightMedium: number; euiFontWeightSemiBold: number; euiFontWeightBold: number; euiCodeFontWeightRegular: number; euiCodeFontWeightBold: number; euiFormMaxWidth: string; euiFormControlHeight: string; euiFormControlCompressedHeight: string; euiFormControlPadding: string; euiFormControlCompressedPadding: string; euiFormControlBorderRadius: string; euiFormControlCompressedBorderRadius: string; euiRadioSize: string; euiCheckBoxSize: string; euiCheckboxBorderRadius: string; euiSwitchHeight: string; euiSwitchWidth: string; euiSwitchThumbSize: string; euiSwitchIconHeight: string; euiSwitchHeightCompressed: string; euiSwitchWidthCompressed: string; euiSwitchThumbSizeCompressed: string; euiSwitchHeightMini: string; euiSwitchWidthMini: string; euiSwitchThumbSizeMini: string; euiFormBackgroundColor: string; euiFormBackgroundDisabledColor: string; euiFormBackgroundReadOnlyColor: string; euiFormBorderOpaqueColor: string; euiFormBorderColor: string; euiFormBorderDisabledColor: string; euiFormCustomControlDisabledIconColor: string; euiFormCustomControlBorderColor: string; euiFormControlDisabledColor: string; euiFormControlBoxShadow: string; euiFormControlPlaceholderText: string; euiFormInputGroupLabelBackground: string; euiFormInputGroupBorder: string; euiSwitchOffColor: string; euiFormControlLayoutGroupInputHeight: string; euiFormControlLayoutGroupInputCompressedHeight: string; euiFormControlLayoutGroupInputCompressedBorderRadius: string; euiRangeTrackColor: string; euiRangeThumbRadius: string; euiRangeThumbHeight: string; euiRangeThumbWidth: string; euiRangeThumbBorderColor: string; euiRangeTrackWidth: string; euiRangeTrackHeight: string; euiRangeTrackBorderWidth: number; euiRangeTrackBorderColor: string; euiRangeTrackRadius: string; euiRangeDisabledOpacity: number; euiRangeHighlightHeight: string; euiHeaderBackgroundColor: string; euiHeaderDarkBackgroundColor: string; euiHeaderBorderColor: string; euiHeaderBreadcrumbColor: string; euiHeaderHeight: string; euiHeaderChildSize: string; euiHeaderHeightCompensation: string; euiPageDefaultMaxWidth: string; euiPageSidebarMinWidth: string; euiPanelPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiPanelBorderRadiusModifiers: { borderRadiusNone: number; borderRadiusMedium: string; }; euiPanelBackgroundColorModifiers: { transparent: string; plain: string; subdued: string; accent: string; primary: string; success: string; warning: string; danger: string; }; euiBreakpoints: { xs: number; s: string; m: string; l: string; xl: string; }; euiBreakpointKeys: string; euiShadowColor: string; euiShadowColorLarge: string; euiSize: string; euiSizeXS: string; euiSizeS: string; euiSizeM: string; euiSizeL: string; euiSizeXL: string; euiSizeXXL: string; euiButtonMinWidth: string; euiScrollBar: string; euiScrollBarCorner: string; euiScrollBarCornerThin: string; euiFocusRingColor: string; euiFocusRingAnimStartColor: string; euiFocusRingAnimStartSize: string; euiFocusRingAnimStartSizeLarge: string; euiFocusRingSizeLarge: string; euiFocusRingSize: string; euiFocusTransparency: number; euiFocusTransparencyPercent: string; euiFocusBackgroundColor: string; euiTooltipBackgroundColor: string; euiTooltipBorderColor: string; euiTooltipAnimations: { top: string; left: string; bottom: string; right: string; }; euiFontFamily: string; euiCodeFontFamily: string; euiFontFeatureSettings: string; euiTextScale: string; euiFontSize: string; euiFontSizeXS: string; euiFontSizeS: string; euiFontSizeM: string; euiFontSizeL: string; euiFontSizeXL: string; euiFontSizeXXL: string; euiLineHeight: number; euiBodyLineHeight: number; euiTitles: { xxxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; s: { 'font-size': string; 'line-height': string; 'font-weight': number; }; m: { 'font-size': string; 'line-height': string; 'font-weight': number; }; l: { 'font-size': string; 'line-height': string; 'font-weight': number; }; }; euiZLevel0: number; euiZLevel1: number; euiZLevel2: number; euiZLevel3: number; euiZLevel4: number; euiZLevel5: number; euiZLevel6: number; euiZLevel7: number; euiZLevel8: number; euiZLevel9: number; euiZToastList: number; euiZModal: number; euiZMask: number; euiZNavigation: number; euiZContentMenu: number; euiZHeader: number; euiZFlyout: number; euiZMaskBelowHeader: number; euiZContent: number; euiColorGhost: string; euiColorInk: string; euiColorPrimary: string; euiColorAccent: string; euiColorSuccess: string; euiColorWarning: string; euiColorDanger: string; euiColorEmptyShade: string; euiColorLightestShade: string; euiColorLightShade: string; euiColorMediumShade: string; euiColorDarkShade: string; euiColorDarkestShade: string; euiColorFullShade: string; euiPageBackgroundColor: string; euiColorHighlight: string; euiTextColor: string; euiTitleColor: string; euiTextSubduedColor: string; euiColorDisabled: string; euiColorPrimaryText: string; euiColorSuccessText: string; euiColorAccentText: string; euiColorWarningText: string; euiColorDangerText: string; euiColorDisabledText: string; euiLinkColor: string; euiColorChartLines: string; euiColorChartBand: string; euiDatePickerCalendarWidth: string; euiDatePickerPadding: string; euiDatePickerGap: string; euiDatePickerCalendarColumns: number; euiDatePickerButtonSize: string; euiDatePickerMinControlWidth: string; euiDatePickerMaxControlWidth: string; euiButtonDefaultTransparency: number; euiButtonFontWeight: number; euiRangeHighlightColor: string; euiRangeThumbBackgroundColor: string; euiRangeTrackCompressedHeight: string; euiRangeHighlightCompressedHeight: string; euiRangeHeight: string; euiRangeCompressedHeight: string; euiStepStatusColors: { default: string; complete: string; warning: string; danger: string; }; }" + "{ paddingSizes: { xs: string; s: string; m: string; l: string; xl: string; }; euiBadgeGroupGutterTypes: { gutterExtraSmall: string; gutterSmall: string; }; euiBreadcrumbSpacing: string; euiBreadcrumbTruncateWidth: string; euiButtonEmptyTypes: { primary: string; danger: string; disabled: string; ghost: string; text: string; success: string; warning: string; }; euiCallOutTypes: { primary: string; success: string; warning: string; danger: string; }; euiCardSpacing: string; euiCardBottomNodeHeight: string; euiCardSelectButtonBorders: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardSelectButtonBackgrounds: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCheckableCardPadding: string; euiCodeBlockPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCollapsibleNavGroupLightBackgroundColor: string; euiCollapsibleNavGroupDarkBackgroundColor: string; euiCollapsibleNavGroupDarkHighContrastColor: string; euiColorPickerValueRange0: string; euiColorPickerValueRange1: string; euiColorPickerSaturationRange0: string; euiColorPickerSaturationRange1: string; euiColorPickerIndicatorSize: string; euiColorPickerWidth: string; euiColorPaletteDisplaySizes: { sizeExtraSmall: string; sizeSmall: string; sizeMedium: string; }; euiContextMenuWidth: string; euiControlBarBackground: string; euiControlBarText: string; euiControlBarBorderColor: string; euiControlBarInitialHeight: string; euiControlBarMaxHeight: string; euiControlBarHeights: { s: string; m: string; l: string; }; euiDataGridPrefix: string; euiDataGridStyles: string; euiZDataGrid: number; euiZHeaderBelowDataGrid: number; euiZDataGridCellPopover: number; euiDataGridColumnResizerWidth: string; euiDataGridPopoverMaxHeight: string; euiDataGridCellPaddingS: string; euiDataGridCellPaddingM: string; euiDataGridCellPaddingL: string; euiDataGridVerticalBorder: string; euiSuperDatePickerWidth: string; euiSuperDatePickerButtonWidth: string; euiDragAndDropSpacing: { s: string; m: string; l: string; }; euiExpressionColors: { subdued: string; primary: string; success: string; warning: string; danger: string; accent: string; }; euiFacetGutterSizes: { gutterNone: number; gutterSmall: string; gutterMedium: string; gutterLarge: string; }; gutterTypes: { gutterExtraSmall: string; gutterSmall: string; gutterMedium: string; gutterLarge: string; gutterExtraLarge: string; }; fractions: { fourths: { percentage: string; count: number; }; thirds: { percentage: string; count: number; }; halves: { percentage: string; count: number; }; single: { percentage: string; count: number; }; }; flyoutSizes: { small: { min: string; width: string; max: string; }; medium: { min: string; width: string; max: string; }; large: { min: string; width: string; max: string; }; }; euiFlyoutBorder: string; euiFlyoutPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiFilePickerTallHeight: string; euiRangeLevelColors: { primary: string; success: string; warning: string; danger: string; }; textareaResizing: { vertical: string; horizontal: string; both: string; none: string; }; euiHeaderLinksGutterSizes: { gutterXS: string; gutterS: string; gutterM: string; gutterL: string; }; ruleMargins: { marginXSmall: string; marginSmall: string; marginMedium: string; marginLarge: string; marginXLarge: string; marginXXLarge: string; }; euiIconLoadingOpacity: number; euiIconColors: { accent: string; danger: string; ghost: string; primary: string; success: string; subdued: string; text: string; warning: string; inherit: string; }; euiIconSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiKeyPadMenuSize: string; euiKeyPadMenuMarginSize: string; euiLinkColors: { subdued: string; primary: string; success: string; accent: string; warning: string; danger: string; text: string; ghost: string; }; euiListGroupItemHoverBackground: string; euiListGroupItemHoverBackgroundGhost: string; euiListGroupGutterTypes: { gutterSmall: string; gutterMedium: string; }; euiListGroupItemColorTypes: { primary: string; text: string; subdued: string; ghost: string; }; euiListGroupItemSizeTypes: { xSmall: string; small: string; medium: string; large: string; }; euiGradientStartStop: string; euiGradientMiddle: string; euiLoadingSpinnerSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiMarkdownEditorMinHeight: string; euiPopoverArrowSize: string; euiPopoverTranslateDistance: string; euiProgressSizes: { xs: string; s: string; m: string; l: string; }; euiProgressColors: { primary: string; success: string; warning: string; danger: string; accent: string; subdued: string; vis0: string; vis1: string; vis2: string; vis3: string; vis4: string; vis5: string; vis6: string; vis7: string; vis8: string; vis9: string; customColor: string; }; euiResizableButtonTransitionSpeed: string; euiResizableButtonSize: string; euiSelectableListItemBorder: string; euiSelectableListItemPadding: string; euiSelectableTemplateSitewideTypes: { application: { color: string; 'font-weight': number; }; deployment: { color: string; 'font-weight': number; }; article: { color: string; 'font-weight': number; }; case: { color: string; 'font-weight': number; }; platform: { color: string; 'font-weight': number; }; }; euiSideNavEmphasizedBackgroundColor: string; euiSideNavRootTextcolor: string; euiSideNavBranchTextcolor: string; euiSideNavSelectedTextcolor: string; euiSideNavDisabledTextcolor: string; spacerSizes: { xs: string; s: string; m: string; l: string; xl: string; xxl: string; }; euiStepNumberSize: string; euiStepNumberSmallSize: string; euiStepNumberMargin: string; euiStepStatusColorsToFade: { warning: string; danger: string; disabled: string; incomplete: string; }; euiSuggestItemColors: { tint0: string; tint1: string; tint2: string; tint3: string; tint4: string; tint5: string; tint6: string; tint7: string; tint8: string; tint9: string; tint10: string; }; euiTableCellContentPadding: string; euiTableCellContentPaddingCompressed: string; euiTableCellCheckboxWidth: string; euiTableActionsAreaWidth: string; euiTableHoverColor: string; euiTableSelectedColor: string; euiTableHoverSelectedColor: string; euiTableActionsBorderColor: string; euiTableHoverClickableColor: string; euiTableFocusClickableColor: string; euiTextColors: { default: string; subdued: string; success: string; accent: string; warning: string; danger: string; ghost: string; inherit: string; }; euiTextConstrainedMaxWidth: string; euiToastWidth: string; euiToastTypes: { primary: string; success: string; warning: string; danger: string; }; euiTokenGrayColor: string; euiTokenTypes: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; gray: { graphic: string; behindText: string; }; }; euiTokenTypeKeys: string; euiContrastRatioText: number; euiContrastRatioGraphic: number; euiContrastRatioDisabled: number; euiAnimSlightBounce: string; euiAnimSlightResistance: string; euiAnimSpeedExtraFast: string; euiAnimSpeedFast: string; euiAnimSpeedNormal: string; euiAnimSpeedSlow: string; euiAnimSpeedExtraSlow: string; euiBorderWidthThin: string; euiBorderWidthThick: string; euiBorderColor: string; euiBorderRadius: string; euiBorderRadiusSmall: string; euiBorderThick: string; euiBorderThin: string; euiBorderEditable: string; euiButtonHeight: string; euiButtonHeightSmall: string; euiButtonHeightXSmall: string; euiButtonColorDisabled: string; euiButtonColorDisabledText: string; euiButtonColorGhostDisabled: string; euiButtonTypes: { primary: string; accent: string; success: string; warning: string; danger: string; subdued: string; ghost: string; text: string; }; euiCodeBlockBackgroundColor: string; euiCodeBlockColor: string; euiCodeBlockSelectedBackgroundColor: string; euiCodeBlockCommentColor: string; euiCodeBlockSelectorTagColor: string; euiCodeBlockStringColor: string; euiCodeBlockTagColor: string; euiCodeBlockNameColor: string; euiCodeBlockNumberColor: string; euiCodeBlockKeywordColor: string; euiCodeBlockFunctionTitleColor: string; euiCodeBlockTypeColor: string; euiCodeBlockAttributeColor: string; euiCodeBlockSymbolColor: string; euiCodeBlockParamsColor: string; euiCodeBlockMetaColor: string; euiCodeBlockTitleColor: string; euiCodeBlockSectionColor: string; euiCodeBlockAdditionColor: string; euiCodeBlockDeletionColor: string; euiCodeBlockSelectorClassColor: string; euiCodeBlockSelectorIdColor: string; euiPaletteColorBlind: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; }; euiPaletteColorBlindKeys: string; euiColorVis0: string; euiColorVis1: string; euiColorVis2: string; euiColorVis3: string; euiColorVis4: string; euiColorVis5: string; euiColorVis6: string; euiColorVis7: string; euiColorVis8: string; euiColorVis9: string; euiColorVis0_behindText: string; euiColorVis1_behindText: string; euiColorVis2_behindText: string; euiColorVis3_behindText: string; euiColorVis4_behindText: string; euiColorVis5_behindText: string; euiColorVis6_behindText: string; euiColorVis7_behindText: string; euiColorVis8_behindText: string; euiColorVis9_behindText: string; euiFontWeightLight: number; euiFontWeightRegular: number; euiFontWeightMedium: number; euiFontWeightSemiBold: number; euiFontWeightBold: number; euiCodeFontWeightRegular: number; euiCodeFontWeightBold: number; euiFormMaxWidth: string; euiFormControlHeight: string; euiFormControlCompressedHeight: string; euiFormControlPadding: string; euiFormControlCompressedPadding: string; euiFormControlBorderRadius: string; euiFormControlCompressedBorderRadius: string; euiRadioSize: string; euiCheckBoxSize: string; euiCheckboxBorderRadius: string; euiSwitchHeight: string; euiSwitchWidth: string; euiSwitchThumbSize: string; euiSwitchIconHeight: string; euiSwitchHeightCompressed: string; euiSwitchWidthCompressed: string; euiSwitchThumbSizeCompressed: string; euiSwitchHeightMini: string; euiSwitchWidthMini: string; euiSwitchThumbSizeMini: string; euiFormBackgroundColor: string; euiFormBackgroundDisabledColor: string; euiFormBackgroundReadOnlyColor: string; euiFormBorderOpaqueColor: string; euiFormBorderColor: string; euiFormBorderDisabledColor: string; euiFormCustomControlDisabledIconColor: string; euiFormCustomControlBorderColor: string; euiFormControlDisabledColor: string; euiFormControlBoxShadow: string; euiFormControlPlaceholderText: string; euiFormInputGroupLabelBackground: string; euiFormInputGroupBorder: string; euiSwitchOffColor: string; euiFormControlLayoutGroupInputHeight: string; euiFormControlLayoutGroupInputCompressedHeight: string; euiFormControlLayoutGroupInputCompressedBorderRadius: string; euiRangeTrackColor: string; euiRangeThumbRadius: string; euiRangeThumbHeight: string; euiRangeThumbWidth: string; euiRangeThumbBorderColor: string; euiRangeTrackWidth: string; euiRangeTrackHeight: string; euiRangeTrackBorderWidth: number; euiRangeTrackBorderColor: string; euiRangeTrackRadius: string; euiRangeDisabledOpacity: number; euiRangeHighlightHeight: string; euiHeaderBackgroundColor: string; euiHeaderDarkBackgroundColor: string; euiHeaderBorderColor: string; euiHeaderBreadcrumbColor: string; euiHeaderHeight: string; euiHeaderChildSize: string; euiHeaderHeightCompensation: string; euiPageDefaultMaxWidth: string; euiPageSidebarMinWidth: string; euiPanelPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiPanelBorderRadiusModifiers: { borderRadiusNone: number; borderRadiusMedium: string; }; euiPanelBackgroundColorModifiers: { transparent: string; plain: string; subdued: string; accent: string; primary: string; success: string; warning: string; danger: string; }; euiBreakpoints: { xs: number; s: string; m: string; l: string; xl: string; }; euiBreakpointKeys: string; euiShadowColor: string; euiShadowColorLarge: string; euiSize: string; euiSizeXS: string; euiSizeS: string; euiSizeM: string; euiSizeL: string; euiSizeXL: string; euiSizeXXL: string; euiButtonMinWidth: string; euiScrollBar: string; euiScrollBarCorner: string; euiScrollBarCornerThin: string; euiFocusRingColor: string; euiFocusRingAnimStartColor: string; euiFocusRingAnimStartSize: string; euiFocusRingAnimStartSizeLarge: string; euiFocusRingSizeLarge: string; euiFocusRingSize: string; euiFocusTransparency: number; euiFocusTransparencyPercent: string; euiFocusBackgroundColor: string; euiTooltipBackgroundColor: string; euiTooltipBorderColor: string; euiTooltipAnimations: { top: string; left: string; bottom: string; right: string; }; euiFontFamily: string; euiCodeFontFamily: string; euiFontFeatureSettings: string; euiTextScale: string; euiFontSize: string; euiFontSizeXS: string; euiFontSizeS: string; euiFontSizeM: string; euiFontSizeL: string; euiFontSizeXL: string; euiFontSizeXXL: string; euiLineHeight: number; euiBodyLineHeight: number; euiTitles: { xxxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; s: { 'font-size': string; 'line-height': string; 'font-weight': number; }; m: { 'font-size': string; 'line-height': string; 'font-weight': number; }; l: { 'font-size': string; 'line-height': string; 'font-weight': number; }; }; euiZLevel0: number; euiZLevel1: number; euiZLevel2: number; euiZLevel3: number; euiZLevel4: number; euiZLevel5: number; euiZLevel6: number; euiZLevel7: number; euiZLevel8: number; euiZLevel9: number; euiZToastList: number; euiZModal: number; euiZMask: number; euiZNavigation: number; euiZContentMenu: number; euiZHeader: number; euiZFlyout: number; euiZMaskBelowHeader: number; euiZContent: number; euiColorGhost: string; euiColorInk: string; euiColorPrimary: string; euiColorAccent: string; euiColorSuccess: string; euiColorWarning: string; euiColorDanger: string; euiColorEmptyShade: string; euiColorLightestShade: string; euiColorLightShade: string; euiColorMediumShade: string; euiColorDarkShade: string; euiColorDarkestShade: string; euiColorFullShade: string; euiPageBackgroundColor: string; euiColorHighlight: string; euiTextColor: string; euiTitleColor: string; euiTextSubduedColor: string; euiColorDisabled: string; euiColorPrimaryText: string; euiColorSuccessText: string; euiColorAccentText: string; euiColorWarningText: string; euiColorDangerText: string; euiColorDisabledText: string; euiLinkColor: string; euiColorChartLines: string; euiColorChartBand: string; euiDatePickerCalendarWidth: string; euiDatePickerPadding: string; euiDatePickerGap: string; euiDatePickerCalendarColumns: number; euiDatePickerButtonSize: string; euiDatePickerMinControlWidth: string; euiDatePickerMaxControlWidth: string; euiButtonDefaultTransparency: number; euiButtonFontWeight: number; euiRangeHighlightColor: string; euiRangeThumbBackgroundColor: string; euiRangeTrackCompressedHeight: string; euiRangeHighlightCompressedHeight: string; euiRangeHeight: string; euiRangeCompressedHeight: string; euiStepStatusColors: { default: string; complete: string; warning: string; danger: string; }; }" ], "path": "packages/kbn-ui-theme/src/theme.ts", "deprecated": false, @@ -112,7 +112,7 @@ "\nEUI Theme vars that automatically adjust to light/dark theme" ], "signature": [ - "{ paddingSizes: { xs: string; s: string; m: string; l: string; xl: string; }; avatarSizing: { s: { size: string; 'font-size': string; }; m: { size: string; 'font-size': string; }; l: { size: string; 'font-size': string; }; xl: { size: string; 'font-size': string; }; }; euiBadgeGroupGutterTypes: { gutterExtraSmall: string; gutterSmall: string; }; euiBreadcrumbSpacing: string; euiBreadcrumbTruncateWidth: string; euiButtonEmptyTypes: { primary: string; danger: string; disabled: string; ghost: string; text: string; success: string; warning: string; }; euiCallOutTypes: { primary: string; success: string; warning: string; danger: string; }; euiCardSpacing: string; euiCardBottomNodeHeight: string; euiCardSelectButtonBorders: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardSelectButtonBackgrounds: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCheckableCardPadding: string; euiCodeBlockPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCollapsibleNavGroupLightBackgroundColor: string; euiCollapsibleNavGroupDarkBackgroundColor: string; euiCollapsibleNavGroupDarkHighContrastColor: string; euiColorPickerValueRange0: string; euiColorPickerValueRange1: string; euiColorPickerSaturationRange0: string; euiColorPickerSaturationRange1: string; euiColorPickerIndicatorSize: string; euiColorPickerWidth: string; euiColorPaletteDisplaySizes: { sizeExtraSmall: string; sizeSmall: string; sizeMedium: string; }; euiContextMenuWidth: string; euiControlBarBackground: string; euiControlBarText: string; euiControlBarBorderColor: string; euiControlBarInitialHeight: string; euiControlBarMaxHeight: string; euiControlBarHeights: { s: string; m: string; l: string; }; euiDataGridPrefix: string; euiDataGridStyles: string; euiZDataGrid: number; euiZHeaderBelowDataGrid: number; euiZDataGridCellPopover: number; euiDataGridColumnResizerWidth: string; euiDataGridPopoverMaxHeight: string; euiDataGridCellPaddingS: string; euiDataGridCellPaddingM: string; euiDataGridCellPaddingL: string; euiDataGridVerticalBorder: string; euiSuperDatePickerWidth: string; euiSuperDatePickerButtonWidth: string; euiDragAndDropSpacing: { s: string; m: string; l: string; }; euiExpressionColors: { subdued: string; primary: string; success: string; warning: string; danger: string; accent: string; }; euiFacetGutterSizes: { gutterNone: number; gutterSmall: string; gutterMedium: string; gutterLarge: string; }; gutterTypes: { gutterExtraSmall: string; gutterSmall: string; gutterMedium: string; gutterLarge: string; gutterExtraLarge: string; }; fractions: { fourths: { percentage: string; count: number; }; thirds: { percentage: string; count: number; }; halves: { percentage: string; count: number; }; single: { percentage: string; count: number; }; }; flyoutSizes: { small: { min: string; width: string; max: string; }; medium: { min: string; width: string; max: string; }; large: { min: string; width: string; max: string; }; }; euiFlyoutBorder: string; euiFlyoutPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiFilePickerTallHeight: string; euiRangeLevelColors: { primary: string; success: string; warning: string; danger: string; }; textareaResizing: { vertical: string; horizontal: string; both: string; none: string; }; euiHeaderLinksGutterSizes: { gutterXS: string; gutterS: string; gutterM: string; gutterL: string; }; ruleMargins: { marginXSmall: string; marginSmall: string; marginMedium: string; marginLarge: string; marginXLarge: string; marginXXLarge: string; }; euiIconLoadingOpacity: number; euiIconColors: { accent: string; danger: string; ghost: string; primary: string; success: string; subdued: string; text: string; warning: string; inherit: string; }; euiIconSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiKeyPadMenuSize: string; euiKeyPadMenuMarginSize: string; euiLinkColors: { subdued: string; primary: string; success: string; accent: string; warning: string; danger: string; text: string; ghost: string; }; euiListGroupItemHoverBackground: string; euiListGroupItemHoverBackgroundGhost: string; euiListGroupGutterTypes: { gutterSmall: string; gutterMedium: string; }; euiListGroupItemColorTypes: { primary: string; text: string; subdued: string; ghost: string; }; euiListGroupItemSizeTypes: { xSmall: string; small: string; medium: string; large: string; }; euiGradientStartStop: string; euiGradientMiddle: string; euiLoadingSpinnerSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiMarkdownEditorMinHeight: string; euiPopoverArrowSize: string; euiPopoverTranslateDistance: string; euiProgressSizes: { xs: string; s: string; m: string; l: string; }; euiProgressColors: { primary: string; success: string; warning: string; danger: string; accent: string; subdued: string; vis0: string; vis1: string; vis2: string; vis3: string; vis4: string; vis5: string; vis6: string; vis7: string; vis8: string; vis9: string; customColor: string; }; euiResizableButtonTransitionSpeed: string; euiResizableButtonSize: string; euiSelectableListItemBorder: string; euiSelectableListItemPadding: string; euiSelectableTemplateSitewideTypes: { application: { color: string; 'font-weight': number; }; deployment: { color: string; 'font-weight': number; }; article: { color: string; 'font-weight': number; }; case: { color: string; 'font-weight': number; }; platform: { color: string; 'font-weight': number; }; }; euiSideNavEmphasizedBackgroundColor: string; euiSideNavRootTextcolor: string; euiSideNavBranchTextcolor: string; euiSideNavSelectedTextcolor: string; euiSideNavDisabledTextcolor: string; spacerSizes: { xs: string; s: string; m: string; l: string; xl: string; xxl: string; }; euiStepNumberSize: string; euiStepNumberSmallSize: string; euiStepNumberMargin: string; euiStepStatusColorsToFade: { warning: string; danger: string; disabled: string; incomplete: string; }; euiSuggestItemColors: { tint0: string; tint1: string; tint2: string; tint3: string; tint4: string; tint5: string; tint6: string; tint7: string; tint8: string; tint9: string; tint10: string; }; euiTableCellContentPadding: string; euiTableCellContentPaddingCompressed: string; euiTableCellCheckboxWidth: string; euiTableActionsAreaWidth: string; euiTableHoverColor: string; euiTableSelectedColor: string; euiTableHoverSelectedColor: string; euiTableActionsBorderColor: string; euiTableHoverClickableColor: string; euiTableFocusClickableColor: string; euiTextColors: { default: string; subdued: string; success: string; accent: string; warning: string; danger: string; ghost: string; inherit: string; }; euiTextConstrainedMaxWidth: string; euiToastWidth: string; euiToastTypes: { primary: string; success: string; warning: string; danger: string; }; euiTokenGrayColor: string; euiTokenTypes: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; gray: { graphic: string; behindText: string; }; }; euiTokenTypeKeys: string; euiContrastRatioText: number; euiContrastRatioGraphic: number; euiContrastRatioDisabled: number; euiAnimSlightBounce: string; euiAnimSlightResistance: string; euiAnimSpeedExtraFast: string; euiAnimSpeedFast: string; euiAnimSpeedNormal: string; euiAnimSpeedSlow: string; euiAnimSpeedExtraSlow: string; euiBorderWidthThin: string; euiBorderWidthThick: string; euiBorderColor: string; euiBorderRadius: string; euiBorderRadiusSmall: string; euiBorderThick: string; euiBorderThin: string; euiBorderEditable: string; euiButtonHeight: string; euiButtonHeightSmall: string; euiButtonHeightXSmall: string; euiButtonColorDisabled: string; euiButtonColorDisabledText: string; euiButtonColorGhostDisabled: string; euiButtonTypes: { primary: string; accent: string; success: string; warning: string; danger: string; subdued: string; ghost: string; text: string; }; euiCodeBlockBackgroundColor: string; euiCodeBlockColor: string; euiCodeBlockSelectedBackgroundColor: string; euiCodeBlockCommentColor: string; euiCodeBlockSelectorTagColor: string; euiCodeBlockStringColor: string; euiCodeBlockTagColor: string; euiCodeBlockNameColor: string; euiCodeBlockNumberColor: string; euiCodeBlockKeywordColor: string; euiCodeBlockFunctionTitleColor: string; euiCodeBlockTypeColor: string; euiCodeBlockAttributeColor: string; euiCodeBlockSymbolColor: string; euiCodeBlockParamsColor: string; euiCodeBlockMetaColor: string; euiCodeBlockTitleColor: string; euiCodeBlockSectionColor: string; euiCodeBlockAdditionColor: string; euiCodeBlockDeletionColor: string; euiCodeBlockSelectorClassColor: string; euiCodeBlockSelectorIdColor: string; euiPaletteColorBlind: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; }; euiPaletteColorBlindKeys: string; euiColorVis0: string; euiColorVis1: string; euiColorVis2: string; euiColorVis3: string; euiColorVis4: string; euiColorVis5: string; euiColorVis6: string; euiColorVis7: string; euiColorVis8: string; euiColorVis9: string; euiColorVis0_behindText: string; euiColorVis1_behindText: string; euiColorVis2_behindText: string; euiColorVis3_behindText: string; euiColorVis4_behindText: string; euiColorVis5_behindText: string; euiColorVis6_behindText: string; euiColorVis7_behindText: string; euiColorVis8_behindText: string; euiColorVis9_behindText: string; euiFontWeightLight: number; euiFontWeightRegular: number; euiFontWeightMedium: number; euiFontWeightSemiBold: number; euiFontWeightBold: number; euiCodeFontWeightRegular: number; euiCodeFontWeightBold: number; euiFormMaxWidth: string; euiFormControlHeight: string; euiFormControlCompressedHeight: string; euiFormControlPadding: string; euiFormControlCompressedPadding: string; euiFormControlBorderRadius: string; euiFormControlCompressedBorderRadius: string; euiRadioSize: string; euiCheckBoxSize: string; euiCheckboxBorderRadius: string; euiSwitchHeight: string; euiSwitchWidth: string; euiSwitchThumbSize: string; euiSwitchIconHeight: string; euiSwitchHeightCompressed: string; euiSwitchWidthCompressed: string; euiSwitchThumbSizeCompressed: string; euiSwitchHeightMini: string; euiSwitchWidthMini: string; euiSwitchThumbSizeMini: string; euiFormBackgroundColor: string; euiFormBackgroundDisabledColor: string; euiFormBackgroundReadOnlyColor: string; euiFormBorderOpaqueColor: string; euiFormBorderColor: string; euiFormBorderDisabledColor: string; euiFormCustomControlDisabledIconColor: string; euiFormCustomControlBorderColor: string; euiFormControlDisabledColor: string; euiFormControlBoxShadow: string; euiFormControlPlaceholderText: string; euiFormInputGroupLabelBackground: string; euiFormInputGroupBorder: string; euiSwitchOffColor: string; euiFormControlLayoutGroupInputHeight: string; euiFormControlLayoutGroupInputCompressedHeight: string; euiFormControlLayoutGroupInputCompressedBorderRadius: string; euiRangeTrackColor: string; euiRangeThumbRadius: string; euiRangeThumbHeight: string; euiRangeThumbWidth: string; euiRangeThumbBorderColor: string; euiRangeTrackWidth: string; euiRangeTrackHeight: string; euiRangeTrackBorderWidth: number; euiRangeTrackBorderColor: string; euiRangeTrackRadius: string; euiRangeDisabledOpacity: number; euiRangeHighlightHeight: string; euiHeaderBackgroundColor: string; euiHeaderDarkBackgroundColor: string; euiHeaderBorderColor: string; euiHeaderBreadcrumbColor: string; euiHeaderHeight: string; euiHeaderChildSize: string; euiHeaderHeightCompensation: string; euiPageDefaultMaxWidth: string; euiPageSidebarMinWidth: string; euiPanelPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiPanelBorderRadiusModifiers: { borderRadiusNone: number; borderRadiusMedium: string; }; euiPanelBackgroundColorModifiers: { transparent: string; plain: string; subdued: string; accent: string; primary: string; success: string; warning: string; danger: string; }; euiBreakpoints: { xs: number; s: string; m: string; l: string; xl: string; }; euiBreakpointKeys: string; euiShadowColor: string; euiShadowColorLarge: string; euiSize: string; euiSizeXS: string; euiSizeS: string; euiSizeM: string; euiSizeL: string; euiSizeXL: string; euiSizeXXL: string; euiButtonMinWidth: string; euiScrollBar: string; euiScrollBarCorner: string; euiScrollBarCornerThin: string; euiFocusRingColor: string; euiFocusRingAnimStartColor: string; euiFocusRingAnimStartSize: string; euiFocusRingAnimStartSizeLarge: string; euiFocusRingSizeLarge: string; euiFocusRingSize: string; euiFocusTransparency: number; euiFocusTransparencyPercent: string; euiFocusBackgroundColor: string; euiTooltipBackgroundColor: string; euiTooltipBorderColor: string; euiTooltipAnimations: { top: string; left: string; bottom: string; right: string; }; euiFontFamily: string; euiCodeFontFamily: string; euiFontFeatureSettings: string; euiTextScale: string; euiFontSize: string; euiFontSizeXS: string; euiFontSizeS: string; euiFontSizeM: string; euiFontSizeL: string; euiFontSizeXL: string; euiFontSizeXXL: string; euiLineHeight: number; euiBodyLineHeight: number; euiTitles: { xxxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; s: { 'font-size': string; 'line-height': string; 'font-weight': number; }; m: { 'font-size': string; 'line-height': string; 'font-weight': number; }; l: { 'font-size': string; 'line-height': string; 'font-weight': number; }; }; euiZLevel0: number; euiZLevel1: number; euiZLevel2: number; euiZLevel3: number; euiZLevel4: number; euiZLevel5: number; euiZLevel6: number; euiZLevel7: number; euiZLevel8: number; euiZLevel9: number; euiZToastList: number; euiZModal: number; euiZMask: number; euiZNavigation: number; euiZContentMenu: number; euiZHeader: number; euiZFlyout: number; euiZMaskBelowHeader: number; euiZContent: number; euiColorGhost: string; euiColorInk: string; euiColorPrimary: string; euiColorAccent: string; euiColorSuccess: string; euiColorWarning: string; euiColorDanger: string; euiColorEmptyShade: string; euiColorLightestShade: string; euiColorLightShade: string; euiColorMediumShade: string; euiColorDarkShade: string; euiColorDarkestShade: string; euiColorFullShade: string; euiPageBackgroundColor: string; euiColorHighlight: string; euiTextColor: string; euiTitleColor: string; euiTextSubduedColor: string; euiColorDisabled: string; euiColorPrimaryText: string; euiColorSuccessText: string; euiColorAccentText: string; euiColorWarningText: string; euiColorDangerText: string; euiColorDisabledText: string; euiLinkColor: string; euiColorChartLines: string; euiColorChartBand: string; euiDatePickerCalendarWidth: string; euiDatePickerPadding: string; euiDatePickerGap: string; euiDatePickerCalendarColumns: number; euiDatePickerButtonSize: string; euiDatePickerMinControlWidth: string; euiDatePickerMaxControlWidth: string; euiButtonDefaultTransparency: number; euiButtonFontWeight: number; euiRangeHighlightColor: string; euiRangeThumbBackgroundColor: string; euiRangeTrackCompressedHeight: string; euiRangeHighlightCompressedHeight: string; euiRangeHeight: string; euiRangeCompressedHeight: string; euiStepStatusColors: { default: string; complete: string; warning: string; danger: string; }; }" + "{ paddingSizes: { xs: string; s: string; m: string; l: string; xl: string; }; euiBadgeGroupGutterTypes: { gutterExtraSmall: string; gutterSmall: string; }; euiBreadcrumbSpacing: string; euiBreadcrumbTruncateWidth: string; euiButtonEmptyTypes: { primary: string; danger: string; disabled: string; ghost: string; text: string; success: string; warning: string; }; euiCallOutTypes: { primary: string; success: string; warning: string; danger: string; }; euiCardSpacing: string; euiCardBottomNodeHeight: string; euiCardSelectButtonBorders: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardSelectButtonBackgrounds: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCheckableCardPadding: string; euiCodeBlockPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCollapsibleNavGroupLightBackgroundColor: string; euiCollapsibleNavGroupDarkBackgroundColor: string; euiCollapsibleNavGroupDarkHighContrastColor: string; euiColorPickerValueRange0: string; euiColorPickerValueRange1: string; euiColorPickerSaturationRange0: string; euiColorPickerSaturationRange1: string; euiColorPickerIndicatorSize: string; euiColorPickerWidth: string; euiColorPaletteDisplaySizes: { sizeExtraSmall: string; sizeSmall: string; sizeMedium: string; }; euiContextMenuWidth: string; euiControlBarBackground: string; euiControlBarText: string; euiControlBarBorderColor: string; euiControlBarInitialHeight: string; euiControlBarMaxHeight: string; euiControlBarHeights: { s: string; m: string; l: string; }; euiDataGridPrefix: string; euiDataGridStyles: string; euiZDataGrid: number; euiZHeaderBelowDataGrid: number; euiZDataGridCellPopover: number; euiDataGridColumnResizerWidth: string; euiDataGridPopoverMaxHeight: string; euiDataGridCellPaddingS: string; euiDataGridCellPaddingM: string; euiDataGridCellPaddingL: string; euiDataGridVerticalBorder: string; euiSuperDatePickerWidth: string; euiSuperDatePickerButtonWidth: string; euiDragAndDropSpacing: { s: string; m: string; l: string; }; euiExpressionColors: { subdued: string; primary: string; success: string; warning: string; danger: string; accent: string; }; euiFacetGutterSizes: { gutterNone: number; gutterSmall: string; gutterMedium: string; gutterLarge: string; }; gutterTypes: { gutterExtraSmall: string; gutterSmall: string; gutterMedium: string; gutterLarge: string; gutterExtraLarge: string; }; fractions: { fourths: { percentage: string; count: number; }; thirds: { percentage: string; count: number; }; halves: { percentage: string; count: number; }; single: { percentage: string; count: number; }; }; flyoutSizes: { small: { min: string; width: string; max: string; }; medium: { min: string; width: string; max: string; }; large: { min: string; width: string; max: string; }; }; euiFlyoutBorder: string; euiFlyoutPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiFilePickerTallHeight: string; euiRangeLevelColors: { primary: string; success: string; warning: string; danger: string; }; textareaResizing: { vertical: string; horizontal: string; both: string; none: string; }; euiHeaderLinksGutterSizes: { gutterXS: string; gutterS: string; gutterM: string; gutterL: string; }; ruleMargins: { marginXSmall: string; marginSmall: string; marginMedium: string; marginLarge: string; marginXLarge: string; marginXXLarge: string; }; euiIconLoadingOpacity: number; euiIconColors: { accent: string; danger: string; ghost: string; primary: string; success: string; subdued: string; text: string; warning: string; inherit: string; }; euiIconSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiKeyPadMenuSize: string; euiKeyPadMenuMarginSize: string; euiLinkColors: { subdued: string; primary: string; success: string; accent: string; warning: string; danger: string; text: string; ghost: string; }; euiListGroupItemHoverBackground: string; euiListGroupItemHoverBackgroundGhost: string; euiListGroupGutterTypes: { gutterSmall: string; gutterMedium: string; }; euiListGroupItemColorTypes: { primary: string; text: string; subdued: string; ghost: string; }; euiListGroupItemSizeTypes: { xSmall: string; small: string; medium: string; large: string; }; euiGradientStartStop: string; euiGradientMiddle: string; euiLoadingSpinnerSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiMarkdownEditorMinHeight: string; euiPopoverArrowSize: string; euiPopoverTranslateDistance: string; euiProgressSizes: { xs: string; s: string; m: string; l: string; }; euiProgressColors: { primary: string; success: string; warning: string; danger: string; accent: string; subdued: string; vis0: string; vis1: string; vis2: string; vis3: string; vis4: string; vis5: string; vis6: string; vis7: string; vis8: string; vis9: string; customColor: string; }; euiResizableButtonTransitionSpeed: string; euiResizableButtonSize: string; euiSelectableListItemBorder: string; euiSelectableListItemPadding: string; euiSelectableTemplateSitewideTypes: { application: { color: string; 'font-weight': number; }; deployment: { color: string; 'font-weight': number; }; article: { color: string; 'font-weight': number; }; case: { color: string; 'font-weight': number; }; platform: { color: string; 'font-weight': number; }; }; euiSideNavEmphasizedBackgroundColor: string; euiSideNavRootTextcolor: string; euiSideNavBranchTextcolor: string; euiSideNavSelectedTextcolor: string; euiSideNavDisabledTextcolor: string; spacerSizes: { xs: string; s: string; m: string; l: string; xl: string; xxl: string; }; euiStepNumberSize: string; euiStepNumberSmallSize: string; euiStepNumberMargin: string; euiStepStatusColorsToFade: { warning: string; danger: string; disabled: string; incomplete: string; }; euiSuggestItemColors: { tint0: string; tint1: string; tint2: string; tint3: string; tint4: string; tint5: string; tint6: string; tint7: string; tint8: string; tint9: string; tint10: string; }; euiTableCellContentPadding: string; euiTableCellContentPaddingCompressed: string; euiTableCellCheckboxWidth: string; euiTableActionsAreaWidth: string; euiTableHoverColor: string; euiTableSelectedColor: string; euiTableHoverSelectedColor: string; euiTableActionsBorderColor: string; euiTableHoverClickableColor: string; euiTableFocusClickableColor: string; euiTextColors: { default: string; subdued: string; success: string; accent: string; warning: string; danger: string; ghost: string; inherit: string; }; euiTextConstrainedMaxWidth: string; euiToastWidth: string; euiToastTypes: { primary: string; success: string; warning: string; danger: string; }; euiTokenGrayColor: string; euiTokenTypes: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; gray: { graphic: string; behindText: string; }; }; euiTokenTypeKeys: string; euiContrastRatioText: number; euiContrastRatioGraphic: number; euiContrastRatioDisabled: number; euiAnimSlightBounce: string; euiAnimSlightResistance: string; euiAnimSpeedExtraFast: string; euiAnimSpeedFast: string; euiAnimSpeedNormal: string; euiAnimSpeedSlow: string; euiAnimSpeedExtraSlow: string; euiBorderWidthThin: string; euiBorderWidthThick: string; euiBorderColor: string; euiBorderRadius: string; euiBorderRadiusSmall: string; euiBorderThick: string; euiBorderThin: string; euiBorderEditable: string; euiButtonHeight: string; euiButtonHeightSmall: string; euiButtonHeightXSmall: string; euiButtonColorDisabled: string; euiButtonColorDisabledText: string; euiButtonColorGhostDisabled: string; euiButtonTypes: { primary: string; accent: string; success: string; warning: string; danger: string; subdued: string; ghost: string; text: string; }; euiCodeBlockBackgroundColor: string; euiCodeBlockColor: string; euiCodeBlockSelectedBackgroundColor: string; euiCodeBlockCommentColor: string; euiCodeBlockSelectorTagColor: string; euiCodeBlockStringColor: string; euiCodeBlockTagColor: string; euiCodeBlockNameColor: string; euiCodeBlockNumberColor: string; euiCodeBlockKeywordColor: string; euiCodeBlockFunctionTitleColor: string; euiCodeBlockTypeColor: string; euiCodeBlockAttributeColor: string; euiCodeBlockSymbolColor: string; euiCodeBlockParamsColor: string; euiCodeBlockMetaColor: string; euiCodeBlockTitleColor: string; euiCodeBlockSectionColor: string; euiCodeBlockAdditionColor: string; euiCodeBlockDeletionColor: string; euiCodeBlockSelectorClassColor: string; euiCodeBlockSelectorIdColor: string; euiPaletteColorBlind: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; }; euiPaletteColorBlindKeys: string; euiColorVis0: string; euiColorVis1: string; euiColorVis2: string; euiColorVis3: string; euiColorVis4: string; euiColorVis5: string; euiColorVis6: string; euiColorVis7: string; euiColorVis8: string; euiColorVis9: string; euiColorVis0_behindText: string; euiColorVis1_behindText: string; euiColorVis2_behindText: string; euiColorVis3_behindText: string; euiColorVis4_behindText: string; euiColorVis5_behindText: string; euiColorVis6_behindText: string; euiColorVis7_behindText: string; euiColorVis8_behindText: string; euiColorVis9_behindText: string; euiFontWeightLight: number; euiFontWeightRegular: number; euiFontWeightMedium: number; euiFontWeightSemiBold: number; euiFontWeightBold: number; euiCodeFontWeightRegular: number; euiCodeFontWeightBold: number; euiFormMaxWidth: string; euiFormControlHeight: string; euiFormControlCompressedHeight: string; euiFormControlPadding: string; euiFormControlCompressedPadding: string; euiFormControlBorderRadius: string; euiFormControlCompressedBorderRadius: string; euiRadioSize: string; euiCheckBoxSize: string; euiCheckboxBorderRadius: string; euiSwitchHeight: string; euiSwitchWidth: string; euiSwitchThumbSize: string; euiSwitchIconHeight: string; euiSwitchHeightCompressed: string; euiSwitchWidthCompressed: string; euiSwitchThumbSizeCompressed: string; euiSwitchHeightMini: string; euiSwitchWidthMini: string; euiSwitchThumbSizeMini: string; euiFormBackgroundColor: string; euiFormBackgroundDisabledColor: string; euiFormBackgroundReadOnlyColor: string; euiFormBorderOpaqueColor: string; euiFormBorderColor: string; euiFormBorderDisabledColor: string; euiFormCustomControlDisabledIconColor: string; euiFormCustomControlBorderColor: string; euiFormControlDisabledColor: string; euiFormControlBoxShadow: string; euiFormControlPlaceholderText: string; euiFormInputGroupLabelBackground: string; euiFormInputGroupBorder: string; euiSwitchOffColor: string; euiFormControlLayoutGroupInputHeight: string; euiFormControlLayoutGroupInputCompressedHeight: string; euiFormControlLayoutGroupInputCompressedBorderRadius: string; euiRangeTrackColor: string; euiRangeThumbRadius: string; euiRangeThumbHeight: string; euiRangeThumbWidth: string; euiRangeThumbBorderColor: string; euiRangeTrackWidth: string; euiRangeTrackHeight: string; euiRangeTrackBorderWidth: number; euiRangeTrackBorderColor: string; euiRangeTrackRadius: string; euiRangeDisabledOpacity: number; euiRangeHighlightHeight: string; euiHeaderBackgroundColor: string; euiHeaderDarkBackgroundColor: string; euiHeaderBorderColor: string; euiHeaderBreadcrumbColor: string; euiHeaderHeight: string; euiHeaderChildSize: string; euiHeaderHeightCompensation: string; euiPageDefaultMaxWidth: string; euiPageSidebarMinWidth: string; euiPanelPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiPanelBorderRadiusModifiers: { borderRadiusNone: number; borderRadiusMedium: string; }; euiPanelBackgroundColorModifiers: { transparent: string; plain: string; subdued: string; accent: string; primary: string; success: string; warning: string; danger: string; }; euiBreakpoints: { xs: number; s: string; m: string; l: string; xl: string; }; euiBreakpointKeys: string; euiShadowColor: string; euiShadowColorLarge: string; euiSize: string; euiSizeXS: string; euiSizeS: string; euiSizeM: string; euiSizeL: string; euiSizeXL: string; euiSizeXXL: string; euiButtonMinWidth: string; euiScrollBar: string; euiScrollBarCorner: string; euiScrollBarCornerThin: string; euiFocusRingColor: string; euiFocusRingAnimStartColor: string; euiFocusRingAnimStartSize: string; euiFocusRingAnimStartSizeLarge: string; euiFocusRingSizeLarge: string; euiFocusRingSize: string; euiFocusTransparency: number; euiFocusTransparencyPercent: string; euiFocusBackgroundColor: string; euiTooltipBackgroundColor: string; euiTooltipBorderColor: string; euiTooltipAnimations: { top: string; left: string; bottom: string; right: string; }; euiFontFamily: string; euiCodeFontFamily: string; euiFontFeatureSettings: string; euiTextScale: string; euiFontSize: string; euiFontSizeXS: string; euiFontSizeS: string; euiFontSizeM: string; euiFontSizeL: string; euiFontSizeXL: string; euiFontSizeXXL: string; euiLineHeight: number; euiBodyLineHeight: number; euiTitles: { xxxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; s: { 'font-size': string; 'line-height': string; 'font-weight': number; }; m: { 'font-size': string; 'line-height': string; 'font-weight': number; }; l: { 'font-size': string; 'line-height': string; 'font-weight': number; }; }; euiZLevel0: number; euiZLevel1: number; euiZLevel2: number; euiZLevel3: number; euiZLevel4: number; euiZLevel5: number; euiZLevel6: number; euiZLevel7: number; euiZLevel8: number; euiZLevel9: number; euiZToastList: number; euiZModal: number; euiZMask: number; euiZNavigation: number; euiZContentMenu: number; euiZHeader: number; euiZFlyout: number; euiZMaskBelowHeader: number; euiZContent: number; euiColorGhost: string; euiColorInk: string; euiColorPrimary: string; euiColorAccent: string; euiColorSuccess: string; euiColorWarning: string; euiColorDanger: string; euiColorEmptyShade: string; euiColorLightestShade: string; euiColorLightShade: string; euiColorMediumShade: string; euiColorDarkShade: string; euiColorDarkestShade: string; euiColorFullShade: string; euiPageBackgroundColor: string; euiColorHighlight: string; euiTextColor: string; euiTitleColor: string; euiTextSubduedColor: string; euiColorDisabled: string; euiColorPrimaryText: string; euiColorSuccessText: string; euiColorAccentText: string; euiColorWarningText: string; euiColorDangerText: string; euiColorDisabledText: string; euiLinkColor: string; euiColorChartLines: string; euiColorChartBand: string; euiDatePickerCalendarWidth: string; euiDatePickerPadding: string; euiDatePickerGap: string; euiDatePickerCalendarColumns: number; euiDatePickerButtonSize: string; euiDatePickerMinControlWidth: string; euiDatePickerMaxControlWidth: string; euiButtonDefaultTransparency: number; euiButtonFontWeight: number; euiRangeHighlightColor: string; euiRangeThumbBackgroundColor: string; euiRangeTrackCompressedHeight: string; euiRangeHighlightCompressedHeight: string; euiRangeHeight: string; euiRangeCompressedHeight: string; euiStepStatusColors: { default: string; complete: string; warning: string; danger: string; }; }" ], "path": "packages/kbn-ui-theme/src/theme.ts", "deprecated": false, diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx index 48796dd5266f6..bb34a249143f0 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/ui-theme plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_utility_types.devdocs.json b/api_docs/kbn_utility_types.devdocs.json index 2734d6eadc135..bb3eb25102399 100644 --- a/api_docs/kbn_utility_types.devdocs.json +++ b/api_docs/kbn_utility_types.devdocs.json @@ -249,6 +249,22 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "@kbn/utility-types", + "id": "def-server.AwaitedProperties", + "type": "Type", + "tags": [], + "label": "AwaitedProperties", + "description": [ + "\nUnwrap all promise attributes of the given type" + ], + "signature": [ + "{ [K in keyof T]: Awaited; }" + ], + "path": "packages/kbn-utility-types/src/index.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "@kbn/utility-types", "id": "def-server.Class", diff --git a/api_docs/kbn_utility_types.mdx b/api_docs/kbn_utility_types.mdx index f000ebff89f1f..5af644c15e127 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/utility-types plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 27 | 0 | 10 | 1 | +| 28 | 0 | 10 | 1 | ## Server diff --git a/api_docs/kbn_utils.mdx b/api_docs/kbn_utils.mdx index 5359a84655647..3ada49f8bdb89 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/utils plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index e61834056f960..155ccdd4f45b8 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github summary: API docs for the kibanaOverview plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kibana_react.devdocs.json b/api_docs/kibana_react.devdocs.json index fa0be3526203f..36fdcb2139cdf 100644 --- a/api_docs/kibana_react.devdocs.json +++ b/api_docs/kibana_react.devdocs.json @@ -885,7 +885,9 @@ "parentPluginId": "kibanaReact", "id": "def-public.KibanaPageTemplate", "type": "Function", - "tags": [], + "tags": [ + "deprecated" + ], "label": "KibanaPageTemplate", "description": [], "signature": [ @@ -900,7 +902,193 @@ ">) => JSX.Element" ], "path": "src/plugins/kibana_react/public/page_template/page_template.tsx", - "deprecated": false, + "deprecated": true, + "references": [ + { + "plugin": "management", + "path": "src/plugins/management/public/components/management_app/management_app.tsx" + }, + { + "plugin": "management", + "path": "src/plugins/management/public/components/management_app/management_app.tsx" + }, + { + "plugin": "management", + "path": "src/plugins/management/public/components/management_app/management_app.tsx" + }, + { + "plugin": "spaces", + "path": "x-pack/plugins/spaces/public/space_selector/space_selector.tsx" + }, + { + "plugin": "spaces", + "path": "x-pack/plugins/spaces/public/space_selector/space_selector.tsx" + }, + { + "plugin": "spaces", + "path": "x-pack/plugins/spaces/public/space_selector/space_selector.tsx" + }, + { + "plugin": "observability", + "path": "x-pack/plugins/observability/public/components/shared/page_template/page_template.tsx" + }, + { + "plugin": "observability", + "path": "x-pack/plugins/observability/public/components/shared/page_template/page_template.tsx" + }, + { + "plugin": "observability", + "path": "x-pack/plugins/observability/public/components/shared/page_template/page_template.tsx" + }, + { + "plugin": "ml", + "path": "x-pack/plugins/ml/public/application/components/ml_page/ml_page.tsx" + }, + { + "plugin": "ml", + "path": "x-pack/plugins/ml/public/application/components/ml_page/ml_page.tsx" + }, + { + "plugin": "ml", + "path": "x-pack/plugins/ml/public/application/components/ml_page/ml_page.tsx" + }, + { + "plugin": "canvas", + "path": "x-pack/plugins/canvas/public/components/home/home.component.tsx" + }, + { + "plugin": "canvas", + "path": "x-pack/plugins/canvas/public/components/home/home.component.tsx" + }, + { + "plugin": "canvas", + "path": "x-pack/plugins/canvas/public/components/home/home.component.tsx" + }, + { + "plugin": "cloudSecurityPosture", + "path": "x-pack/plugins/cloud_security_posture/public/components/csp_page_template.tsx" + }, + { + "plugin": "cloudSecurityPosture", + "path": "x-pack/plugins/cloud_security_posture/public/components/csp_page_template.tsx" + }, + { + "plugin": "cloudSecurityPosture", + "path": "x-pack/plugins/cloud_security_posture/public/components/csp_page_template.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/shared/version_mismatch/version_mismatch_page.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/shared/version_mismatch/version_mismatch_page.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/shared/version_mismatch/version_mismatch_page.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/error_connecting/error_connecting.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/error_connecting/error_connecting.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/error_connecting/error_connecting.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/product_selector/product_selector.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/product_selector/product_selector.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/product_selector/product_selector.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/shared/layout/page_template.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/shared/layout/page_template.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/shared/layout/page_template.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/error_connecting/error_connecting.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/error_connecting/error_connecting.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/error_connecting/error_connecting.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/app_search/components/error_connecting/error_connecting.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/app_search/components/error_connecting/error_connecting.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/app_search/components/error_connecting/error_connecting.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.tsx" + }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/public/components/empty_state.tsx" + }, + { + "plugin": "osquery", + "path": "x-pack/plugins/osquery/public/components/empty_state.tsx" + }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx" + }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx" + }, + { + "plugin": "kibanaOverview", + "path": "src/plugins/kibana_overview/public/components/overview/overview.tsx" + }, + { + "plugin": "kibanaOverview", + "path": "src/plugins/kibana_overview/public/components/overview/overview.tsx" + }, + { + "plugin": "kibanaOverview", + "path": "src/plugins/kibana_overview/public/components/overview/overview.tsx" + } + ], "children": [ { "parentPluginId": "kibanaReact", @@ -1689,44 +1877,44 @@ "path": "x-pack/plugins/index_lifecycle_management/public/application/index.tsx" }, { - "plugin": "upgradeAssistant", - "path": "x-pack/plugins/upgrade_assistant/public/shared_imports.ts" + "plugin": "synthetics", + "path": "x-pack/plugins/synthetics/public/lib/alert_types/alert_messages.tsx" }, { - "plugin": "upgradeAssistant", - "path": "x-pack/plugins/upgrade_assistant/public/application/app.tsx" + "plugin": "synthetics", + "path": "x-pack/plugins/synthetics/public/lib/alert_types/alert_messages.tsx" }, { - "plugin": "upgradeAssistant", - "path": "x-pack/plugins/upgrade_assistant/public/application/app.tsx" + "plugin": "synthetics", + "path": "x-pack/plugins/synthetics/public/lib/alert_types/alert_messages.tsx" }, { - "plugin": "upgradeAssistant", - "path": "x-pack/plugins/upgrade_assistant/public/application/app.tsx" + "plugin": "synthetics", + "path": "x-pack/plugins/synthetics/public/apps/uptime_app.tsx" }, { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/lib/alert_types/alert_messages.tsx" + "plugin": "synthetics", + "path": "x-pack/plugins/synthetics/public/apps/uptime_app.tsx" }, { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/lib/alert_types/alert_messages.tsx" + "plugin": "synthetics", + "path": "x-pack/plugins/synthetics/public/apps/uptime_app.tsx" }, { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/lib/alert_types/alert_messages.tsx" + "plugin": "upgradeAssistant", + "path": "x-pack/plugins/upgrade_assistant/public/shared_imports.ts" }, { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/apps/uptime_app.tsx" + "plugin": "upgradeAssistant", + "path": "x-pack/plugins/upgrade_assistant/public/application/app.tsx" }, { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/apps/uptime_app.tsx" + "plugin": "upgradeAssistant", + "path": "x-pack/plugins/upgrade_assistant/public/application/app.tsx" }, { - "plugin": "uptime", - "path": "x-pack/plugins/uptime/public/apps/uptime_app.tsx" + "plugin": "upgradeAssistant", + "path": "x-pack/plugins/upgrade_assistant/public/application/app.tsx" }, { "plugin": "ux", @@ -3370,6 +3558,25 @@ ], "path": "src/plugins/kibana_react/public/table_list_view/table_list_view.tsx", "deprecated": false + }, + { + "parentPluginId": "kibanaReact", + "id": "def-public.TableListViewProps.application", + "type": "Object", + "tags": [], + "label": "application", + "description": [], + "signature": [ + { + "pluginId": "core", + "scope": "public", + "docId": "kibCoreApplicationPluginApi", + "section": "def-public.ApplicationStart", + "text": "ApplicationStart" + } + ], + "path": "src/plugins/kibana_react/public/table_list_view/table_list_view.tsx", + "deprecated": false } ], "initialIsOpen": false @@ -3884,7 +4091,9 @@ "parentPluginId": "kibanaReact", "id": "def-public.KibanaPageTemplateProps", "type": "Type", - "tags": [], + "tags": [ + "deprecated" + ], "label": "KibanaPageTemplateProps", "description": [ "\nA thin wrapper around EuiPageTemplate with a few Kibana specific additions" @@ -3919,7 +4128,169 @@ " | undefined; }" ], "path": "src/plugins/kibana_react/public/page_template/page_template.tsx", - "deprecated": false, + "deprecated": true, + "references": [ + { + "plugin": "management", + "path": "src/plugins/management/public/components/management_app/management_app.tsx" + }, + { + "plugin": "management", + "path": "src/plugins/management/public/components/management_app/management_app.tsx" + }, + { + "plugin": "observability", + "path": "x-pack/plugins/observability/public/components/shared/page_template/page_template.tsx" + }, + { + "plugin": "observability", + "path": "x-pack/plugins/observability/public/components/shared/page_template/page_template.tsx" + }, + { + "plugin": "observability", + "path": "x-pack/plugins/observability/public/utils/no_data_config.ts" + }, + { + "plugin": "observability", + "path": "x-pack/plugins/observability/public/utils/no_data_config.ts" + }, + { + "plugin": "infra", + "path": "x-pack/plugins/infra/public/pages/logs/page_template.tsx" + }, + { + "plugin": "infra", + "path": "x-pack/plugins/infra/public/pages/logs/page_template.tsx" + }, + { + "plugin": "infra", + "path": "x-pack/plugins/infra/public/pages/metrics/page_template.tsx" + }, + { + "plugin": "infra", + "path": "x-pack/plugins/infra/public/pages/metrics/page_template.tsx" + }, + { + "plugin": "apm", + "path": "x-pack/plugins/apm/public/components/routing/templates/no_data_config.ts" + }, + { + "plugin": "apm", + "path": "x-pack/plugins/apm/public/components/routing/templates/no_data_config.ts" + }, + { + "plugin": "apm", + "path": "x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx" + }, + { + "plugin": "apm", + "path": "x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx" + }, + { + "plugin": "apm", + "path": "x-pack/plugins/apm/public/components/routing/templates/service_group_template.tsx" + }, + { + "plugin": "apm", + "path": "x-pack/plugins/apm/public/components/routing/templates/service_group_template.tsx" + }, + { + "plugin": "cloudSecurityPosture", + "path": "x-pack/plugins/cloud_security_posture/public/components/csp_page_template.tsx" + }, + { + "plugin": "cloudSecurityPosture", + "path": "x-pack/plugins/cloud_security_posture/public/components/csp_page_template.tsx" + }, + { + "plugin": "cloudSecurityPosture", + "path": "x-pack/plugins/cloud_security_posture/public/components/csp_page_template.tsx" + }, + { + "plugin": "cloudSecurityPosture", + "path": "x-pack/plugins/cloud_security_posture/public/components/csp_page_template.tsx" + }, + { + "plugin": "cloudSecurityPosture", + "path": "x-pack/plugins/cloud_security_posture/public/components/csp_page_template.tsx" + }, + { + "plugin": "cloudSecurityPosture", + "path": "x-pack/plugins/cloud_security_posture/public/components/csp_page_template.tsx" + }, + { + "plugin": "cloudSecurityPosture", + "path": "x-pack/plugins/cloud_security_posture/public/components/csp_page_template.tsx" + }, + { + "plugin": "cloudSecurityPosture", + "path": "x-pack/plugins/cloud_security_posture/public/components/csp_page_template.tsx" + }, + { + "plugin": "cloudSecurityPosture", + "path": "x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.tsx" + }, + { + "plugin": "cloudSecurityPosture", + "path": "x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.tsx" + }, + { + "plugin": "cloudSecurityPosture", + "path": "x-pack/plugins/cloud_security_posture/public/pages/rules/index.tsx" + }, + { + "plugin": "cloudSecurityPosture", + "path": "x-pack/plugins/cloud_security_posture/public/pages/rules/index.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/shared/layout/page_template.tsx" + }, + { + "plugin": "enterpriseSearch", + "path": "x-pack/plugins/enterprise_search/public/applications/shared/layout/page_template.tsx" + }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_primary_navigation.tsx" + }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_primary_navigation.tsx" + }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/public/app/home/template_wrapper/bottom_bar/index.tsx" + }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/public/app/home/template_wrapper/bottom_bar/index.tsx" + }, + { + "plugin": "synthetics", + "path": "x-pack/plugins/synthetics/public/apps/use_no_data_config.ts" + }, + { + "plugin": "synthetics", + "path": "x-pack/plugins/synthetics/public/apps/use_no_data_config.ts" + }, + { + "plugin": "ux", + "path": "x-pack/plugins/ux/public/components/app/rum_dashboard/rum_home.tsx" + }, + { + "plugin": "ux", + "path": "x-pack/plugins/ux/public/components/app/rum_dashboard/rum_home.tsx" + }, + { + "plugin": "kibanaOverview", + "path": "src/plugins/kibana_overview/public/components/overview/overview.tsx" + }, + { + "plugin": "kibanaOverview", + "path": "src/plugins/kibana_overview/public/components/overview/overview.tsx" + } + ], "initialIsOpen": false }, { @@ -4333,14 +4704,6 @@ { "plugin": "dashboard", "path": "src/plugins/dashboard/public/plugin.tsx" - }, - { - "plugin": "maps", - "path": "x-pack/plugins/maps/public/connected_components/map_container/map_container.tsx" - }, - { - "plugin": "maps", - "path": "x-pack/plugins/maps/public/connected_components/map_container/map_container.tsx" } ], "initialIsOpen": false @@ -4793,7 +5156,7 @@ "label": "eui", "description": [], "signature": [ - "{ paddingSizes: { xs: string; s: string; m: string; l: string; xl: string; }; avatarSizing: { s: { size: string; 'font-size': string; }; m: { size: string; 'font-size': string; }; l: { size: string; 'font-size': string; }; xl: { size: string; 'font-size': string; }; }; euiBadgeGroupGutterTypes: { gutterExtraSmall: string; gutterSmall: string; }; euiBreadcrumbSpacing: string; euiBreadcrumbTruncateWidth: string; euiButtonEmptyTypes: { primary: string; danger: string; disabled: string; ghost: string; text: string; success: string; warning: string; }; euiCallOutTypes: { primary: string; success: string; warning: string; danger: string; }; euiCardSpacing: string; euiCardBottomNodeHeight: string; euiCardSelectButtonBorders: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardSelectButtonBackgrounds: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCheckableCardPadding: string; euiCodeBlockPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCollapsibleNavGroupLightBackgroundColor: string; euiCollapsibleNavGroupDarkBackgroundColor: string; euiCollapsibleNavGroupDarkHighContrastColor: string; euiColorPickerValueRange0: string; euiColorPickerValueRange1: string; euiColorPickerSaturationRange0: string; euiColorPickerSaturationRange1: string; euiColorPickerIndicatorSize: string; euiColorPickerWidth: string; euiColorPaletteDisplaySizes: { sizeExtraSmall: string; sizeSmall: string; sizeMedium: string; }; euiContextMenuWidth: string; euiControlBarBackground: string; euiControlBarText: string; euiControlBarBorderColor: string; euiControlBarInitialHeight: string; euiControlBarMaxHeight: string; euiControlBarHeights: { s: string; m: string; l: string; }; euiDataGridPrefix: string; euiDataGridStyles: string; euiZDataGrid: number; euiZHeaderBelowDataGrid: number; euiZDataGridCellPopover: number; euiDataGridColumnResizerWidth: string; euiDataGridPopoverMaxHeight: string; euiDataGridCellPaddingS: string; euiDataGridCellPaddingM: string; euiDataGridCellPaddingL: string; euiDataGridVerticalBorder: string; euiSuperDatePickerWidth: string; euiSuperDatePickerButtonWidth: string; euiDragAndDropSpacing: { s: string; m: string; l: string; }; euiExpressionColors: { subdued: string; primary: string; success: string; warning: string; danger: string; accent: string; }; euiFacetGutterSizes: { gutterNone: number; gutterSmall: string; gutterMedium: string; gutterLarge: string; }; gutterTypes: { gutterExtraSmall: string; gutterSmall: string; gutterMedium: string; gutterLarge: string; gutterExtraLarge: string; }; fractions: { fourths: { percentage: string; count: number; }; thirds: { percentage: string; count: number; }; halves: { percentage: string; count: number; }; single: { percentage: string; count: number; }; }; flyoutSizes: { small: { min: string; width: string; max: string; }; medium: { min: string; width: string; max: string; }; large: { min: string; width: string; max: string; }; }; euiFlyoutBorder: string; euiFlyoutPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiFilePickerTallHeight: string; euiRangeLevelColors: { primary: string; success: string; warning: string; danger: string; }; textareaResizing: { vertical: string; horizontal: string; both: string; none: string; }; euiHeaderLinksGutterSizes: { gutterXS: string; gutterS: string; gutterM: string; gutterL: string; }; ruleMargins: { marginXSmall: string; marginSmall: string; marginMedium: string; marginLarge: string; marginXLarge: string; marginXXLarge: string; }; euiIconLoadingOpacity: number; euiIconColors: { accent: string; danger: string; ghost: string; primary: string; success: string; subdued: string; text: string; warning: string; inherit: string; }; euiIconSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiKeyPadMenuSize: string; euiKeyPadMenuMarginSize: string; euiLinkColors: { subdued: string; primary: string; success: string; accent: string; warning: string; danger: string; text: string; ghost: string; }; euiListGroupItemHoverBackground: string; euiListGroupItemHoverBackgroundGhost: string; euiListGroupGutterTypes: { gutterSmall: string; gutterMedium: string; }; euiListGroupItemColorTypes: { primary: string; text: string; subdued: string; ghost: string; }; euiListGroupItemSizeTypes: { xSmall: string; small: string; medium: string; large: string; }; euiGradientStartStop: string; euiGradientMiddle: string; euiLoadingSpinnerSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiMarkdownEditorMinHeight: string; euiPopoverArrowSize: string; euiPopoverTranslateDistance: string; euiProgressSizes: { xs: string; s: string; m: string; l: string; }; euiProgressColors: { primary: string; success: string; warning: string; danger: string; accent: string; subdued: string; vis0: string; vis1: string; vis2: string; vis3: string; vis4: string; vis5: string; vis6: string; vis7: string; vis8: string; vis9: string; customColor: string; }; euiResizableButtonTransitionSpeed: string; euiResizableButtonSize: string; euiSelectableListItemBorder: string; euiSelectableListItemPadding: string; euiSelectableTemplateSitewideTypes: { application: { color: string; 'font-weight': number; }; deployment: { color: string; 'font-weight': number; }; article: { color: string; 'font-weight': number; }; case: { color: string; 'font-weight': number; }; platform: { color: string; 'font-weight': number; }; }; euiSideNavEmphasizedBackgroundColor: string; euiSideNavRootTextcolor: string; euiSideNavBranchTextcolor: string; euiSideNavSelectedTextcolor: string; euiSideNavDisabledTextcolor: string; spacerSizes: { xs: string; s: string; m: string; l: string; xl: string; xxl: string; }; euiStepNumberSize: string; euiStepNumberSmallSize: string; euiStepNumberMargin: string; euiStepStatusColorsToFade: { warning: string; danger: string; disabled: string; incomplete: string; }; euiSuggestItemColors: { tint0: string; tint1: string; tint2: string; tint3: string; tint4: string; tint5: string; tint6: string; tint7: string; tint8: string; tint9: string; tint10: string; }; euiTableCellContentPadding: string; euiTableCellContentPaddingCompressed: string; euiTableCellCheckboxWidth: string; euiTableActionsAreaWidth: string; euiTableHoverColor: string; euiTableSelectedColor: string; euiTableHoverSelectedColor: string; euiTableActionsBorderColor: string; euiTableHoverClickableColor: string; euiTableFocusClickableColor: string; euiTextColors: { default: string; subdued: string; success: string; accent: string; warning: string; danger: string; ghost: string; inherit: string; }; euiTextConstrainedMaxWidth: string; euiToastWidth: string; euiToastTypes: { primary: string; success: string; warning: string; danger: string; }; euiTokenGrayColor: string; euiTokenTypes: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; gray: { graphic: string; behindText: string; }; }; euiTokenTypeKeys: string; euiContrastRatioText: number; euiContrastRatioGraphic: number; euiContrastRatioDisabled: number; euiAnimSlightBounce: string; euiAnimSlightResistance: string; euiAnimSpeedExtraFast: string; euiAnimSpeedFast: string; euiAnimSpeedNormal: string; euiAnimSpeedSlow: string; euiAnimSpeedExtraSlow: string; euiBorderWidthThin: string; euiBorderWidthThick: string; euiBorderColor: string; euiBorderRadius: string; euiBorderRadiusSmall: string; euiBorderThick: string; euiBorderThin: string; euiBorderEditable: string; euiButtonHeight: string; euiButtonHeightSmall: string; euiButtonHeightXSmall: string; euiButtonColorDisabled: string; euiButtonColorDisabledText: string; euiButtonColorGhostDisabled: string; euiButtonTypes: { primary: string; accent: string; success: string; warning: string; danger: string; subdued: string; ghost: string; text: string; }; euiCodeBlockBackgroundColor: string; euiCodeBlockColor: string; euiCodeBlockSelectedBackgroundColor: string; euiCodeBlockCommentColor: string; euiCodeBlockSelectorTagColor: string; euiCodeBlockStringColor: string; euiCodeBlockTagColor: string; euiCodeBlockNameColor: string; euiCodeBlockNumberColor: string; euiCodeBlockKeywordColor: string; euiCodeBlockFunctionTitleColor: string; euiCodeBlockTypeColor: string; euiCodeBlockAttributeColor: string; euiCodeBlockSymbolColor: string; euiCodeBlockParamsColor: string; euiCodeBlockMetaColor: string; euiCodeBlockTitleColor: string; euiCodeBlockSectionColor: string; euiCodeBlockAdditionColor: string; euiCodeBlockDeletionColor: string; euiCodeBlockSelectorClassColor: string; euiCodeBlockSelectorIdColor: string; euiPaletteColorBlind: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; }; euiPaletteColorBlindKeys: string; euiColorVis0: string; euiColorVis1: string; euiColorVis2: string; euiColorVis3: string; euiColorVis4: string; euiColorVis5: string; euiColorVis6: string; euiColorVis7: string; euiColorVis8: string; euiColorVis9: string; euiColorVis0_behindText: string; euiColorVis1_behindText: string; euiColorVis2_behindText: string; euiColorVis3_behindText: string; euiColorVis4_behindText: string; euiColorVis5_behindText: string; euiColorVis6_behindText: string; euiColorVis7_behindText: string; euiColorVis8_behindText: string; euiColorVis9_behindText: string; euiFontWeightLight: number; euiFontWeightRegular: number; euiFontWeightMedium: number; euiFontWeightSemiBold: number; euiFontWeightBold: number; euiCodeFontWeightRegular: number; euiCodeFontWeightBold: number; euiFormMaxWidth: string; euiFormControlHeight: string; euiFormControlCompressedHeight: string; euiFormControlPadding: string; euiFormControlCompressedPadding: string; euiFormControlBorderRadius: string; euiFormControlCompressedBorderRadius: string; euiRadioSize: string; euiCheckBoxSize: string; euiCheckboxBorderRadius: string; euiSwitchHeight: string; euiSwitchWidth: string; euiSwitchThumbSize: string; euiSwitchIconHeight: string; euiSwitchHeightCompressed: string; euiSwitchWidthCompressed: string; euiSwitchThumbSizeCompressed: string; euiSwitchHeightMini: string; euiSwitchWidthMini: string; euiSwitchThumbSizeMini: string; euiFormBackgroundColor: string; euiFormBackgroundDisabledColor: string; euiFormBackgroundReadOnlyColor: string; euiFormBorderOpaqueColor: string; euiFormBorderColor: string; euiFormBorderDisabledColor: string; euiFormCustomControlDisabledIconColor: string; euiFormCustomControlBorderColor: string; euiFormControlDisabledColor: string; euiFormControlBoxShadow: string; euiFormControlPlaceholderText: string; euiFormInputGroupLabelBackground: string; euiFormInputGroupBorder: string; euiSwitchOffColor: string; euiFormControlLayoutGroupInputHeight: string; euiFormControlLayoutGroupInputCompressedHeight: string; euiFormControlLayoutGroupInputCompressedBorderRadius: string; euiRangeTrackColor: string; euiRangeThumbRadius: string; euiRangeThumbHeight: string; euiRangeThumbWidth: string; euiRangeThumbBorderColor: string; euiRangeTrackWidth: string; euiRangeTrackHeight: string; euiRangeTrackBorderWidth: number; euiRangeTrackBorderColor: string; euiRangeTrackRadius: string; euiRangeDisabledOpacity: number; euiRangeHighlightHeight: string; euiHeaderBackgroundColor: string; euiHeaderDarkBackgroundColor: string; euiHeaderBorderColor: string; euiHeaderBreadcrumbColor: string; euiHeaderHeight: string; euiHeaderChildSize: string; euiHeaderHeightCompensation: string; euiPageDefaultMaxWidth: string; euiPageSidebarMinWidth: string; euiPanelPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiPanelBorderRadiusModifiers: { borderRadiusNone: number; borderRadiusMedium: string; }; euiPanelBackgroundColorModifiers: { transparent: string; plain: string; subdued: string; accent: string; primary: string; success: string; warning: string; danger: string; }; euiBreakpoints: { xs: number; s: string; m: string; l: string; xl: string; }; euiBreakpointKeys: string; euiShadowColor: string; euiShadowColorLarge: string; euiSize: string; euiSizeXS: string; euiSizeS: string; euiSizeM: string; euiSizeL: string; euiSizeXL: string; euiSizeXXL: string; euiButtonMinWidth: string; euiScrollBar: string; euiScrollBarCorner: string; euiScrollBarCornerThin: string; euiFocusRingColor: string; euiFocusRingAnimStartColor: string; euiFocusRingAnimStartSize: string; euiFocusRingAnimStartSizeLarge: string; euiFocusRingSizeLarge: string; euiFocusRingSize: string; euiFocusTransparency: number; euiFocusTransparencyPercent: string; euiFocusBackgroundColor: string; euiTooltipBackgroundColor: string; euiTooltipBorderColor: string; euiTooltipAnimations: { top: string; left: string; bottom: string; right: string; }; euiFontFamily: string; euiCodeFontFamily: string; euiFontFeatureSettings: string; euiTextScale: string; euiFontSize: string; euiFontSizeXS: string; euiFontSizeS: string; euiFontSizeM: string; euiFontSizeL: string; euiFontSizeXL: string; euiFontSizeXXL: string; euiLineHeight: number; euiBodyLineHeight: number; euiTitles: { xxxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; s: { 'font-size': string; 'line-height': string; 'font-weight': number; }; m: { 'font-size': string; 'line-height': string; 'font-weight': number; }; l: { 'font-size': string; 'line-height': string; 'font-weight': number; }; }; euiZLevel0: number; euiZLevel1: number; euiZLevel2: number; euiZLevel3: number; euiZLevel4: number; euiZLevel5: number; euiZLevel6: number; euiZLevel7: number; euiZLevel8: number; euiZLevel9: number; euiZToastList: number; euiZModal: number; euiZMask: number; euiZNavigation: number; euiZContentMenu: number; euiZHeader: number; euiZFlyout: number; euiZMaskBelowHeader: number; euiZContent: number; euiColorGhost: string; euiColorInk: string; euiColorPrimary: string; euiColorAccent: string; euiColorSuccess: string; euiColorWarning: string; euiColorDanger: string; euiColorEmptyShade: string; euiColorLightestShade: string; euiColorLightShade: string; euiColorMediumShade: string; euiColorDarkShade: string; euiColorDarkestShade: string; euiColorFullShade: string; euiPageBackgroundColor: string; euiColorHighlight: string; euiTextColor: string; euiTitleColor: string; euiTextSubduedColor: string; euiColorDisabled: string; euiColorPrimaryText: string; euiColorSuccessText: string; euiColorAccentText: string; euiColorWarningText: string; euiColorDangerText: string; euiColorDisabledText: string; euiLinkColor: string; euiColorChartLines: string; euiColorChartBand: string; euiDatePickerCalendarWidth: string; euiDatePickerPadding: string; euiDatePickerGap: string; euiDatePickerCalendarColumns: number; euiDatePickerButtonSize: string; euiDatePickerMinControlWidth: string; euiDatePickerMaxControlWidth: string; euiButtonDefaultTransparency: number; euiButtonFontWeight: number; euiRangeHighlightColor: string; euiRangeThumbBackgroundColor: string; euiRangeTrackCompressedHeight: string; euiRangeHighlightCompressedHeight: string; euiRangeHeight: string; euiRangeCompressedHeight: string; euiStepStatusColors: { default: string; complete: string; warning: string; danger: string; }; }" + "{ paddingSizes: { xs: string; s: string; m: string; l: string; xl: string; }; euiBadgeGroupGutterTypes: { gutterExtraSmall: string; gutterSmall: string; }; euiBreadcrumbSpacing: string; euiBreadcrumbTruncateWidth: string; euiButtonEmptyTypes: { primary: string; danger: string; disabled: string; ghost: string; text: string; success: string; warning: string; }; euiCallOutTypes: { primary: string; success: string; warning: string; danger: string; }; euiCardSpacing: string; euiCardBottomNodeHeight: string; euiCardSelectButtonBorders: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardSelectButtonBackgrounds: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCheckableCardPadding: string; euiCodeBlockPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCollapsibleNavGroupLightBackgroundColor: string; euiCollapsibleNavGroupDarkBackgroundColor: string; euiCollapsibleNavGroupDarkHighContrastColor: string; euiColorPickerValueRange0: string; euiColorPickerValueRange1: string; euiColorPickerSaturationRange0: string; euiColorPickerSaturationRange1: string; euiColorPickerIndicatorSize: string; euiColorPickerWidth: string; euiColorPaletteDisplaySizes: { sizeExtraSmall: string; sizeSmall: string; sizeMedium: string; }; euiContextMenuWidth: string; euiControlBarBackground: string; euiControlBarText: string; euiControlBarBorderColor: string; euiControlBarInitialHeight: string; euiControlBarMaxHeight: string; euiControlBarHeights: { s: string; m: string; l: string; }; euiDataGridPrefix: string; euiDataGridStyles: string; euiZDataGrid: number; euiZHeaderBelowDataGrid: number; euiZDataGridCellPopover: number; euiDataGridColumnResizerWidth: string; euiDataGridPopoverMaxHeight: string; euiDataGridCellPaddingS: string; euiDataGridCellPaddingM: string; euiDataGridCellPaddingL: string; euiDataGridVerticalBorder: string; euiSuperDatePickerWidth: string; euiSuperDatePickerButtonWidth: string; euiDragAndDropSpacing: { s: string; m: string; l: string; }; euiExpressionColors: { subdued: string; primary: string; success: string; warning: string; danger: string; accent: string; }; euiFacetGutterSizes: { gutterNone: number; gutterSmall: string; gutterMedium: string; gutterLarge: string; }; gutterTypes: { gutterExtraSmall: string; gutterSmall: string; gutterMedium: string; gutterLarge: string; gutterExtraLarge: string; }; fractions: { fourths: { percentage: string; count: number; }; thirds: { percentage: string; count: number; }; halves: { percentage: string; count: number; }; single: { percentage: string; count: number; }; }; flyoutSizes: { small: { min: string; width: string; max: string; }; medium: { min: string; width: string; max: string; }; large: { min: string; width: string; max: string; }; }; euiFlyoutBorder: string; euiFlyoutPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiFilePickerTallHeight: string; euiRangeLevelColors: { primary: string; success: string; warning: string; danger: string; }; textareaResizing: { vertical: string; horizontal: string; both: string; none: string; }; euiHeaderLinksGutterSizes: { gutterXS: string; gutterS: string; gutterM: string; gutterL: string; }; ruleMargins: { marginXSmall: string; marginSmall: string; marginMedium: string; marginLarge: string; marginXLarge: string; marginXXLarge: string; }; euiIconLoadingOpacity: number; euiIconColors: { accent: string; danger: string; ghost: string; primary: string; success: string; subdued: string; text: string; warning: string; inherit: string; }; euiIconSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiKeyPadMenuSize: string; euiKeyPadMenuMarginSize: string; euiLinkColors: { subdued: string; primary: string; success: string; accent: string; warning: string; danger: string; text: string; ghost: string; }; euiListGroupItemHoverBackground: string; euiListGroupItemHoverBackgroundGhost: string; euiListGroupGutterTypes: { gutterSmall: string; gutterMedium: string; }; euiListGroupItemColorTypes: { primary: string; text: string; subdued: string; ghost: string; }; euiListGroupItemSizeTypes: { xSmall: string; small: string; medium: string; large: string; }; euiGradientStartStop: string; euiGradientMiddle: string; euiLoadingSpinnerSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiMarkdownEditorMinHeight: string; euiPopoverArrowSize: string; euiPopoverTranslateDistance: string; euiProgressSizes: { xs: string; s: string; m: string; l: string; }; euiProgressColors: { primary: string; success: string; warning: string; danger: string; accent: string; subdued: string; vis0: string; vis1: string; vis2: string; vis3: string; vis4: string; vis5: string; vis6: string; vis7: string; vis8: string; vis9: string; customColor: string; }; euiResizableButtonTransitionSpeed: string; euiResizableButtonSize: string; euiSelectableListItemBorder: string; euiSelectableListItemPadding: string; euiSelectableTemplateSitewideTypes: { application: { color: string; 'font-weight': number; }; deployment: { color: string; 'font-weight': number; }; article: { color: string; 'font-weight': number; }; case: { color: string; 'font-weight': number; }; platform: { color: string; 'font-weight': number; }; }; euiSideNavEmphasizedBackgroundColor: string; euiSideNavRootTextcolor: string; euiSideNavBranchTextcolor: string; euiSideNavSelectedTextcolor: string; euiSideNavDisabledTextcolor: string; spacerSizes: { xs: string; s: string; m: string; l: string; xl: string; xxl: string; }; euiStepNumberSize: string; euiStepNumberSmallSize: string; euiStepNumberMargin: string; euiStepStatusColorsToFade: { warning: string; danger: string; disabled: string; incomplete: string; }; euiSuggestItemColors: { tint0: string; tint1: string; tint2: string; tint3: string; tint4: string; tint5: string; tint6: string; tint7: string; tint8: string; tint9: string; tint10: string; }; euiTableCellContentPadding: string; euiTableCellContentPaddingCompressed: string; euiTableCellCheckboxWidth: string; euiTableActionsAreaWidth: string; euiTableHoverColor: string; euiTableSelectedColor: string; euiTableHoverSelectedColor: string; euiTableActionsBorderColor: string; euiTableHoverClickableColor: string; euiTableFocusClickableColor: string; euiTextColors: { default: string; subdued: string; success: string; accent: string; warning: string; danger: string; ghost: string; inherit: string; }; euiTextConstrainedMaxWidth: string; euiToastWidth: string; euiToastTypes: { primary: string; success: string; warning: string; danger: string; }; euiTokenGrayColor: string; euiTokenTypes: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; gray: { graphic: string; behindText: string; }; }; euiTokenTypeKeys: string; euiContrastRatioText: number; euiContrastRatioGraphic: number; euiContrastRatioDisabled: number; euiAnimSlightBounce: string; euiAnimSlightResistance: string; euiAnimSpeedExtraFast: string; euiAnimSpeedFast: string; euiAnimSpeedNormal: string; euiAnimSpeedSlow: string; euiAnimSpeedExtraSlow: string; euiBorderWidthThin: string; euiBorderWidthThick: string; euiBorderColor: string; euiBorderRadius: string; euiBorderRadiusSmall: string; euiBorderThick: string; euiBorderThin: string; euiBorderEditable: string; euiButtonHeight: string; euiButtonHeightSmall: string; euiButtonHeightXSmall: string; euiButtonColorDisabled: string; euiButtonColorDisabledText: string; euiButtonColorGhostDisabled: string; euiButtonTypes: { primary: string; accent: string; success: string; warning: string; danger: string; subdued: string; ghost: string; text: string; }; euiCodeBlockBackgroundColor: string; euiCodeBlockColor: string; euiCodeBlockSelectedBackgroundColor: string; euiCodeBlockCommentColor: string; euiCodeBlockSelectorTagColor: string; euiCodeBlockStringColor: string; euiCodeBlockTagColor: string; euiCodeBlockNameColor: string; euiCodeBlockNumberColor: string; euiCodeBlockKeywordColor: string; euiCodeBlockFunctionTitleColor: string; euiCodeBlockTypeColor: string; euiCodeBlockAttributeColor: string; euiCodeBlockSymbolColor: string; euiCodeBlockParamsColor: string; euiCodeBlockMetaColor: string; euiCodeBlockTitleColor: string; euiCodeBlockSectionColor: string; euiCodeBlockAdditionColor: string; euiCodeBlockDeletionColor: string; euiCodeBlockSelectorClassColor: string; euiCodeBlockSelectorIdColor: string; euiPaletteColorBlind: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; }; euiPaletteColorBlindKeys: string; euiColorVis0: string; euiColorVis1: string; euiColorVis2: string; euiColorVis3: string; euiColorVis4: string; euiColorVis5: string; euiColorVis6: string; euiColorVis7: string; euiColorVis8: string; euiColorVis9: string; euiColorVis0_behindText: string; euiColorVis1_behindText: string; euiColorVis2_behindText: string; euiColorVis3_behindText: string; euiColorVis4_behindText: string; euiColorVis5_behindText: string; euiColorVis6_behindText: string; euiColorVis7_behindText: string; euiColorVis8_behindText: string; euiColorVis9_behindText: string; euiFontWeightLight: number; euiFontWeightRegular: number; euiFontWeightMedium: number; euiFontWeightSemiBold: number; euiFontWeightBold: number; euiCodeFontWeightRegular: number; euiCodeFontWeightBold: number; euiFormMaxWidth: string; euiFormControlHeight: string; euiFormControlCompressedHeight: string; euiFormControlPadding: string; euiFormControlCompressedPadding: string; euiFormControlBorderRadius: string; euiFormControlCompressedBorderRadius: string; euiRadioSize: string; euiCheckBoxSize: string; euiCheckboxBorderRadius: string; euiSwitchHeight: string; euiSwitchWidth: string; euiSwitchThumbSize: string; euiSwitchIconHeight: string; euiSwitchHeightCompressed: string; euiSwitchWidthCompressed: string; euiSwitchThumbSizeCompressed: string; euiSwitchHeightMini: string; euiSwitchWidthMini: string; euiSwitchThumbSizeMini: string; euiFormBackgroundColor: string; euiFormBackgroundDisabledColor: string; euiFormBackgroundReadOnlyColor: string; euiFormBorderOpaqueColor: string; euiFormBorderColor: string; euiFormBorderDisabledColor: string; euiFormCustomControlDisabledIconColor: string; euiFormCustomControlBorderColor: string; euiFormControlDisabledColor: string; euiFormControlBoxShadow: string; euiFormControlPlaceholderText: string; euiFormInputGroupLabelBackground: string; euiFormInputGroupBorder: string; euiSwitchOffColor: string; euiFormControlLayoutGroupInputHeight: string; euiFormControlLayoutGroupInputCompressedHeight: string; euiFormControlLayoutGroupInputCompressedBorderRadius: string; euiRangeTrackColor: string; euiRangeThumbRadius: string; euiRangeThumbHeight: string; euiRangeThumbWidth: string; euiRangeThumbBorderColor: string; euiRangeTrackWidth: string; euiRangeTrackHeight: string; euiRangeTrackBorderWidth: number; euiRangeTrackBorderColor: string; euiRangeTrackRadius: string; euiRangeDisabledOpacity: number; euiRangeHighlightHeight: string; euiHeaderBackgroundColor: string; euiHeaderDarkBackgroundColor: string; euiHeaderBorderColor: string; euiHeaderBreadcrumbColor: string; euiHeaderHeight: string; euiHeaderChildSize: string; euiHeaderHeightCompensation: string; euiPageDefaultMaxWidth: string; euiPageSidebarMinWidth: string; euiPanelPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiPanelBorderRadiusModifiers: { borderRadiusNone: number; borderRadiusMedium: string; }; euiPanelBackgroundColorModifiers: { transparent: string; plain: string; subdued: string; accent: string; primary: string; success: string; warning: string; danger: string; }; euiBreakpoints: { xs: number; s: string; m: string; l: string; xl: string; }; euiBreakpointKeys: string; euiShadowColor: string; euiShadowColorLarge: string; euiSize: string; euiSizeXS: string; euiSizeS: string; euiSizeM: string; euiSizeL: string; euiSizeXL: string; euiSizeXXL: string; euiButtonMinWidth: string; euiScrollBar: string; euiScrollBarCorner: string; euiScrollBarCornerThin: string; euiFocusRingColor: string; euiFocusRingAnimStartColor: string; euiFocusRingAnimStartSize: string; euiFocusRingAnimStartSizeLarge: string; euiFocusRingSizeLarge: string; euiFocusRingSize: string; euiFocusTransparency: number; euiFocusTransparencyPercent: string; euiFocusBackgroundColor: string; euiTooltipBackgroundColor: string; euiTooltipBorderColor: string; euiTooltipAnimations: { top: string; left: string; bottom: string; right: string; }; euiFontFamily: string; euiCodeFontFamily: string; euiFontFeatureSettings: string; euiTextScale: string; euiFontSize: string; euiFontSizeXS: string; euiFontSizeS: string; euiFontSizeM: string; euiFontSizeL: string; euiFontSizeXL: string; euiFontSizeXXL: string; euiLineHeight: number; euiBodyLineHeight: number; euiTitles: { xxxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; s: { 'font-size': string; 'line-height': string; 'font-weight': number; }; m: { 'font-size': string; 'line-height': string; 'font-weight': number; }; l: { 'font-size': string; 'line-height': string; 'font-weight': number; }; }; euiZLevel0: number; euiZLevel1: number; euiZLevel2: number; euiZLevel3: number; euiZLevel4: number; euiZLevel5: number; euiZLevel6: number; euiZLevel7: number; euiZLevel8: number; euiZLevel9: number; euiZToastList: number; euiZModal: number; euiZMask: number; euiZNavigation: number; euiZContentMenu: number; euiZHeader: number; euiZFlyout: number; euiZMaskBelowHeader: number; euiZContent: number; euiColorGhost: string; euiColorInk: string; euiColorPrimary: string; euiColorAccent: string; euiColorSuccess: string; euiColorWarning: string; euiColorDanger: string; euiColorEmptyShade: string; euiColorLightestShade: string; euiColorLightShade: string; euiColorMediumShade: string; euiColorDarkShade: string; euiColorDarkestShade: string; euiColorFullShade: string; euiPageBackgroundColor: string; euiColorHighlight: string; euiTextColor: string; euiTitleColor: string; euiTextSubduedColor: string; euiColorDisabled: string; euiColorPrimaryText: string; euiColorSuccessText: string; euiColorAccentText: string; euiColorWarningText: string; euiColorDangerText: string; euiColorDisabledText: string; euiLinkColor: string; euiColorChartLines: string; euiColorChartBand: string; euiDatePickerCalendarWidth: string; euiDatePickerPadding: string; euiDatePickerGap: string; euiDatePickerCalendarColumns: number; euiDatePickerButtonSize: string; euiDatePickerMinControlWidth: string; euiDatePickerMaxControlWidth: string; euiButtonDefaultTransparency: number; euiButtonFontWeight: number; euiRangeHighlightColor: string; euiRangeThumbBackgroundColor: string; euiRangeTrackCompressedHeight: string; euiRangeHighlightCompressedHeight: string; euiRangeHeight: string; euiRangeCompressedHeight: string; euiStepStatusColors: { default: string; complete: string; warning: string; danger: string; }; }" ], "path": "src/plugins/kibana_react/common/eui_styled_components.tsx", "deprecated": false diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index 60767318538de..3def8e96dfcf8 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github summary: API docs for the kibanaReact plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 239 | 0 | 203 | 5 | +| 240 | 0 | 204 | 5 | ## Client diff --git a/api_docs/kibana_utils.devdocs.json b/api_docs/kibana_utils.devdocs.json index 18bb3b4a35d4a..ff686632d0f4a 100644 --- a/api_docs/kibana_utils.devdocs.json +++ b/api_docs/kibana_utils.devdocs.json @@ -7606,6 +7606,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -7680,7 +7684,9 @@ "section": "def-server.ResponseErrorAttributes", "text": "ResponseErrorAttributes" }, - " | undefined; }>" + " | undefined; } | Buffer | ", + "Stream", + ">" ], "path": "src/plugins/kibana_utils/server/report_server_error.ts", "deprecated": false, @@ -7821,6 +7827,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx index e049912e4e732..b639f92c9c96c 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github summary: API docs for the kibanaUtils plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaUtils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/lens.devdocs.json b/api_docs/lens.devdocs.json index 53b0ee481dc97..ae98881027a3b 100644 --- a/api_docs/lens.devdocs.json +++ b/api_docs/lens.devdocs.json @@ -335,13 +335,7 @@ "label": "palette", "description": [], "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, + "PaletteOutput", "<{ [key: string]: unknown; }>" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", @@ -491,7 +485,7 @@ "section": "def-common.Datatable", "text": "Datatable" }, - "> | undefined) => Record<\"enabled\" | \"disabled\", { kuery: ", + "> | undefined) => Record<\"disabled\" | \"enabled\", { kuery: ", "Query", "[][]; lucene: ", "Query", @@ -1958,13 +1952,7 @@ "label": "palette", "description": [], "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, + "PaletteOutput", "<{ [key: string]: unknown; }> | undefined" ], "path": "x-pack/plugins/lens/common/types.ts", @@ -2403,13 +2391,7 @@ "label": "mainPalette", "description": [], "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, + "PaletteOutput", "<{ [key: string]: unknown; }> | undefined" ], "path": "x-pack/plugins/lens/public/types.ts", @@ -2615,7 +2597,7 @@ "label": "params", "description": [], "signature": [ - "{ size: number; orderBy: { type: \"alphabetical\"; fallback?: boolean | undefined; } | { type: \"rare\"; maxDocCount: number; } | { type: \"column\"; columnId: string; }; orderDirection: \"asc\" | \"desc\"; otherBucket?: boolean | undefined; missingBucket?: boolean | undefined; secondaryFields?: string[] | undefined; format?: ", + "{ size: number; accuracyMode?: boolean | undefined; orderBy: { type: \"alphabetical\"; fallback?: boolean | undefined; } | { type: \"rare\"; maxDocCount: number; } | { type: \"column\"; columnId: string; }; orderDirection: \"asc\" | \"desc\"; otherBucket?: boolean | undefined; missingBucket?: boolean | undefined; secondaryFields?: string[] | undefined; format?: ", "ValueFormatConfig", " | undefined; parentFormat?: { id: string; } | undefined; }" ], @@ -2708,13 +2690,7 @@ ], "signature": [ "(addNewLayer: () => string, state?: T | undefined, mainPalette?: ", - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, + "PaletteOutput", "<{ [key: string]: unknown; }> | undefined) => T" ], "path": "x-pack/plugins/lens/public/types.ts", @@ -2756,13 +2732,7 @@ "label": "mainPalette", "description": [], "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, + "PaletteOutput", "<{ [key: string]: unknown; }> | undefined" ], "path": "x-pack/plugins/lens/public/types.ts", @@ -2781,13 +2751,7 @@ "description": [], "signature": [ "((state: T) => ", - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, + "PaletteOutput", "<{ [key: string]: unknown; }> | undefined) | undefined" ], "path": "x-pack/plugins/lens/public/types.ts", @@ -3805,15 +3769,9 @@ "label": "toExpression", "description": [], "signature": [ - "(state: T, datasourceLayers: Record, attributes?: Partial<{ title: string; description: string; }> | undefined) => string | ", + "(state: T, datasourceLayers: ", + "DatasourceLayers", + ", attributes?: Partial<{ title: string; description: string; }> | undefined) => string | ", { "pluginId": "expressions", "scope": "common", @@ -3848,15 +3806,7 @@ "label": "datasourceLayers", "description": [], "signature": [ - "Record" + "DatasourceLayers" ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, @@ -3889,15 +3839,9 @@ "\nExpression to render a preview version of the chart in very constrained space.\nIf there is no expression provided, the preview icon is used." ], "signature": [ - "((state: T, datasourceLayers: Record) => string | ", + "((state: T, datasourceLayers: ", + "DatasourceLayers", + ") => string | ", { "pluginId": "expressions", "scope": "common", @@ -3932,15 +3876,7 @@ "label": "datasourceLayers", "description": [], "signature": [ - "Record" + "DatasourceLayers" ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, @@ -3959,15 +3895,9 @@ "\nThe frame will call this function on all visualizations at few stages (pre-build/build error) in order\nto provide more context to the error and show it to the user" ], "signature": [ - "(state: T, datasourceLayers?: Record | undefined) => { shortMessage: string; longMessage: React.ReactNode; }[] | undefined" + "(state: T, datasourceLayers?: ", + "DatasourceLayers", + " | undefined) => { shortMessage: string; longMessage: React.ReactNode; }[] | undefined" ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, @@ -3994,15 +3924,8 @@ "label": "datasourceLayers", "description": [], "signature": [ - "Record | undefined" + "DatasourceLayers", + " | undefined" ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, @@ -4822,13 +4745,7 @@ "label": "palette", "description": [], "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, + "PaletteOutput", "<{ [key: string]: unknown; }> | undefined" ], "path": "x-pack/plugins/lens/public/xy_visualization/types.ts", @@ -7445,37 +7362,13 @@ "description": [], "signature": [ "{ columns: { palette?: ", - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, + "PaletteOutput", "<", - { - "pluginId": "lens", - "scope": "common", - "docId": "kibLensPluginApi", - "section": "def-common.CustomPaletteParams", - "text": "CustomPaletteParams" - }, + "CustomPaletteParams", "> | undefined; colorMode?: \"none\" | \"text\" | \"cell\" | undefined; }[]; } | { palette?: ", - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, + "PaletteOutput", "<", - { - "pluginId": "lens", - "scope": "common", - "docId": "kibLensPluginApi", - "section": "def-common.CustomPaletteParams", - "text": "CustomPaletteParams" - }, + "CustomPaletteParams", "> | undefined; }" ], "path": "x-pack/plugins/lens/server/migrations/types.ts", @@ -7769,203 +7662,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "lens", - "id": "def-common.ColorStop", - "type": "Interface", - "tags": [], - "label": "ColorStop", - "description": [], - "path": "x-pack/plugins/lens/common/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "lens", - "id": "def-common.ColorStop.color", - "type": "string", - "tags": [], - "label": "color", - "description": [], - "path": "x-pack/plugins/lens/common/types.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-common.ColorStop.stop", - "type": "number", - "tags": [], - "label": "stop", - "description": [], - "path": "x-pack/plugins/lens/common/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "lens", - "id": "def-common.CustomPaletteParams", - "type": "Interface", - "tags": [], - "label": "CustomPaletteParams", - "description": [], - "path": "x-pack/plugins/lens/common/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "lens", - "id": "def-common.CustomPaletteParams.name", - "type": "string", - "tags": [], - "label": "name", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "x-pack/plugins/lens/common/types.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-common.CustomPaletteParams.reverse", - "type": "CompoundType", - "tags": [], - "label": "reverse", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "x-pack/plugins/lens/common/types.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-common.CustomPaletteParams.rangeType", - "type": "CompoundType", - "tags": [], - "label": "rangeType", - "description": [], - "signature": [ - "\"number\" | \"percent\" | undefined" - ], - "path": "x-pack/plugins/lens/common/types.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-common.CustomPaletteParams.continuity", - "type": "CompoundType", - "tags": [], - "label": "continuity", - "description": [], - "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteContinuity", - "text": "PaletteContinuity" - }, - " | undefined" - ], - "path": "x-pack/plugins/lens/common/types.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-common.CustomPaletteParams.progression", - "type": "string", - "tags": [], - "label": "progression", - "description": [], - "signature": [ - "\"fixed\" | undefined" - ], - "path": "x-pack/plugins/lens/common/types.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-common.CustomPaletteParams.rangeMin", - "type": "number", - "tags": [], - "label": "rangeMin", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "x-pack/plugins/lens/common/types.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-common.CustomPaletteParams.rangeMax", - "type": "number", - "tags": [], - "label": "rangeMax", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "x-pack/plugins/lens/common/types.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-common.CustomPaletteParams.stops", - "type": "Array", - "tags": [], - "label": "stops", - "description": [], - "signature": [ - { - "pluginId": "lens", - "scope": "common", - "docId": "kibLensPluginApi", - "section": "def-common.ColorStop", - "text": "ColorStop" - }, - "[] | undefined" - ], - "path": "x-pack/plugins/lens/common/types.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-common.CustomPaletteParams.colorStops", - "type": "Array", - "tags": [], - "label": "colorStops", - "description": [], - "signature": [ - { - "pluginId": "lens", - "scope": "common", - "docId": "kibLensPluginApi", - "section": "def-common.ColorStop", - "text": "ColorStop" - }, - "[] | undefined" - ], - "path": "x-pack/plugins/lens/common/types.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-common.CustomPaletteParams.steps", - "type": "number", - "tags": [], - "label": "steps", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "x-pack/plugins/lens/common/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "lens", "id": "def-common.DateRange", @@ -8271,21 +7967,9 @@ "label": "palette", "description": [], "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, + "PaletteOutput", "<", - { - "pluginId": "lens", - "scope": "common", - "docId": "kibLensPluginApi", - "section": "def-common.CustomPaletteParams", - "text": "CustomPaletteParams" - }, + "CustomPaletteParams", "> | undefined" ], "path": "x-pack/plugins/lens/common/types.ts", @@ -8527,13 +8211,7 @@ "label": "palette", "description": [], "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, + "PaletteOutput", "<{ [key: string]: unknown; }> | undefined" ], "path": "x-pack/plugins/lens/common/types.ts", @@ -8833,13 +8511,7 @@ "label": "CustomPaletteParamsConfig", "description": [], "signature": [ - { - "pluginId": "lens", - "scope": "common", - "docId": "kibLensPluginApi", - "section": "def-common.CustomPaletteParams", - "text": "CustomPaletteParams" - }, + "CustomPaletteParams", " & { maxSteps?: number | undefined; }" ], "path": "x-pack/plugins/lens/common/types.ts", @@ -9083,28 +8755,6 @@ "deprecated": false, "initialIsOpen": false }, - { - "parentPluginId": "lens", - "id": "def-common.RequiredPaletteParamTypes", - "type": "Type", - "tags": [], - "label": "RequiredPaletteParamTypes", - "description": [], - "signature": [ - "Required<", - { - "pluginId": "lens", - "scope": "common", - "docId": "kibLensPluginApi", - "section": "def-common.CustomPaletteParams", - "text": "CustomPaletteParams" - }, - "> & { maxSteps?: number | undefined; }" - ], - "path": "x-pack/plugins/lens/common/types.ts", - "deprecated": false, - "initialIsOpen": false - }, { "parentPluginId": "lens", "id": "def-common.SortingHint", diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index 2974c7140ed53..13b19ffe60e56 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github summary: API docs for the lens plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 542 | 0 | 467 | 29 | +| 527 | 0 | 452 | 30 | ## Client diff --git a/api_docs/license_api_guard.devdocs.json b/api_docs/license_api_guard.devdocs.json index 3cb1dbcca2a83..06339738fe611 100644 --- a/api_docs/license_api_guard.devdocs.json +++ b/api_docs/license_api_guard.devdocs.json @@ -230,6 +230,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -420,6 +424,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -638,6 +646,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index ff9b643e9d694..875d654c0267b 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github summary: API docs for the licenseApiGuard plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseApiGuard'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/license_management.mdx b/api_docs/license_management.mdx index f2ad339d8c0d8..d81ae2975260d 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github summary: API docs for the licenseManagement plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/licensing.devdocs.json b/api_docs/licensing.devdocs.json index 7d63612c554c2..264859dfa2e6a 100644 --- a/api_docs/licensing.devdocs.json +++ b/api_docs/licensing.devdocs.json @@ -1037,6 +1037,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -1227,6 +1231,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", @@ -1449,6 +1457,8 @@ "section": "def-server.ResponseError", "text": "ResponseError" }, + " | Buffer | ", + "Stream", ">) => ", "KibanaResponse", "; redirected: (options: ", + " | undefined; } | Buffer | ", + "Stream", + ">; redirected: (options: ", { "pluginId": "core", "scope": "server", diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index e9208ee1f9f8e..cb395af82c70a 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github summary: API docs for the licensing plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/lists.devdocs.json b/api_docs/lists.devdocs.json index 950e244c88b49..a2134a2c8ffb3 100644 --- a/api_docs/lists.devdocs.json +++ b/api_docs/lists.devdocs.json @@ -311,7 +311,7 @@ "label": "exceptionItems", "description": [], "signature": [ - "({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]" + "({ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | ({ description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; })[]; list_id: string; name: string; type: \"simple\"; } & { comments?: { comment: string; }[] | undefined; item_id?: string | undefined; meta?: object | undefined; namespace_type?: \"single\" | \"agnostic\" | undefined; os_types?: (\"windows\" | \"linux\" | \"macos\")[] | undefined; tags?: string[] | undefined; }))[]" ], "path": "x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.tsx", "deprecated": false @@ -324,7 +324,7 @@ "label": "exceptionsToDelete", "description": [], "signature": [ - "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]" + "{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]" ], "path": "x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.tsx", "deprecated": false @@ -463,7 +463,9 @@ "type": "Class", "tags": [], "label": "ExceptionListClient", - "description": [], + "description": [ + "\nClass for use for exceptions that are with trusted applications or\nwith rules." + ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, "children": [ @@ -473,7 +475,9 @@ "type": "Function", "tags": [], "label": "Constructor", - "description": [], + "description": [ + "\nConstructs the exception list" + ], "signature": [ "any" ], @@ -501,12 +505,7 @@ "parentPluginId": "lists", "id": "def-server.ExceptionListClient.getExceptionList", "type": "Function", - "tags": [ - "params", - "params", - "params", - "return" - ], + "tags": [], "label": "getExceptionList", "description": [ "\nFetch an exception list parent container" @@ -535,20 +534,14 @@ } ], "returnComment": [ - "the found exception list or null if none exists" + "The found exception list or null if none exists" ] }, { "parentPluginId": "lists", "id": "def-server.ExceptionListClient.getExceptionListSummary", "type": "Function", - "tags": [ - "params", - "params", - "params", - "params", - "return" - ], + "tags": [], "label": "getExceptionListSummary", "description": [ "\nFetch an exception list parent container" @@ -577,19 +570,14 @@ } ], "returnComment": [ - "summary of exception list item os types" + "Summary of exception list item os types" ] }, { "parentPluginId": "lists", "id": "def-server.ExceptionListClient.getExceptionListItem", "type": "Function", - "tags": [ - "params", - "params", - "params", - "return" - ], + "tags": [], "label": "getExceptionListItem", "description": [ "\nFetch an exception list item container" @@ -597,7 +585,7 @@ "signature": [ "({ itemId, id, namespaceType, }: ", "GetExceptionListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -655,7 +643,9 @@ "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The exception list schema or null if it does not exist" + ] }, { "parentPluginId": "lists", @@ -669,7 +659,7 @@ "signature": [ "({ comments, description, entries, itemId, meta, name, osTypes, tags, type, }: ", "CreateEndpointListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -689,7 +679,9 @@ "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The exception list item created, otherwise null if not created" + ] }, { "parentPluginId": "lists", @@ -703,7 +695,7 @@ "signature": [ "({ _version, comments, description, entries, id, itemId, meta, name, osTypes, tags, type, }: ", "UpdateEndpointListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -723,7 +715,9 @@ "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The exception list item updated, otherwise null if not updated" + ] }, { "parentPluginId": "lists", @@ -737,7 +731,7 @@ "signature": [ "({ itemId, id, }: ", "GetEndpointListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -757,24 +751,15 @@ "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The exception list item found, otherwise null" + ] }, { "parentPluginId": "lists", "id": "def-server.ExceptionListClient.createExceptionList", "type": "Function", - "tags": [ - "params", - "params", - "params", - "params", - "params", - "params", - "params", - "params", - "params", - "return" - ], + "tags": [], "label": "createExceptionList", "description": [ "\nCreate an exception list container" @@ -810,19 +795,7 @@ "parentPluginId": "lists", "id": "def-server.ExceptionListClient.updateExceptionList", "type": "Function", - "tags": [ - "params", - "params", - "params", - "params", - "params", - "params", - "params", - "params", - "params", - "params", - "return" - ], + "tags": [], "label": "updateExceptionList", "description": [ "\nUpdate an existing exception list container" @@ -858,12 +831,7 @@ "parentPluginId": "lists", "id": "def-server.ExceptionListClient.deleteExceptionList", "type": "Function", - "tags": [ - "params", - "params", - "params", - "return" - ], + "tags": [], "label": "deleteExceptionList", "description": [ "\nDelete an exception list container by either id or list_id" @@ -899,19 +867,7 @@ "parentPluginId": "lists", "id": "def-server.ExceptionListClient.createExceptionListItem", "type": "Function", - "tags": [ - "params", - "params", - "params", - "params", - "params", - "params", - "params", - "params", - "params", - "params", - "return" - ], + "tags": [], "label": "createExceptionListItem", "description": [ "\nCreate an exception list item container" @@ -925,7 +881,7 @@ "section": "def-server.CreateExceptionListItemOptions", "text": "CreateExceptionListItemOptions" }, - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -959,21 +915,7 @@ "parentPluginId": "lists", "id": "def-server.ExceptionListClient.updateExceptionListItem", "type": "Function", - "tags": [ - "params", - "params", - "params", - "params", - "params", - "params", - "params", - "params", - "params", - "params", - "params", - "params", - "return" - ], + "tags": [], "label": "updateExceptionListItem", "description": [ "\nUpdate an existing exception list item" @@ -987,7 +929,7 @@ "section": "def-server.UpdateExceptionListItemOptions", "text": "UpdateExceptionListItemOptions" }, - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1021,12 +963,7 @@ "parentPluginId": "lists", "id": "def-server.ExceptionListClient.deleteExceptionListItem", "type": "Function", - "tags": [ - "params", - "params", - "params", - "return" - ], + "tags": [], "label": "deleteExceptionListItem", "description": [ "\nDelete an exception list item by either id or item_id" @@ -1034,7 +971,7 @@ "signature": [ "({ id, itemId, namespaceType, }: ", "DeleteExceptionListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1062,11 +999,7 @@ "parentPluginId": "lists", "id": "def-server.ExceptionListClient.deleteExceptionListItemById", "type": "Function", - "tags": [ - "params", - "params", - "return" - ], + "tags": [], "label": "deleteExceptionListItemById", "description": [ "\nDelete an exception list item by id" @@ -1103,12 +1036,12 @@ "tags": [], "label": "deleteEndpointListItem", "description": [ - "\nThis is the same as \"deleteExceptionListItem\" except it applies specifically to the endpoint list." + "\nThis is the same as \"deleteExceptionListItem\" except it applies specifically to the endpoint list.\nEither id or itemId has to be defined to delete but not both is required. If both are provided, the id\nis preferred." ], "signature": [ "({ id, itemId, }: ", "DeleteEndpointListItemOptions", - ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" + ") => Promise<{ _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1136,11 +1069,13 @@ "type": "Function", "tags": [], "label": "findExceptionListItem", - "description": [], + "description": [ + "\nFinds an exception list item given a set of criteria." + ], "signature": [ "({ listId, filter, perPage, pit, page, searchAfter, sortField, sortOrder, namespaceType, }: ", "FindExceptionListItemOptions", - ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" + ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1160,7 +1095,9 @@ "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The found exception list items or null if nothing is found" + ] }, { "parentPluginId": "lists", @@ -1168,11 +1105,13 @@ "type": "Function", "tags": [], "label": "findExceptionListsItem", - "description": [], + "description": [ + "\nFinds exception lists items given a set of criteria." + ], "signature": [ "({ listId, filter, perPage, pit, page, searchAfter, sortField, sortOrder, namespaceType, }: ", "FindExceptionListsItemOptions", - ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" + ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1192,7 +1131,9 @@ "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The found exception lists items or null if nothing is found" + ] }, { "parentPluginId": "lists", @@ -1200,11 +1141,13 @@ "type": "Function", "tags": [], "label": "findValueListExceptionListItems", - "description": [], + "description": [ + "\nFinds value list exception items given a set of criteria." + ], "signature": [ "({ perPage, pit, page, searchAfter, sortField, sortOrder, valueListId, }: ", "FindValueListExceptionListsItems", - ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" + ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1224,7 +1167,9 @@ "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The found value list exception list item or null if nothing is found" + ] }, { "parentPluginId": "lists", @@ -1232,7 +1177,9 @@ "type": "Function", "tags": [], "label": "findExceptionList", - "description": [], + "description": [ + "\nFinds exception lists given a set of criteria." + ], "signature": [ "({ filter, perPage, page, pit, searchAfter, sortField, sortOrder, namespaceType, }: ", "FindExceptionListOptions", @@ -1256,7 +1203,9 @@ "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The found exception lists or null if nothing is found" + ] }, { "parentPluginId": "lists", @@ -1270,7 +1219,7 @@ "signature": [ "({ filter, perPage, page, pit, searchAfter, sortField, sortOrder, }: ", "FindEndpointListItemOptions", - ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" + ") => Promise<({ data: { _version: string | undefined; comments: ({ comment: string; created_at: string; created_by: string; id: string; } & { updated_at?: string | undefined; updated_by?: string | undefined; })[]; created_at: string; created_by: string; description: string; entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]; id: string; item_id: string; list_id: string; meta: object | undefined; name: string; namespace_type: \"single\" | \"agnostic\"; os_types: (\"windows\" | \"linux\" | \"macos\")[]; tags: string[]; tie_breaker_id: string; type: \"simple\"; updated_at: string; updated_by: string; }[]; page: number; per_page: number; total: number; } & { pit?: string | undefined; }) | null>" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts", "deprecated": false, @@ -1290,18 +1239,15 @@ "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The found exception list items or null if nothing is found" + ] }, { "parentPluginId": "lists", "id": "def-server.ExceptionListClient.exportExceptionListAndItems", "type": "Function", - "tags": [ - "params", - "params", - "params", - "return" - ], + "tags": [], "label": "exportExceptionListAndItems", "description": [ "\nExport an exception list parent container and it's items" @@ -1345,12 +1291,7 @@ "parentPluginId": "lists", "id": "def-server.ExceptionListClient.importExceptionListAndItems", "type": "Function", - "tags": [ - "params", - "params", - "params", - "return" - ], + "tags": [], "label": "importExceptionListAndItems", "description": [ "\nImport exception lists parent containers and items as stream" @@ -1386,12 +1327,7 @@ "parentPluginId": "lists", "id": "def-server.ExceptionListClient.importExceptionListAndItemsAsArray", "type": "Function", - "tags": [ - "params", - "params", - "params", - "return" - ], + "tags": [], "label": "importExceptionListAndItemsAsArray", "description": [ "\nImport exception lists parent containers and items as array" @@ -1427,11 +1363,7 @@ "parentPluginId": "lists", "id": "def-server.ExceptionListClient.openPointInTime", "type": "Function", - "tags": [ - "params", - "params", - "return" - ], + "tags": [], "label": "openPointInTime", "description": [ "\nOpens a point in time (PIT) for either exception lists or exception list items.\nSee: https://www.elastic.co/guide/en/elasticsearch/reference/current/point-in-time-api.html" @@ -1475,10 +1407,7 @@ "parentPluginId": "lists", "id": "def-server.ExceptionListClient.closePointInTime", "type": "Function", - "tags": [ - "params", - "return" - ], + "tags": [], "label": "closePointInTime", "description": [ "\nCloses a point in time (PIT) for either exception lists or exception list items.\nSee: https://www.elastic.co/guide/en/elasticsearch/reference/current/point-in-time-api.html" @@ -1663,7 +1592,9 @@ "type": "Class", "tags": [], "label": "ListClient", - "description": [], + "description": [ + "\nClass for use for value lists are are associated with exception lists.\nSee {@link https://www.elastic.co/guide/en/security/current/lists-api-create-container.html}" + ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [ @@ -1673,7 +1604,9 @@ "type": "Function", "tags": [], "label": "Constructor", - "description": [], + "description": [ + "\nConstructs the value list" + ], "signature": [ "any" ], @@ -1703,14 +1636,18 @@ "type": "Function", "tags": [], "label": "getListIndex", - "description": [], + "description": [ + "\nReturns the list index name" + ], "signature": [ "() => string" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The list index name" + ] }, { "parentPluginId": "lists", @@ -1718,14 +1655,18 @@ "type": "Function", "tags": [], "label": "getListItemIndex", - "description": [], + "description": [ + "\nReturns the list item index name" + ], "signature": [ "() => string" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The list item index name" + ] }, { "parentPluginId": "lists", @@ -1733,11 +1674,13 @@ "type": "Function", "tags": [], "label": "getList", - "description": [], + "description": [ + "\nGiven a list id, this will return the list container" + ], "signature": [ "({ id }: ", "GetListOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1757,7 +1700,9 @@ "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The List container if found, otherwise null" + ] }, { "parentPluginId": "lists", @@ -1765,11 +1710,13 @@ "type": "Function", "tags": [], "label": "createList", - "description": [], + "description": [ + "\nCreates a list, if given at least the \"name\", \"description\", \"type\", and \"version\"\nSee {@link https://www.elastic.co/guide/en/security/current/lists-api-create-container.html}\nfor more information around formats of the deserializer and serializer" + ], "signature": [ "({ id, deserializer, immutable, serializer, name, description, type, meta, version, }: ", "CreateListOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1789,7 +1736,9 @@ "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The list created" + ] }, { "parentPluginId": "lists", @@ -1797,11 +1746,13 @@ "type": "Function", "tags": [], "label": "createListIfItDoesNotExist", - "description": [], + "description": [ + "\nCreates a list, if given at least the \"name\", \"description\", \"type\", and \"version\"\nSee {@link https://www.elastic.co/guide/en/security/current/lists-api-create-container.html}\nfor more information around formats of the deserializer and serializer.\nThis will create the list if it does not exist. If the list exists, this will ignore creating\nanything and just return the existing list." + ], "signature": [ "({ id, deserializer, serializer, name, description, immutable, type, meta, version, }: ", "CreateListIfItDoesNotExistOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -1821,7 +1772,9 @@ "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The list created" + ] }, { "parentPluginId": "lists", @@ -1829,14 +1782,18 @@ "type": "Function", "tags": [], "label": "getListIndexExists", - "description": [], + "description": [ + "\nTrue if the list index exists, otherwise false" + ], "signature": [ "() => Promise" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "True if the list index exists, otherwise false" + ] }, { "parentPluginId": "lists", @@ -1844,14 +1801,18 @@ "type": "Function", "tags": [], "label": "getListItemIndexExists", - "description": [], + "description": [ + "\nTrue if the list index item exists, otherwise false" + ], "signature": [ "() => Promise" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "True if the list item index exists, otherwise false" + ] }, { "parentPluginId": "lists", @@ -1859,14 +1820,18 @@ "type": "Function", "tags": [], "label": "createListBootStrapIndex", - "description": [], + "description": [ + "\nCreates the list boot strap index for ILM policies." + ], "signature": [ "() => Promise" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The contents of the bootstrap response from Elasticsearch" + ] }, { "parentPluginId": "lists", @@ -1874,14 +1839,18 @@ "type": "Function", "tags": [], "label": "createListItemBootStrapIndex", - "description": [], + "description": [ + "\nCreates the list item boot strap index for ILM policies." + ], "signature": [ "() => Promise" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The contents of the bootstrap response from Elasticsearch" + ] }, { "parentPluginId": "lists", @@ -1889,14 +1858,18 @@ "type": "Function", "tags": [], "label": "getListPolicyExists", - "description": [], + "description": [ + "\nReturns true if the list policy for ILM exists, otherwise false" + ], "signature": [ "() => Promise" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "True if the list policy for ILM exists, otherwise false." + ] }, { "parentPluginId": "lists", @@ -1904,14 +1877,18 @@ "type": "Function", "tags": [], "label": "getListItemPolicyExists", - "description": [], + "description": [ + "\nReturns true if the list item policy for ILM exists, otherwise false" + ], "signature": [ "() => Promise" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "True if the list item policy for ILM exists, otherwise false." + ] }, { "parentPluginId": "lists", @@ -1919,14 +1896,18 @@ "type": "Function", "tags": [], "label": "getListTemplateExists", - "description": [], + "description": [ + "\nReturns true if the list template for ILM exists, otherwise false" + ], "signature": [ "() => Promise" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "True if the list template for ILM exists, otherwise false." + ] }, { "parentPluginId": "lists", @@ -1934,14 +1915,18 @@ "type": "Function", "tags": [], "label": "getListItemTemplateExists", - "description": [], + "description": [ + "\nReturns true if the list item template for ILM exists, otherwise false" + ], "signature": [ "() => Promise" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "True if the list item template for ILM exists, otherwise false." + ] }, { "parentPluginId": "lists", @@ -1949,14 +1934,18 @@ "type": "Function", "tags": [], "label": "getListTemplate", - "description": [], + "description": [ + "\nReturns the list template for ILM." + ], "signature": [ "() => Record" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The contents of the list template for ILM." + ] }, { "parentPluginId": "lists", @@ -1964,14 +1953,18 @@ "type": "Function", "tags": [], "label": "getListItemTemplate", - "description": [], + "description": [ + "\nReturns the list item template for ILM." + ], "signature": [ "() => Record" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The contents of the list item template for ILM." + ] }, { "parentPluginId": "lists", @@ -1979,14 +1972,18 @@ "type": "Function", "tags": [], "label": "setListTemplate", - "description": [], + "description": [ + "\nSets the list template for ILM." + ], "signature": [ "() => Promise" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The contents of the list template for ILM." + ] }, { "parentPluginId": "lists", @@ -1994,14 +1991,18 @@ "type": "Function", "tags": [], "label": "setListItemTemplate", - "description": [], + "description": [ + "\nSets the list item template for ILM." + ], "signature": [ "() => Promise" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The contents of the list item template for ILM." + ] }, { "parentPluginId": "lists", @@ -2009,14 +2010,18 @@ "type": "Function", "tags": [], "label": "setListPolicy", - "description": [], + "description": [ + "\nSets the list policy" + ], "signature": [ "() => Promise" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The contents of the list policy set" + ] }, { "parentPluginId": "lists", @@ -2024,14 +2029,18 @@ "type": "Function", "tags": [], "label": "setListItemPolicy", - "description": [], + "description": [ + "\nSets the list item policy" + ], "signature": [ "() => Promise" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The contents of the list policy set" + ] }, { "parentPluginId": "lists", @@ -2039,14 +2048,18 @@ "type": "Function", "tags": [], "label": "deleteListIndex", - "description": [], + "description": [ + "\nDeletes the list index" + ], "signature": [ "() => Promise" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "True if the list index was deleted, otherwise false" + ] }, { "parentPluginId": "lists", @@ -2054,14 +2067,18 @@ "type": "Function", "tags": [], "label": "deleteListItemIndex", - "description": [], + "description": [ + "\nDeletes the list item index" + ], "signature": [ "() => Promise" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "True if the list item index was deleted, otherwise false" + ] }, { "parentPluginId": "lists", @@ -2069,14 +2086,18 @@ "type": "Function", "tags": [], "label": "deleteListPolicy", - "description": [], + "description": [ + "\nDeletes the list policy" + ], "signature": [ "() => Promise" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The contents of the list policy" + ] }, { "parentPluginId": "lists", @@ -2084,14 +2105,18 @@ "type": "Function", "tags": [], "label": "deleteListItemPolicy", - "description": [], + "description": [ + "\nDeletes the list item policy" + ], "signature": [ "() => Promise" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The contents of the list item policy" + ] }, { "parentPluginId": "lists", @@ -2099,14 +2124,18 @@ "type": "Function", "tags": [], "label": "deleteListTemplate", - "description": [], + "description": [ + "\nDeletes the list template" + ], "signature": [ "() => Promise" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The contents of the list template" + ] }, { "parentPluginId": "lists", @@ -2114,14 +2143,18 @@ "type": "Function", "tags": [], "label": "deleteListItemTemplate", - "description": [], + "description": [ + "\nDeletes the list item template" + ], "signature": [ "() => Promise" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, "children": [], - "returnComment": [] + "returnComment": [ + "The contents of the list item template" + ] }, { "parentPluginId": "lists", @@ -2129,11 +2162,13 @@ "type": "Function", "tags": [], "label": "deleteListItem", - "description": [], + "description": [ + "\nGiven a list item id, this will delete the single list item" + ], "signature": [ "({ id }: ", "DeleteListItemOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2153,7 +2188,9 @@ "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The list item if found, otherwise null" + ] }, { "parentPluginId": "lists", @@ -2161,11 +2198,13 @@ "type": "Function", "tags": [], "label": "deleteListItemByValue", - "description": [], + "description": [ + "\nGiven a list value, this will delete all list items that have that value" + ], "signature": [ "({ listId, value, type, }: ", "DeleteListItemByValueOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; }[]>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; }[]>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2185,7 +2224,9 @@ "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The list items deleted." + ] }, { "parentPluginId": "lists", @@ -2193,11 +2234,13 @@ "type": "Function", "tags": [], "label": "deleteList", - "description": [], + "description": [ + "\nGiven a list id, this will delete the list from the id" + ], "signature": [ "({ id }: ", "DeleteListOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2217,7 +2260,9 @@ "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The list deleted if found, otherwise null" + ] }, { "parentPluginId": "lists", @@ -2225,7 +2270,9 @@ "type": "Function", "tags": [], "label": "exportListItemsToStream", - "description": [], + "description": [ + "\nExports list items to a stream" + ], "signature": [ "({ stringToAppend, listId, stream, }: ", "ExportListItemsToStreamOptions", @@ -2257,11 +2304,13 @@ "type": "Function", "tags": [], "label": "importListItemsToStream", - "description": [], + "description": [ + "\nImports list items to a stream. If the list already exists, this will append the list items to the existing list.\nIf the list does not exist, this will auto-create the list and then add the items to that list.\nSee {@link https://www.elastic.co/guide/en/security/current/lists-api-create-container.html}\nfor more information around formats of the deserializer and serializer." + ], "signature": [ "({ deserializer, serializer, type, listId, stream, meta, version, }: ", "ImportListItemsToStreamOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2289,11 +2338,13 @@ "type": "Function", "tags": [], "label": "getListItemByValue", - "description": [], + "description": [ + "\nReturns all list items found by value." + ], "signature": [ "({ listId, value, type, }: ", "GetListItemByValueOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; }[]>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; }[]>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2313,7 +2364,9 @@ "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The list items by value found." + ] }, { "parentPluginId": "lists", @@ -2321,11 +2374,13 @@ "type": "Function", "tags": [], "label": "createListItem", - "description": [], + "description": [ + "\nCreates a list item given at least \"value\", \"type\", and a \"listId\" where \"listId\" is the parent container that this list\nitem belongs to.\nSee {@link https://www.elastic.co/guide/en/security/current/lists-api-create-container.html}\nfor more information around formats of the deserializer and serializer." + ], "signature": [ "({ id, deserializer, serializer, listId, value, type, meta, }: ", "CreateListItemOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2353,11 +2408,13 @@ "type": "Function", "tags": [], "label": "updateListItem", - "description": [], + "description": [ + "\nUpdates a list item's value given the id of the list item.\nSee {@link https://www.elastic.co/guide/en/elasticsearch/reference/current/optimistic-concurrency-control.html}\nfor more information around optimistic concurrency control." + ], "signature": [ "({ _version, id, value, meta, }: ", "UpdateListItemOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2385,11 +2442,13 @@ "type": "Function", "tags": [], "label": "updateList", - "description": [], + "description": [ + "\nUpdates a list container's value given the id of the list.\nSee {@link https://www.elastic.co/guide/en/elasticsearch/reference/current/optimistic-concurrency-control.html}\nfor more information around optimistic concurrency control." + ], "signature": [ "({ _version, id, name, description, meta, version, }: ", "UpdateListOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2417,11 +2476,13 @@ "type": "Function", "tags": [], "label": "getListItem", - "description": [], + "description": [ + "\nGiven a list item id, this returns the list item if it exists, otherwise \"null\"." + ], "signature": [ "({ id }: ", "GetListItemOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; } | null>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2441,7 +2502,9 @@ "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "The list item found if it exists, otherwise \"null\"." + ] }, { "parentPluginId": "lists", @@ -2449,11 +2512,13 @@ "type": "Function", "tags": [], "label": "getListItemByValues", - "description": [], + "description": [ + "\nGiven a list item value, this returns all list items found with that value." + ], "signature": [ "({ type, listId, value, }: ", "GetListItemsByValueOptions", - ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; }[]>" + ") => Promise<{ _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; }[]>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2473,7 +2538,9 @@ "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "All list items that match the value sent in." + ] }, { "parentPluginId": "lists", @@ -2481,11 +2548,13 @@ "type": "Function", "tags": [], "label": "searchListItemByValues", - "description": [], + "description": [ + "\nGiven a list item value, this search for all list items found with that value." + ], "signature": [ "({ type, listId, value, }: ", "SearchListItemByValuesOptions", - ") => Promise<{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }[]>" + ") => Promise<{ items: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; }[]; value: unknown; }[]>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2505,7 +2574,9 @@ "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "All list items that match the value sent in." + ] }, { "parentPluginId": "lists", @@ -2513,11 +2584,13 @@ "type": "Function", "tags": [], "label": "findList", - "description": [], + "description": [ + "\nFinds lists based on a filter passed in. This is a bit complicated as it existed before\nPIT (Point in Time) and other mechanisms. This uses an older way of doing \"hops\" and\naccepting a \"currentIndexPosition\" which acts like a pointer to where the search should continue." + ], "signature": [ "({ filter, currentIndexPosition, perPage, page, sortField, sortOrder, searchAfter, }: ", "FindListOptions", - ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" + ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; description: string; deserializer: string | undefined; id: string; immutable: boolean; meta: object | undefined; name: string; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; version: number; }[]; page: number; per_page: number; total: number; }>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2537,7 +2610,9 @@ "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "All lists found based on the passed in filter." + ] }, { "parentPluginId": "lists", @@ -2545,11 +2620,13 @@ "type": "Function", "tags": [], "label": "findListItem", - "description": [], + "description": [ + "\nFinds list items based on a filter passed in. This is a bit complicated as it existed before\nPIT (Point in Time) and other mechanisms. This uses an older way of doing \"hops\" and\naccepting a \"currentIndexPosition\" which acts like a pointer to where the search should continue." + ], "signature": [ "({ listId, filter, currentIndexPosition, perPage, page, sortField, sortOrder, searchAfter, }: ", "FindListItemOptions", - ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; }[]; page: number; per_page: number; total: number; } | null>" + ") => Promise<{ cursor: string; data: { _version: string | undefined; created_at: string; created_by: string; deserializer: string | undefined; id: string; list_id: string; meta: object | undefined; serializer: string | undefined; tie_breaker_id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; updated_at: string; updated_by: string; value: string; }[]; page: number; per_page: number; total: number; } | null>" ], "path": "x-pack/plugins/lists/server/services/lists/list_client.ts", "deprecated": false, @@ -2569,7 +2646,9 @@ "isRequired": true } ], - "returnComment": [] + "returnComment": [ + "All list items found based on the passed in filter." + ] } ], "initialIsOpen": false @@ -2583,7 +2662,9 @@ "type": "Interface", "tags": [], "label": "CreateExceptionListItemOptions", - "description": [], + "description": [ + "\nExceptionListClient.createExceptionListItem\n{@link ExceptionListClient.createExceptionListItem}" + ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts", "deprecated": false, "children": [ @@ -2593,7 +2674,9 @@ "type": "Array", "tags": [], "label": "comments", - "description": [], + "description": [ + "User comments for the exception list item" + ], "signature": [ "{ comment: string; }[]" ], @@ -2606,9 +2689,11 @@ "type": "Array", "tags": [], "label": "entries", - "description": [], + "description": [ + "an array with the exception list item entries" + ], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts", "deprecated": false @@ -2619,7 +2704,9 @@ "type": "string", "tags": [], "label": "itemId", - "description": [], + "description": [ + "the \"item_id\" of the exception list item" + ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts", "deprecated": false }, @@ -2629,7 +2716,9 @@ "type": "string", "tags": [], "label": "listId", - "description": [], + "description": [ + "the \"list_id\" of the parent exception list" + ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts", "deprecated": false }, @@ -2639,7 +2728,9 @@ "type": "CompoundType", "tags": [], "label": "namespaceType", - "description": [], + "description": [ + "saved object namespace (single | agnostic)" + ], "signature": [ "\"single\" | \"agnostic\"" ], @@ -2652,7 +2743,9 @@ "type": "string", "tags": [], "label": "name", - "description": [], + "description": [ + "the \"name\" of the exception list" + ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts", "deprecated": false }, @@ -2662,7 +2755,9 @@ "type": "Array", "tags": [], "label": "osTypes", - "description": [], + "description": [ + "item os types to apply" + ], "signature": [ "(\"windows\" | \"linux\" | \"macos\")[]" ], @@ -2675,7 +2770,9 @@ "type": "string", "tags": [], "label": "description", - "description": [], + "description": [ + "a description of the exception list" + ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts", "deprecated": false }, @@ -2685,7 +2782,9 @@ "type": "Uncategorized", "tags": [], "label": "meta", - "description": [], + "description": [ + "Optional meta data about the list item" + ], "signature": [ "object | undefined" ], @@ -2698,7 +2797,9 @@ "type": "Array", "tags": [], "label": "tags", - "description": [], + "description": [ + "user assigned tags of exception list" + ], "signature": [ "string[]" ], @@ -2711,7 +2812,9 @@ "type": "string", "tags": [], "label": "type", - "description": [], + "description": [ + "container type" + ], "signature": [ "\"simple\"" ], @@ -2836,7 +2939,9 @@ "type": "Interface", "tags": [], "label": "UpdateExceptionListItemOptions", - "description": [], + "description": [ + "\nExceptionListClient.updateExceptionListItem\n{@link ExceptionListClient.updateExceptionListItem}" + ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts", "deprecated": false, "children": [ @@ -2846,7 +2951,9 @@ "type": "string", "tags": [], "label": "_version", - "description": [], + "description": [ + "document version" + ], "signature": [ "string | undefined" ], @@ -2859,7 +2966,9 @@ "type": "Array", "tags": [], "label": "comments", - "description": [], + "description": [ + "user comments attached to item" + ], "signature": [ "({ comment: string; } & { id?: string | undefined; })[]" ], @@ -2872,9 +2981,11 @@ "type": "Array", "tags": [], "label": "entries", - "description": [], + "description": [ + "item exception entries logic" + ], "signature": [ - "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"text\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" + "({ field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; } | { field: string; list: { id: string; type: \"boolean\" | \"keyword\" | \"ip\" | \"text\" | \"date\" | \"geo_point\" | \"geo_shape\" | \"binary\" | \"date_nanos\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"half_float\" | \"double\" | \"integer_range\" | \"float_range\" | \"long_range\" | \"double_range\" | \"date_range\" | \"ip_range\" | \"shape\"; }; operator: \"excluded\" | \"included\"; type: \"list\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { entries: ({ field: string; operator: \"excluded\" | \"included\"; type: \"exists\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match\"; value: string; } | { field: string; operator: \"excluded\" | \"included\"; type: \"match_any\"; value: string[]; })[]; field: string; type: \"nested\"; } | { field: string; operator: \"excluded\" | \"included\"; type: \"wildcard\"; value: string; })[]" ], "path": "x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts", "deprecated": false @@ -2885,7 +2996,9 @@ "type": "string", "tags": [], "label": "id", - "description": [], + "description": [ + "the \"id\" of the exception list item" + ], "signature": [ "string | undefined" ], @@ -2898,7 +3011,9 @@ "type": "string", "tags": [], "label": "itemId", - "description": [], + "description": [ + "the \"item_id\" of the exception list item" + ], "signature": [ "string | undefined" ], @@ -2911,7 +3026,9 @@ "type": "CompoundType", "tags": [], "label": "namespaceType", - "description": [], + "description": [ + "saved object namespace (single | agnostic)" + ], "signature": [ "\"single\" | \"agnostic\"" ], @@ -2924,7 +3041,9 @@ "type": "string", "tags": [], "label": "name", - "description": [], + "description": [ + "the \"name\" of the exception list" + ], "signature": [ "string | undefined" ], @@ -2937,7 +3056,9 @@ "type": "Array", "tags": [], "label": "osTypes", - "description": [], + "description": [ + "item os types to apply" + ], "signature": [ "(\"windows\" | \"linux\" | \"macos\")[]" ], @@ -2950,7 +3071,9 @@ "type": "string", "tags": [], "label": "description", - "description": [], + "description": [ + "a description of the exception list" + ], "signature": [ "string | undefined" ], @@ -2963,7 +3086,9 @@ "type": "Uncategorized", "tags": [], "label": "meta", - "description": [], + "description": [ + "Optional meta data about the exception list item" + ], "signature": [ "object | undefined" ], @@ -2976,7 +3101,9 @@ "type": "Array", "tags": [], "label": "tags", - "description": [], + "description": [ + "user assigned tags of exception list" + ], "signature": [ "string[] | undefined" ], @@ -2989,7 +3116,9 @@ "type": "string", "tags": [], "label": "type", - "description": [], + "description": [ + "container type" + ], "signature": [ "\"simple\" | undefined" ], diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 4be9824f833d2..d41261a0cd841 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github summary: API docs for the lists plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Security detections response](https://github.com/orgs/elastic/teams/sec | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 198 | 0 | 162 | 49 | +| 198 | 0 | 90 | 49 | ## Client diff --git a/api_docs/management.mdx b/api_docs/management.mdx index 3f6a113909a8b..30294c621c92c 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github summary: API docs for the management plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/maps.devdocs.json b/api_docs/maps.devdocs.json index 7b25903f0b349..63493ac786c58 100644 --- a/api_docs/maps.devdocs.json +++ b/api_docs/maps.devdocs.json @@ -80,29 +80,8 @@ "label": "getMeta", "description": [], "signature": [ - "() => Partial<", - "DataFilters", - " & { applyGlobalQuery: boolean; applyGlobalTime: boolean; applyForceRefresh: boolean; fieldNames: string[]; geogridPrecision?: number | undefined; timesliceMaskField?: string | undefined; sourceQuery?: ", - "Query", - " | undefined; sourceMeta: object | null; isForceRefresh: boolean; } & ", - "VectorJoinSourceRequestMeta", - " & { dynamicStyleFields: string[]; isTimeAware: boolean; sourceQuery: ", - "Query", - "; timeFilters: ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataQueryPluginApi", - "section": "def-common.TimeRange", - "text": "TimeRange" - }, - "; } & ", - "ESSearchSourceResponseMeta", - " & ", - "ESGeoLineSourceResponseMeta", - " & ", - "VectorTileLayerMeta", - ">" + "() => ", + "DataRequestMeta" ], "path": "x-pack/plugins/maps/public/classes/util/data_request.ts", "deprecated": false, @@ -1188,6 +1167,20 @@ ], "path": "x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx", "deprecated": false + }, + { + "parentPluginId": "maps", + "id": "def-public.BoundsRequestMeta.joinKeyFilter", + "type": "Object", + "tags": [], + "label": "joinKeyFilter", + "description": [], + "signature": [ + "Filter", + " | undefined" + ], + "path": "x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx", + "deprecated": false } ], "initialIsOpen": false @@ -3051,7 +3044,7 @@ "label": "SourceEditorArgs", "description": [], "signature": [ - "{ clearJoins: () => void; currentLayerType: string; hasJoins: boolean; onChange: (...args: ", + "{ currentLayerType: string; numberOfJoins: number; onChange: (...args: ", "OnSourceChangeArgs", "[]) => Promise; }" ], diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index ae9babe656796..980ecd53f8ee9 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github summary: API docs for the maps plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [GIS](https://github.com/orgs/elastic/teams/kibana-gis) for questions re | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 223 | 0 | 222 | 27 | +| 224 | 0 | 223 | 25 | ## Client diff --git a/api_docs/maps_ems.devdocs.json b/api_docs/maps_ems.devdocs.json index 18ef0a3cf340b..0649ee441acdf 100644 --- a/api_docs/maps_ems.devdocs.json +++ b/api_docs/maps_ems.devdocs.json @@ -88,7 +88,7 @@ "label": "MapConfig", "description": [], "signature": [ - "{ readonly tilemap: Readonly<{ url?: string | undefined; } & { options: Readonly<{ default?: boolean | undefined; tileSize?: number | undefined; subdomains?: string[] | undefined; errorTileUrl?: string | undefined; tms?: boolean | undefined; reuseTiles?: boolean | undefined; bounds?: number[] | undefined; } & { attribution: string; minZoom: number; maxZoom: number; }>; }>; readonly includeElasticMapsService: boolean; readonly emsUrl: string; readonly emsFileApiUrl: string; readonly emsTileApiUrl: string; readonly emsLandingPageUrl: string; readonly emsFontLibraryUrl: string; readonly emsTileLayerId: Readonly<{} & { bright: string; desaturated: string; dark: string; }>; }" + "{ readonly tilemap: Readonly<{ url?: string | undefined; } & { options: Readonly<{ default?: boolean | undefined; tileSize?: number | undefined; subdomains?: string[] | undefined; errorTileUrl?: string | undefined; tms?: boolean | undefined; reuseTiles?: boolean | undefined; bounds?: number[] | undefined; } & { attribution: string; minZoom: number; maxZoom: number; }>; }>; readonly includeElasticMapsService: boolean; readonly emsUrl: string; readonly emsFileApiUrl: string; readonly emsTileApiUrl: string; readonly emsLandingPageUrl: string; readonly emsFontLibraryUrl: string; readonly emsTileLayerId: Readonly<{} & { dark: string; bright: string; desaturated: string; }>; }" ], "path": "src/plugins/maps_ems/config.ts", "deprecated": false, @@ -141,7 +141,7 @@ "label": "config", "description": [], "signature": [ - "{ readonly tilemap: Readonly<{ url?: string | undefined; } & { options: Readonly<{ default?: boolean | undefined; tileSize?: number | undefined; subdomains?: string[] | undefined; errorTileUrl?: string | undefined; tms?: boolean | undefined; reuseTiles?: boolean | undefined; bounds?: number[] | undefined; } & { attribution: string; minZoom: number; maxZoom: number; }>; }>; readonly includeElasticMapsService: boolean; readonly emsUrl: string; readonly emsFileApiUrl: string; readonly emsTileApiUrl: string; readonly emsLandingPageUrl: string; readonly emsFontLibraryUrl: string; readonly emsTileLayerId: Readonly<{} & { bright: string; desaturated: string; dark: string; }>; }" + "{ readonly tilemap: Readonly<{ url?: string | undefined; } & { options: Readonly<{ default?: boolean | undefined; tileSize?: number | undefined; subdomains?: string[] | undefined; errorTileUrl?: string | undefined; tms?: boolean | undefined; reuseTiles?: boolean | undefined; bounds?: number[] | undefined; } & { attribution: string; minZoom: number; maxZoom: number; }>; }>; readonly includeElasticMapsService: boolean; readonly emsUrl: string; readonly emsFileApiUrl: string; readonly emsTileApiUrl: string; readonly emsLandingPageUrl: string; readonly emsFontLibraryUrl: string; readonly emsTileLayerId: Readonly<{} & { dark: string; bright: string; desaturated: string; }>; }" ], "path": "src/plugins/maps_ems/public/index.ts", "deprecated": false @@ -441,7 +441,7 @@ "section": "def-server.PluginInitializerContext", "text": "PluginInitializerContext" }, - "; }>; includeElasticMapsService: boolean; emsUrl: string; emsFileApiUrl: string; emsTileApiUrl: string; emsLandingPageUrl: string; emsFontLibraryUrl: string; emsTileLayerId: Readonly<{} & { bright: string; desaturated: string; dark: string; }>; }>>" + "; }>; includeElasticMapsService: boolean; emsUrl: string; emsFileApiUrl: string; emsTileApiUrl: string; emsLandingPageUrl: string; emsFontLibraryUrl: string; emsTileLayerId: Readonly<{} & { dark: string; bright: string; desaturated: string; }>; }>>" ], "path": "src/plugins/maps_ems/server/index.ts", "deprecated": false @@ -474,7 +474,7 @@ "section": "def-server.PluginInitializerContext", "text": "PluginInitializerContext" }, - "; }>; includeElasticMapsService: boolean; emsUrl: string; emsFileApiUrl: string; emsTileApiUrl: string; emsLandingPageUrl: string; emsFontLibraryUrl: string; emsTileLayerId: Readonly<{} & { bright: string; desaturated: string; dark: string; }>; }>>" + "; }>; includeElasticMapsService: boolean; emsUrl: string; emsFileApiUrl: string; emsTileApiUrl: string; emsLandingPageUrl: string; emsFontLibraryUrl: string; emsTileLayerId: Readonly<{} & { dark: string; bright: string; desaturated: string; }>; }>>" ], "path": "src/plugins/maps_ems/server/index.ts", "deprecated": false, @@ -499,7 +499,7 @@ "section": "def-server.CoreSetup", "text": "CoreSetup" }, - ", plugins: MapsEmsSetupServerDependencies) => { config: Readonly<{} & { tilemap: Readonly<{ url?: string | undefined; } & { options: Readonly<{ default?: boolean | undefined; tileSize?: number | undefined; subdomains?: string[] | undefined; errorTileUrl?: string | undefined; tms?: boolean | undefined; reuseTiles?: boolean | undefined; bounds?: number[] | undefined; } & { attribution: string; minZoom: number; maxZoom: number; }>; }>; includeElasticMapsService: boolean; emsUrl: string; emsFileApiUrl: string; emsTileApiUrl: string; emsLandingPageUrl: string; emsFontLibraryUrl: string; emsTileLayerId: Readonly<{} & { bright: string; desaturated: string; dark: string; }>; }>; createEMSSettings: () => ", + ", plugins: MapsEmsSetupServerDependencies) => { config: Readonly<{} & { tilemap: Readonly<{ url?: string | undefined; } & { options: Readonly<{ default?: boolean | undefined; tileSize?: number | undefined; subdomains?: string[] | undefined; errorTileUrl?: string | undefined; tms?: boolean | undefined; reuseTiles?: boolean | undefined; bounds?: number[] | undefined; } & { attribution: string; minZoom: number; maxZoom: number; }>; }>; includeElasticMapsService: boolean; emsUrl: string; emsFileApiUrl: string; emsTileApiUrl: string; emsLandingPageUrl: string; emsFontLibraryUrl: string; emsTileLayerId: Readonly<{} & { dark: string; bright: string; desaturated: string; }>; }>; createEMSSettings: () => ", { "pluginId": "mapsEms", "scope": "common", @@ -589,7 +589,7 @@ "label": "config", "description": [], "signature": [ - "{ readonly tilemap: Readonly<{ url?: string | undefined; } & { options: Readonly<{ default?: boolean | undefined; tileSize?: number | undefined; subdomains?: string[] | undefined; errorTileUrl?: string | undefined; tms?: boolean | undefined; reuseTiles?: boolean | undefined; bounds?: number[] | undefined; } & { attribution: string; minZoom: number; maxZoom: number; }>; }>; readonly includeElasticMapsService: boolean; readonly emsUrl: string; readonly emsFileApiUrl: string; readonly emsTileApiUrl: string; readonly emsLandingPageUrl: string; readonly emsFontLibraryUrl: string; readonly emsTileLayerId: Readonly<{} & { bright: string; desaturated: string; dark: string; }>; }" + "{ readonly tilemap: Readonly<{ url?: string | undefined; } & { options: Readonly<{ default?: boolean | undefined; tileSize?: number | undefined; subdomains?: string[] | undefined; errorTileUrl?: string | undefined; tms?: boolean | undefined; reuseTiles?: boolean | undefined; bounds?: number[] | undefined; } & { attribution: string; minZoom: number; maxZoom: number; }>; }>; readonly includeElasticMapsService: boolean; readonly emsUrl: string; readonly emsFileApiUrl: string; readonly emsTileApiUrl: string; readonly emsLandingPageUrl: string; readonly emsFontLibraryUrl: string; readonly emsTileLayerId: Readonly<{} & { dark: string; bright: string; desaturated: string; }>; }" ], "path": "src/plugins/maps_ems/server/index.ts", "deprecated": false diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx index 4fa7850a0e9c9..5fc5483e9d64c 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github summary: API docs for the mapsEms plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/metrics_entities.devdocs.json b/api_docs/metrics_entities.devdocs.json deleted file mode 100644 index 8a4c69fc1e824..0000000000000 --- a/api_docs/metrics_entities.devdocs.json +++ /dev/null @@ -1,1282 +0,0 @@ -{ - "id": "metricsEntities", - "client": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - }, - "server": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [], - "setup": { - "parentPluginId": "metricsEntities", - "id": "def-server.MetricsEntitiesPluginSetup", - "type": "Interface", - "tags": [], - "label": "MetricsEntitiesPluginSetup", - "description": [], - "path": "x-pack/plugins/metrics_entities/server/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "metricsEntities", - "id": "def-server.MetricsEntitiesPluginSetup.getMetricsEntitiesClient", - "type": "Function", - "tags": [], - "label": "getMetricsEntitiesClient", - "description": [], - "signature": [ - "(esClient: ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCorePluginApi", - "section": "def-server.ElasticsearchClient", - "text": "ElasticsearchClient" - }, - ") => ", - "MetricsEntitiesClient" - ], - "path": "x-pack/plugins/metrics_entities/server/types.ts", - "deprecated": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "metricsEntities", - "id": "def-server.MetricsEntitiesPluginSetup.getMetricsEntitiesClient.$1", - "type": "Object", - "tags": [], - "label": "esClient", - "description": [], - "signature": [ - "{ eql: ", - "default", - "; search: { >(this: That, params?: ", - "SearchRequest", - " | ", - "SearchRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "SearchResponse", - ">; >(this: That, params?: ", - "SearchRequest", - " | ", - "SearchRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "SearchResponse", - ", unknown>>; >(this: That, params?: ", - "SearchRequest", - " | ", - "SearchRequest", - " | undefined, options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "SearchResponse", - ">; }; create: { (this: That, params: ", - "CreateRequest", - " | ", - "CreateRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "WriteResponseBase", - ">; (this: That, params: ", - "CreateRequest", - " | ", - "CreateRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "WriteResponseBase", - ", unknown>>; (this: That, params: ", - "CreateRequest", - " | ", - "CreateRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "WriteResponseBase", - ">; }; monitoring: ", - "default", - "; security: ", - "default", - "; name: string | symbol; index: { (this: That, params: ", - "IndexRequest", - " | ", - "IndexRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "WriteResponseBase", - ">; (this: That, params: ", - "IndexRequest", - " | ", - "IndexRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "WriteResponseBase", - ", unknown>>; (this: That, params: ", - "IndexRequest", - " | ", - "IndexRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "WriteResponseBase", - ">; }; delete: { (this: That, params: ", - "DeleteRequest", - " | ", - "DeleteRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "WriteResponseBase", - ">; (this: That, params: ", - "DeleteRequest", - " | ", - "DeleteRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "WriteResponseBase", - ", unknown>>; (this: That, params: ", - "DeleteRequest", - " | ", - "DeleteRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "WriteResponseBase", - ">; }; get: { (this: That, params: ", - "GetRequest", - " | ", - "GetRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "GetResponse", - ">; (this: That, params: ", - "GetRequest", - " | ", - "GetRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "GetResponse", - ", unknown>>; (this: That, params: ", - "GetRequest", - " | ", - "GetRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "GetResponse", - ">; }; update: { (this: That, params: ", - "UpdateRequest", - " | ", - "UpdateRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "UpdateResponse", - ">; (this: That, params: ", - "UpdateRequest", - " | ", - "UpdateRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "UpdateResponse", - ", unknown>>; (this: That, params: ", - "UpdateRequest", - " | ", - "UpdateRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "UpdateResponse", - ">; }; closePointInTime: { (this: That, params: ", - "ClosePointInTimeRequest", - " | ", - "ClosePointInTimeRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "ClosePointInTimeResponse", - ">; (this: That, params: ", - "ClosePointInTimeRequest", - " | ", - "ClosePointInTimeRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "ClosePointInTimeResponse", - ", unknown>>; (this: That, params: ", - "ClosePointInTimeRequest", - " | ", - "ClosePointInTimeRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "ClosePointInTimeResponse", - ">; }; helpers: ", - "default", - "; [kInternal]: symbol | null; [kAsyncSearch]: symbol | null; [kAutoscaling]: symbol | null; [kCat]: symbol | null; [kCcr]: symbol | null; [kCluster]: symbol | null; [kDanglingIndices]: symbol | null; [kEnrich]: symbol | null; [kEql]: symbol | null; [kFeatures]: symbol | null; [kFleet]: symbol | null; [kGraph]: symbol | null; [kIlm]: symbol | null; [kIndices]: symbol | null; [kIngest]: symbol | null; [kLicense]: symbol | null; [kLogstash]: symbol | null; [kMigration]: symbol | null; [kMl]: symbol | null; [kMonitoring]: symbol | null; [kNodes]: symbol | null; [kRollup]: symbol | null; [kSearchableSnapshots]: symbol | null; [kSecurity]: symbol | null; [kShutdown]: symbol | null; [kSlm]: symbol | null; [kSnapshot]: symbol | null; [kSql]: symbol | null; [kSsl]: symbol | null; [kTasks]: symbol | null; [kTextStructure]: symbol | null; [kTransform]: symbol | null; [kWatcher]: symbol | null; [kXpack]: symbol | null; transport: ", - "default", - "; child: (opts: ", - "ClientOptions", - ") => ", - "default", - "; Internal: ", - "default", - "; asyncSearch: ", - "default", - "; autoscaling: ", - "default", - "; bulk: { (this: That, params: ", - "BulkRequest", - " | ", - "BulkRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "BulkResponse", - ">; (this: That, params: ", - "BulkRequest", - " | ", - "BulkRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "BulkResponse", - ", unknown>>; (this: That, params: ", - "BulkRequest", - " | ", - "BulkRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "BulkResponse", - ">; }; cat: ", - "default", - "; ccr: ", - "default", - "; clearScroll: { (this: That, params?: ", - "ClearScrollRequest", - " | ", - "ClearScrollRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "ClearScrollResponse", - ">; (this: That, params?: ", - "ClearScrollRequest", - " | ", - "ClearScrollRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "ClearScrollResponse", - ", unknown>>; (this: That, params?: ", - "ClearScrollRequest", - " | ", - "ClearScrollRequest", - " | undefined, options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "ClearScrollResponse", - ">; }; cluster: ", - "default", - "; count: { (this: That, params?: ", - "CountRequest", - " | ", - "CountRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "CountResponse", - ">; (this: That, params?: ", - "CountRequest", - " | ", - "CountRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "CountResponse", - ", unknown>>; (this: That, params?: ", - "CountRequest", - " | ", - "CountRequest", - " | undefined, options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "CountResponse", - ">; }; danglingIndices: ", - "default", - "; deleteByQuery: { (this: That, params: ", - "DeleteByQueryRequest", - " | ", - "DeleteByQueryRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "DeleteByQueryResponse", - ">; (this: That, params: ", - "DeleteByQueryRequest", - " | ", - "DeleteByQueryRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "DeleteByQueryResponse", - ", unknown>>; (this: That, params: ", - "DeleteByQueryRequest", - " | ", - "DeleteByQueryRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "DeleteByQueryResponse", - ">; }; deleteByQueryRethrottle: { (this: That, params: ", - "DeleteByQueryRethrottleRequest", - " | ", - "DeleteByQueryRethrottleRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "TasksTaskListResponseBase", - ">; (this: That, params: ", - "DeleteByQueryRethrottleRequest", - " | ", - "DeleteByQueryRethrottleRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "TasksTaskListResponseBase", - ", unknown>>; (this: That, params: ", - "DeleteByQueryRethrottleRequest", - " | ", - "DeleteByQueryRethrottleRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "TasksTaskListResponseBase", - ">; }; deleteScript: { (this: That, params: ", - "DeleteScriptRequest", - " | ", - "DeleteScriptRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "AcknowledgedResponseBase", - ">; (this: That, params: ", - "DeleteScriptRequest", - " | ", - "DeleteScriptRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "AcknowledgedResponseBase", - ", unknown>>; (this: That, params: ", - "DeleteScriptRequest", - " | ", - "DeleteScriptRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "AcknowledgedResponseBase", - ">; }; enrich: ", - "default", - "; exists: { (this: That, params: ", - "ExistsRequest", - " | ", - "ExistsRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise; (this: That, params: ", - "ExistsRequest", - " | ", - "ExistsRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - ">; (this: That, params: ", - "ExistsRequest", - " | ", - "ExistsRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise; }; existsSource: { (this: That, params: ", - "ExistsSourceRequest", - " | ", - "ExistsSourceRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise; (this: That, params: ", - "ExistsSourceRequest", - " | ", - "ExistsSourceRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - ">; (this: That, params: ", - "ExistsSourceRequest", - " | ", - "ExistsSourceRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise; }; explain: { (this: That, params: ", - "ExplainRequest", - " | ", - "ExplainRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "ExplainResponse", - ">; (this: That, params: ", - "ExplainRequest", - " | ", - "ExplainRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "ExplainResponse", - ", unknown>>; (this: That, params: ", - "ExplainRequest", - " | ", - "ExplainRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "ExplainResponse", - ">; }; features: ", - "default", - "; fieldCaps: { (this: That, params: ", - "FieldCapsRequest", - " | ", - "FieldCapsRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "FieldCapsResponse", - ">; (this: That, params: ", - "FieldCapsRequest", - " | ", - "FieldCapsRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "FieldCapsResponse", - ", unknown>>; (this: That, params: ", - "FieldCapsRequest", - " | ", - "FieldCapsRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "FieldCapsResponse", - ">; }; fleet: ", - "default", - "; getScript: { (this: That, params: ", - "GetScriptRequest", - " | ", - "GetScriptRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "GetScriptResponse", - ">; (this: That, params: ", - "GetScriptRequest", - " | ", - "GetScriptRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "GetScriptResponse", - ", unknown>>; (this: That, params: ", - "GetScriptRequest", - " | ", - "GetScriptRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "GetScriptResponse", - ">; }; getScriptContext: { (this: That, params?: ", - "GetScriptContextRequest", - " | ", - "GetScriptContextRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "GetScriptContextResponse", - ">; (this: That, params?: ", - "GetScriptContextRequest", - " | ", - "GetScriptContextRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "GetScriptContextResponse", - ", unknown>>; (this: That, params?: ", - "GetScriptContextRequest", - " | ", - "GetScriptContextRequest", - " | undefined, options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "GetScriptContextResponse", - ">; }; getScriptLanguages: { (this: That, params?: ", - "GetScriptLanguagesRequest", - " | ", - "GetScriptLanguagesRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "GetScriptLanguagesResponse", - ">; (this: That, params?: ", - "GetScriptLanguagesRequest", - " | ", - "GetScriptLanguagesRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "GetScriptLanguagesResponse", - ", unknown>>; (this: That, params?: ", - "GetScriptLanguagesRequest", - " | ", - "GetScriptLanguagesRequest", - " | undefined, options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "GetScriptLanguagesResponse", - ">; }; getSource: { (this: That, params: ", - "GetSourceRequest", - " | ", - "GetSourceRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise; (this: That, params: ", - "GetSourceRequest", - " | ", - "GetSourceRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - ">; (this: That, params: ", - "GetSourceRequest", - " | ", - "GetSourceRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise; }; graph: ", - "default", - "; ilm: ", - "default", - "; indices: ", - "default", - "; info: { (this: That, params?: ", - "InfoRequest", - " | ", - "InfoRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "InfoResponse", - ">; (this: That, params?: ", - "InfoRequest", - " | ", - "InfoRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "InfoResponse", - ", unknown>>; (this: That, params?: ", - "InfoRequest", - " | ", - "InfoRequest", - " | undefined, options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "InfoResponse", - ">; }; ingest: ", - "default", - "; knnSearch: { (this: That, params: ", - "KnnSearchRequest", - " | ", - "KnnSearchRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "KnnSearchResponse", - ">; (this: That, params: ", - "KnnSearchRequest", - " | ", - "KnnSearchRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "KnnSearchResponse", - ", unknown>>; (this: That, params: ", - "KnnSearchRequest", - " | ", - "KnnSearchRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "KnnSearchResponse", - ">; }; license: ", - "default", - "; logstash: ", - "default", - "; mget: { (this: That, params?: ", - "MgetRequest", - " | ", - "MgetRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "MgetResponse", - ">; (this: That, params?: ", - "MgetRequest", - " | ", - "MgetRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "MgetResponse", - ", unknown>>; (this: That, params?: ", - "MgetRequest", - " | ", - "MgetRequest", - " | undefined, options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "MgetResponse", - ">; }; migration: ", - "default", - "; ml: ", - "default", - "; msearch: { >(this: That, params: ", - "MsearchRequest", - " | ", - "MsearchRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "MsearchResponse", - ">; >(this: That, params: ", - "MsearchRequest", - " | ", - "MsearchRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "MsearchResponse", - ", unknown>>; >(this: That, params: ", - "MsearchRequest", - " | ", - "MsearchRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "MsearchResponse", - ">; }; msearchTemplate: { >(this: That, params: ", - "MsearchTemplateRequest", - " | ", - "MsearchTemplateRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "MsearchTemplateResponse", - ">; >(this: That, params: ", - "MsearchTemplateRequest", - " | ", - "MsearchTemplateRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "MsearchTemplateResponse", - ", unknown>>; >(this: That, params: ", - "MsearchTemplateRequest", - " | ", - "MsearchTemplateRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "MsearchTemplateResponse", - ">; }; mtermvectors: { (this: That, params?: ", - "MtermvectorsRequest", - " | ", - "MtermvectorsRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "MtermvectorsResponse", - ">; (this: That, params?: ", - "MtermvectorsRequest", - " | ", - "MtermvectorsRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "MtermvectorsResponse", - ", unknown>>; (this: That, params?: ", - "MtermvectorsRequest", - " | ", - "MtermvectorsRequest", - " | undefined, options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "MtermvectorsResponse", - ">; }; nodes: ", - "default", - "; openPointInTime: { (this: That, params: ", - "OpenPointInTimeRequest", - " | ", - "OpenPointInTimeRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "OpenPointInTimeResponse", - ">; (this: That, params: ", - "OpenPointInTimeRequest", - " | ", - "OpenPointInTimeRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "OpenPointInTimeResponse", - ", unknown>>; (this: That, params: ", - "OpenPointInTimeRequest", - " | ", - "OpenPointInTimeRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "OpenPointInTimeResponse", - ">; }; ping: { (this: That, params?: ", - "PingRequest", - " | ", - "PingRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise; (this: That, params?: ", - "PingRequest", - " | ", - "PingRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - ">; (this: That, params?: ", - "PingRequest", - " | ", - "PingRequest", - " | undefined, options?: ", - "TransportRequestOptions", - " | undefined): Promise; }; putScript: { (this: That, params: ", - "PutScriptRequest", - " | ", - "PutScriptRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "AcknowledgedResponseBase", - ">; (this: That, params: ", - "PutScriptRequest", - " | ", - "PutScriptRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "AcknowledgedResponseBase", - ", unknown>>; (this: That, params: ", - "PutScriptRequest", - " | ", - "PutScriptRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "AcknowledgedResponseBase", - ">; }; rankEval: { (this: That, params: ", - "RankEvalRequest", - " | ", - "RankEvalRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "RankEvalResponse", - ">; (this: That, params: ", - "RankEvalRequest", - " | ", - "RankEvalRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "RankEvalResponse", - ", unknown>>; (this: That, params: ", - "RankEvalRequest", - " | ", - "RankEvalRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "RankEvalResponse", - ">; }; reindex: { (this: That, params: ", - "ReindexRequest", - " | ", - "ReindexRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "ReindexResponse", - ">; (this: That, params: ", - "ReindexRequest", - " | ", - "ReindexRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "ReindexResponse", - ", unknown>>; (this: That, params: ", - "ReindexRequest", - " | ", - "ReindexRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "ReindexResponse", - ">; }; reindexRethrottle: { (this: That, params: ", - "ReindexRethrottleRequest", - " | ", - "ReindexRethrottleRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "ReindexRethrottleResponse", - ">; (this: That, params: ", - "ReindexRethrottleRequest", - " | ", - "ReindexRethrottleRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "ReindexRethrottleResponse", - ", unknown>>; (this: That, params: ", - "ReindexRethrottleRequest", - " | ", - "ReindexRethrottleRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "ReindexRethrottleResponse", - ">; }; renderSearchTemplate: { (this: That, params?: ", - "RenderSearchTemplateRequest", - " | ", - "RenderSearchTemplateRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "RenderSearchTemplateResponse", - ">; (this: That, params?: ", - "RenderSearchTemplateRequest", - " | ", - "RenderSearchTemplateRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "RenderSearchTemplateResponse", - ", unknown>>; (this: That, params?: ", - "RenderSearchTemplateRequest", - " | ", - "RenderSearchTemplateRequest", - " | undefined, options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "RenderSearchTemplateResponse", - ">; }; rollup: ", - "default", - "; scriptsPainlessExecute: { (this: That, params?: ", - "ScriptsPainlessExecuteRequest", - " | ", - "ScriptsPainlessExecuteRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "ScriptsPainlessExecuteResponse", - ">; (this: That, params?: ", - "ScriptsPainlessExecuteRequest", - " | ", - "ScriptsPainlessExecuteRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "ScriptsPainlessExecuteResponse", - ", unknown>>; (this: That, params?: ", - "ScriptsPainlessExecuteRequest", - " | ", - "ScriptsPainlessExecuteRequest", - " | undefined, options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "ScriptsPainlessExecuteResponse", - ">; }; scroll: { >(this: That, params: ", - "ScrollRequest", - " | ", - "ScrollRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "ScrollResponse", - ">; >(this: That, params: ", - "ScrollRequest", - " | ", - "ScrollRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "ScrollResponse", - ", unknown>>; >(this: That, params: ", - "ScrollRequest", - " | ", - "ScrollRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "ScrollResponse", - ">; }; searchMvt: { (this: That, params: ", - "SearchMvtRequest", - " | ", - "SearchMvtRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise; (this: That, params: ", - "SearchMvtRequest", - " | ", - "SearchMvtRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - ">; (this: That, params: ", - "SearchMvtRequest", - " | ", - "SearchMvtRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise; }; searchShards: { (this: That, params?: ", - "SearchShardsRequest", - " | ", - "SearchShardsRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "SearchShardsResponse", - ">; (this: That, params?: ", - "SearchShardsRequest", - " | ", - "SearchShardsRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "SearchShardsResponse", - ", unknown>>; (this: That, params?: ", - "SearchShardsRequest", - " | ", - "SearchShardsRequest", - " | undefined, options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "SearchShardsResponse", - ">; }; searchTemplate: { (this: That, params?: ", - "SearchTemplateRequest", - " | ", - "SearchTemplateRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "SearchTemplateResponse", - ">; (this: That, params?: ", - "SearchTemplateRequest", - " | ", - "SearchTemplateRequest", - " | undefined, options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "SearchTemplateResponse", - ", unknown>>; (this: That, params?: ", - "SearchTemplateRequest", - " | ", - "SearchTemplateRequest", - " | undefined, options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "SearchTemplateResponse", - ">; }; searchableSnapshots: ", - "default", - "; shutdown: ", - "default", - "; slm: ", - "default", - "; snapshot: ", - "default", - "; sql: ", - "default", - "; ssl: ", - "default", - "; tasks: ", - "default", - "; termsEnum: { (this: That, params: ", - "TermsEnumRequest", - " | ", - "TermsEnumRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "TermsEnumResponse", - ">; (this: That, params: ", - "TermsEnumRequest", - " | ", - "TermsEnumRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "TermsEnumResponse", - ", unknown>>; (this: That, params: ", - "TermsEnumRequest", - " | ", - "TermsEnumRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "TermsEnumResponse", - ">; }; termvectors: { (this: That, params: ", - "TermvectorsRequest", - " | ", - "TermvectorsRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "TermvectorsResponse", - ">; (this: That, params: ", - "TermvectorsRequest", - " | ", - "TermvectorsRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "TermvectorsResponse", - ", unknown>>; (this: That, params: ", - "TermvectorsRequest", - " | ", - "TermvectorsRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "TermvectorsResponse", - ">; }; textStructure: ", - "default", - "; transform: ", - "default", - "; updateByQuery: { (this: That, params: ", - "UpdateByQueryRequest", - " | ", - "UpdateByQueryRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "UpdateByQueryResponse", - ">; (this: That, params: ", - "UpdateByQueryRequest", - " | ", - "UpdateByQueryRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "UpdateByQueryResponse", - ", unknown>>; (this: That, params: ", - "UpdateByQueryRequest", - " | ", - "UpdateByQueryRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "UpdateByQueryResponse", - ">; }; updateByQueryRethrottle: { (this: That, params: ", - "UpdateByQueryRethrottleRequest", - " | ", - "UpdateByQueryRethrottleRequest", - ", options?: ", - "TransportRequestOptionsWithOutMeta", - " | undefined): Promise<", - "UpdateByQueryRethrottleResponse", - ">; (this: That, params: ", - "UpdateByQueryRethrottleRequest", - " | ", - "UpdateByQueryRethrottleRequest", - ", options?: ", - "TransportRequestOptionsWithMeta", - " | undefined): Promise<", - "TransportResult", - "<", - "UpdateByQueryRethrottleResponse", - ", unknown>>; (this: That, params: ", - "UpdateByQueryRethrottleRequest", - " | ", - "UpdateByQueryRethrottleRequest", - ", options?: ", - "TransportRequestOptions", - " | undefined): Promise<", - "UpdateByQueryRethrottleResponse", - ">; }; watcher: ", - "default", - "; xpack: ", - "default", - "; }" - ], - "path": "x-pack/plugins/metrics_entities/server/types.ts", - "deprecated": false - } - ] - } - ], - "lifecycle": "setup", - "initialIsOpen": true - }, - "start": { - "parentPluginId": "metricsEntities", - "id": "def-server.MetricsEntitiesPluginStart", - "type": "Type", - "tags": [], - "label": "MetricsEntitiesPluginStart", - "description": [], - "signature": [ - "void" - ], - "path": "x-pack/plugins/metrics_entities/server/types.ts", - "deprecated": false, - "lifecycle": "start", - "initialIsOpen": true - } - }, - "common": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - } -} \ No newline at end of file diff --git a/api_docs/metrics_entities.mdx b/api_docs/metrics_entities.mdx deleted file mode 100644 index cbe21f8f4da51..0000000000000 --- a/api_docs/metrics_entities.mdx +++ /dev/null @@ -1,30 +0,0 @@ ---- -id: kibMetricsEntitiesPluginApi -slug: /kibana-dev-docs/api/metricsEntities -title: "metricsEntities" -image: https://source.unsplash.com/400x175/?github -summary: API docs for the metricsEntities plugin -date: 2022-04-05 -tags: ['contributor', 'dev', 'apidocs', 'kibana', 'metricsEntities'] -warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. ---- -import metricsEntitiesObj from './metrics_entities.devdocs.json'; - - - -Contact [Security solution](https://github.com/orgs/elastic/teams/security-solution) for questions regarding this plugin. - -**Code health stats** - -| Public API count | Any count | Items lacking comments | Missing exports | -|-------------------|-----------|------------------------|-----------------| -| 4 | 0 | 4 | 1 | - -## Server - -### Setup - - -### Start - - diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index f78b0773ab8b7..c53f258b23ce2 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github summary: API docs for the ml plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index 9d4656621ad0b..f4ccaa0afb22f 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github summary: API docs for the monitoring plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoring'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/monitoring_collection.mdx b/api_docs/monitoring_collection.mdx index fd085531e49d8..6862c66127338 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github summary: API docs for the monitoringCollection plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoringCollection'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/navigation.devdocs.json b/api_docs/navigation.devdocs.json index 7512f5d4cd86e..8c183c4b321ad 100644 --- a/api_docs/navigation.devdocs.json +++ b/api_docs/navigation.devdocs.json @@ -143,7 +143,7 @@ "label": "start", "description": [], "signature": [ - "({ i18n }: ", + "(core: ", { "pluginId": "core", "scope": "public", @@ -170,7 +170,7 @@ "id": "def-public.NavigationPublicPlugin.start.$1", "type": "Object", "tags": [], - "label": "{ i18n }", + "label": "core", "description": [], "signature": [ { @@ -410,9 +410,9 @@ "DisambiguateSet", "<(", "DisambiguateSet", - " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"onClick\" | \"color\" | \"href\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", - " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"onClick\" | \"color\">), WithSpanProps> & WithSpanProps & { iconType?: ", + " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">), WithSpanProps> & WithSpanProps & { iconType?: ", "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", @@ -426,9 +426,9 @@ "DisambiguateSet", "<(", "DisambiguateSet", - " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"onClick\" | \"color\" | \"href\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", - " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"onClick\" | \"color\">), WithSpanProps> & WithSpanProps & { iconType?: ", + " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">), WithSpanProps> & WithSpanProps & { iconType?: ", "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", @@ -444,11 +444,11 @@ "DisambiguateSet", " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"onClick\" | \"color\" | \"href\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", - " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"onClick\" | \"color\">)> & ", + " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">)> & ", "DisambiguateSet", - " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"onClick\" | \"color\" | \"href\"> & { iconType?: ", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\"> & { iconType?: ", "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", @@ -462,11 +462,11 @@ "DisambiguateSet", " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"onClick\" | \"color\" | \"href\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", - " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"onClick\" | \"color\">)> & ", + " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">)> & ", "DisambiguateSet", - " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"onClick\" | \"color\" | \"href\"> & { iconType?: ", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\"> & { iconType?: ", "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", @@ -482,11 +482,11 @@ "DisambiguateSet", " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"onClick\" | \"color\" | \"href\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", - " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"onClick\" | \"color\">)> & ", + " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">)> & ", "DisambiguateSet", - " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"onClick\" | \"color\" | \"href\"> & { iconType?: ", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\"> & { iconType?: ", "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", @@ -502,11 +502,11 @@ "DisambiguateSet", " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"onClick\" | \"color\" | \"href\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", - " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"onClick\" | \"color\">)> & ", + " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">)> & ", "DisambiguateSet", - " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"onClick\" | \"color\"> & { iconType?: ", + " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\"> & { iconType?: ", "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", @@ -520,11 +520,11 @@ "DisambiguateSet", " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"onClick\" | \"color\" | \"href\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", - " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"onClick\" | \"color\">)> & ", + " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">)> & ", "DisambiguateSet", - " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"onClick\" | \"color\"> & { iconType?: ", + " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\"> & { iconType?: ", "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", @@ -540,11 +540,11 @@ "DisambiguateSet", " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"onClick\" | \"color\" | \"href\">) | (", + " & { href: string; target?: string | undefined; rel?: string | undefined; } & Omit, \"color\" | \"onClick\" | \"href\">) | (", "DisambiguateSet", - " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"onClick\" | \"color\">)> & ", + " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\">)> & ", "DisambiguateSet", - " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"onClick\" | \"color\"> & { iconType?: ", + " & { onClick?: React.MouseEventHandler | undefined; onClickAriaLabel?: string | undefined; } & Omit, \"color\" | \"onClick\"> & { iconType?: ", "IconType", " | undefined; label: React.ReactNode; tooltipContent?: React.ReactNode; tooltipPosition?: ", "ToolTipPositions", diff --git a/api_docs/navigation.mdx b/api_docs/navigation.mdx index 5c0088964dbc6..a7aee0a91e834 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github summary: API docs for the navigation plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'navigation'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/newsfeed.mdx b/api_docs/newsfeed.mdx index 1e3cfb7a6fa96..9dc6262d29612 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github summary: API docs for the newsfeed plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/observability.devdocs.json b/api_docs/observability.devdocs.json index 6dde3e0820d9a..1167181e14f56 100644 --- a/api_docs/observability.devdocs.json +++ b/api_docs/observability.devdocs.json @@ -678,9 +678,9 @@ }, " | undefined; }; selectedAlertId?: string | undefined; } & ", "CommonProps", - " & { as?: \"div\" | undefined; } & _EuiFlyoutProps & Omit, HTMLDivElement>, keyof _EuiFlyoutProps> & Omit, HTMLDivElement>, \"key\" | \"css\" | keyof React.HTMLAttributes> & { ref?: React.RefObject | ((instance: HTMLDivElement | null) => void) | null | undefined; }, \"children\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"title\" | \"id\" | \"security\" | \"defaultValue\" | \"hidden\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"as\" | keyof ", + " & { as?: \"div\" | undefined; } & _EuiFlyoutProps & Omit, HTMLDivElement>, keyof _EuiFlyoutProps> & Omit, HTMLDivElement>, \"key\" | \"css\" | keyof React.HTMLAttributes> & { ref?: React.RefObject | ((instance: HTMLDivElement | null) => void) | null | undefined; }, \"children\" | \"color\" | \"title\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"id\" | \"security\" | \"defaultValue\" | \"hidden\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"as\" | keyof ", "CommonProps", - " | keyof React.ClassAttributes | keyof _EuiFlyoutProps>, \"children\" | \"onClick\" | \"onChange\" | \"color\" | \"onKeyDown\" | \"alert\" | \"key\" | \"title\" | \"id\" | \"css\" | \"security\" | \"defaultValue\" | \"hidden\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"as\" | keyof ", + " | keyof React.ClassAttributes | keyof _EuiFlyoutProps>, \"children\" | \"alert\" | \"color\" | \"title\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"key\" | \"id\" | \"css\" | \"security\" | \"defaultValue\" | \"hidden\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"lang\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onError\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"as\" | keyof ", "CommonProps", " | \"alerts\" | keyof _EuiFlyoutProps | \"isInApp\" | \"observabilityRuleTypeRegistry\" | \"selectedAlertId\"> & { ref?: React.RefObject | ((instance: HTMLDivElement | null) => void) | null | undefined; }> & { readonly _result: ({ alert, alerts, isInApp, observabilityRuleTypeRegistry, onClose, selectedAlertId, }: AlertsFlyoutProps) => JSX.Element | null; }" ], @@ -3683,13 +3683,7 @@ "label": "palette", "description": [], "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, + "PaletteOutput", "<{ [key: string]: unknown; }> | undefined" ], "path": "x-pack/plugins/observability/public/components/shared/exploratory_view/types.ts", @@ -4798,7 +4792,7 @@ "DisambiguateSet", ", Omit, \"href\">> & Omit, \"href\">) | (", "DisambiguateSet", - ", \"href\">, React.ButtonHTMLAttributes> & React.ButtonHTMLAttributes))), \"onClick\" | \"color\" | \"rel\" | \"target\"> & { size?: ItemSize | undefined; color?: Color | undefined; label: React.ReactNode; isActive?: boolean | undefined; isDisabled?: boolean | undefined; href?: string | undefined; target?: string | undefined; rel?: string | undefined; iconType?: ", + ", \"href\">, React.ButtonHTMLAttributes> & React.ButtonHTMLAttributes))), \"color\" | \"onClick\" | \"rel\" | \"target\"> & { size?: ItemSize | undefined; color?: Color | undefined; label: React.ReactNode; isActive?: boolean | undefined; isDisabled?: boolean | undefined; href?: string | undefined; target?: string | undefined; rel?: string | undefined; iconType?: ", "IconType", " | undefined; iconProps?: Omit<", "EuiIconProps", @@ -6859,12 +6853,35 @@ { "parentPluginId": "observability", "id": "def-server.ObservabilityRouteHandlerResources.context", - "type": "Object", + "type": "CompoundType", "tags": [], "label": "context", "description": [], "signature": [ - "ObservabilityRequestHandlerContext" + { + "pluginId": "core", + "scope": "server", + "docId": "kibCorePluginApi", + "section": "def-server.RequestHandlerContext", + "text": "RequestHandlerContext" + }, + " & { licensing: Promise<", + { + "pluginId": "licensing", + "scope": "server", + "docId": "kibLicensingPluginApi", + "section": "def-server.LicensingApiRequestHandlerContext", + "text": "LicensingApiRequestHandlerContext" + }, + ">; alerting: Promise<", + { + "pluginId": "alerting", + "scope": "server", + "docId": "kibAlertingPluginApi", + "section": "def-server.AlertingApiRequestHandlerContext", + "text": "AlertingApiRequestHandlerContext" + }, + ">; }" ], "path": "x-pack/plugins/observability/server/routes/types.ts", "deprecated": false @@ -7077,7 +7094,7 @@ "section": "def-server.RequestHandlerContext", "text": "RequestHandlerContext" }, - " & { licensing: ", + " & { licensing: Promise<", { "pluginId": "licensing", "scope": "server", @@ -7085,7 +7102,7 @@ "section": "def-server.LicensingApiRequestHandlerContext", "text": "LicensingApiRequestHandlerContext" }, - "; }, request: ", + ">; }, request: ", { "pluginId": "core", "scope": "server", @@ -7168,11 +7185,82 @@ ], "returnComment": [], "initialIsOpen": false + }, + { + "parentPluginId": "observability", + "id": "def-common.getProbabilityFromProgressiveLoadingQuality", + "type": "Function", + "tags": [], + "label": "getProbabilityFromProgressiveLoadingQuality", + "description": [], + "signature": [ + "(quality: ", + { + "pluginId": "observability", + "scope": "common", + "docId": "kibObservabilityPluginApi", + "section": "def-common.ProgressiveLoadingQuality", + "text": "ProgressiveLoadingQuality" + }, + ") => number" + ], + "path": "x-pack/plugins/observability/common/progressive_loading.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "observability", + "id": "def-common.getProbabilityFromProgressiveLoadingQuality.$1", + "type": "Enum", + "tags": [], + "label": "quality", + "description": [], + "signature": [ + { + "pluginId": "observability", + "scope": "common", + "docId": "kibObservabilityPluginApi", + "section": "def-common.ProgressiveLoadingQuality", + "text": "ProgressiveLoadingQuality" + } + ], + "path": "x-pack/plugins/observability/common/progressive_loading.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false } ], "interfaces": [], - "enums": [], + "enums": [ + { + "parentPluginId": "observability", + "id": "def-common.ProgressiveLoadingQuality", + "type": "Enum", + "tags": [], + "label": "ProgressiveLoadingQuality", + "description": [], + "path": "x-pack/plugins/observability/common/progressive_loading.ts", + "deprecated": false, + "initialIsOpen": false + } + ], "misc": [ + { + "parentPluginId": "observability", + "id": "def-common.apmProgressiveLoading", + "type": "string", + "tags": [], + "label": "apmProgressiveLoading", + "description": [], + "signature": [ + "\"observability:apmProgressiveLoading\"" + ], + "path": "x-pack/plugins/observability/common/ui_settings_keys.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "observability", "id": "def-common.apmServiceInventoryOptimizedSorting", diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index 9675c6927423c..958f5d5f0f061 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github summary: API docs for the observability plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Observability UI](https://github.com/orgs/elastic/teams/observability-u | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 369 | 2 | 366 | 31 | +| 373 | 2 | 370 | 30 | ## Client @@ -62,6 +62,9 @@ Contact [Observability UI](https://github.com/orgs/elastic/teams/observability-u ### Functions +### Enums + + ### Consts, variables and types diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index 7c84da2e6ca7a..e5785b58293ea 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github summary: API docs for the osquery plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index 84e92c68c5944..f43ac68f5f298 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -3,7 +3,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory summary: Directory of public APIs available through plugins or packages. -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -12,37 +12,37 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Count | Plugins or Packages with a
public API | Number of teams | |--------------|----------|------------------------| -| 231 | 188 | 35 | +| 247 | 201 | 35 | ### Public API health stats | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 25613 | 171 | 19521 | 1128 | +| 25958 | 170 | 19687 | 1153 | ## Plugin Directory | Plugin name           | Maintaining team | Description | API Cnt | Any Cnt | Missing
comments | Missing
exports | |--------------|----------------|-----------|--------------|----------|---------------|--------| -| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 127 | 0 | 127 | 10 | +| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 195 | 0 | 191 | 11 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 23 | 0 | 19 | 1 | -| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 334 | 0 | 325 | 20 | +| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 325 | 0 | 316 | 19 | | | [APM UI](https://github.com/orgs/elastic/teams/apm-ui) | The user interface for Elastic APM | 40 | 0 | 40 | 50 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 9 | 0 | 9 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Considering using bfetch capabilities when fetching large amounts of data. This services supports batching HTTP requests and streaming responses back. | 78 | 1 | 69 | 2 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds Canvas application to Kibana | 9 | 0 | 8 | 3 | -| | [ResponseOps](https://github.com/orgs/elastic/teams/response-ops) | The Case management system in Kibana | 71 | 0 | 58 | 19 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | - | 322 | 2 | 289 | 4 | +| | [ResponseOps](https://github.com/orgs/elastic/teams/response-ops) | The Case management system in Kibana | 71 | 0 | 57 | 19 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | - | 272 | 2 | 253 | 9 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 28 | 0 | 23 | 0 | | | [Cloud Security Posture](https://github.com/orgs/elastic/teams/cloud-posture-security) | The cloud security posture plugin | 14 | 0 | 14 | 0 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 13 | 0 | 13 | 1 | -| | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Controls Plugin contains embeddable components intended to create a simple query interface for end users, and a powerful editing suite that allows dashboard authors to build controls | 188 | 0 | 182 | 4 | -| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 2497 | 15 | 971 | 33 | +| | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Controls Plugin contains embeddable components intended to create a simple query interface for end users, and a powerful editing suite that allows dashboard authors to build controls | 203 | 0 | 197 | 6 | +| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 2524 | 15 | 977 | 33 | | crossClusterReplication | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | | | [Fleet](https://github.com/orgs/elastic/teams/fleet) | Add custom data integrations so they can be displayed in the Fleet integrations app | 98 | 0 | 79 | 1 | -| | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds the Dashboard app to Kibana | 151 | 0 | 149 | 14 | +| | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds the Dashboard app to Kibana | 142 | 0 | 140 | 12 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 52 | 0 | 51 | 0 | -| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3426 | 40 | 2816 | 20 | +| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3414 | 38 | 2802 | 18 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Enhanced data plugin. (See src/plugins/data.) Enhances the main data plugin with a search session management UI. Includes a reusable search session indicator component to use in other applications. Exposes routes for managing search sessions. Includes a service that monitors, updates, and cleans up search session saved objects. | 16 | 0 | 16 | 2 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | This plugin provides the ability to create data views via a modal flyout from any kibana app | 13 | 0 | 7 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Reusable data view field editor across Kibana | 42 | 0 | 37 | 3 | @@ -50,7 +50,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 862 | 3 | 710 | 15 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | The Data Visualizer tools help you understand your data, by analyzing the metrics and fields in a log file or an existing Elasticsearch index. | 23 | 2 | 19 | 1 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 10 | 0 | 8 | 2 | -| | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 77 | 0 | 61 | 7 | +| | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 76 | 0 | 60 | 7 | | | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 37 | 0 | 35 | 2 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds embeddables service to Kibana | 476 | 0 | 386 | 4 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Extends embeddable plugin with more functionality | 14 | 0 | 14 | 0 | @@ -60,8 +60,8 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | The Event Annotation service contains expressions for event annotations | 49 | 0 | 49 | 3 | | | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 91 | 0 | 91 | 9 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'error' renderer to expressions | 17 | 0 | 15 | 2 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression Gauge plugin adds a `gauge` renderer and function to the expression plugin. The renderer will display the `gauge` chart. | 76 | 0 | 76 | 2 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression Heatmap plugin adds a `heatmap` renderer and function to the expression plugin. The renderer will display the `heatmap` chart. | 119 | 0 | 115 | 3 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression Gauge plugin adds a `gauge` renderer and function to the expression plugin. The renderer will display the `gauge` chart. | 61 | 0 | 61 | 2 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression Heatmap plugin adds a `heatmap` renderer and function to the expression plugin. The renderer will display the `heatmap` chart. | 104 | 0 | 100 | 3 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'image' function and renderer to expressions | 26 | 0 | 26 | 0 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'metric' function and renderer to expressions | 32 | 0 | 27 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression MetricVis plugin adds a `metric` renderer and function to the expression plugin. The renderer will display the `metric` chart. | 46 | 0 | 46 | 1 | @@ -71,11 +71,11 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'shape' function and renderer to expressions | 148 | 0 | 146 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression Tagcloud plugin adds a `tagcloud` renderer and function to the expression plugin. The renderer will display the `Wordcloud` chart. | 7 | 0 | 7 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression XY plugin adds a `xy` renderer and function to the expression plugin. The renderer will display the `xy` chart. | 473 | 0 | 463 | 0 | -| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds expression runtime to Kibana | 2145 | 17 | 1701 | 6 | +| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds expression runtime to Kibana | 2158 | 17 | 1713 | 5 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 222 | 0 | 95 | 2 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Index pattern fields and ambiguous values formatters | 286 | 6 | 247 | 3 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | The file upload plugin contains components and services for uploading a file, analyzing its data, and then importing the data into an Elasticsearch index. Supported file types include CSV, TSV, newline-delimited JSON and GeoJSON. | 62 | 0 | 62 | 2 | -| | [Fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1379 | 8 | 1262 | 9 | +| | [Fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1385 | 8 | 1268 | 10 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 68 | 0 | 14 | 5 | | globalSearchBar | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | | globalSearchProviders | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | @@ -90,25 +90,24 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 123 | 2 | 96 | 4 | | | [Platform Security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides UI and APIs for the interactive setup mode. | 28 | 0 | 18 | 0 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 6 | 0 | 6 | 0 | -| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 239 | 0 | 203 | 5 | +| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 240 | 0 | 204 | 5 | | kibanaUsageCollection | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 0 | 0 | 0 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 615 | 3 | 420 | 9 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Visualization editor allowing to quickly and easily configure compelling visualizations to use on dashboards and canvas workpads. Exposes components to embed visualizations and link into the Lens editor from within other apps in Kibana. | 542 | 0 | 467 | 29 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Visualization editor allowing to quickly and easily configure compelling visualizations to use on dashboards and canvas workpads. Exposes components to embed visualizations and link into the Lens editor from within other apps in Kibana. | 527 | 0 | 452 | 30 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 8 | 0 | 8 | 0 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 3 | 0 | 3 | 0 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 117 | 0 | 42 | 10 | -| | [Security detections response](https://github.com/orgs/elastic/teams/security-detections-response) | - | 198 | 0 | 162 | 49 | +| | [Security detections response](https://github.com/orgs/elastic/teams/security-detections-response) | - | 198 | 0 | 90 | 49 | | logstash | [Logstash](https://github.com/orgs/elastic/teams/logstash) | - | 0 | 0 | 0 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | - | 41 | 0 | 41 | 6 | -| | [GIS](https://github.com/orgs/elastic/teams/kibana-gis) | - | 223 | 0 | 222 | 27 | +| | [GIS](https://github.com/orgs/elastic/teams/kibana-gis) | - | 224 | 0 | 223 | 25 | | | [GIS](https://github.com/orgs/elastic/teams/kibana-gis) | - | 67 | 0 | 67 | 0 | -| | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 4 | 0 | 4 | 1 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the machine learning features provided by Elastic. | 196 | 8 | 79 | 30 | | | [Stack Monitoring](https://github.com/orgs/elastic/teams/stack-monitoring-ui) | - | 11 | 0 | 9 | 1 | | | [Stack Monitoring](https://github.com/orgs/elastic/teams/stack-monitoring-ui) | - | 9 | 0 | 9 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 34 | 0 | 34 | 2 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 17 | 0 | 17 | 0 | -| | [Observability UI](https://github.com/orgs/elastic/teams/observability-ui) | - | 369 | 2 | 366 | 31 | +| | [Observability UI](https://github.com/orgs/elastic/teams/observability-ui) | - | 373 | 2 | 370 | 30 | | | [Security asset management](https://github.com/orgs/elastic/teams/security-asset-management) | - | 13 | 0 | 13 | 0 | | painlessLab | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Presentation Utility Plugin is a set of common, shared components and toolkits for solutions within the Presentation space, (e.g. Dashboards, Canvas). | 228 | 2 | 177 | 11 | @@ -121,31 +120,31 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 110 | 0 | 97 | 0 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 54 | 0 | 50 | 0 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 90 | 0 | 45 | 0 | -| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 33 | 0 | 14 | 0 | -| | [Kibana Reporting Services](https://github.com/orgs/elastic/teams/kibana-reporting-services) | Kibana Screenshotting Plugin | 24 | 0 | 12 | 5 | +| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 32 | 0 | 13 | 0 | +| | [Kibana Reporting Services](https://github.com/orgs/elastic/teams/kibana-reporting-services) | Kibana Screenshotting Plugin | 27 | 0 | 7 | 4 | | searchprofiler | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | | | [Platform Security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides authentication and authorization features, and exposes functionality to understand the capabilities of the currently authenticated user. | 183 | 0 | 103 | 0 | -| | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 45 | 0 | 45 | 18 | +| | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 46 | 0 | 46 | 19 | | | [Security Team](https://github.com/orgs/elastic/teams/security-team) | - | 3 | 0 | 3 | 1 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds URL Service and sharing capabilities to Kibana | 113 | 0 | 54 | 10 | | | [Shared UX](https://github.com/orgs/elastic/teams/shared-ux) | A plugin providing components and services for shared user experiences in Kibana. | 4 | 0 | 0 | 0 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 21 | 1 | 21 | 1 | | | [Platform Security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides the Spaces feature, which allows saved objects to be organized into meaningful categories. | 260 | 0 | 64 | 0 | | | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 4 | 0 | 4 | 0 | +| synthetics | [Uptime](https://github.com/orgs/elastic/teams/uptime) | This plugin visualizes data from Synthetics and Heartbeat, and integrates with other Observability solutions. | 0 | 0 | 0 | 0 | | | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 77 | 0 | 39 | 7 | -| | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 43 | 0 | 1 | 0 | +| | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 44 | 0 | 1 | 0 | | | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 32 | 0 | 32 | 6 | | | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 1 | 0 | 1 | 0 | | | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 11 | 0 | 10 | 0 | -| | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 435 | 1 | 331 | 35 | +| | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 434 | 1 | 330 | 35 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the transforms features provided by Elastic. Transforms enable you to convert existing Elasticsearch indices into summarized indices, which provide opportunities for new insights and analytics. | 4 | 0 | 4 | 1 | | translations | [Kibana Localization](https://github.com/orgs/elastic/teams/kibana-localization) | - | 0 | 0 | 0 | 0 | -| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 304 | 0 | 290 | 23 | +| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 321 | 0 | 307 | 25 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds UI Actions service to Kibana | 130 | 0 | 91 | 11 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Extends UI Actions plugin with more functionality | 203 | 0 | 141 | 9 | -| | [Unified Search](https://github.com/orgs/elastic/teams/kibana-app-services) | Contains all the key functionality of Kibana's unified search experience.Contains all the key functionality of Kibana's unified search experience. | 48 | 1 | 45 | 6 | +| | [Unified Search](https://github.com/orgs/elastic/teams/kibana-app-services) | Contains all the key functionality of Kibana's unified search experience.Contains all the key functionality of Kibana's unified search experience. | 79 | 2 | 75 | 11 | | upgradeAssistant | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | -| uptime | [Uptime](https://github.com/orgs/elastic/teams/uptime) | This plugin visualizes data from Synthetics and Heartbeat, and integrates with other Observability solutions. | 0 | 0 | 0 | 0 | | urlDrilldown | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds drilldown implementations to Kibana | 0 | 0 | 0 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | - | 12 | 0 | 12 | 0 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 58 | 0 | 15 | 1 | @@ -163,47 +162,57 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Registers the vega visualization. Is the elastic version of vega and vega-lite libraries. | 2 | 0 | 2 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the vislib visualizations. These are the classical area/line/bar, pie, gauge/goal and heatmap charts. We want to replace them with elastic-charts. | 26 | 0 | 25 | 1 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the new xy-axis chart using the elastic-charts library, which will eventually replace the vislib xy-axis charts including bar, area, and line. | 57 | 0 | 51 | 5 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the shared architecture among all the legacy visualizations, e.g. the visualization type registry or the visualization embeddable. | 363 | 12 | 342 | 14 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the shared architecture among all the legacy visualizations, e.g. the visualization type registry or the visualization embeddable. | 365 | 12 | 344 | 14 | | watcher | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | ## Package Directory | Package name           | Maintaining team | Description | API Cnt | Any Cnt | Missing
comments | Missing
exports | |--------------|----------------|-----------|--------------|----------|---------------|--------| -| | [Owner missing] | - | 82 | 1 | 11 | 0 | -| | [Owner missing] | Elastic APM trace data generator | 62 | 0 | 62 | 9 | -| | [Owner missing] | elasticsearch datemath parser, used in kibana | 44 | 0 | 43 | 0 | +| | [Owner missing] | Elastic APM trace data generator | 70 | 0 | 70 | 10 | | | [Owner missing] | - | 11 | 5 | 11 | 0 | | | [Owner missing] | Alerts components and hooks | 9 | 1 | 9 | 0 | | | Ahmad Bamieh ahmadbamieh@gmail.com | Kibana Analytics tool | 69 | 0 | 69 | 2 | +| | [Owner missing] | - | 88 | 1 | 10 | 0 | +| | [Owner missing] | - | 18 | 0 | 13 | 0 | | | [Owner missing] | - | 16 | 0 | 16 | 0 | | | [Owner missing] | - | 11 | 0 | 11 | 0 | | | [Owner missing] | - | 10 | 0 | 10 | 0 | -| | [Owner missing] | - | 12 | 0 | 5 | 1 | +| | [Owner missing] | - | 18 | 0 | 9 | 1 | +| | [Owner missing] | - | 4 | 0 | 4 | 0 | +| | [Owner missing] | - | 8 | 0 | 7 | 0 | +| | [Owner missing] | - | 7 | 0 | 2 | 0 | +| | [Owner missing] | - | 59 | 0 | 15 | 0 | | | [Owner missing] | - | 2 | 0 | 2 | 0 | -| | [Owner missing] | - | 66 | 0 | 46 | 2 | -| | [Owner missing] | - | 125 | 3 | 123 | 17 | +| | [Owner missing] | - | 106 | 0 | 80 | 1 | +| | [Owner missing] | - | 64 | 0 | 44 | 2 | +| | [Owner missing] | - | 129 | 3 | 127 | 17 | | | [Owner missing] | - | 13 | 0 | 7 | 0 | -| | [Owner missing] | - | 277 | 3 | 199 | 1 | -| | [Owner missing] | - | 63 | 0 | 63 | 2 | +| | [Owner missing] | elasticsearch datemath parser, used in kibana | 44 | 0 | 43 | 0 | +| | [Owner missing] | - | 120 | 3 | 109 | 0 | +| | [Owner missing] | - | 64 | 0 | 64 | 2 | | | [Owner missing] | - | 1 | 0 | 1 | 0 | | | [Owner missing] | - | 27 | 0 | 14 | 1 | | | [Owner missing] | - | 213 | 1 | 159 | 11 | -| | [Owner missing] | - | 13 | 0 | 6 | 0 | +| | [Owner missing] | - | 2 | 0 | 1 | 0 | | | [Owner missing] | - | 20 | 0 | 16 | 0 | +| | [Owner missing] | - | 2 | 0 | 0 | 0 | | | [Owner missing] | - | 1 | 0 | 0 | 0 | | | [Owner missing] | - | 51 | 0 | 48 | 0 | +| | [Owner missing] | - | 43 | 0 | 36 | 0 | | | App Services | - | 35 | 4 | 35 | 0 | | | [Owner missing] | - | 20 | 0 | 20 | 2 | +| | [Owner missing] | - | 13 | 0 | 13 | 0 | +| | [Owner missing] | - | 69 | 0 | 69 | 0 | | | [Owner missing] | - | 30 | 0 | 5 | 36 | | | [Owner missing] | - | 8 | 0 | 8 | 0 | -| | [Owner missing] | - | 466 | 1 | 1 | 0 | +| | [Owner missing] | - | 494 | 1 | 1 | 0 | | | [Owner missing] | - | 55 | 0 | 55 | 2 | | | [Owner missing] | - | 45 | 0 | 45 | 10 | -| | [Owner missing] | - | 28 | 0 | 27 | 0 | +| | [Owner missing] | - | 30 | 0 | 29 | 0 | | | [Owner missing] | - | 1 | 0 | 1 | 0 | | | [Owner missing] | Just some helpers for kibana plugin devs. | 1 | 0 | 1 | 0 | -| | [Owner missing] | - | 63 | 0 | 49 | 5 | +| | [Owner missing] | - | 47 | 0 | 35 | 5 | | | [Owner missing] | - | 21 | 0 | 10 | 0 | | | [Owner missing] | - | 74 | 0 | 71 | 0 | | | [Owner missing] | Security Solution auto complete | 50 | 1 | 35 | 0 | @@ -222,18 +231,22 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [Owner missing] | security solution utilities to use across plugins such lists, security_solution, cases, etc... | 31 | 0 | 29 | 0 | | | [Owner missing] | - | 53 | 0 | 50 | 1 | | | [Owner missing] | - | 25 | 0 | 24 | 1 | -| | [Owner missing] | - | 32 | 0 | 4 | 4 | +| | [Owner missing] | - | 12 | 0 | 2 | 3 | +| | [Owner missing] | - | 34 | 0 | 6 | 6 | | | [Owner missing] | - | 67 | 0 | 43 | 0 | | | [Owner missing] | - | 10 | 0 | 2 | 0 | | | [Owner missing] | - | 9 | 0 | 3 | 0 | -| | [Owner missing] | - | 96 | 1 | 63 | 2 | +| | [Owner missing] | - | 2 | 0 | 2 | 0 | +| | [Owner missing] | - | 92 | 1 | 59 | 1 | +| | [Owner missing] | - | 4 | 0 | 2 | 0 | | | Operations | - | 22 | 2 | 21 | 0 | | | [Owner missing] | - | 2 | 0 | 2 | 0 | | | Operations | - | 252 | 6 | 214 | 9 | | | [Owner missing] | - | 132 | 8 | 103 | 2 | +| | [Owner missing] | - | 72 | 0 | 55 | 0 | | | [Owner missing] | - | 29 | 0 | 2 | 0 | | | [Owner missing] | - | 83 | 0 | 83 | 1 | | | [Owner missing] | - | 7 | 0 | 6 | 0 | -| | [Owner missing] | - | 27 | 0 | 10 | 1 | +| | [Owner missing] | - | 28 | 0 | 10 | 1 | | | [Owner missing] | - | 31 | 1 | 21 | 0 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index ad2ac1542b0e2..edceb320dace9 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github summary: API docs for the presentationUtil plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationUtil'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index b4d4cc4459eb6..a05a7407d5658 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github summary: API docs for the remoteClusters plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'remoteClusters'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/reporting.mdx b/api_docs/reporting.mdx index 976c1fc50da8d..185a48b5d4218 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github summary: API docs for the reporting plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index febdb7ef3b9de..b9e0c8be22113 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github summary: API docs for the rollup plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'rollup'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/rule_registry.devdocs.json b/api_docs/rule_registry.devdocs.json index 7bf4b15d0ef30..194d13b78917a 100644 --- a/api_docs/rule_registry.devdocs.json +++ b/api_docs/rule_registry.devdocs.json @@ -1376,9 +1376,7 @@ }, ">) => Promise; id: string; name: string; validate?: { params?: ", "RuleTypeParamsValidator", - " | undefined; } | undefined; cancelAlertsOnRuleTimeout?: boolean | undefined; config?: ", - "RuleTypeConfig", - " | undefined; actionGroups: ", + " | undefined; } | undefined; cancelAlertsOnRuleTimeout?: boolean | undefined; actionGroups: ", { "pluginId": "alerting", "scope": "common", diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx index 854a6a476ec5a..e9a4921bf6d5a 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github summary: API docs for the ruleRegistry plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ruleRegistry'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/runtime_fields.mdx b/api_docs/runtime_fields.mdx index 8a045ddd337d6..f582632ea2d18 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github summary: API docs for the runtimeFields plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'runtimeFields'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/saved_objects.devdocs.json b/api_docs/saved_objects.devdocs.json index c8dbdfc152759..fe5794ec8c9ef 100644 --- a/api_docs/saved_objects.devdocs.json +++ b/api_docs/saved_objects.devdocs.json @@ -587,14 +587,6 @@ "plugin": "embeddable", "path": "src/plugins/embeddable/public/lib/attribute_service/attribute_service.tsx" }, - { - "plugin": "presentationUtil", - "path": "src/plugins/presentation_util/public/components/saved_object_save_modal_dashboard.tsx" - }, - { - "plugin": "presentationUtil", - "path": "src/plugins/presentation_util/public/components/saved_object_save_modal_dashboard.tsx" - }, { "plugin": "discover", "path": "src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx" @@ -603,6 +595,14 @@ "plugin": "discover", "path": "src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx" }, + { + "plugin": "presentationUtil", + "path": "src/plugins/presentation_util/public/components/saved_object_save_modal_dashboard.tsx" + }, + { + "plugin": "presentationUtil", + "path": "src/plugins/presentation_util/public/components/saved_object_save_modal_dashboard.tsx" + }, { "plugin": "dashboard", "path": "src/plugins/dashboard/public/services/saved_objects.ts" @@ -1607,22 +1607,6 @@ "plugin": "savedObjectsTaggingOss", "path": "src/plugins/saved_objects_tagging_oss/public/api.ts" }, - { - "plugin": "visualizations", - "path": "src/plugins/visualizations/public/utils/saved_objects_utils/display_duplicate_title_confirm_modal.ts" - }, - { - "plugin": "visualizations", - "path": "src/plugins/visualizations/public/utils/saved_objects_utils/display_duplicate_title_confirm_modal.ts" - }, - { - "plugin": "visualizations", - "path": "src/plugins/visualizations/public/utils/saved_objects_utils/check_for_duplicate_title.ts" - }, - { - "plugin": "visualizations", - "path": "src/plugins/visualizations/public/utils/saved_objects_utils/check_for_duplicate_title.ts" - }, { "plugin": "savedObjectsTaggingOss", "path": "src/plugins/saved_objects_tagging_oss/public/decorator/types.ts" @@ -1639,6 +1623,22 @@ "plugin": "savedObjectsTaggingOss", "path": "src/plugins/saved_objects_tagging_oss/public/api.ts" }, + { + "plugin": "visualizations", + "path": "src/plugins/visualizations/public/utils/saved_objects_utils/display_duplicate_title_confirm_modal.ts" + }, + { + "plugin": "visualizations", + "path": "src/plugins/visualizations/public/utils/saved_objects_utils/display_duplicate_title_confirm_modal.ts" + }, + { + "plugin": "visualizations", + "path": "src/plugins/visualizations/public/utils/saved_objects_utils/check_for_duplicate_title.ts" + }, + { + "plugin": "visualizations", + "path": "src/plugins/visualizations/public/utils/saved_objects_utils/check_for_duplicate_title.ts" + }, { "plugin": "dashboard", "path": "src/plugins/dashboard/public/services/saved_object_loader.ts" @@ -3191,44 +3191,7 @@ "path": "src/plugins/saved_objects/public/plugin.ts", "deprecated": true, "removeBy": "8.8.0", - "references": [ - { - "plugin": "visualizations", - "path": "src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx" - }, - { - "plugin": "visualizations", - "path": "src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx" - }, - { - "plugin": "dashboard", - "path": "src/plugins/dashboard/public/application/listing/dashboard_listing.tsx" - }, - { - "plugin": "dashboard", - "path": "src/plugins/dashboard/public/application/listing/dashboard_listing.tsx" - }, - { - "plugin": "maps", - "path": "x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx" - }, - { - "plugin": "maps", - "path": "x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx" - }, - { - "plugin": "maps", - "path": "x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx" - }, - { - "plugin": "graph", - "path": "x-pack/plugins/graph/public/apps/listing_route.tsx" - }, - { - "plugin": "graph", - "path": "x-pack/plugins/graph/public/apps/listing_route.tsx" - } - ] + "references": [] } ], "lifecycle": "start", diff --git a/api_docs/saved_objects.mdx b/api_docs/saved_objects.mdx index 977cd0b83c007..204b0f19f5d68 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github summary: API docs for the savedObjects plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjects'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/saved_objects_management.devdocs.json b/api_docs/saved_objects_management.devdocs.json index a7fe1019e0858..baa484f82f10d 100644 --- a/api_docs/saved_objects_management.devdocs.json +++ b/api_docs/saved_objects_management.devdocs.json @@ -278,7 +278,7 @@ "label": "euiColumn", "description": [], "signature": [ - "{ children?: React.ReactNode; onClick?: React.MouseEventHandler | undefined; onChange?: React.FormEventHandler | undefined; color?: string | undefined; onKeyDown?: React.KeyboardEventHandler | undefined; className?: string | undefined; title?: string | undefined; id?: string | undefined; description?: string | undefined; security?: string | undefined; name: React.ReactNode; field: (string & {}) | keyof ", + "{ children?: React.ReactNode; color?: string | undefined; className?: string | undefined; title?: string | undefined; onChange?: React.FormEventHandler | undefined; onKeyDown?: React.KeyboardEventHandler | undefined; onClick?: React.MouseEventHandler | undefined; id?: string | undefined; description?: string | undefined; security?: string | undefined; name: React.ReactNode; field: (string & {}) | keyof ", { "pluginId": "savedObjectsManagement", "scope": "public", @@ -501,7 +501,7 @@ "label": "obj", "description": [], "signature": [ - "{ type: string; id: string; meta: { title?: string | undefined; icon?: string | undefined; }; overwrite?: boolean | undefined; }" + "{ id: string; type: string; meta: { title?: string | undefined; icon?: string | undefined; }; overwrite?: boolean | undefined; }" ], "path": "src/plugins/saved_objects_management/public/lib/process_import_response.ts", "deprecated": false diff --git a/api_docs/saved_objects_management.mdx b/api_docs/saved_objects_management.mdx index 19d9efeb08286..0f610adb83a73 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github summary: API docs for the savedObjectsManagement plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsManagement'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/saved_objects_tagging.mdx b/api_docs/saved_objects_tagging.mdx index 10b3bdaa00b3f..e8b5d1d6a8d6b 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github summary: API docs for the savedObjectsTagging plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTagging'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/saved_objects_tagging_oss.mdx b/api_docs/saved_objects_tagging_oss.mdx index 9d5079950e171..ed29900a22d7a 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github summary: API docs for the savedObjectsTaggingOss plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTaggingOss'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/screenshot_mode.devdocs.json b/api_docs/screenshot_mode.devdocs.json index 65ac948800747..fead68be2cb62 100644 --- a/api_docs/screenshot_mode.devdocs.json +++ b/api_docs/screenshot_mode.devdocs.json @@ -96,51 +96,7 @@ "initialIsOpen": false } ], - "interfaces": [ - { - "parentPluginId": "screenshotMode", - "id": "def-server.ScreenshotModeRequestHandlerContext", - "type": "Interface", - "tags": [], - "label": "ScreenshotModeRequestHandlerContext", - "description": [], - "signature": [ - { - "pluginId": "screenshotMode", - "scope": "server", - "docId": "kibScreenshotModePluginApi", - "section": "def-server.ScreenshotModeRequestHandlerContext", - "text": "ScreenshotModeRequestHandlerContext" - }, - " extends ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCorePluginApi", - "section": "def-server.RequestHandlerContext", - "text": "RequestHandlerContext" - } - ], - "path": "src/plugins/screenshot_mode/server/types.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "screenshotMode", - "id": "def-server.ScreenshotModeRequestHandlerContext.screenshotMode", - "type": "Object", - "tags": [], - "label": "screenshotMode", - "description": [], - "signature": [ - "{ isScreenshot: boolean; }" - ], - "path": "src/plugins/screenshot_mode/server/types.ts", - "deprecated": false - } - ], - "initialIsOpen": false - } - ], + "interfaces": [], "enums": [], "misc": [ { @@ -167,6 +123,27 @@ "path": "src/plugins/screenshot_mode/common/constants.ts", "deprecated": false, "initialIsOpen": false + }, + { + "parentPluginId": "screenshotMode", + "id": "def-server.ScreenshotModeRequestHandlerContext", + "type": "Type", + "tags": [], + "label": "ScreenshotModeRequestHandlerContext", + "description": [], + "signature": [ + { + "pluginId": "core", + "scope": "server", + "docId": "kibCorePluginApi", + "section": "def-server.RequestHandlerContext", + "text": "RequestHandlerContext" + }, + " & { screenshotMode: Promise<{ isScreenshot: boolean; }>; }" + ], + "path": "src/plugins/screenshot_mode/server/types.ts", + "deprecated": false, + "initialIsOpen": false } ], "objects": [], diff --git a/api_docs/screenshot_mode.mdx b/api_docs/screenshot_mode.mdx index ad29af1bd007a..5782e32098b7f 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github summary: API docs for the screenshotMode plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotMode'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 33 | 0 | 14 | 0 | +| 32 | 0 | 13 | 0 | ## Client @@ -42,9 +42,6 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services ### Functions -### Interfaces - - ### Consts, variables and types diff --git a/api_docs/screenshotting.devdocs.json b/api_docs/screenshotting.devdocs.json index fe79cd45375c2..7b1a506b3accb 100644 --- a/api_docs/screenshotting.devdocs.json +++ b/api_docs/screenshotting.devdocs.json @@ -4,8 +4,47 @@ "classes": [], "functions": [], "interfaces": [], - "enums": [], - "misc": [], + "enums": [ + { + "parentPluginId": "screenshotting", + "id": "def-public.LayoutTypes", + "type": "Enum", + "tags": [], + "label": "LayoutTypes", + "description": [ + "\nSupported layout types." + ], + "path": "x-pack/plugins/screenshotting/common/layout.ts", + "deprecated": false, + "initialIsOpen": false + } + ], + "misc": [ + { + "parentPluginId": "screenshotting", + "id": "def-public.LayoutParams", + "type": "Type", + "tags": [], + "label": "LayoutParams", + "description": [ + "\nScreenshot layout parameters." + ], + "signature": [ + "{ id?: Id | undefined; dimensions?: { width: number; height: number; } | undefined; selectors?: Partial<", + "LayoutSelectorDictionary", + "> | undefined; zoom?: number | undefined; } extends ", + "SerializableRecord", + " ? ", + "SerializableRecord", + " & { id?: Id | undefined; dimensions?: { width: number; height: number; } | undefined; selectors?: Partial<", + "LayoutSelectorDictionary", + "> | undefined; zoom?: number | undefined; } : never" + ], + "path": "x-pack/plugins/screenshotting/common/layout.ts", + "deprecated": false, + "initialIsOpen": false + } + ], "objects": [] }, "server": { @@ -30,19 +69,35 @@ "text": "PdfScreenshotOptions" }, " extends ", - "ScreenshotOptions", - "<\"pdf\">" + "CaptureOptions" ], "path": "x-pack/plugins/screenshotting/server/formats/pdf/index.ts", "deprecated": false, "children": [ + { + "parentPluginId": "screenshotting", + "id": "def-server.PdfScreenshotOptions.format", + "type": "string", + "tags": [], + "label": "format", + "description": [ + "\nWhether to format the output as a PDF." + ], + "signature": [ + "\"pdf\"" + ], + "path": "x-pack/plugins/screenshotting/server/formats/pdf/index.ts", + "deprecated": false + }, { "parentPluginId": "screenshotting", "id": "def-server.PdfScreenshotOptions.title", "type": "string", "tags": [], "label": "title", - "description": [], + "description": [ + "\nDocument title." + ], "signature": [ "string | undefined" ], @@ -55,7 +110,9 @@ "type": "string", "tags": [], "label": "logo", - "description": [], + "description": [ + "\nLogo at the footer." + ], "signature": [ "string | undefined" ], @@ -72,9 +129,17 @@ "\nWe default to the \"print\" layout if no ID is specified for the layout" ], "signature": [ - "{ id?: \"canvas\" | \"print\" | \"preserve_layout\" | undefined; dimensions?: { width: number; height: number; } | undefined; selectors?: Partial<", + "{ id?: ", + { + "pluginId": "screenshotting", + "scope": "common", + "docId": "kibScreenshottingPluginApi", + "section": "def-common.LayoutTypes", + "text": "LayoutTypes" + }, + " | undefined; dimensions?: { width: number; height: number; } | undefined; selectors?: Partial<", "LayoutSelectorDictionary", - "> | undefined; zoom?: number | undefined; }" + "> | undefined; zoom?: number | undefined; } | undefined" ], "path": "x-pack/plugins/screenshotting/server/formats/pdf/index.ts", "deprecated": false @@ -91,50 +156,65 @@ "description": [ "\nFinal, formatted PDF result" ], - "signature": [ - { - "pluginId": "screenshotting", - "scope": "server", - "docId": "kibScreenshottingPluginApi", - "section": "def-server.PdfScreenshotResult", - "text": "PdfScreenshotResult" - }, - " extends Omit<", - { - "pluginId": "screenshotting", - "scope": "server", - "docId": "kibScreenshottingPluginApi", - "section": "def-server.FormattedScreenshotResult", - "text": "FormattedScreenshotResult" - }, - ", \"results\">" - ], "path": "x-pack/plugins/screenshotting/server/formats/pdf/index.ts", "deprecated": false, "children": [ { "parentPluginId": "screenshotting", "id": "def-server.PdfScreenshotResult.metrics", - "type": "CompoundType", + "type": "Object", "tags": [], "label": "metrics", - "description": [], + "description": [ + "\nCollected performance metrics during the screenshotting session along with the PDF generation ones." + ], "signature": [ - "PerformanceMetrics", - " & { pageCount: number; }" + "PdfScreenshotMetrics" ], "path": "x-pack/plugins/screenshotting/server/formats/pdf/index.ts", "deprecated": false }, { "parentPluginId": "screenshotting", - "id": "def-server.PdfScreenshotResult.result", + "id": "def-server.PdfScreenshotResult.data", "type": "Object", "tags": [], - "label": "result", - "description": [], + "label": "data", + "description": [ + "\nPDF document data buffer." + ], "signature": [ - "{ data: Buffer; errors: Error[]; renderErrors: string[]; }" + "Buffer" + ], + "path": "x-pack/plugins/screenshotting/server/formats/pdf/index.ts", + "deprecated": false + }, + { + "parentPluginId": "screenshotting", + "id": "def-server.PdfScreenshotResult.errors", + "type": "Array", + "tags": [], + "label": "errors", + "description": [ + "\nAny errors that were encountered while create the PDF and navigating between pages" + ], + "signature": [ + "Error[]" + ], + "path": "x-pack/plugins/screenshotting/server/formats/pdf/index.ts", + "deprecated": false + }, + { + "parentPluginId": "screenshotting", + "id": "def-server.PdfScreenshotResult.renderErrors", + "type": "Array", + "tags": [], + "label": "renderErrors", + "description": [ + "\nAny render errors that could mean some visualizations are missing from the end result." + ], + "signature": [ + "string[]" ], "path": "x-pack/plugins/screenshotting/server/formats/pdf/index.ts", "deprecated": false @@ -160,68 +240,47 @@ "text": "PngScreenshotOptions" }, " extends ", - "ScreenshotOptions", - "<\"png\">" + "CaptureOptions" ], "path": "x-pack/plugins/screenshotting/server/formats/png.ts", "deprecated": false, "children": [ { "parentPluginId": "screenshotting", - "id": "def-server.PngScreenshotOptions.layout", - "type": "Object", - "tags": [], - "label": "layout", - "description": [], + "id": "def-server.PngScreenshotOptions.format", + "type": "string", + "tags": [ + "default" + ], + "label": "format", + "description": [ + "\nWhether to format the output as a PNG." + ], "signature": [ - "{ id?: \"preserve_layout\" | undefined; dimensions?: { width: number; height: number; } | undefined; selectors?: Partial<", - "LayoutSelectorDictionary", - "> | undefined; zoom?: number | undefined; }" + "\"png\" | undefined" ], "path": "x-pack/plugins/screenshotting/server/formats/png.ts", "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "screenshotting", - "id": "def-server.PngScreenshotResult", - "type": "Interface", - "tags": [], - "label": "PngScreenshotResult", - "description": [ - "\nThe final output of a PNG screenshot" - ], - "signature": [ - { - "pluginId": "screenshotting", - "scope": "server", - "docId": "kibScreenshottingPluginApi", - "section": "def-server.PngScreenshotResult", - "text": "PngScreenshotResult" }, - " extends ", - { - "pluginId": "screenshotting", - "scope": "server", - "docId": "kibScreenshottingPluginApi", - "section": "def-server.FormattedScreenshotResult", - "text": "FormattedScreenshotResult" - } - ], - "path": "x-pack/plugins/screenshotting/server/formats/png.ts", - "deprecated": false, - "children": [ { "parentPluginId": "screenshotting", - "id": "def-server.PngScreenshotResult.metadata", - "type": "Uncategorized", + "id": "def-server.PngScreenshotOptions.layout", + "type": "Object", "tags": [], - "label": "metadata", + "label": "layout", "description": [], "signature": [ - "undefined" + "{ id?: ", + { + "pluginId": "screenshotting", + "scope": "common", + "docId": "kibScreenshottingPluginApi", + "section": "def-common.LayoutTypes", + "text": "LayoutTypes" + }, + ".PRESERVE_LAYOUT | undefined; dimensions?: { width: number; height: number; } | undefined; selectors?: Partial<", + "LayoutSelectorDictionary", + "> | undefined; zoom?: number | undefined; } | undefined" ], "path": "x-pack/plugins/screenshotting/server/formats/png.ts", "deprecated": false @@ -234,50 +293,67 @@ "misc": [ { "parentPluginId": "screenshotting", - "id": "def-server.FormattedScreenshotResult", + "id": "def-server.PngScreenshotResult", "type": "Type", "tags": [], - "label": "FormattedScreenshotResult", + "label": "PngScreenshotResult", "description": [ - "\nA general, overridable type of screenshot result\n\nPDF or PNG screenshots should extend this and convert the output to a type\nthat best suits their use cases.\n\nThis type documents what might appear on any given output type" + "\nThe final output of a PNG screenshot" ], "signature": [ - "{ metrics?: ", - "PerformanceMetrics", - " | undefined; results: ", - "ScreenshotObservableResult", - "[]; }" + "CaptureResult" ], - "path": "x-pack/plugins/screenshotting/server/formats/types.ts", + "path": "x-pack/plugins/screenshotting/server/formats/png.ts", "deprecated": false, "initialIsOpen": false }, { "parentPluginId": "screenshotting", - "id": "def-server.Layout", + "id": "def-server.ScreenshotOptions", "type": "Type", "tags": [], - "label": "Layout", + "label": "ScreenshotOptions", "description": [], "signature": [ - "BaseLayout", - " & LayoutSelectors & Partial<{ width: number; height: number; }>" + { + "pluginId": "screenshotting", + "scope": "server", + "docId": "kibScreenshottingPluginApi", + "section": "def-server.PdfScreenshotOptions", + "text": "PdfScreenshotOptions" + }, + " | ", + { + "pluginId": "screenshotting", + "scope": "server", + "docId": "kibScreenshottingPluginApi", + "section": "def-server.PngScreenshotOptions", + "text": "PngScreenshotOptions" + } ], - "path": "x-pack/plugins/screenshotting/server/layouts/index.ts", + "path": "x-pack/plugins/screenshotting/server/screenshots/index.ts", "deprecated": false, "initialIsOpen": false }, { "parentPluginId": "screenshotting", - "id": "def-server.UrlOrUrlWithContext", + "id": "def-server.ScreenshotResult", "type": "Type", "tags": [], - "label": "UrlOrUrlWithContext", + "label": "ScreenshotResult", "description": [], "signature": [ - "string | UrlWithContext" + { + "pluginId": "screenshotting", + "scope": "server", + "docId": "kibScreenshottingPluginApi", + "section": "def-server.PdfScreenshotResult", + "text": "PdfScreenshotResult" + }, + " | ", + "CaptureResult" ], - "path": "x-pack/plugins/screenshotting/server/screenshots/observable.ts", + "path": "x-pack/plugins/screenshotting/server/screenshots/index.ts", "deprecated": false, "initialIsOpen": false } @@ -340,25 +416,29 @@ "\nTakes screenshots of multiple pages." ], "signature": [ - "; (options: ", { "pluginId": "screenshotting", "scope": "server", "docId": "kibScreenshottingPluginApi", - "section": "def-server.PngScreenshotOptions", - "text": "PngScreenshotOptions" + "section": "def-server.PdfScreenshotOptions", + "text": "PdfScreenshotOptions" }, - ">(options: O) => ", + "): ", "Observable", - "; (options: ", { "pluginId": "screenshotting", "scope": "server", "docId": "kibScreenshottingPluginApi", - "section": "def-server.PngScreenshotResult", - "text": "PngScreenshotResult" + "section": "def-server.ScreenshotOptions", + "text": "ScreenshotOptions" }, - ">" - ], - "path": "x-pack/plugins/screenshotting/server/plugin.ts", - "deprecated": false, - "children": [ + "): ", + "Observable", + "<", { - "parentPluginId": "screenshotting", - "id": "def-server.ScreenshottingStart.getScreenshots.$1", - "type": "Uncategorized", - "tags": [], - "label": "options", - "description": [ - "Screenshots session options." - ], - "signature": [ - "O" - ], - "path": "x-pack/plugins/screenshotting/server/plugin.ts", - "deprecated": false, - "isRequired": true - } + "pluginId": "screenshotting", + "scope": "server", + "docId": "kibScreenshottingPluginApi", + "section": "def-server.ScreenshotResult", + "text": "ScreenshotResult" + }, + ">; }" ], - "returnComment": [ - "Observable with screenshotting results." - ] + "path": "x-pack/plugins/screenshotting/server/plugin.ts", + "deprecated": false } ], "lifecycle": "start", @@ -409,7 +478,21 @@ "classes": [], "functions": [], "interfaces": [], - "enums": [], + "enums": [ + { + "parentPluginId": "screenshotting", + "id": "def-common.LayoutTypes", + "type": "Enum", + "tags": [], + "label": "LayoutTypes", + "description": [ + "\nSupported layout types." + ], + "path": "x-pack/plugins/screenshotting/common/layout.ts", + "deprecated": false, + "initialIsOpen": false + } + ], "misc": [ { "parentPluginId": "screenshotting", @@ -421,76 +504,63 @@ "\nScreenshot layout parameters." ], "signature": [ - "{ id?: ID | undefined; dimensions?: { width: number; height: number; } | undefined; selectors?: Partial<", + "{ id?: Id | undefined; dimensions?: { width: number; height: number; } | undefined; selectors?: Partial<", "LayoutSelectorDictionary", "> | undefined; zoom?: number | undefined; } extends ", "SerializableRecord", " ? ", "SerializableRecord", - " & { id?: ID | undefined; dimensions?: { width: number; height: number; } | undefined; selectors?: Partial<", + " & { id?: Id | undefined; dimensions?: { width: number; height: number; } | undefined; selectors?: Partial<", "LayoutSelectorDictionary", "> | undefined; zoom?: number | undefined; } : never" ], "path": "x-pack/plugins/screenshotting/common/layout.ts", "deprecated": false, "initialIsOpen": false - } - ], - "objects": [ + }, { "parentPluginId": "screenshotting", - "id": "def-common.LayoutTypes", - "type": "Object", + "id": "def-common.SCREENSHOTTING_APP_ID", + "type": "string", "tags": [], - "label": "LayoutTypes", - "description": [ - "\nSupported layout types." + "label": "SCREENSHOTTING_APP_ID", + "description": [], + "signature": [ + "\"screenshotting\"" ], - "path": "x-pack/plugins/screenshotting/common/layout.ts", + "path": "x-pack/plugins/screenshotting/common/expression.ts", "deprecated": false, - "children": [ - { - "parentPluginId": "screenshotting", - "id": "def-common.LayoutTypes.PRESERVE_LAYOUT", - "type": "string", - "tags": [], - "label": "PRESERVE_LAYOUT", - "description": [], - "signature": [ - "\"preserve_layout\"" - ], - "path": "x-pack/plugins/screenshotting/common/layout.ts", - "deprecated": false - }, - { - "parentPluginId": "screenshotting", - "id": "def-common.LayoutTypes.PRINT", - "type": "string", - "tags": [], - "label": "PRINT", - "description": [], - "signature": [ - "\"print\"" - ], - "path": "x-pack/plugins/screenshotting/common/layout.ts", - "deprecated": false - }, - { - "parentPluginId": "screenshotting", - "id": "def-common.LayoutTypes.CANVAS", - "type": "string", - "tags": [], - "label": "CANVAS", - "description": [], - "signature": [ - "\"canvas\"" - ], - "path": "x-pack/plugins/screenshotting/common/layout.ts", - "deprecated": false - } + "initialIsOpen": false + }, + { + "parentPluginId": "screenshotting", + "id": "def-common.SCREENSHOTTING_EXPRESSION", + "type": "string", + "tags": [], + "label": "SCREENSHOTTING_EXPRESSION", + "description": [], + "signature": [ + "\"expression\"" + ], + "path": "x-pack/plugins/screenshotting/common/expression.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "screenshotting", + "id": "def-common.SCREENSHOTTING_EXPRESSION_INPUT", + "type": "string", + "tags": [], + "label": "SCREENSHOTTING_EXPRESSION_INPUT", + "description": [], + "signature": [ + "\"input\"" ], + "path": "x-pack/plugins/screenshotting/common/expression.ts", + "deprecated": false, "initialIsOpen": false } - ] + ], + "objects": [] } } \ No newline at end of file diff --git a/api_docs/screenshotting.mdx b/api_docs/screenshotting.mdx index fb6bac64aa793..c61700bd608f0 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github summary: API docs for the screenshotting plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,15 @@ Contact [Kibana Reporting Services](https://github.com/orgs/elastic/teams/kibana | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 24 | 0 | 12 | 5 | +| 27 | 0 | 7 | 4 | + +## Client + +### Enums + + +### Consts, variables and types + ## Server @@ -33,8 +41,8 @@ Contact [Kibana Reporting Services](https://github.com/orgs/elastic/teams/kibana ## Common -### Objects - +### Enums + ### Consts, variables and types diff --git a/api_docs/security.mdx b/api_docs/security.mdx index c2ca4891fb327..bcb2ef6b82133 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github summary: API docs for the security plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/security_solution.devdocs.json b/api_docs/security_solution.devdocs.json index b8e6e83318a0b..07770d1883ef0 100644 --- a/api_docs/security_solution.devdocs.json +++ b/api_docs/security_solution.devdocs.json @@ -62,7 +62,7 @@ "label": "experimentalFeatures", "description": [], "signature": [ - "{ readonly metricsEntitiesEnabled: boolean; readonly ruleRegistryEnabled: boolean; readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly usersEnabled: boolean; readonly detectionResponseEnabled: boolean; readonly disableIsolationUIPendingStatuses: boolean; readonly riskyHostsEnabled: boolean; readonly riskyUsersEnabled: boolean; readonly securityRulesCancelEnabled: boolean; readonly pendingActionResponsesWithAck: boolean; readonly policyListEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly responseActionsConsoleEnabled: boolean; }" + "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly usersEnabled: boolean; readonly detectionResponseEnabled: boolean; readonly disableIsolationUIPendingStatuses: boolean; readonly riskyHostsEnabled: boolean; readonly riskyUsersEnabled: boolean; readonly pendingActionResponsesWithAck: boolean; readonly policyListEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly responseActionsConsoleEnabled: boolean; }" ], "path": "x-pack/plugins/security_solution/public/plugin.tsx", "deprecated": false @@ -302,7 +302,9 @@ "PinnedEvent", ">; resolveTimelineConfig?: ", "ResolveTimelineConfig", - " | undefined; showSaveModal?: boolean | undefined; savedQueryId?: string | null | undefined; sessionViewId: string | null; show: boolean; status: ", + " | undefined; showSaveModal?: boolean | undefined; savedQueryId?: string | null | undefined; sessionViewConfig: ", + "SessionViewConfig", + " | null; show: boolean; status: ", "TimelineStatus", "; updated?: number | undefined; updatedBy?: string | null | undefined; isSaving: boolean; version: string | null; initialized?: boolean | undefined; }" ], @@ -704,26 +706,28 @@ "tags": [], "label": "SecuritySolutionApiRequestHandlerContext", "description": [], - "signature": [ - { - "pluginId": "securitySolution", - "scope": "server", - "docId": "kibSecuritySolutionPluginApi", - "section": "def-server.SecuritySolutionApiRequestHandlerContext", - "text": "SecuritySolutionApiRequestHandlerContext" - }, - " extends ", - { - "pluginId": "core", - "scope": "server", - "docId": "kibCorePluginApi", - "section": "def-server.RequestHandlerContext", - "text": "RequestHandlerContext" - } - ], "path": "x-pack/plugins/security_solution/server/types.ts", "deprecated": false, "children": [ + { + "parentPluginId": "securitySolution", + "id": "def-server.SecuritySolutionApiRequestHandlerContext.core", + "type": "Object", + "tags": [], + "label": "core", + "description": [], + "signature": [ + { + "pluginId": "core", + "scope": "server", + "docId": "kibCorePluginApi", + "section": "def-server.CoreRequestHandlerContext", + "text": "CoreRequestHandlerContext" + } + ], + "path": "x-pack/plugins/security_solution/server/types.ts", + "deprecated": false + }, { "parentPluginId": "securitySolution", "id": "def-server.SecuritySolutionApiRequestHandlerContext.endpointAuthz", @@ -887,7 +891,7 @@ "label": "ConfigType", "description": [], "signature": [ - "Readonly<{} & { signalsIndex: string; maxRuleImportExportSize: number; maxRuleImportPayloadBytes: number; maxTimelineImportExportSize: number; maxTimelineImportPayloadBytes: number; alertMergeStrategy: \"allFields\" | \"missingFields\" | \"noFields\"; alertIgnoreFields: string[]; enableExperimental: string[]; packagerTaskInterval: string; prebuiltRulesFromFileSystem: boolean; prebuiltRulesFromSavedObjects: boolean; }> & { experimentalFeatures: Readonly<{ metricsEntitiesEnabled: boolean; ruleRegistryEnabled: boolean; tGridEnabled: boolean; tGridEventRenderedViewEnabled: boolean; excludePoliciesInFilterEnabled: boolean; usersEnabled: boolean; detectionResponseEnabled: boolean; disableIsolationUIPendingStatuses: boolean; riskyHostsEnabled: boolean; riskyUsersEnabled: boolean; securityRulesCancelEnabled: boolean; pendingActionResponsesWithAck: boolean; policyListEnabled: boolean; previewTelemetryUrlEnabled: boolean; responseActionsConsoleEnabled: boolean; }>; }" + "Readonly<{} & { signalsIndex: string; maxRuleImportExportSize: number; maxRuleImportPayloadBytes: number; maxTimelineImportExportSize: number; maxTimelineImportPayloadBytes: number; alertMergeStrategy: \"allFields\" | \"missingFields\" | \"noFields\"; alertIgnoreFields: string[]; enableExperimental: string[]; packagerTaskInterval: string; prebuiltRulesFromFileSystem: boolean; prebuiltRulesFromSavedObjects: boolean; }> & { experimentalFeatures: Readonly<{ tGridEnabled: boolean; tGridEventRenderedViewEnabled: boolean; excludePoliciesInFilterEnabled: boolean; usersEnabled: boolean; detectionResponseEnabled: boolean; disableIsolationUIPendingStatuses: boolean; riskyHostsEnabled: boolean; riskyUsersEnabled: boolean; pendingActionResponsesWithAck: boolean; policyListEnabled: boolean; previewTelemetryUrlEnabled: boolean; responseActionsConsoleEnabled: boolean; }>; }" ], "path": "x-pack/plugins/security_solution/server/config.ts", "deprecated": false, diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index 52564d9c3f7ad..12032a091582a 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github summary: API docs for the securitySolution plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Security solution](https://github.com/orgs/elastic/teams/security-solut | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 45 | 0 | 45 | 18 | +| 46 | 0 | 46 | 19 | ## Client diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index 8d8ff594c127f..86ade737ae827 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github summary: API docs for the sessionView plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sessionView'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/share.mdx b/api_docs/share.mdx index 04dfc6ca76d26..571fa5d590783 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github summary: API docs for the share plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/shared_u_x.mdx b/api_docs/shared_u_x.mdx index 555c0c3a3c255..d255d87e8bd8e 100644 --- a/api_docs/shared_u_x.mdx +++ b/api_docs/shared_u_x.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/sharedUX title: "sharedUX" image: https://source.unsplash.com/400x175/?github summary: API docs for the sharedUX plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sharedUX'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index de02f4b4b2387..ee9d6cb524f39 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github summary: API docs for the snapshotRestore plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'snapshotRestore'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/spaces.mdx b/api_docs/spaces.mdx index cd2fa16dd5876..6c7d81d1ad99c 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github summary: API docs for the spaces plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'spaces'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/stack_alerts.mdx b/api_docs/stack_alerts.mdx index c48f110748511..dedfaf95ecd53 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github summary: API docs for the stackAlerts plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackAlerts'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/task_manager.mdx b/api_docs/task_manager.mdx index cade7c0b9b88e..87ff82d41875d 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github summary: API docs for the taskManager plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'taskManager'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/telemetry.devdocs.json b/api_docs/telemetry.devdocs.json index c95f1325348d3..c1b9f1acae9fa 100644 --- a/api_docs/telemetry.devdocs.json +++ b/api_docs/telemetry.devdocs.json @@ -158,6 +158,21 @@ ], "path": "src/plugins/telemetry/public/plugin.ts", "deprecated": false + }, + { + "parentPluginId": "telemetry", + "id": "def-public.TelemetryPluginConfig.hidePrivacyStatement", + "type": "CompoundType", + "tags": [], + "label": "hidePrivacyStatement", + "description": [ + "Should we hide the privacy statement notice? Useful on some environments, e.g. Cloud" + ], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/telemetry/public/plugin.ts", + "deprecated": false } ], "initialIsOpen": false diff --git a/api_docs/telemetry.mdx b/api_docs/telemetry.mdx index 94652e3525420..29c538adcdd73 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github summary: API docs for the telemetry plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetry'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetr | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 43 | 0 | 1 | 0 | +| 44 | 0 | 1 | 0 | ## Client diff --git a/api_docs/telemetry_collection_manager.mdx b/api_docs/telemetry_collection_manager.mdx index af2ea6cc6e530..2b4bb32e9071a 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github summary: API docs for the telemetryCollectionManager plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx index 1034c582fe31a..dae291cc27ca0 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github summary: API docs for the telemetryCollectionXpack plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index 7067c7e1d3ae6..0d8f8313d1651 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github summary: API docs for the telemetryManagementSection plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/timelines.devdocs.json b/api_docs/timelines.devdocs.json index 4853c844a07fe..aa0ca4894966c 100644 --- a/api_docs/timelines.devdocs.json +++ b/api_docs/timelines.devdocs.json @@ -2594,7 +2594,7 @@ "label": "TGridModelForTimeline", "description": [], "signature": [ - "{ columns: (Pick<", + "{ title: string; columns: (Pick<", "EuiDataGridColumn", ", \"id\" | \"display\" | \"displayAsText\" | \"initialWidth\"> & Pick<", "EuiDataGridColumn", @@ -2610,7 +2610,7 @@ }, "; description?: string | null | undefined; example?: string | number | null | undefined; format?: string | undefined; linkField?: string | undefined; placeholder?: string | undefined; subType?: ", "IFieldSubType", - " | undefined; type?: string | undefined; })[]; title: string; id: string; filters?: ", + " | undefined; type?: string | undefined; })[]; id: string; filters?: ", "Filter", "[] | undefined; dataViewId: string | null; sort: ", "SortColumnTimeline", @@ -4927,15 +4927,7 @@ "label": "renderRow", "description": [], "signature": [ - "({ browserFields, data, isDraggable, timelineId, }: { browserFields: Readonly>>; data: ", + "({ data, isDraggable, timelineId, }: { data: ", "Ecs", "; isDraggable: boolean; timelineId: string; }) => React.ReactNode" ], @@ -4947,32 +4939,11 @@ "id": "def-common.RowRenderer.renderRow.$1", "type": "Object", "tags": [], - "label": "{\n browserFields,\n data,\n isDraggable,\n timelineId,\n }", + "label": "{\n data,\n isDraggable,\n timelineId,\n }", "description": [], "path": "x-pack/plugins/timelines/common/types/timeline/rows/index.ts", "deprecated": false, "children": [ - { - "parentPluginId": "timelines", - "id": "def-common.RowRenderer.renderRow.$1.browserFields", - "type": "Object", - "tags": [], - "label": "browserFields", - "description": [], - "signature": [ - "{ readonly [x: string]: Partial<", - { - "pluginId": "timelines", - "scope": "common", - "docId": "kibTimelinesPluginApi", - "section": "def-common.BrowserField", - "text": "BrowserField" - }, - ">; }" - ], - "path": "x-pack/plugins/timelines/common/types/timeline/rows/index.ts", - "deprecated": false - }, { "parentPluginId": "timelines", "id": "def-common.RowRenderer.renderRow.$1.data", @@ -6439,7 +6410,7 @@ "label": "DataProvidersAnd", "description": [], "signature": [ - "{ type?: ", + "{ id: string; type?: ", { "pluginId": "timelines", "scope": "common", @@ -6447,7 +6418,7 @@ "section": "def-common.DataProviderType", "text": "DataProviderType" }, - " | undefined; id: string; name: string; enabled: boolean; excluded: boolean; kqlQuery: string; queryMatch: ", + " | undefined; name: string; enabled: boolean; excluded: boolean; kqlQuery: string; queryMatch: ", { "pluginId": "timelines", "scope": "common", diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx index 1c5a341eabe9a..c0002d87729aa 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github summary: API docs for the timelines plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'timelines'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Security solution](https://github.com/orgs/elastic/teams/security-solut | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 435 | 1 | 331 | 35 | +| 434 | 1 | 330 | 35 | ## Client diff --git a/api_docs/transform.mdx b/api_docs/transform.mdx index ea19c16ba59fe..fe76107b5c7af 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github summary: API docs for the transform plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'transform'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/triggers_actions_ui.devdocs.json b/api_docs/triggers_actions_ui.devdocs.json index 16508005f0572..5c5963cb8c7bd 100644 --- a/api_docs/triggers_actions_ui.devdocs.json +++ b/api_docs/triggers_actions_ui.devdocs.json @@ -54,7 +54,7 @@ "label": "experimentalFeatures", "description": [], "signature": [ - "{ readonly rulesListDatagrid: boolean; readonly internalAlertsTable: boolean; readonly rulesDetailLogs: boolean; }" + "{ readonly rulesListDatagrid: boolean; readonly internalAlertsTable: boolean; readonly internalShareableComponentsSandbox: boolean; readonly rulesDetailLogs: boolean; }" ], "path": "x-pack/plugins/triggers_actions_ui/public/plugin.ts", "deprecated": false @@ -1323,6 +1323,85 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.snoozeRule", + "type": "Function", + "tags": [], + "label": "snoozeRule", + "description": [], + "signature": [ + "({\n id,\n snoozeEndTime,\n http,\n}: { id: string; snoozeEndTime: string | -1; http: ", + { + "pluginId": "core", + "scope": "public", + "docId": "kibCoreHttpPluginApi", + "section": "def-public.HttpSetup", + "text": "HttpSetup" + }, + "; }) => Promise" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/snooze.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.snoozeRule.$1", + "type": "Object", + "tags": [], + "label": "{\n id,\n snoozeEndTime,\n http,\n}", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/snooze.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.snoozeRule.$1.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/snooze.ts", + "deprecated": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.snoozeRule.$1.snoozeEndTime", + "type": "CompoundType", + "tags": [], + "label": "snoozeEndTime", + "description": [], + "signature": [ + "string | -1" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/snooze.ts", + "deprecated": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.snoozeRule.$1.http", + "type": "Object", + "tags": [], + "label": "http", + "description": [], + "signature": [ + { + "pluginId": "core", + "scope": "public", + "docId": "kibCoreHttpPluginApi", + "section": "def-public.HttpSetup", + "text": "HttpSetup" + } + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/snooze.ts", + "deprecated": false + } + ] + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-public.ThresholdExpression", @@ -1421,6 +1500,72 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.unsnoozeRule", + "type": "Function", + "tags": [], + "label": "unsnoozeRule", + "description": [], + "signature": [ + "({ id, http }: { id: string; http: ", + { + "pluginId": "core", + "scope": "public", + "docId": "kibCoreHttpPluginApi", + "section": "def-public.HttpSetup", + "text": "HttpSetup" + }, + "; }) => Promise" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/unsnooze.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.unsnoozeRule.$1", + "type": "Object", + "tags": [], + "label": "{ id, http }", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/unsnooze.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.unsnoozeRule.$1.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/unsnooze.ts", + "deprecated": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.unsnoozeRule.$1.http", + "type": "Object", + "tags": [], + "label": "http", + "description": [], + "signature": [ + { + "pluginId": "core", + "scope": "public", + "docId": "kibCoreHttpPluginApi", + "section": "def-public.HttpSetup", + "text": "HttpSetup" + } + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/unsnooze.ts", + "deprecated": false + } + ] + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-public.useLoadRuleTypes", @@ -2487,6 +2632,19 @@ "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", "deprecated": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.RuleTypeParamsExpressionProps.dataViews", + "type": "Object", + "tags": [], + "label": "dataViews", + "description": [], + "signature": [ + "DataViewsServicePublic" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-public.RuleTypeParamsExpressionProps.unifiedSearch", @@ -2555,6 +2713,19 @@ "path": "x-pack/plugins/triggers_actions_ui/public/application/app.tsx", "deprecated": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.TriggersAndActionsUiServices.dataViews", + "type": "Object", + "tags": [], + "label": "dataViews", + "description": [], + "signature": [ + "DataViewsServicePublic" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/app.tsx", + "deprecated": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-public.TriggersAndActionsUiServices.charts", @@ -2760,6 +2931,25 @@ "path": "x-pack/plugins/triggers_actions_ui/public/application/app.tsx", "deprecated": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.TriggersAndActionsUiServices.alertsTableConfigurationRegistry", + "type": "Object", + "tags": [], + "label": "alertsTableConfigurationRegistry", + "description": [], + "signature": [ + "{ list: () => ", + "AlertsTableConfigurationRegistry", + "[]; get: (id: string) => ", + "AlertsTableConfigurationRegistry", + "; register: (objectType: ", + "AlertsTableConfigurationRegistry", + ") => void; has: (id: string) => boolean; }" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/app.tsx", + "deprecated": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-public.TriggersAndActionsUiServices.history", @@ -3031,6 +3221,20 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.PLUGIN_ID", + "type": "string", + "tags": [], + "label": "PLUGIN_ID", + "description": [], + "signature": [ + "\"triggersActions\"" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/common/constants/index.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-public.Rule", @@ -3993,6 +4197,22 @@ ], "path": "x-pack/plugins/triggers_actions_ui/public/plugin.ts", "deprecated": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.TriggersAndActionsUIPublicPluginSetup.alertsTableConfigurationRegistry", + "type": "Object", + "tags": [], + "label": "alertsTableConfigurationRegistry", + "description": [], + "signature": [ + "TypeRegistry", + "<", + "AlertsTableConfigurationRegistry", + ">" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/plugin.ts", + "deprecated": false } ], "lifecycle": "setup", @@ -4046,6 +4266,22 @@ "path": "x-pack/plugins/triggers_actions_ui/public/plugin.ts", "deprecated": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.TriggersAndActionsUIPublicPluginStart.alertsTableConfigurationRegistry", + "type": "Object", + "tags": [], + "label": "alertsTableConfigurationRegistry", + "description": [], + "signature": [ + "TypeRegistry", + "<", + "AlertsTableConfigurationRegistry", + ">" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/plugin.ts", + "deprecated": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-public.TriggersAndActionsUIPublicPluginStart.getAddConnectorFlyout", @@ -4223,6 +4459,40 @@ } ], "returnComment": [] + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.TriggersAndActionsUIPublicPluginStart.getRuleStatusDropdown", + "type": "Function", + "tags": [], + "label": "getRuleStatusDropdown", + "description": [], + "signature": [ + "(props: ", + "ComponentOpts", + ") => React.ReactElement<", + "ComponentOpts", + ", string | React.JSXElementConstructor>" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/plugin.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.TriggersAndActionsUIPublicPluginStart.getRuleStatusDropdown.$1", + "type": "Object", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "ComponentOpts" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/plugin.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] } ], "lifecycle": "start", @@ -4625,10 +4895,10 @@ ], "label": "parseExperimentalConfigValue", "description": [ - "\nParses the string value used in `xpack.triggersActionsUi.enableExperimental` kibana configuration,\nwhich should be a string of values delimited by a comma (`,`)\n" + "\nParses the string value used in `xpack.trigger_actions_ui.enableExperimental` kibana configuration,\nwhich should be a string of values delimited by a comma (`,`)\n" ], "signature": [ - "(configValue: string[]) => Readonly<{ rulesListDatagrid: boolean; internalAlertsTable: boolean; rulesDetailLogs: boolean; }>" + "(configValue: string[]) => Readonly<{ rulesListDatagrid: boolean; internalAlertsTable: boolean; internalShareableComponentsSandbox: boolean; rulesDetailLogs: boolean; }>" ], "path": "x-pack/plugins/triggers_actions_ui/common/experimental_features.ts", "deprecated": false, @@ -4785,7 +5055,7 @@ "label": "ExperimentalFeatures", "description": [], "signature": [ - "{ readonly rulesListDatagrid: boolean; readonly internalAlertsTable: boolean; readonly rulesDetailLogs: boolean; }" + "{ readonly rulesListDatagrid: boolean; readonly internalAlertsTable: boolean; readonly internalShareableComponentsSandbox: boolean; readonly rulesDetailLogs: boolean; }" ], "path": "x-pack/plugins/triggers_actions_ui/common/experimental_features.ts", "deprecated": false, @@ -4814,10 +5084,10 @@ "tags": [], "label": "allowedExperimentalValues", "description": [ - "\nA list of allowed values that can be used in `xpack.triggersActionsUi.enableExperimental`.\nThis object is then used to validate and parse the value entered." + "\nA list of allowed values that can be used in `xpack.trigger_actions_ui.enableExperimental`.\nThis object is then used to validate and parse the value entered." ], "signature": [ - "{ readonly rulesListDatagrid: boolean; readonly internalAlertsTable: boolean; readonly rulesDetailLogs: boolean; }" + "{ readonly rulesListDatagrid: boolean; readonly internalAlertsTable: boolean; readonly internalShareableComponentsSandbox: boolean; readonly rulesDetailLogs: boolean; }" ], "path": "x-pack/plugins/triggers_actions_ui/common/experimental_features.ts", "deprecated": false, diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index 88c76bf1729fd..20c5152aa8df3 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github summary: API docs for the triggersActionsUi plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Response Ops](https://github.com/orgs/elastic/teams/response-ops) for q | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 304 | 0 | 290 | 23 | +| 321 | 0 | 307 | 25 | ## Client diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx index 4bd49250ad905..5038ea2fa6daa 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github summary: API docs for the uiActions plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActions'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/ui_actions_enhanced.mdx b/api_docs/ui_actions_enhanced.mdx index 51e13512c54de..7aeea3d866aad 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github summary: API docs for the uiActionsEnhanced plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/unified_search.devdocs.json b/api_docs/unified_search.devdocs.json index 5d2e50e061270..28d29d8e5f2db 100644 --- a/api_docs/unified_search.devdocs.json +++ b/api_docs/unified_search.devdocs.json @@ -205,8 +205,8 @@ "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.IIndexPattern", - "text": "IIndexPattern" + "section": "def-common.DataView", + "text": "DataView" }, ")[]" ], @@ -547,7 +547,7 @@ "label": "nonKqlMode", "description": [], "signature": [ - "\"lucene\" | \"text\" | undefined" + "\"text\" | \"lucene\" | undefined" ], "path": "src/plugins/unified_search/public/query_string_input/query_string_input.tsx", "deprecated": false @@ -714,6 +714,31 @@ "path": "src/plugins/unified_search/public/types.ts", "deprecated": false, "children": [ + { + "parentPluginId": "unifiedSearch", + "id": "def-public.UnifiedSearchPublicPluginStart.autocomplete", + "type": "Object", + "tags": [], + "label": "autocomplete", + "description": [ + "\nautocomplete service\n{@link AutocompleteStart}" + ], + "signature": [ + "{ getQuerySuggestions: ", + { + "pluginId": "unifiedSearch", + "scope": "public", + "docId": "kibUnifiedSearchAutocompletePluginApi", + "section": "def-public.QuerySuggestionGetFn", + "text": "QuerySuggestionGetFn" + }, + "; hasQuerySuggestions: (language: string) => boolean; getValueSuggestions: ", + "ValueSuggestionsGetFn", + "; }" + ], + "path": "src/plugins/unified_search/public/types.ts", + "deprecated": false + }, { "parentPluginId": "unifiedSearch", "id": "def-public.UnifiedSearchPublicPluginStart.ui", @@ -732,15 +757,323 @@ ], "lifecycle": "start", "initialIsOpen": true + }, + "setup": { + "parentPluginId": "unifiedSearch", + "id": "def-public.UnifiedSearchPluginSetup", + "type": "Interface", + "tags": [], + "label": "UnifiedSearchPluginSetup", + "description": [], + "path": "src/plugins/unified_search/public/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "unifiedSearch", + "id": "def-public.UnifiedSearchPluginSetup.autocomplete", + "type": "Object", + "tags": [], + "label": "autocomplete", + "description": [], + "signature": [ + "{ getQuerySuggestions: ", + { + "pluginId": "unifiedSearch", + "scope": "public", + "docId": "kibUnifiedSearchAutocompletePluginApi", + "section": "def-public.QuerySuggestionGetFn", + "text": "QuerySuggestionGetFn" + }, + "; getAutocompleteSettings: () => { terminateAfter: number; timeout: number; }; }" + ], + "path": "src/plugins/unified_search/public/types.ts", + "deprecated": false + } + ], + "lifecycle": "setup", + "initialIsOpen": true } }, "server": { - "classes": [], + "classes": [ + { + "parentPluginId": "unifiedSearch", + "id": "def-server.UnifiedSearchServerPlugin", + "type": "Class", + "tags": [], + "label": "UnifiedSearchServerPlugin", + "description": [], + "signature": [ + { + "pluginId": "unifiedSearch", + "scope": "server", + "docId": "kibUnifiedSearchPluginApi", + "section": "def-server.UnifiedSearchServerPlugin", + "text": "UnifiedSearchServerPlugin" + }, + " implements ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCorePluginApi", + "section": "def-server.Plugin", + "text": "Plugin" + }, + "<", + { + "pluginId": "unifiedSearch", + "scope": "server", + "docId": "kibUnifiedSearchPluginApi", + "section": "def-server.UnifiedSearchServerPluginSetup", + "text": "UnifiedSearchServerPluginSetup" + }, + ", void, object, object>" + ], + "path": "src/plugins/unified_search/server/plugin.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "unifiedSearch", + "id": "def-server.UnifiedSearchServerPlugin.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "src/plugins/unified_search/server/plugin.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "unifiedSearch", + "id": "def-server.UnifiedSearchServerPlugin.Unnamed.$1", + "type": "Object", + "tags": [], + "label": "initializerContext", + "description": [], + "signature": [ + { + "pluginId": "core", + "scope": "server", + "docId": "kibCorePluginApi", + "section": "def-server.PluginInitializerContext", + "text": "PluginInitializerContext" + }, + "; valueSuggestions: Readonly<{} & { timeout: moment.Duration; enabled: boolean; tiers: string[]; terminateAfter: moment.Duration; }>; }>; }>>" + ], + "path": "src/plugins/unified_search/server/plugin.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "unifiedSearch", + "id": "def-server.UnifiedSearchServerPlugin.setup", + "type": "Function", + "tags": [], + "label": "setup", + "description": [], + "signature": [ + "(core: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCorePluginApi", + "section": "def-server.CoreSetup", + "text": "CoreSetup" + }, + "<", + "UnifiedSearchServerPluginStartDependencies", + ", ", + { + "pluginId": "unifiedSearch", + "scope": "server", + "docId": "kibUnifiedSearchPluginApi", + "section": "def-server.UnifiedSearchServerPluginStart", + "text": "UnifiedSearchServerPluginStart" + }, + ">, {}: ", + "UnifiedSearchServerPluginSetupDependencies", + ") => { autocomplete: { getAutocompleteSettings: () => { terminateAfter: number; timeout: number; }; }; }" + ], + "path": "src/plugins/unified_search/server/plugin.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "unifiedSearch", + "id": "def-server.UnifiedSearchServerPlugin.setup.$1", + "type": "Object", + "tags": [], + "label": "core", + "description": [], + "signature": [ + { + "pluginId": "core", + "scope": "server", + "docId": "kibCorePluginApi", + "section": "def-server.CoreSetup", + "text": "CoreSetup" + }, + "<", + "UnifiedSearchServerPluginStartDependencies", + ", ", + { + "pluginId": "unifiedSearch", + "scope": "server", + "docId": "kibUnifiedSearchPluginApi", + "section": "def-server.UnifiedSearchServerPluginStart", + "text": "UnifiedSearchServerPluginStart" + }, + ">" + ], + "path": "src/plugins/unified_search/server/plugin.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "unifiedSearch", + "id": "def-server.UnifiedSearchServerPlugin.setup.$2", + "type": "Object", + "tags": [], + "label": "{}", + "description": [], + "signature": [ + "UnifiedSearchServerPluginSetupDependencies" + ], + "path": "src/plugins/unified_search/server/plugin.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "unifiedSearch", + "id": "def-server.UnifiedSearchServerPlugin.start", + "type": "Function", + "tags": [], + "label": "start", + "description": [], + "signature": [ + "(core: ", + { + "pluginId": "core", + "scope": "server", + "docId": "kibCorePluginApi", + "section": "def-server.CoreStart", + "text": "CoreStart" + }, + ", {}: ", + "UnifiedSearchServerPluginStartDependencies", + ") => {}" + ], + "path": "src/plugins/unified_search/server/plugin.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "unifiedSearch", + "id": "def-server.UnifiedSearchServerPlugin.start.$1", + "type": "Object", + "tags": [], + "label": "core", + "description": [], + "signature": [ + { + "pluginId": "core", + "scope": "server", + "docId": "kibCorePluginApi", + "section": "def-server.CoreStart", + "text": "CoreStart" + } + ], + "path": "src/plugins/unified_search/server/plugin.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "unifiedSearch", + "id": "def-server.UnifiedSearchServerPlugin.start.$2", + "type": "Object", + "tags": [], + "label": "{}", + "description": [], + "signature": [ + "UnifiedSearchServerPluginStartDependencies" + ], + "path": "src/plugins/unified_search/server/plugin.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "unifiedSearch", + "id": "def-server.UnifiedSearchServerPlugin.stop", + "type": "Function", + "tags": [], + "label": "stop", + "description": [], + "signature": [ + "() => void" + ], + "path": "src/plugins/unified_search/server/plugin.ts", + "deprecated": false, + "children": [], + "returnComment": [] + } + ], + "initialIsOpen": false + } + ], "functions": [], - "interfaces": [], + "interfaces": [ + { + "parentPluginId": "unifiedSearch", + "id": "def-server.UnifiedSearchServerPluginStart", + "type": "Interface", + "tags": [], + "label": "UnifiedSearchServerPluginStart", + "description": [], + "path": "src/plugins/unified_search/server/plugin.ts", + "deprecated": false, + "children": [], + "initialIsOpen": false + } + ], "enums": [], "misc": [], - "objects": [] + "objects": [], + "setup": { + "parentPluginId": "unifiedSearch", + "id": "def-server.UnifiedSearchServerPluginSetup", + "type": "Interface", + "tags": [], + "label": "UnifiedSearchServerPluginSetup", + "description": [], + "path": "src/plugins/unified_search/server/plugin.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "unifiedSearch", + "id": "def-server.UnifiedSearchServerPluginSetup.autocomplete", + "type": "Object", + "tags": [], + "label": "autocomplete", + "description": [], + "signature": [ + "{ getAutocompleteSettings: () => { terminateAfter: number; timeout: number; }; }" + ], + "path": "src/plugins/unified_search/server/plugin.ts", + "deprecated": false + } + ], + "lifecycle": "setup", + "initialIsOpen": true + } }, "common": { "classes": [], diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index 5090a1f15bee8..285d17efcba81 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github summary: API docs for the unifiedSearch plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,10 +18,13 @@ Contact [Unified Search](https://github.com/orgs/elastic/teams/kibana-app-servic | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 48 | 1 | 45 | 6 | +| 79 | 2 | 75 | 11 | ## Client +### Setup + + ### Start @@ -34,3 +37,14 @@ Contact [Unified Search](https://github.com/orgs/elastic/teams/kibana-app-servic ### Consts, variables and types +## Server + +### Setup + + +### Classes + + +### Interfaces + + diff --git a/api_docs/unified_search_autocomplete.devdocs.json b/api_docs/unified_search_autocomplete.devdocs.json new file mode 100644 index 0000000000000..c3f2543a9c9cb --- /dev/null +++ b/api_docs/unified_search_autocomplete.devdocs.json @@ -0,0 +1,265 @@ +{ + "id": "unifiedSearch.autocomplete", + "client": { + "classes": [], + "functions": [], + "interfaces": [ + { + "parentPluginId": "unifiedSearch", + "id": "def-public.QuerySuggestionGetFnArgs", + "type": "Interface", + "tags": [], + "label": "QuerySuggestionGetFnArgs", + "description": [], + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "unifiedSearch", + "id": "def-public.QuerySuggestionGetFnArgs.language", + "type": "string", + "tags": [], + "label": "language", + "description": [], + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts", + "deprecated": false + }, + { + "parentPluginId": "unifiedSearch", + "id": "def-public.QuerySuggestionGetFnArgs.indexPatterns", + "type": "Array", + "tags": [], + "label": "indexPatterns", + "description": [], + "signature": [ + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.IIndexPattern", + "text": "IIndexPattern" + }, + "[]" + ], + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts", + "deprecated": false + }, + { + "parentPluginId": "unifiedSearch", + "id": "def-public.QuerySuggestionGetFnArgs.query", + "type": "string", + "tags": [], + "label": "query", + "description": [], + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts", + "deprecated": false + }, + { + "parentPluginId": "unifiedSearch", + "id": "def-public.QuerySuggestionGetFnArgs.selectionStart", + "type": "number", + "tags": [], + "label": "selectionStart", + "description": [], + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts", + "deprecated": false + }, + { + "parentPluginId": "unifiedSearch", + "id": "def-public.QuerySuggestionGetFnArgs.selectionEnd", + "type": "number", + "tags": [], + "label": "selectionEnd", + "description": [], + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts", + "deprecated": false + }, + { + "parentPluginId": "unifiedSearch", + "id": "def-public.QuerySuggestionGetFnArgs.signal", + "type": "Object", + "tags": [], + "label": "signal", + "description": [], + "signature": [ + "AbortSignal | undefined" + ], + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts", + "deprecated": false + }, + { + "parentPluginId": "unifiedSearch", + "id": "def-public.QuerySuggestionGetFnArgs.useTimeRange", + "type": "CompoundType", + "tags": [], + "label": "useTimeRange", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts", + "deprecated": false + }, + { + "parentPluginId": "unifiedSearch", + "id": "def-public.QuerySuggestionGetFnArgs.boolFilter", + "type": "Any", + "tags": [], + "label": "boolFilter", + "description": [], + "signature": [ + "any" + ], + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts", + "deprecated": false + }, + { + "parentPluginId": "unifiedSearch", + "id": "def-public.QuerySuggestionGetFnArgs.method", + "type": "CompoundType", + "tags": [], + "label": "method", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataPluginApi", + "section": "def-common.ValueSuggestionsMethod", + "text": "ValueSuggestionsMethod" + }, + " | undefined" + ], + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts", + "deprecated": false + } + ], + "initialIsOpen": false + } + ], + "enums": [ + { + "parentPluginId": "unifiedSearch", + "id": "def-public.QuerySuggestionTypes", + "type": "Enum", + "tags": [], + "label": "QuerySuggestionTypes", + "description": [], + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts", + "deprecated": false, + "initialIsOpen": false + } + ], + "misc": [ + { + "parentPluginId": "unifiedSearch", + "id": "def-public.AutocompleteStart", + "type": "Type", + "tags": [], + "label": "AutocompleteStart", + "description": [], + "signature": [ + "{ getQuerySuggestions: ", + { + "pluginId": "unifiedSearch", + "scope": "public", + "docId": "kibUnifiedSearchAutocompletePluginApi", + "section": "def-public.QuerySuggestionGetFn", + "text": "QuerySuggestionGetFn" + }, + "; hasQuerySuggestions: (language: string) => boolean; getValueSuggestions: ", + "ValueSuggestionsGetFn", + "; }" + ], + "path": "src/plugins/unified_search/public/autocomplete/autocomplete_service.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "unifiedSearch", + "id": "def-public.QuerySuggestion", + "type": "Type", + "tags": [], + "label": "QuerySuggestion", + "description": [], + "signature": [ + "QuerySuggestionBasic", + " | ", + "QuerySuggestionField" + ], + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "unifiedSearch", + "id": "def-public.QuerySuggestionGetFn", + "type": "Type", + "tags": [], + "label": "QuerySuggestionGetFn", + "description": [], + "signature": [ + "(args: ", + { + "pluginId": "unifiedSearch", + "scope": "public", + "docId": "kibUnifiedSearchAutocompletePluginApi", + "section": "def-public.QuerySuggestionGetFnArgs", + "text": "QuerySuggestionGetFnArgs" + }, + ") => Promise<", + { + "pluginId": "unifiedSearch", + "scope": "public", + "docId": "kibUnifiedSearchAutocompletePluginApi", + "section": "def-public.QuerySuggestion", + "text": "QuerySuggestion" + }, + "[]> | undefined" + ], + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts", + "deprecated": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "unifiedSearch", + "id": "def-public.QuerySuggestionGetFn.$1", + "type": "Object", + "tags": [], + "label": "args", + "description": [], + "signature": [ + { + "pluginId": "unifiedSearch", + "scope": "public", + "docId": "kibUnifiedSearchAutocompletePluginApi", + "section": "def-public.QuerySuggestionGetFnArgs", + "text": "QuerySuggestionGetFnArgs" + } + ], + "path": "src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts", + "deprecated": false + } + ], + "initialIsOpen": false + } + ], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/unified_search_autocomplete.mdx b/api_docs/unified_search_autocomplete.mdx new file mode 100644 index 0000000000000..f6c59fdec600f --- /dev/null +++ b/api_docs/unified_search_autocomplete.mdx @@ -0,0 +1,33 @@ +--- +id: kibUnifiedSearchAutocompletePluginApi +slug: /kibana-dev-docs/api/unifiedSearch-autocomplete +title: "unifiedSearch.autocomplete" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the unifiedSearch.autocomplete plugin +date: 2022-04-26 +tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; + +Contains all the key functionality of Kibana's unified search experience.Contains all the key functionality of Kibana's unified search experience. + +Contact [Unified Search](https://github.com/orgs/elastic/teams/kibana-app-services) for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 79 | 2 | 75 | 11 | + +## Client + +### Interfaces + + +### Enums + + +### Consts, variables and types + + diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 49e61cb0452fe..3ba684cb1b7fe 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github summary: API docs for the urlForwarding plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'urlForwarding'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/usage_collection.devdocs.json b/api_docs/usage_collection.devdocs.json index 46559368d5450..8978c71dc262e 100644 --- a/api_docs/usage_collection.devdocs.json +++ b/api_docs/usage_collection.devdocs.json @@ -2190,9 +2190,9 @@ "\r\nPossible type values in the schema" ], "signature": [ - "\"boolean\" | \"keyword\" | \"date\" | \"text\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"double\"" + "\"boolean\" | \"keyword\" | \"text\" | \"date\" | \"integer\" | \"long\" | \"short\" | \"byte\" | \"float\" | \"double\"" ], - "path": "node_modules/@types/elastic__analytics/index.d.ts", + "path": "node_modules/@types/kbn__analytics-client/index.d.ts", "deprecated": false, "initialIsOpen": false }, diff --git a/api_docs/usage_collection.mdx b/api_docs/usage_collection.mdx index 362ddd4e39eb8..121a877b20b16 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github summary: API docs for the usageCollection plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'usageCollection'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/ux.mdx b/api_docs/ux.mdx index 6ccc23ba38612..ef94504e31dc9 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github summary: API docs for the ux plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ux'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/vis_default_editor.mdx b/api_docs/vis_default_editor.mdx index c335a368d7b71..42f51f6f9501c 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github summary: API docs for the visDefaultEditor plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visDefaultEditor'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/vis_type_gauge.mdx b/api_docs/vis_type_gauge.mdx index f1504dbc739ba..15770aeb62c3d 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github summary: API docs for the visTypeGauge plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeGauge'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/vis_type_heatmap.mdx b/api_docs/vis_type_heatmap.mdx index e36cb3c375d3c..6460ab30cde48 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github summary: API docs for the visTypeHeatmap plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeHeatmap'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/vis_type_pie.mdx b/api_docs/vis_type_pie.mdx index 6fd8b8f633d78..1e97d6977d0df 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github summary: API docs for the visTypePie plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypePie'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/vis_type_table.mdx b/api_docs/vis_type_table.mdx index 9fb56a55bd2d9..0bdbae2ed0092 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github summary: API docs for the visTypeTable plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTable'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/vis_type_timelion.mdx b/api_docs/vis_type_timelion.mdx index 91e5141ff9cfd..962bbd0c90c3f 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github summary: API docs for the visTypeTimelion plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimelion'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/vis_type_timeseries.devdocs.json b/api_docs/vis_type_timeseries.devdocs.json index 77a7ac1e67ce5..afd54c07290ff 100644 --- a/api_docs/vis_type_timeseries.devdocs.json +++ b/api_docs/vis_type_timeseries.devdocs.json @@ -145,7 +145,7 @@ { "parentPluginId": "visTypeTimeseries", "id": "def-server.VisTypeTimeseriesSetup.getVisData.$1", - "type": "Object", + "type": "CompoundType", "tags": [], "label": "requestContext", "description": [], diff --git a/api_docs/vis_type_timeseries.mdx b/api_docs/vis_type_timeseries.mdx index ba5ac71899536..b26a90a93f8f0 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github summary: API docs for the visTypeTimeseries plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimeseries'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/vis_type_vega.mdx b/api_docs/vis_type_vega.mdx index c978eed560309..e65deb3cea8a9 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github summary: API docs for the visTypeVega plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVega'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/vis_type_vislib.mdx b/api_docs/vis_type_vislib.mdx index 9638ab6b1db54..aba082b0dfb43 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github summary: API docs for the visTypeVislib plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVislib'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/vis_type_xy.mdx b/api_docs/vis_type_xy.mdx index 6728cabe0e78c..8b80289230ed5 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github summary: API docs for the visTypeXy plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/visualizations.devdocs.json b/api_docs/visualizations.devdocs.json index 9cd950856997f..500393546b819 100644 --- a/api_docs/visualizations.devdocs.json +++ b/api_docs/visualizations.devdocs.json @@ -3162,9 +3162,9 @@ "Observable", "; getTimeUpdate$: () => ", "Observable", - "; getRefreshIntervalUpdate$: () => ", + "; getRefreshIntervalUpdate$: () => ", "Observable", - "; getAutoRefreshFetch$: () => ", + "; getAutoRefreshFetch$: () => ", "Observable", "<", { @@ -3176,7 +3176,7 @@ }, ">; getFetch$: () => ", "Observable", - "; getTime: () => ", + "; getTime: () => ", { "pluginId": "data", "scope": "common", @@ -4496,13 +4496,7 @@ "label": "palette", "description": [], "signature": [ - { - "pluginId": "charts", - "scope": "common", - "docId": "kibChartsPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, + "PaletteOutput", "<{ [key: string]: unknown; }> | undefined" ], "path": "src/plugins/visualizations/public/vis_types/types.ts", @@ -4850,6 +4844,34 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "visualizations", + "id": "def-public.SAVED_OBJECTS_LIMIT_SETTING", + "type": "string", + "tags": [], + "label": "SAVED_OBJECTS_LIMIT_SETTING", + "description": [], + "signature": [ + "\"savedObjects:listingLimit\"" + ], + "path": "src/plugins/visualizations/common/constants.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "visualizations", + "id": "def-public.SAVED_OBJECTS_PER_PAGE_SETTING", + "type": "string", + "tags": [], + "label": "SAVED_OBJECTS_PER_PAGE_SETTING", + "description": [], + "signature": [ + "\"savedObjects:perPage\"" + ], + "path": "src/plugins/visualizations/common/constants.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "visualizations", "id": "def-public.SavedVisState", @@ -5018,7 +5040,7 @@ "label": "VisualizeEmbeddableContract", "description": [], "signature": [ - "{ readonly type: \"visualization\"; readonly id: string; getExplicitInput: () => ", + "{ readonly id: string; readonly type: \"visualization\"; getExplicitInput: () => ", { "pluginId": "visualizations", "scope": "public", @@ -5234,7 +5256,7 @@ "label": "VisualizeEmbeddableFactoryContract", "description": [], "signature": [ - "{ readonly type: \"visualization\"; create: (input: ", + "{ create: (input: ", { "pluginId": "visualizations", "scope": "public", @@ -5294,7 +5316,7 @@ "VisualizeEmbeddable", " | ", "DisabledLabEmbeddable", - " | undefined>; isEditable: () => Promise; getDisplayName: () => string; createFromSavedObject: (savedObjectId: string, input: Partial<", + " | undefined>; readonly type: \"visualization\"; isEditable: () => Promise; getDisplayName: () => string; createFromSavedObject: (savedObjectId: string, input: Partial<", { "pluginId": "visualizations", "scope": "public", diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index abd99851677e0..992f0475d6f4f 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github summary: API docs for the visualizations plugin -date: 2022-04-05 +date: 2022-04-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 363 | 12 | 342 | 14 | +| 365 | 12 | 344 | 14 | ## Client diff --git a/config/kibana.yml b/config/kibana.yml index 50ddad9a4b32a..4233bf2882a29 100644 --- a/config/kibana.yml +++ b/config/kibana.yml @@ -159,8 +159,8 @@ # =================== Search Autocomplete =================== # Time in milliseconds to wait for autocomplete suggestions from Elasticsearch. # This value must be a whole number greater than zero. Defaults to 1000ms -#data.autocomplete.valueSuggestions.timeout: 1000 +#unifiedSearch.autocomplete.valueSuggestions.timeout: 1000 # Maximum number of documents loaded by each shard to generate autocomplete suggestions. # This value must be a whole number greater than zero. Defaults to 100_000 -#data.autocomplete.valueSuggestions.terminateAfter: 100000 +#unifiedSearch.autocomplete.valueSuggestions.terminateAfter: 100000 diff --git a/dev_docs/getting_started/hello_world_plugin.mdx b/dev_docs/getting_started/hello_world_plugin.mdx index be4fcf5671a42..8fa4ea4316129 100644 --- a/dev_docs/getting_started/hello_world_plugin.mdx +++ b/dev_docs/getting_started/hello_world_plugin.mdx @@ -40,6 +40,10 @@ and add the following: "id": "helloWorld", "version": "1.0.0", "kibanaVersion": "kibana", + "owner": { + "name": "Kibana Core", + "githubTeam": "kibana-core" + }, "ui": true } ``` @@ -77,6 +81,7 @@ And add the following to it: ``` $ mkdir public +$ cd public $ touch plugin.tsx ``` diff --git a/dev_docs/getting_started/setting_up_a_development_env.mdx b/dev_docs/getting_started/setting_up_a_development_env.mdx index ae994d6a018de..570dcb57a56b8 100644 --- a/dev_docs/getting_started/setting_up_a_development_env.mdx +++ b/dev_docs/getting_started/setting_up_a_development_env.mdx @@ -72,7 +72,7 @@ In another terminal tab/window you can start Kibana. yarn start ``` -If you include the `--run-examples` flag then all of the [developer examples](https://github.com/elastic/kibana/tree/{branch}/examples). Read more about the advanced options for [Running Kibana](https://www.elastic.co/guide/en/kibana/current/running-kibana-advanced.html). +Include developer examples](https://github.com/elastic/kibana/tree/main/examples) by adding an optional `--run-examples` flag. Read more about the advanced options for [Running Kibana](https://www.elastic.co/guide/en/kibana/current/running-kibana-advanced.html). ## Code away! diff --git a/dev_docs/tutorials/data/search.mdx b/dev_docs/tutorials/data/search.mdx index 0787c44b632ec..ab5c3f29ea1be 100644 --- a/dev_docs/tutorials/data/search.mdx +++ b/dev_docs/tutorials/data/search.mdx @@ -259,7 +259,7 @@ export const myEnhancedSearchStrategyProvider = ( await ese.cancel(id, options, deps); }, extend: async (id, keepAlive, options, deps) => { - // async search results are not stored indefinitely. By default, they expire after 7 days (or as defined by xpack.data_enhanced.search.sessions.defaultExpiration setting in kibana.yml). + // async search results are not stored indefinitely. By default, they expire after 7 days (or as defined by data.search.sessions.defaultExpiration setting in kibana.yml). // call the extend method of the async strategy you are using or implement your own extend function. await ese.extend(id, options, deps); }, diff --git a/docs/api/actions-and-connectors/create.asciidoc b/docs/api/actions-and-connectors/create.asciidoc index c9ea31c98cf19..401f4c5372688 100644 --- a/docs/api/actions-and-connectors/create.asciidoc +++ b/docs/api/actions-and-connectors/create.asciidoc @@ -74,6 +74,7 @@ The API returns the following: "executionTimeField": null }, "is_preconfigured": false, + "is_deprecated": false, "is_missing_secrets": false } -------------------------------------------------- diff --git a/docs/api/actions-and-connectors/get.asciidoc b/docs/api/actions-and-connectors/get.asciidoc index 95336e7f55d30..bc6b5fa8f364c 100644 --- a/docs/api/actions-and-connectors/get.asciidoc +++ b/docs/api/actions-and-connectors/get.asciidoc @@ -51,6 +51,7 @@ The API returns the following: "executionTimeField": null }, "is_preconfigured": false, + "is_deprecated": false, "is_missing_secrets": false } -------------------------------------------------- diff --git a/docs/api/actions-and-connectors/get_all.asciidoc b/docs/api/actions-and-connectors/get_all.asciidoc index 943c7d123775f..26bb7247e2ce1 100644 --- a/docs/api/actions-and-connectors/get_all.asciidoc +++ b/docs/api/actions-and-connectors/get_all.asciidoc @@ -44,6 +44,7 @@ The API returns the following: "connector_type_id": ".email", "name": "email: preconfigured-mail-connector", "is_preconfigured": true, + "is_deprecated": false, "referenced_by_count": 0 <1> }, { @@ -56,6 +57,7 @@ The API returns the following: "executionTimeField": null }, "is_preconfigured": false, + "is_deprecated": false, "is_missing_secrets": false, "referenced_by_count": 3 } diff --git a/docs/api/actions-and-connectors/legacy/create.asciidoc b/docs/api/actions-and-connectors/legacy/create.asciidoc index e0d531a2befb9..5b5b71b1d6daa 100644 --- a/docs/api/actions-and-connectors/legacy/create.asciidoc +++ b/docs/api/actions-and-connectors/legacy/create.asciidoc @@ -76,6 +76,7 @@ The API returns the following: "executionTimeField": null }, "isPreconfigured": false, + "isDeprecated": false, "isMissingSecrets": false } -------------------------------------------------- diff --git a/docs/api/actions-and-connectors/legacy/get.asciidoc b/docs/api/actions-and-connectors/legacy/get.asciidoc index dab462e3ae4fb..d6554d606a286 100644 --- a/docs/api/actions-and-connectors/legacy/get.asciidoc +++ b/docs/api/actions-and-connectors/legacy/get.asciidoc @@ -53,6 +53,7 @@ The API returns the following: "executionTimeField": null }, "isPreconfigured": false, + "isDeprecated": false, "isMissingSecrets": false } -------------------------------------------------- diff --git a/docs/api/actions-and-connectors/legacy/get_all.asciidoc b/docs/api/actions-and-connectors/legacy/get_all.asciidoc index 2180720ce6542..9e52b6883ec11 100644 --- a/docs/api/actions-and-connectors/legacy/get_all.asciidoc +++ b/docs/api/actions-and-connectors/legacy/get_all.asciidoc @@ -45,7 +45,8 @@ The API returns the following: "id": "preconfigured-mail-action", "actionTypeId": ".email", "name": "email: preconfigured-mail-action", - "isPreconfigured": true + "isPreconfigured": true, + "isDeprecated": false }, { "id": "c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad", @@ -57,6 +58,7 @@ The API returns the following: "executionTimeField": null }, "isPreconfigured": false, + "isDeprecated": false, "isMissingSecrets": false } ] diff --git a/docs/api/actions-and-connectors/legacy/update.asciidoc b/docs/api/actions-and-connectors/legacy/update.asciidoc index 5202f8124e6a8..1e6a4e71c8b81 100644 --- a/docs/api/actions-and-connectors/legacy/update.asciidoc +++ b/docs/api/actions-and-connectors/legacy/update.asciidoc @@ -71,6 +71,7 @@ The API returns the following: "executionTimeField": null }, "isPreconfigured": false, + "isDeprecated": false, "isMissingSecrets": false } -------------------------------------------------- diff --git a/docs/api/actions-and-connectors/update.asciidoc b/docs/api/actions-and-connectors/update.asciidoc index 0b7dcc898a122..7ccb10714f474 100644 --- a/docs/api/actions-and-connectors/update.asciidoc +++ b/docs/api/actions-and-connectors/update.asciidoc @@ -69,6 +69,7 @@ The API returns the following: "executionTimeField": null }, "is_preconfigured": false, + "is_deprecated": false, "is_missing_secrets": false } -------------------------------------------------- diff --git a/docs/api/cases/cases-api-add-comment.asciidoc b/docs/api/cases/cases-api-add-comment.asciidoc index 20b558a89c683..df63cc0ecd65f 100644 --- a/docs/api/cases/cases-api-add-comment.asciidoc +++ b/docs/api/cases/cases-api-add-comment.asciidoc @@ -6,21 +6,20 @@ Adds a comment to a case. -=== Request +=== {api-request-title} `POST :/api/cases//comments` `POST :/s//api/cases//comments` -=== Prerequisite +=== {api-prereq-title} You must have `all` privileges for the *Cases* feature in the *Management*, *{observability}*, or *Security* section of the <>, depending on the `owner` of the case you're updating. - -=== Path parameters +=== {api-path-parms-title} ``:: (Required,string) The identifier for the case. To retrieve case IDs, use @@ -30,7 +29,7 @@ You must have `all` privileges for the *Cases* feature in the *Management*, (Optional, string) An identifier for the space. If it is not specified, the default space is used. -=== Request body +=== {api-request-body-title} `alertId`:: (Required*, string) The alert identifier. It is required only when `type` is @@ -65,12 +64,12 @@ only when `type` is `alert`. preview:[] `type`:: (Required, string) The comment type, which must be `user` or `alert`. -=== Response code +=== {api-response-codes-title} `200`:: Indicates a successful call. -=== Example +=== {api-examples-title} Add a comment to case ID `293f1bc0-74f6-11ea-b83a-553aecdb28b6`: diff --git a/docs/api/cases/cases-api-create.asciidoc b/docs/api/cases/cases-api-create.asciidoc index f08b69998321f..b7a97fc9cb1b2 100644 --- a/docs/api/cases/cases-api-create.asciidoc +++ b/docs/api/cases/cases-api-create.asciidoc @@ -6,26 +6,26 @@ Creates a case. -=== Request +=== {api-request-title} `POST :/api/cases` `POST :/s//api/cases` -=== Prerequisite +=== {api-prereq-title} You must have `all` privileges for the *Cases* feature in the *Management*, *{observability}*, or *Security* section of the <>, depending on the `owner` of the case you're creating. -=== Path parameters +=== {api-path-parms-title} ``:: (Optional, string) An identifier for the space. If it is not specified, the default space is used. -=== Request body +=== {api-request-body-title} `connector`:: (Required, object) An object that contains the connector configuration. @@ -107,8 +107,8 @@ For {swimlane} connectors, specify: `id`:: (Required, string) The identifier for the connector. To create a case without a -connector, use `none`. -//To retrieve connector IDs, use <>). +connector, use `none`. To retrieve connector IDs, use +<>. `name`:: (Required, string) The name of the connector. To create a case without a @@ -147,12 +147,12 @@ categorize cases. It can be an empty array. `title`:: (Required, string) A title for the case. -=== Response code +=== {api-response-codes-title} `200`:: Indicates a successful call. -=== Example +=== {api-examples-title} [source,sh] -------------------------------------------------- diff --git a/docs/api/cases/cases-api-delete-cases.asciidoc b/docs/api/cases/cases-api-delete-cases.asciidoc index 5e4436806f14f..05e9fe3e2898c 100644 --- a/docs/api/cases/cases-api-delete-cases.asciidoc +++ b/docs/api/cases/cases-api-delete-cases.asciidoc @@ -6,26 +6,26 @@ Deletes one or more cases. -=== Request +=== {api-request-title} `DELETE :/api/cases?ids=["",""]` `DELETE :/s//api/cases?ids=["",""]` -=== Prerequisite +=== {api-prereq-title} You must have `all` privileges for the *Cases* feature in the *Management*, *{observability}*, or *Security* section of the <>, depending on the `owner` of the cases you're deleting. -=== Path parameters +=== {api-path-parms-title} ``:: (Optional, string) An identifier for the space. If it is not specified, the default space is used. -=== Query parameters +=== {api-query-parms-title} `ids`:: (Required, string) The cases that you want to remove. To retrieve case IDs, use @@ -33,12 +33,12 @@ default space is used. + NOTE: All non-ASCII characters must be URL encoded. -==== Response code +=== {api-response-codes-title} `204`:: Indicates a successful call. -=== Example +=== {api-examples-title} Delete cases with these IDs: diff --git a/docs/api/cases/cases-api-delete-comments.asciidoc b/docs/api/cases/cases-api-delete-comments.asciidoc index 0b02786e6659d..c89407fb69ab8 100644 --- a/docs/api/cases/cases-api-delete-comments.asciidoc +++ b/docs/api/cases/cases-api-delete-comments.asciidoc @@ -6,7 +6,7 @@ Deletes one or all comments from a case. -=== Request +=== {api-request-title} `DELETE :/api/cases//comments` @@ -16,14 +16,14 @@ Deletes one or all comments from a case. `DELETE :/s//api/cases//comments/` -=== Prerequisite +=== {api-prereq-title} You must have `all` privileges for the *Cases* feature in the *Management*, *{observability}*, or *Security* section of the <>, depending on the `owner` of the cases you're updating. -=== Path parameters +=== {api-path-parms-title} ``:: (Required, string) The identifier for the case. To retrieve case IDs, use @@ -38,12 +38,12 @@ comments are deleted. (Optional, string) An identifier for the space. If it is not specified, the default space is used. -=== Response code +=== {api-response-codes-title} `204`:: Indicates a successful call. -=== Example +=== {api-examples-title} Delete all comments from case ID `9c235210-6834-11ea-a78c-6ffb38a34414`: diff --git a/docs/api/cases/cases-api-find-cases.asciidoc b/docs/api/cases/cases-api-find-cases.asciidoc index b6e87ad502d21..abd4e186ff706 100644 --- a/docs/api/cases/cases-api-find-cases.asciidoc +++ b/docs/api/cases/cases-api-find-cases.asciidoc @@ -6,26 +6,26 @@ Retrieves a paginated subset of cases. -=== Request +=== {api-request-title} `GET :/api/cases/_find` `GET :/s//api/cases/_find` -=== Prerequisite +=== {api-prereq-title} You must have `read` privileges for the *Cases* feature in the *Management*, *{observability}*, or *Security* section of the <>, depending on the `owner` of the cases you're seeking. -=== Path parameters +=== {api-path-parms-title} ``:: (Optional, string) An identifier for the space. If it is not specified, the default space is used. -=== Query parameters +=== {api-query-parms-title} `defaultSearchOperator`:: (Optional, string) The default operator to use for the `simple_query_string`. @@ -84,12 +84,12 @@ Defaults to `desc`. `to`:: (Optional, string) Returns only cases that were created before a specific date. The date must be specified as a <> data range or date match expression. preview:[] -=== Response code +=== {api-response-codes-title} `200`:: Indicates a successful call. -=== Example +=== {api-examples-title} Retrieve the first five cases with the `phishing` tag, in ascending order by last update time: diff --git a/docs/api/cases/cases-api-find-connectors.asciidoc b/docs/api/cases/cases-api-find-connectors.asciidoc index 8643d569c980b..b12be5621e991 100644 --- a/docs/api/cases/cases-api-find-connectors.asciidoc +++ b/docs/api/cases/cases-api-find-connectors.asciidoc @@ -10,30 +10,30 @@ In particular, only the connectors that are supported for use in cases are returned. Refer to the list of supported external incident management systems in <>. -=== Request +=== {api-request-title} `GET :/api/cases/configure/connectors/_find` `GET :/s//api/cases/configure/connectors/_find` -=== Prerequisite +=== {api-prereq-title} You must have `read` privileges for the *Actions and Connectors* feature in the *Management* section of the <>. -=== Path parameters +=== {api-path-parms-title} ``:: (Optional, string) An identifier for the space. If it is not specified, the default space is used. -=== Response code +=== {api-response-codes-title} `200`:: Indicates a successful call. -=== Example +=== {api-examples-title} [source,sh] -------------------------------------------------- @@ -55,6 +55,7 @@ The API returns a JSON object describing the connectors and their settings: "projectKey":"ES" }, "isPreconfigured":false, + "isDeprecated": false, "referencedByCount":0 }] -------------------------------------------------- \ No newline at end of file diff --git a/docs/api/cases/cases-api-get-alerts.asciidoc b/docs/api/cases/cases-api-get-alerts.asciidoc index 62bca2d38ae8f..7df81f3a8974c 100644 --- a/docs/api/cases/cases-api-get-alerts.asciidoc +++ b/docs/api/cases/cases-api-get-alerts.asciidoc @@ -36,7 +36,7 @@ default space is used. `200`:: Indicates a successful call. -=== {api-example-title} +=== {api-examples-title} Return all alerts attached to case `293f1bc0-74f6-11ea-b83a-553aecdb28b6`: diff --git a/docs/api/cases/cases-api-get-case-activity.asciidoc b/docs/api/cases/cases-api-get-case-activity.asciidoc index 92b16b7862462..25d102dc11ee7 100644 --- a/docs/api/cases/cases-api-get-case-activity.asciidoc +++ b/docs/api/cases/cases-api-get-case-activity.asciidoc @@ -8,20 +8,20 @@ Returns all user activity for the specified case. deprecated::[8.1.0] -=== Request +=== {api-request-title} `GET :/api/cases//user_actions` `GET :/s//api/cases//user_actions` -=== Prerequisite +=== {api-prereq-title} You must have `read` privileges for the *Cases* feature in the *Management*, *{observability}*, or *Security* section of the <>, depending on the `owner` of the cases you're seeking. -=== Path parameters +=== {api-path-parms-title} ``:: (Required, string) An identifier for the case to retrieve. Use @@ -31,12 +31,12 @@ You must have `read` privileges for the *Cases* feature in the *Management*, (Optional, string) An identifier for the space. If it is not specified, the default space is used. -==== Response code +=== {api-response-codes-title} `200`:: Indicates a successful call. -==== Example +=== {api-examples-title} Gets all activity for case ID `a18b38a0-71b0-11ea-a0b2-c51ea50a58e2`: diff --git a/docs/api/cases/cases-api-get-case.asciidoc b/docs/api/cases/cases-api-get-case.asciidoc index 6bd255f6f8326..5abb9ecc1903b 100644 --- a/docs/api/cases/cases-api-get-case.asciidoc +++ b/docs/api/cases/cases-api-get-case.asciidoc @@ -6,20 +6,20 @@ Returns a specified case. -=== Request +=== {api-request-title} `GET :/api/cases/` `GET :/s//api/cases/` -=== Prerequisite +=== {api-prereq-title} You must have `read` privileges for the *Cases* feature in the *Management*, *{observability}*, or *Security* section of the <>, depending on the `owner` of the cases you're seeking. -=== Path parameters +=== {api-path-parms-title} ``:: (Required, string) An identifier for the case to retrieve. Use @@ -29,19 +29,18 @@ You must have `read` privileges for the *Cases* feature in the *Management*, (Optional, string) An identifier for the space. If it is not specified, the default space is used. -=== Query parameters +=== {api-query-parms-title} `includeComments`:: (Optional, boolean) Determines whether case comments are returned. Defaults to `true`. deprecated:[8.1.0, "The `includeComments` query parameter is deprecated and will be removed in a future release."] - -==== Response code +=== {api-response-codes-title} `200`:: Indicates a successful call. -==== Example +=== {api-examples-title} Returns case ID `a18b38a0-71b0-11ea-a0b2-c51ea50a58e2` without comments: diff --git a/docs/api/cases/cases-api-get-cases-by-alert.asciidoc b/docs/api/cases/cases-api-get-cases-by-alert.asciidoc index fb1f7c625c5fc..3bd2e8debb3cd 100644 --- a/docs/api/cases/cases-api-get-cases-by-alert.asciidoc +++ b/docs/api/cases/cases-api-get-cases-by-alert.asciidoc @@ -43,7 +43,7 @@ cases that the user has access to read. `200`:: Indicates a successful call. -=== {api-example-title} +=== {api-examples-title} Return cases associated with the alert ID `09f0c261e39e36351d75995b78bb83673774d1bc2cca9df2d15f0e5c0a99a540`: diff --git a/docs/api/cases/cases-api-get-comments.asciidoc b/docs/api/cases/cases-api-get-comments.asciidoc index 6e88b6ffdf004..103731cd04dd7 100644 --- a/docs/api/cases/cases-api-get-comments.asciidoc +++ b/docs/api/cases/cases-api-get-comments.asciidoc @@ -6,7 +6,7 @@ Gets a comment or all comments for a case. -=== Request +=== {api-request-title} `GET :/api/cases//comments/` @@ -16,14 +16,14 @@ Gets a comment or all comments for a case. `GET :/s//api/cases//comments` deprecated:[8.1.0] -=== Prerequisite +=== {api-prereq-title} You must have `read` privileges for the *Cases* feature in the *Management*, *{observability}*, or *Security* section of the <>, depending on the `owner` of the cases with the comments you're seeking. -=== Path parameters +=== {api-path-parms-title} ``:: (Required, string) The identifier for the case. To retrieve case IDs, use @@ -40,12 +40,12 @@ deprecated:[8.1.0,The comment identifier will no longer be optional.] (Optional, string) An identifier for the space. If it is not specified, the default space is used. -=== Response code +=== {api-response-codes-title} `200`:: Indicates a successful call. -=== Example +=== {api-examples-title} Retrieves comment ID `71ec1870-725b-11ea-a0b2-c51ea50a58e2` from case ID `a18b38a0-71b0-11ea-a0b2-c51ea50a58e2`: diff --git a/docs/api/cases/cases-api-get-reporters.asciidoc b/docs/api/cases/cases-api-get-reporters.asciidoc index eca8d3e45173f..331be71e9123a 100644 --- a/docs/api/cases/cases-api-get-reporters.asciidoc +++ b/docs/api/cases/cases-api-get-reporters.asciidoc @@ -6,32 +6,32 @@ Returns information about the users who opened cases. -=== Request +=== {api-request-title} `GET :/api/cases/reporters` `GET :/s/api/cases/reporters` -=== Prerequisite +=== {api-prereq-title} You must have `read` privileges for the *Cases* feature in the *Management*, *{observability}*, or *Security* section of the <>, depending on the `owner` of the cases you're seeking. -=== Query parameters +=== {api-query-parms-title} `owner`:: (Optional, string or array of strings) A filter to limit the retrieved reporters to a specific set of applications. If this parameter is omitted, the response will contain all reporters from cases that the user has access to read. -==== Response code +=== {api-response-codes-title} `200`:: Indicates a successful call. -==== Example +=== {api-examples-title} Returns all case reporters: diff --git a/docs/api/cases/cases-api-get-status.asciidoc b/docs/api/cases/cases-api-get-status.asciidoc index 62a8181feba8e..f96747dcc1116 100644 --- a/docs/api/cases/cases-api-get-status.asciidoc +++ b/docs/api/cases/cases-api-get-status.asciidoc @@ -8,26 +8,26 @@ Returns the number of cases that are open, closed, and in progress. deprecated::[8.1.0] -=== Request +=== {api-request-title} `GET :/api/cases/status` `GET :/s//api/cases/status` -=== Prerequisite +=== {api-prereq-title} You must have `read` privileges for the *Cases* feature in the *Management*, *{observability}*, or *Security* section of the <>, depending on the `owner` of the cases you're seeking. -=== Path parameters +=== {api-path-parms-title} :: (Optional, string) An identifier for the space. If it is not specified, the default space is used. -=== Query parameters +=== {api-query-parms-title} `owner`:: (Optional, string or array of strings) A filter to limit the retrieved case @@ -35,12 +35,12 @@ statistics to a specific set of applications. Valid values are: `cases`, `observability`, and `securitySolution`. If this parameter is omitted, the response contains all cases that the user has access to read. -=== Response code +=== {api-response-codes-title} `200`:: Indicates a successful call. -=== Example +=== {api-examples-title} [source,sh] -------------------------------------------------- diff --git a/docs/api/cases/cases-api-get-tags.asciidoc b/docs/api/cases/cases-api-get-tags.asciidoc index 44d2bf9fffd1f..5008411f37bdb 100644 --- a/docs/api/cases/cases-api-get-tags.asciidoc +++ b/docs/api/cases/cases-api-get-tags.asciidoc @@ -6,38 +6,38 @@ Aggregates and returns a list of case tags. -=== Request +=== {api-request-title} `GET :/api/cases/tags` `GET :/s//api/cases/tags` -=== Prerequisite +=== {api-prereq-title} You must have `read` privileges for the *Cases* feature in the *Management*, *{observability}*, or *Security* section of the <>, depending on the `owner` of the cases you're seeking. -=== Path parameters +=== {api-path-parms-title} ``:: (Optional, string) An identifier for the space. If it is not specified, the default space is used. -=== Query parameters +=== {api-query-parms-title} `owner`:: (Optional, string or array of strings) A filter to limit the retrieved tags to a specific set of applications. Valid values are: `cases`, `observability`, and `securitySolution`. If this parameter is omitted, the response contains tags from all cases that the user has access to read. -==== Response code +=== {api-response-codes-title} `200`:: Indicates a successful call. -==== Example +=== {api-examples-title} [source,sh] -------------------------------------------------- diff --git a/docs/api/cases/cases-api-push.asciidoc b/docs/api/cases/cases-api-push.asciidoc index e837dc78ad1a4..5b3e4d7c9ef78 100644 --- a/docs/api/cases/cases-api-push.asciidoc +++ b/docs/api/cases/cases-api-push.asciidoc @@ -40,7 +40,7 @@ default space is used. `200`:: Indicates a successful call. -=== {api-example-title} +=== {api-examples-title} Push the case to an external service: diff --git a/docs/api/cases/cases-api-set-configuration.asciidoc b/docs/api/cases/cases-api-set-configuration.asciidoc index 2b0cbefc008ac..6a7a7c26c66d2 100644 --- a/docs/api/cases/cases-api-set-configuration.asciidoc +++ b/docs/api/cases/cases-api-set-configuration.asciidoc @@ -99,7 +99,7 @@ An object that contains the case settings. `200`:: Indicates a successful call. -=== {api-example-title} +=== {api-examples-title} Sets the closure type and default connector for cases in **{stack-manage-app}**: diff --git a/docs/api/cases/cases-api-update-comment.asciidoc b/docs/api/cases/cases-api-update-comment.asciidoc index 98d426cb0c86d..020fe403fa7c5 100644 --- a/docs/api/cases/cases-api-update-comment.asciidoc +++ b/docs/api/cases/cases-api-update-comment.asciidoc @@ -6,20 +6,20 @@ Updates a comment in a case. -=== Request +=== {api-request-title} `PATCH :/api/cases//comments` `PATCH :/s//api/cases//comments` -=== Prerequisite +=== {api-prereq-title} You must have `all` privileges for the *Cases* feature in the *Management*, *{observability}*, or *Security* section of the <>, depending on the `owner` of the case you're updating. -=== Path parameters +=== {api-path-parms-title} ``:: The identifier for the case. To retrieve case IDs, use @@ -29,7 +29,7 @@ The identifier for the case. To retrieve case IDs, use (Optional, string) An identifier for the space. If it is not specified, the default space is used. -=== Request body +=== {api-request-body-title} `alertId`:: (Required*, string) The identifier for the alert. It is required only when @@ -40,8 +40,7 @@ default space is used. `user`. `id`:: -(Required, string) The identifier for the comment. -//To retrieve comment IDs, use <>. +(Required, string) The identifier for the comment. To retrieve comment IDs, use <>. `index`:: (Required*, string) The alert index. It is required only when `type` is `alert`. @@ -75,15 +74,14 @@ The rule that is associated with the alert. It is required only when `type` is NOTE: You cannot change the comment type. `version`:: -(Required, string) The current comment version. -//To retrieve version values, use <>. +(Required, string) The current comment version. To retrieve version values, use <>. -=== Response code +=== {api-response-codes-title} `200`:: Indicates a successful call. -=== Example +=== {api-examples-title} Update comment ID `8af6ac20-74f6-11ea-b83a-553aecdb28b6` (associated with case ID `293f1bc0-74f6-11ea-b83a-553aecdb28b6`): diff --git a/docs/api/cases/cases-api-update.asciidoc b/docs/api/cases/cases-api-update.asciidoc index 522300591d8b7..7a63d0e8a6a33 100644 --- a/docs/api/cases/cases-api-update.asciidoc +++ b/docs/api/cases/cases-api-update.asciidoc @@ -6,26 +6,26 @@ Updates one or more cases. -=== Request +=== {api-request-title} `PATCH :/api/cases` `PATCH :/s//api/cases` -=== Prerequisite +=== {api-prereq-title} You must have `all` privileges for the *Cases* feature in the *Management*, *{observability}*, or *Security* section of the <>, depending on the `owner` of the cases you're updating. -=== Path parameters +=== {api-path-parms-title} ``:: (Optional, string) An identifier for the space. If it is not specified, the default space is used. -=== Request body +=== {api-request-body-title} `cases`:: (Required, array of objects) Array containing one or more case objects. @@ -114,8 +114,7 @@ For {swimlane} connectors, specify: `id`:: (Required, string) The identifier for the connector. To remove the connector, -use `none`. -//To retrieve connector IDs, use <>). +use `none`. To retrieve connector IDs, use <>). `name`:: (Required, string) The name of the connector. To remove the connector, use @@ -159,12 +158,12 @@ and `open`. (Required, string) The current version of the case. To determine this value, use <> or <>. ==== -=== Response code +=== {api-response-codes-title} `200`:: Indicates a successful call. -=== Example +=== {api-examples-title} Update the description, tags, and connector of case ID `a18b38a0-71b0-11ea-a0b2-c51ea50a58e2`: diff --git a/docs/api/machine-learning/sync.asciidoc b/docs/api/machine-learning/sync.asciidoc index 5f19bc17ab2fb..d210a7826d166 100644 --- a/docs/api/machine-learning/sync.asciidoc +++ b/docs/api/machine-learning/sync.asciidoc @@ -4,32 +4,42 @@ Sync {ml} saved objects ++++ -Synchronizes {kib} saved objects for {ml} jobs. +Synchronizes {kib} saved objects for {ml} jobs and trained models. [[machine-learning-api-sync-request]] -==== Request +==== {api-request-title} `GET :/api/ml/saved_objects/sync` `GET :/s//api/ml/saved_objects/sync` +[[machine-learning-api-sync-prereq]] +==== {api-prereq-title} + +You must have `all` privileges for the *Machine Learning* feature in the *Analytics* section of the +<>. + +[[machine-learning-api-sync-desc]] +==== {api-description-title} + +This API runs automatically when you start {kib} and periodically thereafter. [[machine-learning-api-sync-path-params]] -==== Path parameters +==== {api-path-parms-title} `space_id`:: (Optional, string) An identifier for the space. If `space_id` is not provided in the URL the default space is used. [[machine-learning-api-sync-query-params]] -==== Query parameters +==== {api-query-parms-title} `simulate`:: (Optional, boolean) When `true`, simulates the synchronization by only returning the list actions that _would_ be performed. [[machine-learning-api-sync-response-body]] -==== Response body +==== {api-response-body-title} `datafeedsAdded`:: (array) If a saved object for an {anomaly-job} is missing a {dfeed} identifier, @@ -37,28 +47,28 @@ it is added. This list contains the {dfeed} identifiers and indicates whether the synchronization was successful. `datafeedsRemoved`:: -(array) If saved objects exist for {dfeeds} that no longer exist, they are -deleted. This list contains the {dfeed} identifiers and indicates whether the -synchronization was successful. +(array) If a saved object for an anomaly detection job references a datafeed +that no longer exists, it is deleted. This list contains the {dfeed} identifiers +and indicates whether the synchronization was successful. `savedObjectsCreated`:: -(array) If saved objects are missing for {ml} jobs, they are created. This -list contains the job identifiers and indicates whether the synchronization was -successful. +(array) If saved objects are missing for {ml} jobs or trained models, they are +created. This list contains the job and model identifiers and indicates whether +the synchronization was successful. `savedObjectsDeleted`:: -(array) If saved objects exist for jobs that no longer exist, they are deleted. -This list contains the job identifiers and indicates whether the synchronization -was successful. +(array) If saved objects exist for {ml} jobs or trained models that no longer +exist, they are deleted. This list contains the job and model identifiers and +indicates whether the synchronization was successful. [[machine-learning-api-sync-codes]] -==== Response code +==== {api-response-codes-title} `200`:: Indicates a successful call. [[machine-learning-api-sync-example]] -==== Example +==== {api-examples-title} Retrieve the list of {ml} saved objects that require synchronization: @@ -68,12 +78,12 @@ $ curl -X GET api/ml/saved_objects/sync?simulate=true -------------------------------------------------- // KIBANA -If there are two jobs and a {dfeed} that need to be synchronized, for example, -the API returns the following: +If there are two jobs that need to be synchronized, for example, the API returns +the following response: [source,sh] -------------------------------------------------- -{{"savedObjectsCreated":{"myjob1":{"success":true},"myjob2":{"success":true}},"savedObjectsDeleted":{},"datafeedsAdded":{},"datafeedsRemoved":{"myfeed3":{"success":true}}} +{{"savedObjectsCreated":{"anomaly_detector":{"myjob1":{"success":true},"myjob2":{"success":true}}},"savedObjectsDeleted":{},"datafeedsAdded":{},"datafeedsRemoved":{}} -------------------------------------------------- To perform the synchronization, re-run the API and omit the `simulate` parameter. \ No newline at end of file diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index 90bf3d3c29b41..63e104c44b173 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -412,10 +412,6 @@ The plugin exposes the static DefaultEditorController class to consume. |Adds drilldown capabilities to dashboard. Owned by the Kibana App team. -|{kib-repo}blob/{branch}/x-pack/plugins/data_enhanced/README.md[dataEnhanced] -|The data_enhanced plugin is the x-pack counterpart to the src/plguins/data plugin. - - |{kib-repo}blob/{branch}/x-pack/plugins/data_visualizer/README.md[dataVisualizer] |The data_visualizer plugin enables you to explore the fields in your data. diff --git a/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.deprecations.md b/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.deprecations.md new file mode 100644 index 0000000000000..51d93371e518e --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.deprecations.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [CoreRequestHandlerContext](./kibana-plugin-core-server.corerequesthandlercontext.md) > [deprecations](./kibana-plugin-core-server.corerequesthandlercontext.deprecations.md) + +## CoreRequestHandlerContext.deprecations property + +Signature: + +```typescript +deprecations: { + client: DeprecationsClient; + }; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.elasticsearch.md b/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.elasticsearch.md new file mode 100644 index 0000000000000..22ff84ce1cb57 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.elasticsearch.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [CoreRequestHandlerContext](./kibana-plugin-core-server.corerequesthandlercontext.md) > [elasticsearch](./kibana-plugin-core-server.corerequesthandlercontext.elasticsearch.md) + +## CoreRequestHandlerContext.elasticsearch property + +Signature: + +```typescript +elasticsearch: { + client: IScopedClusterClient; + }; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.md b/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.md new file mode 100644 index 0000000000000..47297bcddc906 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.md @@ -0,0 +1,25 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [CoreRequestHandlerContext](./kibana-plugin-core-server.corerequesthandlercontext.md) + +## CoreRequestHandlerContext interface + +The `core` context provided to route handler. + +Provides the following clients and services: - [savedObjects.client](./kibana-plugin-core-server.savedobjectsclient.md) - Saved Objects client which uses the credentials of the incoming request - [savedObjects.typeRegistry](./kibana-plugin-core-server.isavedobjecttyperegistry.md) - Type registry containing all the registered types. - [elasticsearch.client](./kibana-plugin-core-server.iscopedclusterclient.md) - Elasticsearch data client which uses the credentials of the incoming request - [uiSettings.client](./kibana-plugin-core-server.iuisettingsclient.md) - uiSettings client which uses the credentials of the incoming request + +Signature: + +```typescript +export interface CoreRequestHandlerContext +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [deprecations](./kibana-plugin-core-server.corerequesthandlercontext.deprecations.md) | { client: DeprecationsClient; } | | +| [elasticsearch](./kibana-plugin-core-server.corerequesthandlercontext.elasticsearch.md) | { client: IScopedClusterClient; } | | +| [savedObjects](./kibana-plugin-core-server.corerequesthandlercontext.savedobjects.md) | { client: SavedObjectsClientContract; typeRegistry: ISavedObjectTypeRegistry; getClient: (options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract; getExporter: (client: SavedObjectsClientContract) => ISavedObjectsExporter; getImporter: (client: SavedObjectsClientContract) => ISavedObjectsImporter; } | | +| [uiSettings](./kibana-plugin-core-server.corerequesthandlercontext.uisettings.md) | { client: IUiSettingsClient; } | | + diff --git a/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.savedobjects.md b/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.savedobjects.md new file mode 100644 index 0000000000000..6d1aa0a8bb5f1 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.savedobjects.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [CoreRequestHandlerContext](./kibana-plugin-core-server.corerequesthandlercontext.md) > [savedObjects](./kibana-plugin-core-server.corerequesthandlercontext.savedobjects.md) + +## CoreRequestHandlerContext.savedObjects property + +Signature: + +```typescript +savedObjects: { + client: SavedObjectsClientContract; + typeRegistry: ISavedObjectTypeRegistry; + getClient: (options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract; + getExporter: (client: SavedObjectsClientContract) => ISavedObjectsExporter; + getImporter: (client: SavedObjectsClientContract) => ISavedObjectsImporter; + }; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.uisettings.md b/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.uisettings.md new file mode 100644 index 0000000000000..f76dcc8965a03 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.uisettings.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [CoreRequestHandlerContext](./kibana-plugin-core-server.corerequesthandlercontext.md) > [uiSettings](./kibana-plugin-core-server.corerequesthandlercontext.uisettings.md) + +## CoreRequestHandlerContext.uiSettings property + +Signature: + +```typescript +uiSettings: { + client: IUiSettingsClient; + }; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.customrequesthandlercontext.md b/docs/development/core/server/kibana-plugin-core-server.customrequesthandlercontext.md new file mode 100644 index 0000000000000..afaf8c278565a --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.customrequesthandlercontext.md @@ -0,0 +1,14 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [CustomRequestHandlerContext](./kibana-plugin-core-server.customrequesthandlercontext.md) + +## CustomRequestHandlerContext type + + +Signature: + +```typescript +export declare type CustomRequestHandlerContext = RequestHandlerContext & { + [Key in keyof T]: T[Key] extends Promise ? T[Key] : Promise; +}; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.md b/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.md index f3be1a9130b9c..bb03887e547e2 100644 --- a/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.md +++ b/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.md @@ -87,5 +87,5 @@ async (context, request, response) => { | [registerOnPreAuth](./kibana-plugin-core-server.httpservicesetup.registeronpreauth.md) | (handler: OnPreAuthHandler) => void | To define custom logic to perform for incoming requests before the Auth interceptor performs a check that user has access to requested resources. | | [registerOnPreResponse](./kibana-plugin-core-server.httpservicesetup.registeronpreresponse.md) | (handler: OnPreResponseHandler) => void | To define custom logic to perform for the server response. | | [registerOnPreRouting](./kibana-plugin-core-server.httpservicesetup.registeronprerouting.md) | (handler: OnPreRoutingHandler) => void | To define custom logic to perform for incoming requests before server performs a route lookup. | -| [registerRouteHandlerContext](./kibana-plugin-core-server.httpservicesetup.registerroutehandlercontext.md) | <Context extends RequestHandlerContext, ContextName extends keyof Context>(contextName: ContextName, provider: RequestHandlerContextProvider<Context, ContextName>) => RequestHandlerContextContainer | Register a context provider for a route handler. | +| [registerRouteHandlerContext](./kibana-plugin-core-server.httpservicesetup.registerroutehandlercontext.md) | <Context extends RequestHandlerContext, ContextName extends keyof Omit<Context, 'resolve'>>(contextName: ContextName, provider: RequestHandlerContextProvider<Context, ContextName>) => RequestHandlerContextContainer | Register a context provider for a route handler. | diff --git a/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.registerroutehandlercontext.md b/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.registerroutehandlercontext.md index c793080305d0c..23e009864dcd6 100644 --- a/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.registerroutehandlercontext.md +++ b/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.registerroutehandlercontext.md @@ -9,7 +9,7 @@ Register a context provider for a route handler. Signature: ```typescript -registerRouteHandlerContext: (contextName: ContextName, provider: RequestHandlerContextProvider) => RequestHandlerContextContainer; +registerRouteHandlerContext: >(contextName: ContextName, provider: RequestHandlerContextProvider) => RequestHandlerContextContainer; ``` ## Example diff --git a/docs/development/core/server/kibana-plugin-core-server.icontextprovider.md b/docs/development/core/server/kibana-plugin-core-server.icontextprovider.md index ddd8a0e92f465..eb2ec3cbf90b8 100644 --- a/docs/development/core/server/kibana-plugin-core-server.icontextprovider.md +++ b/docs/development/core/server/kibana-plugin-core-server.icontextprovider.md @@ -9,7 +9,7 @@ A function that returns a context value for a specific key of given context type Signature: ```typescript -export declare type IContextProvider = (context: Omit, ...rest: HandlerParameters) => Promise | Context[ContextName]; +export declare type IContextProvider = (context: Omit, ...rest: HandlerParameters) => MaybePromise>; ``` ## Remarks diff --git a/docs/development/core/server/kibana-plugin-core-server.md b/docs/development/core/server/kibana-plugin-core-server.md index d142579e1ced3..e33beb19e01a4 100644 --- a/docs/development/core/server/kibana-plugin-core-server.md +++ b/docs/development/core/server/kibana-plugin-core-server.md @@ -60,6 +60,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [ConfigDeprecationDetails](./kibana-plugin-core-server.configdeprecationdetails.md) | | | [ContextSetup](./kibana-plugin-core-server.contextsetup.md) | An object that handles registration of context providers and configuring handlers with context. | | [CorePreboot](./kibana-plugin-core-server.corepreboot.md) | Context passed to the setup method of preboot plugins. | +| [CoreRequestHandlerContext](./kibana-plugin-core-server.corerequesthandlercontext.md) | The core context provided to route handler.Provides the following clients and services: - [savedObjects.client](./kibana-plugin-core-server.savedobjectsclient.md) - Saved Objects client which uses the credentials of the incoming request - [savedObjects.typeRegistry](./kibana-plugin-core-server.isavedobjecttyperegistry.md) - Type registry containing all the registered types. - [elasticsearch.client](./kibana-plugin-core-server.iscopedclusterclient.md) - Elasticsearch data client which uses the credentials of the incoming request - [uiSettings.client](./kibana-plugin-core-server.iuisettingsclient.md) - uiSettings client which uses the credentials of the incoming request | | [CoreSetup](./kibana-plugin-core-server.coresetup.md) | Context passed to the setup method of standard plugins. | | [CoreStart](./kibana-plugin-core-server.corestart.md) | Context passed to the plugins start method. | | [CoreStatus](./kibana-plugin-core-server.corestatus.md) | Status of core services. | @@ -133,7 +134,8 @@ The plugin integrates with the core system via lifecycle events: `setup` | [PrebootPlugin](./kibana-plugin-core-server.prebootplugin.md) | The interface that should be returned by a PluginInitializer for a preboot plugin. | | [PrebootServicePreboot](./kibana-plugin-core-server.prebootservicepreboot.md) | Kibana Preboot Service allows to control the boot flow of Kibana. Preboot plugins can use it to hold the boot until certain condition is met. | | [RegisterDeprecationsConfig](./kibana-plugin-core-server.registerdeprecationsconfig.md) | | -| [RequestHandlerContext](./kibana-plugin-core-server.requesthandlercontext.md) | Plugin specific context passed to a route handler.Provides the following clients and services: - [savedObjects.client](./kibana-plugin-core-server.savedobjectsclient.md) - Saved Objects client which uses the credentials of the incoming request - [savedObjects.typeRegistry](./kibana-plugin-core-server.isavedobjecttyperegistry.md) - Type registry containing all the registered types. - [elasticsearch.client](./kibana-plugin-core-server.iscopedclusterclient.md) - Elasticsearch data client which uses the credentials of the incoming request - [uiSettings.client](./kibana-plugin-core-server.iuisettingsclient.md) - uiSettings client which uses the credentials of the incoming request | +| [RequestHandlerContext](./kibana-plugin-core-server.requesthandlercontext.md) | Base context passed to a route handler. | +| [RequestHandlerContextBase](./kibana-plugin-core-server.requesthandlercontextbase.md) | \* | | [ResolveCapabilitiesOptions](./kibana-plugin-core-server.resolvecapabilitiesoptions.md) | Defines a set of additional options for the resolveCapabilities method of [CapabilitiesStart](./kibana-plugin-core-server.capabilitiesstart.md). | | [RouteConfig](./kibana-plugin-core-server.routeconfig.md) | Route specific configuration. | | [RouteConfigOptions](./kibana-plugin-core-server.routeconfigoptions.md) | Additional route options. | @@ -262,6 +264,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [AuthResult](./kibana-plugin-core-server.authresult.md) | | | [CapabilitiesProvider](./kibana-plugin-core-server.capabilitiesprovider.md) | See [CapabilitiesSetup](./kibana-plugin-core-server.capabilitiessetup.md) | | [CapabilitiesSwitcher](./kibana-plugin-core-server.capabilitiesswitcher.md) | See [CapabilitiesSetup](./kibana-plugin-core-server.capabilitiessetup.md) | +| [CustomRequestHandlerContext](./kibana-plugin-core-server.customrequesthandlercontext.md) | | | [DeprecationsDetails](./kibana-plugin-core-server.deprecationsdetails.md) | | | [DestructiveRouteMethod](./kibana-plugin-core-server.destructiveroutemethod.md) | Set of HTTP methods changing the state of the server. | | [DocLinksServiceStart](./kibana-plugin-core-server.doclinksservicestart.md) | | diff --git a/docs/development/core/server/kibana-plugin-core-server.requesthandlercontext.core.md b/docs/development/core/server/kibana-plugin-core-server.requesthandlercontext.core.md index dcf6975c5fa70..8d0b715fdef7b 100644 --- a/docs/development/core/server/kibana-plugin-core-server.requesthandlercontext.core.md +++ b/docs/development/core/server/kibana-plugin-core-server.requesthandlercontext.core.md @@ -7,22 +7,5 @@ Signature: ```typescript -core: { - savedObjects: { - client: SavedObjectsClientContract; - typeRegistry: ISavedObjectTypeRegistry; - getClient: (options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract; - getExporter: (client: SavedObjectsClientContract) => ISavedObjectsExporter; - getImporter: (client: SavedObjectsClientContract) => ISavedObjectsImporter; - }; - elasticsearch: { - client: IScopedClusterClient; - }; - uiSettings: { - client: IUiSettingsClient; - }; - deprecations: { - client: DeprecationsClient; - }; - }; +core: Promise; ``` diff --git a/docs/development/core/server/kibana-plugin-core-server.requesthandlercontext.md b/docs/development/core/server/kibana-plugin-core-server.requesthandlercontext.md index 0d705c9daa333..214f8a6f6ba5c 100644 --- a/docs/development/core/server/kibana-plugin-core-server.requesthandlercontext.md +++ b/docs/development/core/server/kibana-plugin-core-server.requesthandlercontext.md @@ -4,19 +4,18 @@ ## RequestHandlerContext interface -Plugin specific context passed to a route handler. - -Provides the following clients and services: - [savedObjects.client](./kibana-plugin-core-server.savedobjectsclient.md) - Saved Objects client which uses the credentials of the incoming request - [savedObjects.typeRegistry](./kibana-plugin-core-server.isavedobjecttyperegistry.md) - Type registry containing all the registered types. - [elasticsearch.client](./kibana-plugin-core-server.iscopedclusterclient.md) - Elasticsearch data client which uses the credentials of the incoming request - [uiSettings.client](./kibana-plugin-core-server.iuisettingsclient.md) - uiSettings client which uses the credentials of the incoming request +Base context passed to a route handler. Signature: ```typescript -export interface RequestHandlerContext +export interface RequestHandlerContext extends RequestHandlerContextBase ``` +Extends: RequestHandlerContextBase ## Properties | Property | Type | Description | | --- | --- | --- | -| [core](./kibana-plugin-core-server.requesthandlercontext.core.md) | { savedObjects: { client: SavedObjectsClientContract; typeRegistry: ISavedObjectTypeRegistry; getClient: (options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract; getExporter: (client: SavedObjectsClientContract) => ISavedObjectsExporter; getImporter: (client: SavedObjectsClientContract) => ISavedObjectsImporter; }; elasticsearch: { client: IScopedClusterClient; }; uiSettings: { client: IUiSettingsClient; }; deprecations: { client: DeprecationsClient; }; } | | +| [core](./kibana-plugin-core-server.requesthandlercontext.core.md) | Promise<CoreRequestHandlerContext> | | diff --git a/docs/development/core/server/kibana-plugin-core-server.requesthandlercontextbase.md b/docs/development/core/server/kibana-plugin-core-server.requesthandlercontextbase.md new file mode 100644 index 0000000000000..33a123eefae63 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.requesthandlercontextbase.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [RequestHandlerContextBase](./kibana-plugin-core-server.requesthandlercontextbase.md) + +## RequestHandlerContextBase interface + +\* + +Signature: + +```typescript +export interface RequestHandlerContextBase +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [resolve](./kibana-plugin-core-server.requesthandlercontextbase.resolve.md) | <T extends keyof Omit<this, 'resolve'>>(parts: T\[\]) => Promise<AwaitedProperties<Pick<this, T>>> | Await all the specified context parts and return them. | + diff --git a/docs/development/core/server/kibana-plugin-core-server.requesthandlercontextbase.resolve.md b/docs/development/core/server/kibana-plugin-core-server.requesthandlercontextbase.resolve.md new file mode 100644 index 0000000000000..74192c0e1aee8 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.requesthandlercontextbase.resolve.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [RequestHandlerContextBase](./kibana-plugin-core-server.requesthandlercontextbase.md) > [resolve](./kibana-plugin-core-server.requesthandlercontextbase.resolve.md) + +## RequestHandlerContextBase.resolve property + +Await all the specified context parts and return them. + +Signature: + +```typescript +resolve: >(parts: T[]) => Promise>>; +``` + +## Example + + +```ts +const resolved = await context.resolve(['core', 'pluginA']); +const esClient = resolved.core.elasticsearch.client; +const pluginAService = resolved.pluginA.someService; +``` + diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsimporter.import.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsimporter.import.md index 1ca6058e7d742..f30ddeddba92d 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsimporter.import.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsimporter.import.md @@ -9,14 +9,14 @@ Import saved objects from given stream. See the [options](./kibana-plugin-core-s Signature: ```typescript -import({ readStream, createNewCopies, namespace, overwrite, }: SavedObjectsImportOptions): Promise; +import({ readStream, createNewCopies, namespace, overwrite, refresh, }: SavedObjectsImportOptions): Promise; ``` ## Parameters | Parameter | Type | Description | | --- | --- | --- | -| { readStream, createNewCopies, namespace, overwrite, } | SavedObjectsImportOptions | | +| { readStream, createNewCopies, namespace, overwrite, refresh, } | SavedObjectsImportOptions | | Returns: diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsimporter.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsimporter.md index 18ce27ca2c0dc..b1035bc247ad1 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsimporter.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsimporter.md @@ -21,6 +21,6 @@ export declare class SavedObjectsImporter | Method | Modifiers | Description | | --- | --- | --- | -| [import({ readStream, createNewCopies, namespace, overwrite, })](./kibana-plugin-core-server.savedobjectsimporter.import.md) | | Import saved objects from given stream. See the [options](./kibana-plugin-core-server.savedobjectsimportoptions.md) for more detailed information. | +| [import({ readStream, createNewCopies, namespace, overwrite, refresh, })](./kibana-plugin-core-server.savedobjectsimporter.import.md) | | Import saved objects from given stream. See the [options](./kibana-plugin-core-server.savedobjectsimportoptions.md) for more detailed information. | | [resolveImportErrors({ readStream, createNewCopies, namespace, retries, })](./kibana-plugin-core-server.savedobjectsimporter.resolveimporterrors.md) | | Resolve and return saved object import errors. See the [options](./kibana-plugin-core-server.savedobjectsresolveimporterrorsoptions.md) for more detailed information. | diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsimportoptions.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsimportoptions.md index 58d0f4bf982c3..775f3a4c9acb3 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsimportoptions.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsimportoptions.md @@ -20,4 +20,5 @@ export interface SavedObjectsImportOptions | [namespace?](./kibana-plugin-core-server.savedobjectsimportoptions.namespace.md) | string | (Optional) if specified, will import in given namespace, else will import as global object | | [overwrite](./kibana-plugin-core-server.savedobjectsimportoptions.overwrite.md) | boolean | If true, will override existing object if present. Note: this has no effect when used with the createNewCopies option. | | [readStream](./kibana-plugin-core-server.savedobjectsimportoptions.readstream.md) | Readable | The stream of [saved objects](./kibana-plugin-core-server.savedobject.md) to import | +| [refresh?](./kibana-plugin-core-server.savedobjectsimportoptions.refresh.md) | boolean \| 'wait\_for' | (Optional) Refresh setting, defaults to wait_for | diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsimportoptions.refresh.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsimportoptions.refresh.md new file mode 100644 index 0000000000000..cc7e36354647a --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsimportoptions.refresh.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [SavedObjectsImportOptions](./kibana-plugin-core-server.savedobjectsimportoptions.md) > [refresh](./kibana-plugin-core-server.savedobjectsimportoptions.refresh.md) + +## SavedObjectsImportOptions.refresh property + +Refresh setting, defaults to `wait_for` + +Signature: + +```typescript +refresh?: boolean | 'wait_for'; +``` diff --git a/docs/management/connectors/action-types/email.asciidoc b/docs/management/connectors/action-types/email.asciidoc index c080c412f0f6b..3571185d0d510 100644 --- a/docs/management/connectors/action-types/email.asciidoc +++ b/docs/management/connectors/action-types/email.asciidoc @@ -7,7 +7,11 @@ The email connector uses the SMTP protocol to send mail messages, using an integration of https://nodemailer.com/[Nodemailer]. An exception is Microsoft Exchange, which uses HTTP protocol for sending emails, https://docs.microsoft.com/en-us/graph/api/user-sendmail[Send mail]. Email message text is sent as both plain text and html text. -NOTE: For emails to have a footer with a link back to {kib}, set the <> configuration setting. +[NOTE] +==== +* For emails to have a footer with a link back to {kib}, set the <> configuration setting. +* When the <> configuration setting is used, the email addresses used for all of the Sender (from), To, CC, and BCC properties must have email domains specified in the configuration setting. +==== [float] [[email-connector-configuration]] diff --git a/docs/maps/import-geospatial-data.asciidoc b/docs/maps/import-geospatial-data.asciidoc index f58077fa38f92..8ee54e5dba638 100644 --- a/docs/maps/import-geospatial-data.asciidoc +++ b/docs/maps/import-geospatial-data.asciidoc @@ -96,12 +96,6 @@ To open an existing index for drawing: . Click *Add layer*. -. Set *Scaling* to *Limit results to 10,000*. - -. In **Filtering**: -** Clear the *Apply global search to layer data* checkbox. -** If your data view contains a default time field, clear the *Apply global time to layer data* checkbox. - . Click *Save & close*. . In the legend, click the layer name and select *Edit features*. diff --git a/docs/osquery/advanced-osquery.asciidoc b/docs/osquery/advanced-osquery.asciidoc deleted file mode 100644 index 4f03a6d5fe5eb..0000000000000 --- a/docs/osquery/advanced-osquery.asciidoc +++ /dev/null @@ -1,103 +0,0 @@ -[[advanced-osquery]] -== Advanced Osquery - -[float] -[[osquery-map-fields]] -=== Map result fields to ECS - -When you save queries or add queries to a pack, you can optionally map Osquery results or static values to fields in -the {ecs-ref}/ecs-reference.html[Elastic Common Schema] (ECS). -This standardizes your Osquery data for use across detections, machine learning, -and any other areas that rely on ECS-compliant data. -When the query is run, the results include the original `osquery.` -and the mapped ECS fields. For example, if you update a query to map `osquery.name` to `user.name`, the query results include both fields. - -. Edit saved queries or queries in a pack to map fields: - -* For *Saved queries*: Open the *Saved queries* tab, and then click the edit icon for the query that you want to map. - -* For *packs*: Open the *Packs* tab, edit a pack, and then click the edit icon for the query that you want to map. - -. In the **ECS mapping** section, select an **ECS field** to map. - -. In the **Value** column, use the dropdown on the left to choose what type of value to map to the ECS field: - -** **Osquery value**: Select an Osquery field. The fields available are based on the SQL query entered, and only include fields that the query returns. When the query runs, the ECS field is set dynamically to the value of the Osquery field selected. - -** **Static value**: Enter a static value. When the query runs, the ECS field is set to the value entered. For example, static fields can be used to apply `tags` or your preferred `event.category` to the query results. - -. Map more fields, as needed. To remove any mapped rows, click the delete icon. - -. Save your changes. - -[NOTE] -========================= - -* Some ECS fields are restricted and cannot be mapped. These are not available in the ECS dropdown. - -* Some ECS fields are restricted to a set of allowed values, like {ecs-ref}/ecs-event.html#field-event-category[event.category]. Use the {ecs-ref}/ecs-field-reference.html[ECS Field Reference] for help when mapping fields. - -* Osquery date fields have a variety of data types (including integer, text, or bigint). When mapping an Osquery date field to an ECS date field, you might need to use SQL operators in the query to get an {es}-compatible -{ref}/date.html[date] type. -========================= - - -[float] -[[osquery-extended-tables]] -=== Extended tables for Kubernetes queries -In addition to the Osquery schema, the Elastic-provided version of Osquery also includes the following tables to support Kubernetes containers. These can be queried with live or scheduled queries. - -* `host_users` - -* `host_groups` - -* `host_processes` - -When querying these tables, the expectation is that the `/etc/passwd`, `/etc/group`, and `/proc` are available in the container under `/hostfs` as: -`/hostfs/etc/passwd`, `/hostfs/etc/group`, and `/hostfs/proc`. For information about the fields available in these tables, see the -https://docs.elastic.co/en/integrations/osquery_manager#exported-fields[exported fields] reference. - -[float] -[[osquery-status]] -=== Osquery status - -A query can have the following status: - -[cols="2*<"] -|=== -| Successful | The query successfully completed. -| Failed | The query encountered a problem, such as an issue with the query or the agent was disconnected, and might have failed. -| Not yet responded | The query has not been sent to the agent. -| Expired | The action request timed out. The agent may be offline. -|=== - -NOTE: If an agent is offline, the request status remains **pending** as {kib} retries the request. -By default, a query request times out after five minutes. The time out applies to the time it takes -to deliver the action request to an agent to run a query. If the action completes after the timeout period, -the results are still returned. - - -[float] -[[osquery-results]] -=== Osquery results -When you run live or scheduled queries, the results are automatically -stored in an {es} index, so that you can search, analyze, and visualize this data in {kib}. -For a list of the Osquery fields that can be returned in query results, -refer to https://docs.elastic.co/en/integrations/osquery_manager#exported-fields[exported fields]. -Query results can also include ECS fields, if the query has a defined ECS mapping. - -Osquery responses include the following information: - -* Everything prefaced with `osquery.` is part of the query response. These fields are not mapped to ECS by default. - -* Results include some ECS fields by default, such as `host.*` and `agent.*`, which provide information about the host that was queried. - -* For live queries, the `action_data.query` is the query that was sent. - -* For scheduled queries in a pack, the `action_id` has the format `pack__`. You can use this information to look up the query that was run. - -* By default, all query results are https://osquery.readthedocs.io/en/stable/deployment/logging/#snapshot-logs[snapshot logs] -that represent a point in time with a set of results, with no -https://osquery.readthedocs.io/en/stable/deployment/logging/#differential-logs[differentials]. - -* Osquery data is stored in the `logs-osquery_manager.result-` datastream, and the result row data is under the `osquery` property in the document. diff --git a/docs/osquery/exported-fields-reference.asciidoc b/docs/osquery/exported-fields-reference.asciidoc index d359c484e4439..600751620c6d9 100644 --- a/docs/osquery/exported-fields-reference.asciidoc +++ b/docs/osquery/exported-fields-reference.asciidoc @@ -1,4 +1,6453 @@ [[exported-fields-osquery]] == Exported fields reference -_Content coming soon._ +The following fields can be returned in osquery results. Note the following about osquery fields: + +* Some fields list multiple descriptions because the one that applies depends on which table was queried. For example, a result stored in the `osquery.autoupdate` field may represent a response from the `firefox_addons` table or the `windows_security_center` table. +* In the cases where a field name is associated with more than one osquery table, we have made a best guess at what the data `type` should be. In the cases where it is unknown, the data type is set as a `keyword` object. + +For more information about osquery tables, see the https://osquery.io/schema[osquery schema documentation]. + +[float] +[[osquery-fields]] +=== Fields + +*UUID* - keyword, text.text + +* _system_extensions.UUID_ - Extension unique id + +*abi* - keyword, text.text + +* _elf_info.abi_ - Section type + +*action* - keyword, text.text + +* _disk_events.action_ - Appear or disappear +* _example.action_ - Action performed in generation +* _file_events.action_ - Change action (UPDATE, REMOVE, etc) +* _hardware_events.action_ - Remove, insert, change properties, etc +* _ntfs_journal_events.action_ - Change action (Write, Delete, etc) +* _scheduled_tasks.action_ - Actions executed by the scheduled task +* _socket_events.action_ - The socket action (bind, listen, close) +* _yara_events.action_ - Change action (UPDATE, REMOVE, etc) + +*activated* - keyword, number.long + +* _tpm_info.activated_ - TPM is activated + +*active* - keyword, number.long + +* _firefox_addons.active_ - 1 If the addon is active else 0 +* _memory_info.active_ - The total amount of buffer or page cache memory, in bytes, that is in active use +* _osquery_events.active_ - 1 if the publisher or subscriber is active else 0 +* _osquery_packs.active_ - Whether this pack is active (the version, platform and discovery queries match) yes=1, no=0. +* _osquery_registry.active_ - 1 If this plugin is active else 0 +* _virtual_memory_info.active_ - Total number of active pages. + +*active_disks* - keyword, number.long + +* _md_devices.active_disks_ - Number of active disks in array + +*active_state* - keyword, text.text + +* _systemd_units.active_state_ - The high-level unit activation state, i.e. generalization of SUB + +*actual* - keyword, number.long + +* _fan_speed_sensors.actual_ - Actual speed + +*additional_product_id* - keyword, text.text + +* _smart_drive_info.additional_product_id_ - An additional drive identifier if any + +*addr* - keyword, number.long + +* _elf_symbols.addr_ - Symbol address (value) + +*address* - keyword, text.text + +* _arp_cache.address_ - IPv4 address target +* _dns_resolvers.address_ - Resolver IP/IPv6 address +* _etc_hosts.address_ - IP address mapping +* _fbsd_kmods.address_ - Kernel module address +* _interface_addresses.address_ - Specific address for interface +* _kernel_modules.address_ - Kernel module address +* _listening_ports.address_ - Specific address for bind +* _platform_info.address_ - Relative address of firmware mapping +* _user_events.address_ - The Internet protocol address or family ID + +*address_width* - keyword, text.text + +* _cpu_info.address_width_ - The width of the CPU address bus. + +*algorithm* - keyword, text.text + +* _authorized_keys.algorithm_ - algorithm of key + +*alias* - keyword, text.text + +* _etc_protocols.alias_ - Protocol alias +* _time_machine_destinations.alias_ - Human readable name of drive + +*aliases* - keyword, text.text + +* _etc_services.aliases_ - Optional space separated list of other names for a service +* _lxd_images.aliases_ - Comma-separated list of image aliases + +*align* - keyword, number.long + +* _elf_sections.align_ - Segment alignment +* _elf_segments.align_ - Segment alignment + +*allow_maximum* - keyword, number.long + +* _shared_resources.allow_maximum_ - Number of concurrent users for this resource has been limited. If True, the value in the MaximumAllowed property is ignored. + +*allow_root* - keyword, text.text + +* _authorizations.allow_root_ - Label top-level key + +*allow_signed_enabled* - keyword, number.long + +* _alf.allow_signed_enabled_ - 1 If allow signed mode is enabled else 0 + +*ami_id* - keyword, text.text + +* _ec2_instance_metadata.ami_id_ - AMI ID used to launch this EC2 instance + +*amperage* - keyword, number.long + +* _battery.amperage_ - The battery's current amperage in mA + +*anonymous* - keyword, number.long + +* _virtual_memory_info.anonymous_ - Total number of anonymous pages. + +*antispyware* - keyword, text.text + +* _windows_security_center.antispyware_ - The health of the monitored Antispyware solution (see windows_security_products) + +*antivirus* - keyword, text.text + +* _windows_security_center.antivirus_ - The health of the monitored Antivirus solution (see windows_security_products) + +*api_version* - keyword, text.text + +* _docker_version.api_version_ - API version + +*apparmor* - keyword, text.text + +* _apparmor_events.apparmor_ - Apparmor Status like ALLOWED, DENIED etc. + +*applescript_enabled* - keyword, text.text + +* _apps.applescript_enabled_ - Info properties NSAppleScriptEnabled label + +*application* - keyword, text.text + +* _office_mru.application_ - Associated Office application + +*arch* - keyword, text.text + +* _deb_packages.arch_ - Package architecture +* _docker_version.arch_ - Hardware architecture +* _os_version.arch_ - OS Architecture +* _pkg_packages.arch_ - Architecture(s) supported +* _rpm_packages.arch_ - Architecture(s) supported +* _seccomp_events.arch_ - Information about the CPU architecture +* _signature.arch_ - If applicable, the arch of the signed code + +*architecture* - keyword, text.text + +* _docker_info.architecture_ - Hardware architecture +* _ec2_instance_metadata.architecture_ - Hardware architecture of this EC2 instance +* _lxd_images.architecture_ - Target architecture for the image +* _lxd_instances.architecture_ - Instance architecture + +*architectures* - keyword, text.text + +* _apt_sources.architectures_ - Repository architectures + +*args* - keyword, text.text + +* _startup_items.args_ - Arguments provided to startup executable + +*arguments* - keyword, text.text + +* _kernel_info.arguments_ - Kernel arguments + +*array_handle* - keyword, text.text + +* _memory_devices.array_handle_ - The memory array that the device is attached to + +*assessments_enabled* - keyword, number.long + +* _gatekeeper.assessments_enabled_ - 1 If a Gatekeeper is enabled else 0 + +*asset_tag* - keyword, text.text + +* _memory_devices.asset_tag_ - Manufacturer specific asset tag of memory device + +*ata_version* - keyword, text.text + +* _smart_drive_info.ata_version_ - ATA version of drive + +*atime* - keyword, number.long + +* _device_file.atime_ - Last access time +* _file.atime_ - Last access time +* _file_events.atime_ - Last access time +* _process_events.atime_ - File last access in UNIX time +* _shared_memory.atime_ - Attached time + +*attach* - keyword, text.text + +* _apparmor_profiles.attach_ - Which executable(s) a profile will attach to. + +*attached* - keyword, number.long + +* _shared_memory.attached_ - Number of attached processes + +*attributes* - keyword, text.text + +* _file.attributes_ - File attrib string. See: https://ss64.com/nt/attrib.html + +*audible_alarm* - keyword, text.text + +* _chassis_info.audible_alarm_ - If TRUE, the frame is equipped with an audible alarm. + +*auid* - keyword + +* _process_events.auid_ - Audit User ID at process start +* _process_file_events.auid_ - Audit user ID of the process using the file +* _seccomp_events.auid_ - Audit user ID (loginuid) of the user who started the analyzed process +* _socket_events.auid_ - Audit User ID +* _user_events.auid_ - Audit User ID + +*authenticate_user* - keyword, text.text + +* _authorizations.authenticate_user_ - Label top-level key + +*authentication_package* - keyword, text.text + +* _logon_sessions.authentication_package_ - The authentication package used to authenticate the owner of the logon session. + +*author* - keyword, text.text + +* _chocolatey_packages.author_ - Optional package author +* _chrome_extensions.author_ - Optional extension author +* _npm_packages.author_ - Package author name +* _python_packages.author_ - Optional package author +* _safari_extensions.author_ - Optional extension author + +*authority* - keyword, text.text + +* _signature.authority_ - Certificate Common Name + +*authority_key_id* - keyword, text.text + +* _certificates.authority_key_id_ - AKID an optionally included SHA1 + +*authority_key_identifier* - keyword, text.text + +* _curl_certificate.authority_key_identifier_ - Authority Key Identifier + +*authorizations* - keyword, text.text + +* _keychain_acls.authorizations_ - A space delimited set of authorization attributes + +*auto_login* - keyword, number.long + +* _wifi_networks.auto_login_ - 1 if auto login is enabled, 0 otherwise + +*auto_update* - keyword, number.long + +* _lxd_images.auto_update_ - Whether the image auto-updates (1) or not (0) + +*autoupdate* - keyword + +* _firefox_addons.autoupdate_ - 1 If the addon applies background updates else 0 +* _windows_security_center.autoupdate_ - The health of the Windows Autoupdate feature + +*availability* - keyword, text.text + +* _cpu_info.availability_ - The availability and status of the CPU. + +*availability_zone* - keyword, text.text + +* _ec2_instance_metadata.availability_zone_ - Availability zone in which this instance launched + +*average* - keyword, text.text + +* _load_average.average_ - Load average over the specified period. + +*average_memory* - keyword, number.long + +* _osquery_schedule.average_memory_ - Average private memory left after executing + +*avg_disk_bytes_per_read* - keyword, number.long + +* _physical_disk_performance.avg_disk_bytes_per_read_ - Average number of bytes transferred from the disk during read operations + +*avg_disk_bytes_per_write* - keyword, number.long + +* _physical_disk_performance.avg_disk_bytes_per_write_ - Average number of bytes transferred to the disk during write operations + +*avg_disk_read_queue_length* - keyword, number.long + +* _physical_disk_performance.avg_disk_read_queue_length_ - Average number of read requests that were queued for the selected disk during the sample interval + +*avg_disk_sec_per_read* - keyword, number.long + +* _physical_disk_performance.avg_disk_sec_per_read_ - Average time, in seconds, of a read operation of data from the disk + +*avg_disk_sec_per_write* - keyword, number.long + +* _physical_disk_performance.avg_disk_sec_per_write_ - Average time, in seconds, of a write operation of data to the disk + +*avg_disk_write_queue_length* - keyword, number.long + +* _physical_disk_performance.avg_disk_write_queue_length_ - Average number of write requests that were queued for the selected disk during the sample interval + +*backup_date* - keyword, number.long + +* _time_machine_backups.backup_date_ - Backup Date + +*bank_locator* - keyword, text.text + +* _memory_devices.bank_locator_ - String number of the string that identifies the physically-labeled bank where the memory device is located + +*base64* - keyword, number.long + +* _extended_attributes.base64_ - 1 if the value is base64 encoded else 0 + +*base_image* - keyword, text.text + +* _lxd_instances.base_image_ - ID of image used to launch this instance + +*base_uri* - keyword, text.text + +* _apt_sources.base_uri_ - Repository base URI + +*baseurl* - keyword, text.text + +* _yum_sources.baseurl_ - Repository base URL + +*basic_constraint* - keyword, text.text + +* _curl_certificate.basic_constraint_ - Basic Constraints + +*binary_queue* - keyword, number.long + +* _carbon_black_info.binary_queue_ - Size in bytes of binaries waiting to be sent to Carbon Black server + +*binding* - keyword, text.text + +* _elf_symbols.binding_ - Binding type + +*bitmap_chunk_size* - keyword, text.text + +* _md_devices.bitmap_chunk_size_ - Bitmap chunk size + +*bitmap_external_file* - keyword, text.text + +* _md_devices.bitmap_external_file_ - External referenced bitmap file + +*bitmap_on_mem* - keyword, text.text + +* _md_devices.bitmap_on_mem_ - Pages allocated in in-memory bitmap, if enabled + +*block* - keyword, text.text + +* _ssh_configs.block_ - The host or match block + +*block_size* - keyword, number.long + +* _block_devices.block_size_ - Block size in bytes +* _device_file.block_size_ - Block size of filesystem +* _file.block_size_ - Block size of filesystem + +*blocks* - keyword, number.long + +* _device_partitions.blocks_ - Number of blocks +* _mounts.blocks_ - Mounted device used blocks + +*blocks_available* - keyword, number.long + +* _mounts.blocks_available_ - Mounted device available blocks + +*blocks_free* - keyword, number.long + +* _mounts.blocks_free_ - Mounted device free blocks + +*blocks_size* - keyword, number.long + +* _device_partitions.blocks_size_ - Byte size of each block +* _mounts.blocks_size_ - Block size in bytes + +*bluetooth_sharing* - keyword, number.long + +* _sharing_preferences.bluetooth_sharing_ - 1 If bluetooth sharing is enabled for any user else 0 + +*board_model* - keyword, text.text + +* _system_info.board_model_ - Board model + +*board_serial* - keyword, text.text + +* _system_info.board_serial_ - Board serial number + +*board_vendor* - keyword, text.text + +* _system_info.board_vendor_ - Board vendor + +*board_version* - keyword, text.text + +* _system_info.board_version_ - Board version + +*boot_partition* - keyword, number.long + +* _logical_drives.boot_partition_ - True if Windows booted from this drive. + +*boot_uuid* - keyword, text.text + +* _ibridge_info.boot_uuid_ - Boot UUID of the iBridge controller + +*bp_microcode_disabled* - keyword, number.long + +* _kva_speculative_info.bp_microcode_disabled_ - Branch Predictions are disabled due to lack of microcode update. + +*bp_mitigations* - keyword, number.long + +* _kva_speculative_info.bp_mitigations_ - Branch Prediction mitigations are enabled. + +*bp_system_pol_disabled* - keyword, number.long + +* _kva_speculative_info.bp_system_pol_disabled_ - Branch Predictions are disabled via system policy. + +*breach_description* - keyword, text.text + +* _chassis_info.breach_description_ - If provided, gives a more detailed description of a detected security breach. + +*bridge_nf_ip6tables* - keyword, number.long + +* _docker_info.bridge_nf_ip6tables_ - 1 if bridge netfilter ip6tables is enabled. 0 otherwise + +*bridge_nf_iptables* - keyword, number.long + +* _docker_info.bridge_nf_iptables_ - 1 if bridge netfilter iptables is enabled. 0 otherwise + +*broadcast* - keyword, text.text + +* _interface_addresses.broadcast_ - Broadcast address for the interface + +*browser_type* - keyword, text.text + +* _chrome_extension_content_scripts.browser_type_ - The browser type (Valid values: chrome, chromium, opera, yandex, brave) +* _chrome_extensions.browser_type_ - The browser type (Valid values: chrome, chromium, opera, yandex, brave, edge, edge_beta) + +*bsd_flags* - keyword, text.text + +* _file.bsd_flags_ - The BSD file flags (chflags). Possible values: NODUMP, UF_IMMUTABLE, UF_APPEND, OPAQUE, HIDDEN, ARCHIVED, SF_IMMUTABLE, SF_APPEND + +*bssid* - keyword, text.text + +* _wifi_status.bssid_ - The current basic service set identifier +* _wifi_survey.bssid_ - The current basic service set identifier + +*btime* - keyword, number.long + +* _file.btime_ - (B)irth or (cr)eate time +* _process_events.btime_ - File creation in UNIX time + +*buffers* - keyword, number.long + +* _memory_info.buffers_ - The amount of physical RAM, in bytes, used for file buffers + +*build* - keyword, text.text + +* _os_version.build_ - Optional build-specific or variant string + +*build_distro* - keyword, text.text + +* _osquery_info.build_distro_ - osquery toolkit platform distribution name (os version) + +*build_id* - keyword, text.text + +* _sandboxes.build_id_ - Sandbox-specific identifier + +*build_number* - keyword, number.long + +* _windows_crashes.build_number_ - Windows build number of the crashing machine + +*build_platform* - keyword, text.text + +* _osquery_info.build_platform_ - osquery toolkit build platform + +*build_time* - keyword, text.text + +* _docker_version.build_time_ - Build time +* _portage_packages.build_time_ - Unix time when package was built + +*bundle_executable* - keyword, text.text + +* _apps.bundle_executable_ - Info properties CFBundleExecutable label + +*bundle_identifier* - keyword, text.text + +* _apps.bundle_identifier_ - Info properties CFBundleIdentifier label +* _running_apps.bundle_identifier_ - The bundle identifier of the application + +*bundle_name* - keyword, text.text + +* _apps.bundle_name_ - Info properties CFBundleName label + +*bundle_package_type* - keyword, text.text + +* _apps.bundle_package_type_ - Info properties CFBundlePackageType label + +*bundle_path* - keyword, text.text + +* _sandboxes.bundle_path_ - Application bundle used by the sandbox +* _system_extensions.bundle_path_ - System extension bundle path + +*bundle_short_version* - keyword, text.text + +* _apps.bundle_short_version_ - Info properties CFBundleShortVersionString label + +*bundle_version* - keyword, text.text + +* _apps.bundle_version_ - Info properties CFBundleVersion label + +*busy_state* - keyword, number.long + +* _iokit_devicetree.busy_state_ - 1 if the device is in a busy state else 0 +* _iokit_registry.busy_state_ - 1 if the node is in a busy state else 0 + +*bytes* - keyword, number.long + +* _curl.bytes_ - Number of bytes in the response +* _iptables.bytes_ - Number of matching bytes for this rule. + +*bytes_available* - keyword, number.long + +* _time_machine_destinations.bytes_available_ - Bytes available on volume + +*bytes_received* - keyword, number.long + +* _lxd_networks.bytes_received_ - Number of bytes received on this network + +*bytes_sent* - keyword, number.long + +* _lxd_networks.bytes_sent_ - Number of bytes sent on this network + +*bytes_used* - keyword, number.long + +* _time_machine_destinations.bytes_used_ - Bytes used on volume + +*ca* - keyword, number.long + +* _certificates.ca_ - 1 if CA: true (certificate is an authority) else 0 + +*cache_path* - keyword, text.text + +* _quicklook_cache.cache_path_ - Path to cache data + +*cached* - keyword, number.long + +* _lxd_images.cached_ - Whether image is cached (1) or not (0) +* _memory_info.cached_ - The amount of physical RAM, in bytes, used as cache memory + +*capability* - keyword, number.long + +* _apparmor_events.capability_ - Capability number + +*capname* - keyword, text.text + +* _apparmor_events.capname_ - Capability requested by the process + +*caption* - keyword, text.text + +* _patches.caption_ - Short description of the patch. +* _windows_optional_features.caption_ - Caption of feature in settings UI + +*captive_portal* - keyword, number.long + +* _wifi_networks.captive_portal_ - 1 if this network has a captive portal, 0 otherwise + +*carve* - keyword, number.long + +* _carves.carve_ - Set this value to '1' to start a file carve + +*carve_guid* - keyword, text.text + +* _carves.carve_guid_ - Identifying value of the carve session + +*category* - keyword, text.text + +* _apps.category_ - The UTI that categorizes the app for the App Store +* _file_events.category_ - The category of the file defined in the config +* _ntfs_journal_events.category_ - The category that the event originated from +* _power_sensors.category_ - The sensor category: currents, voltage, wattage +* _system_extensions.category_ - System extension category +* _yara_events.category_ - The category of the file + +*cdhash* - keyword, text.text + +* _es_process_events.cdhash_ - Codesigning hash of the process +* _signature.cdhash_ - Hash of the application Code Directory + +*celsius* - keyword, number.double + +* _temperature_sensors.celsius_ - Temperature in Celsius + +*certificate* - keyword, text.text + +* _lxd_certificates.certificate_ - Certificate content + +*cgroup_driver* - keyword, text.text + +* _docker_info.cgroup_driver_ - Control groups driver + +*cgroup_namespace* - keyword, text.text + +* _docker_containers.cgroup_namespace_ - cgroup namespace +* _process_namespaces.cgroup_namespace_ - cgroup namespace inode + +*chain* - keyword, text.text + +* _iptables.chain_ - Size of module content. + +*change_type* - keyword, text.text + +* _docker_container_fs_changes.change_type_ - Type of change: C:Modified, A:Added, D:Deleted + +*channel* - keyword + +* _wifi_status.channel_ - Channel number +* _wifi_survey.channel_ - Channel number +* _windows_eventlog.channel_ - Source or channel of the event + +*channel_band* - keyword, number.long + +* _wifi_status.channel_band_ - Channel band +* _wifi_survey.channel_band_ - Channel band + +*channel_width* - keyword, number.long + +* _wifi_status.channel_width_ - Channel width +* _wifi_survey.channel_width_ - Channel width + +*charged* - keyword, number.long + +* _battery.charged_ - 1 if the battery is currently completely charged. 0 otherwise + +*charging* - keyword, number.long + +* _battery.charging_ - 1 if the battery is currently being charged by a power source. 0 otherwise + +*chassis_bridge_capability_available* - keyword, number.long + +* _lldp_neighbors.chassis_bridge_capability_available_ - Chassis bridge capability availability + +*chassis_bridge_capability_enabled* - keyword, number.long + +* _lldp_neighbors.chassis_bridge_capability_enabled_ - Is chassis bridge capability enabled. + +*chassis_docsis_capability_available* - keyword, number.long + +* _lldp_neighbors.chassis_docsis_capability_available_ - Chassis DOCSIS capability availability + +*chassis_docsis_capability_enabled* - keyword, number.long + +* _lldp_neighbors.chassis_docsis_capability_enabled_ - Chassis DOCSIS capability enabled + +*chassis_id* - keyword, text.text + +* _lldp_neighbors.chassis_id_ - Neighbor chassis ID value + +*chassis_id_type* - keyword, text.text + +* _lldp_neighbors.chassis_id_type_ - Neighbor chassis ID type + +*chassis_mgmt_ips* - keyword, text.text + +* _lldp_neighbors.chassis_mgmt_ips_ - Comma delimited list of chassis management IPS + +*chassis_other_capability_available* - keyword, number.long + +* _lldp_neighbors.chassis_other_capability_available_ - Chassis other capability availability + +*chassis_other_capability_enabled* - keyword, number.long + +* _lldp_neighbors.chassis_other_capability_enabled_ - Chassis other capability enabled + +*chassis_repeater_capability_available* - keyword, number.long + +* _lldp_neighbors.chassis_repeater_capability_available_ - Chassis repeater capability availability + +*chassis_repeater_capability_enabled* - keyword, number.long + +* _lldp_neighbors.chassis_repeater_capability_enabled_ - Chassis repeater capability enabled + +*chassis_router_capability_available* - keyword, number.long + +* _lldp_neighbors.chassis_router_capability_available_ - Chassis router capability availability + +*chassis_router_capability_enabled* - keyword, number.long + +* _lldp_neighbors.chassis_router_capability_enabled_ - Chassis router capability enabled + +*chassis_station_capability_available* - keyword, number.long + +* _lldp_neighbors.chassis_station_capability_available_ - Chassis station capability availability + +*chassis_station_capability_enabled* - keyword, number.long + +* _lldp_neighbors.chassis_station_capability_enabled_ - Chassis station capability enabled + +*chassis_sys_description* - keyword, number.long + +* _lldp_neighbors.chassis_sys_description_ - Max number of CPU physical cores + +*chassis_sysname* - keyword, text.text + +* _lldp_neighbors.chassis_sysname_ - CPU brand string, contains vendor and model + +*chassis_tel_capability_available* - keyword, number.long + +* _lldp_neighbors.chassis_tel_capability_available_ - Chassis telephone capability availability + +*chassis_tel_capability_enabled* - keyword, number.long + +* _lldp_neighbors.chassis_tel_capability_enabled_ - Chassis telephone capability enabled + +*chassis_types* - keyword, text.text + +* _chassis_info.chassis_types_ - A comma-separated list of chassis types, such as Desktop or Laptop. + +*chassis_wlan_capability_available* - keyword, number.long + +* _lldp_neighbors.chassis_wlan_capability_available_ - Chassis wlan capability availability + +*chassis_wlan_capability_enabled* - keyword, number.long + +* _lldp_neighbors.chassis_wlan_capability_enabled_ - Chassis wlan capability enabled + +*check_array_finish* - keyword, text.text + +* _md_devices.check_array_finish_ - Estimated duration of the check array activity + +*check_array_progress* - keyword, text.text + +* _md_devices.check_array_progress_ - Progress of the check array activity + +*check_array_speed* - keyword, text.text + +* _md_devices.check_array_speed_ - Speed of the check array activity + +*checksum* - keyword, text.text + +* _disk_events.checksum_ - UDIF Master checksum if available (CRC32) + +*child_pid* - keyword, number.long + +* _es_process_events.child_pid_ - Process ID of a child process in case of a fork event + +*chunk_size* - keyword, number.long + +* _md_devices.chunk_size_ - chunk size in bytes + +*cid* - keyword, number.long + +* _bpf_process_events.cid_ - Cgroup ID +* _bpf_socket_events.cid_ - Cgroup ID + +*class* - keyword, text.text + +* _authorizations.class_ - Label top-level key +* _drivers.class_ - Device/driver class name +* _elf_dynamic.class_ - Class (32 or 64) +* _elf_info.class_ - Class type, 32 or 64bit +* _iokit_devicetree.class_ - Best matching device class (most-specific category) +* _iokit_registry.class_ - Best matching device class (most-specific category) +* _usb_devices.class_ - USB Device class +* _wmi_cli_event_consumers.class_ - The name of the class. +* _wmi_event_filters.class_ - The name of the class. +* _wmi_filter_consumer_binding.class_ - The name of the class. +* _wmi_script_event_consumers.class_ - The name of the class. + +*client_site_name* - keyword, text.text + +* _ntdomains.client_site_name_ - The name of the site where the domain controller is configured. + +*cmdline* - keyword, text.text + +* _bpf_process_events.cmdline_ - Command line arguments +* _docker_container_processes.cmdline_ - Complete argv +* _es_process_events.cmdline_ - Command line arguments (argv) +* _process_events.cmdline_ - Command line arguments (argv) +* _processes.cmdline_ - Complete argv + +*cmdline_count* - keyword, number.long + +* _es_process_events.cmdline_count_ - Number of command line arguments + +*cmdline_size* - keyword, number.long + +* _process_events.cmdline_size_ - Actual size (bytes) of command line arguments + +*code* - keyword, text.text + +* _seccomp_events.code_ - The seccomp action + +*code_integrity_policy_enforcement_status* - keyword, text.text + +* _hvci_status.code_integrity_policy_enforcement_status_ - The status of the code integrity policy enforcement settings. Returns UNKNOWN if an error is encountered. + +*codename* - keyword, text.text + +* _os_version.codename_ - OS version codename + +*collect_cross_processes* - keyword, number.long + +* _carbon_black_info.collect_cross_processes_ - If the sensor is configured to cross process events + +*collect_data_file_writes* - keyword, number.long + +* _carbon_black_info.collect_data_file_writes_ - If the sensor is configured to collect non binary file writes + +*collect_emet_events* - keyword, number.long + +* _carbon_black_info.collect_emet_events_ - If the sensor is configured to EMET events + +*collect_file_mods* - keyword, number.long + +* _carbon_black_info.collect_file_mods_ - If the sensor is configured to collect file modification events + +*collect_module_info* - keyword, number.long + +* _carbon_black_info.collect_module_info_ - If the sensor is configured to collect metadata of binaries + +*collect_module_loads* - keyword, number.long + +* _carbon_black_info.collect_module_loads_ - If the sensor is configured to capture module loads + +*collect_net_conns* - keyword, number.long + +* _carbon_black_info.collect_net_conns_ - If the sensor is configured to collect network connections + +*collect_process_user_context* - keyword, number.long + +* _carbon_black_info.collect_process_user_context_ - If the sensor is configured to collect the user running a process + +*collect_processes* - keyword, number.long + +* _carbon_black_info.collect_processes_ - If the sensor is configured to process events + +*collect_reg_mods* - keyword, number.long + +* _carbon_black_info.collect_reg_mods_ - If the sensor is configured to collect registry modification events + +*collect_sensor_operations* - keyword, number.long + +* _carbon_black_info.collect_sensor_operations_ - Unknown + +*collect_store_files* - keyword, number.long + +* _carbon_black_info.collect_store_files_ - If the sensor is configured to send back binaries to the Carbon Black server + +*collisions* - keyword, number.long + +* _interface_details.collisions_ - Packet Collisions detected + +*color_depth* - keyword, number.long + +* _video_info.color_depth_ - The amount of bits per pixel to represent color. + +*comm* - keyword, text.text + +* _apparmor_events.comm_ - Command-line name of the command that was used to invoke the analyzed process +* _seccomp_events.comm_ - Command-line name of the command that was used to invoke the analyzed process + +*command* - keyword, text.text + +* _crontab.command_ - Raw command string +* _docker_containers.command_ - Command with arguments +* _shell_history.command_ - Unparsed date/line/command history line + +*command_args* - keyword, text.text + +* _shortcut_files.command_args_ - Command args passed to lnk file. + +*command_line* - keyword, text.text + +* _windows_crashes.command_line_ - Command-line string passed to the crashed process + +*command_line_template* - keyword, text.text + +* _wmi_cli_event_consumers.command_line_template_ - Standard string template that specifies the process to be started. This property can be NULL, and the ExecutablePath property is used as the command line. + +*comment* - keyword, text.text + +* _authorizations.comment_ - Label top-level key +* _docker_image_history.comment_ - Instruction comment +* _etc_protocols.comment_ - Comment with protocol description +* _etc_services.comment_ - Optional comment for a service. +* _groups.comment_ - Remarks or comments associated with the group +* _keychain_items.comment_ - Optional keychain comment + +*common_name* - keyword, text.text + +* _certificates.common_name_ - Certificate CommonName +* _curl_certificate.common_name_ - Common name of company issued to + +*common_path* - keyword, text.text + +* _shortcut_files.common_path_ - Common system path to target file. + +*compat* - keyword, number.long + +* _seccomp_events.compat_ - Is system call in compatibility mode + +*compiler* - keyword, text.text + +* _apps.compiler_ - Info properties DTCompiler label + +*completed_time* - keyword, number.long + +* _cups_jobs.completed_time_ - When the job completed printing + +*components* - keyword, text.text + +* _apt_sources.components_ - Repository components + +*compressed* - keyword, number.long + +* _virtual_memory_info.compressed_ - The total number of pages that have been compressed by the VM compressor. + +*compressor* - keyword, number.long + +* _virtual_memory_info.compressor_ - The number of pages used to store compressed VM pages. + +*computer_name* - keyword, text.text + +* _system_info.computer_name_ - Friendly computer name (optional) +* _windows_eventlog.computer_name_ - Hostname of system where event was generated +* _windows_events.computer_name_ - Hostname of system where event was generated + +*condition* - keyword, text.text + +* _battery.condition_ - One of the following: "Normal" indicates the condition of the battery is within normal tolerances, "Service Needed" indicates that the battery should be checked out by a licensed Mac repair service, "Permanent Failure" indicates the battery needs replacement + +*config_entrypoint* - keyword, text.text + +* _docker_containers.config_entrypoint_ - Container entrypoint(s) + +*config_flag* - keyword, text.text + +* _sip_config.config_flag_ - The System Integrity Protection config flag + +*config_hash* - keyword, text.text + +* _osquery_info.config_hash_ - Hash of the working configuration state + +*config_name* - keyword, text.text + +* _carbon_black_info.config_name_ - Sensor group + +*config_valid* - keyword, number.long + +* _osquery_info.config_valid_ - 1 if the config was loaded and considered valid, else 0 + +*config_value* - keyword, text.text + +* _system_controls.config_value_ - The MIB value set in /etc/sysctl.conf + +*configured_clock_speed* - keyword, number.long + +* _memory_devices.configured_clock_speed_ - Configured speed of memory device in megatransfers per second (MT/s) + +*configured_voltage* - keyword, number.long + +* _memory_devices.configured_voltage_ - Configured operating voltage of device in millivolts + +*connection_id* - keyword, text.text + +* _interface_details.connection_id_ - Name of the network connection as it appears in the Network Connections Control Panel program. + +*connection_status* - keyword, text.text + +* _interface_details.connection_status_ - State of the network adapter connection to the network. + +*consistency_scan_date* - keyword, number.long + +* _time_machine_destinations.consistency_scan_date_ - Consistency scan date + +*consumer* - keyword, text.text + +* _wmi_filter_consumer_binding.consumer_ - Reference to an instance of __EventConsumer that represents the object path to a logical consumer, the recipient of an event. + +*containers* - keyword, number.long + +* _docker_info.containers_ - Total number of containers + +*containers_paused* - keyword, number.long + +* _docker_info.containers_paused_ - Number of containers in paused state + +*containers_running* - keyword, number.long + +* _docker_info.containers_running_ - Number of containers currently running + +*containers_stopped* - keyword, number.long + +* _docker_info.containers_stopped_ - Number of containers in stopped state + +*content* - keyword, text.text + +* _disk_events.content_ - Disk event content + +*content_caching* - keyword, number.long + +* _sharing_preferences.content_caching_ - 1 If content caching is enabled else 0 + +*content_type* - keyword, text.text + +* _package_install_history.content_type_ - Package content_type (optional) + +*conversion_status* - keyword, number.long + +* _bitlocker_info.conversion_status_ - The bitlocker conversion status of the drive. + +*coprocessor_version* - keyword, text.text + +* _ibridge_info.coprocessor_version_ - The manufacturer and chip version + +*copy* - keyword, number.long + +* _virtual_memory_info.copy_ - Total number of copy-on-write pages. + +*copyright* - keyword, text.text + +* _apps.copyright_ - Info properties NSHumanReadableCopyright label + +*core* - keyword, number.long + +* _cpu_time.core_ - Name of the cpu (core) + +*cosine_similarity* - keyword, number.double + +* _powershell_events.cosine_similarity_ - How similar the Powershell script is to a provided 'normal' character frequency + +*count* - keyword, number.long + +* _userassist.count_ - Number of times the application has been executed. +* _yara.count_ - Number of YARA matches +* _yara_events.count_ - Number of YARA matches + +*country_code* - keyword, text.text + +* _wifi_status.country_code_ - The country code (ISO/IEC 3166-1:1997) for the network +* _wifi_survey.country_code_ - The country code (ISO/IEC 3166-1:1997) for the network + +*cpu* - keyword, number.double + +* _docker_container_processes.cpu_ - CPU utilization as percentage + +*cpu_brand* - keyword, text.text + +* _system_info.cpu_brand_ - CPU brand string, contains vendor and model + +*cpu_cfs_period* - keyword, number.long + +* _docker_info.cpu_cfs_period_ - 1 if CPU Completely Fair Scheduler (CFS) period support is enabled. 0 otherwise + +*cpu_cfs_quota* - keyword, number.long + +* _docker_info.cpu_cfs_quota_ - 1 if CPU Completely Fair Scheduler (CFS) quota support is enabled. 0 otherwise + +*cpu_kernelmode_usage* - keyword, number.long + +* _docker_container_stats.cpu_kernelmode_usage_ - CPU kernel mode usage + +*cpu_logical_cores* - keyword, number.long + +* _system_info.cpu_logical_cores_ - Number of logical CPU cores available to the system + +*cpu_microcode* - keyword, text.text + +* _system_info.cpu_microcode_ - Microcode version + +*cpu_physical_cores* - keyword, number.long + +* _system_info.cpu_physical_cores_ - Number of physical CPU cores in to the system + +*cpu_pred_cmd_supported* - keyword, number.long + +* _kva_speculative_info.cpu_pred_cmd_supported_ - PRED_CMD MSR supported by CPU Microcode. + +*cpu_set* - keyword, number.long + +* _docker_info.cpu_set_ - 1 if CPU set selection support is enabled. 0 otherwise + +*cpu_shares* - keyword, number.long + +* _docker_info.cpu_shares_ - 1 if CPU share weighting support is enabled. 0 otherwise + +*cpu_spec_ctrl_supported* - keyword, number.long + +* _kva_speculative_info.cpu_spec_ctrl_supported_ - SPEC_CTRL MSR supported by CPU Microcode. + +*cpu_status* - keyword, number.long + +* _cpu_info.cpu_status_ - The current operating status of the CPU. + +*cpu_subtype* - keyword + +* _processes.cpu_subtype_ - Indicates the specific processor on which an entry may be used. +* _system_info.cpu_subtype_ - CPU subtype + +*cpu_total_usage* - keyword, number.long + +* _docker_container_stats.cpu_total_usage_ - Total CPU usage + +*cpu_type* - keyword + +* _processes.cpu_type_ - Indicates the specific processor designed for installation. +* _system_info.cpu_type_ - CPU type + +*cpu_usermode_usage* - keyword, number.long + +* _docker_container_stats.cpu_usermode_usage_ - CPU user mode usage + +*cpus* - keyword, number.long + +* _docker_info.cpus_ - Number of CPUs + +*crash_path* - keyword, text.text + +* _crashes.crash_path_ - Location of log file +* _windows_crashes.crash_path_ - Path of the log file + +*crashed_thread* - keyword, number.long + +* _crashes.crashed_thread_ - Thread ID which crashed + +*created* - keyword, text.text + +* _authorizations.created_ - Label top-level key +* _docker_containers.created_ - Time of creation as UNIX time +* _docker_image_history.created_ - Time of creation as UNIX time +* _docker_images.created_ - Time of creation as UNIX time +* _docker_networks.created_ - Time of creation as UNIX time +* _keychain_items.created_ - Data item was created + +*created_at* - keyword, text.text + +* _lxd_images.created_at_ - ISO time of image creation +* _lxd_instances.created_at_ - ISO time of creation + +*created_by* - keyword, text.text + +* _docker_image_history.created_by_ - Created by instruction + +*created_time* - keyword, number.long + +* _shellbags.created_time_ - Directory Created time. + +*creation_time* - keyword + +* _account_policy_data.creation_time_ - When the account was first created +* _cups_jobs.creation_time_ - When the print request was initiated + +*creator* - keyword, text.text + +* _firefox_addons.creator_ - Addon-supported creator string + +*creator_pid* - keyword, number.long + +* _shared_memory.creator_pid_ - Process ID that created the segment + +*creator_uid* - keyword, number.long + +* _shared_memory.creator_uid_ - User ID of creator process + +*csname* - keyword, text.text + +* _patches.csname_ - The name of the host the patch is installed on. + +*ctime* - keyword + +* _device_file.ctime_ - Creation time +* _file.ctime_ - Last status change time +* _file_events.ctime_ - Last status change time +* _gatekeeper_approved_apps.ctime_ - Last change time +* _process_events.ctime_ - File last metadata change in UNIX time +* _shared_memory.ctime_ - Changed time + +*current_capacity* - keyword, number.long + +* _battery.current_capacity_ - The battery's current charged capacity in mAh + +*current_clock_speed* - keyword, number.long + +* _cpu_info.current_clock_speed_ - The current frequency of the CPU. + +*current_directory* - keyword, text.text + +* _windows_crashes.current_directory_ - Current working directory of the crashed process + +*current_disk_queue_length* - keyword, number.long + +* _physical_disk_performance.current_disk_queue_length_ - Number of requests outstanding on the disk at the time the performance data is collected + +*current_locale* - keyword, text.text + +* _chrome_extensions.current_locale_ - Current locale supported by extension + +*current_value* - keyword, text.text + +* _system_controls.current_value_ - Value of setting + +*cwd* - keyword, text.text + +* _bpf_process_events.cwd_ - Current working directory +* _es_process_events.cwd_ - The process current working directory +* _process_events.cwd_ - The process current working directory +* _process_file_events.cwd_ - The current working directory of the process +* _processes.cwd_ - Process current working directory + +*cycle_count* - keyword, number.long + +* _battery.cycle_count_ - The number of charge/discharge cycles + +*data* - keyword, text.text + +* _magic.data_ - Magic number data from libmagic +* _registry.data_ - Data content of registry value +* _windows_eventlog.data_ - Data associated with the event +* _windows_events.data_ - Data associated with the event + +*data_width* - keyword, number.long + +* _memory_devices.data_width_ - Data width, in bits, of this memory device + +*database* - keyword, number.long + +* _lxd_cluster_members.database_ - Whether the server is a database node (1) or not (0) + +*date* - keyword + +* _drivers.date_ - Driver date +* _platform_info.date_ - Self-reported platform code update date + +*datetime* - keyword, text.text + +* _crashes.datetime_ - Date/Time at which the crash occurred +* _powershell_events.datetime_ - System time at which the Powershell script event occurred +* _syslog_events.datetime_ - Time known to syslog +* _time.datetime_ - Current date and time (ISO format) in the system +* _windows_crashes.datetime_ - Timestamp (log format) of the crash +* _windows_eventlog.datetime_ - System time at which the event occurred +* _windows_events.datetime_ - System time at which the event occurred + +*day* - keyword, number.long + +* _time.day_ - Current day in the system + +*day_of_month* - keyword, text.text + +* _crontab.day_of_month_ - The day of the month for the job + +*day_of_week* - keyword, text.text + +* _crontab.day_of_week_ - The day of the week for the job + +*days* - keyword, number.long + +* _uptime.days_ - Days of uptime + +*dc_site_name* - keyword, text.text + +* _ntdomains.dc_site_name_ - The name of the site where the domain controller is located. + +*decompressed* - keyword, number.long + +* _virtual_memory_info.decompressed_ - The total number of pages that have been decompressed by the VM compressor. + +*default_locale* - keyword, text.text + +* _chrome_extensions.default_locale_ - Default locale supported by extension + +*default_value* - keyword, text.text + +* _osquery_flags.default_value_ - Flag default value + +*denied_mask* - keyword, text.text + +* _apparmor_events.denied_mask_ - Denied permissions for the process + +*denylisted* - keyword, number.long + +* _osquery_schedule.denylisted_ - 1 if the query is denylisted else 0 + +*dependencies* - keyword, text.text + +* _kernel_panics.dependencies_ - Module dependencies existing in crashed module's backtrace + +*depth* - keyword, number.long + +* _iokit_devicetree.depth_ - Device nested depth +* _iokit_registry.depth_ - Node nested depth + +*description* - keyword, text.text + +* _appcompat_shims.description_ - Description of the SDB. +* _atom_packages.description_ - Package supplied description +* _browser_plugins.description_ - Plugin description text +* _chassis_info.description_ - An extended description of the chassis if available. +* _chrome_extensions.description_ - Extension-optional description +* _disk_info.description_ - The OS's description of the disk. +* _drivers.description_ - Driver description +* _firefox_addons.description_ - Addon-supplied description string +* _interface_details.description_ - Short description of the object a one-line string. +* _keychain_acls.description_ - The description included with the ACL entry +* _keychain_items.description_ - Optional item description +* _logical_drives.description_ - The canonical description of the drive, e.g. 'Logical Fixed Disk', 'CD-ROM Disk'. +* _lxd_images.description_ - Image description +* _lxd_instances.description_ - Instance description +* _npm_packages.description_ - Package supplied description +* _osquery_flags.description_ - Flag description +* _patches.description_ - Fuller description of the patch. +* _safari_extensions.description_ - Optional extension description text +* _services.description_ - Service Description +* _shared_resources.description_ - A textual description of the object +* _shortcut_files.description_ - Lnk file description. +* _smbios_tables.description_ - Table entry description +* _systemd_units.description_ - Unit description +* _users.description_ - Optional user description +* _ycloud_instance_metadata.description_ - Description of the VM + +*designed_capacity* - keyword, number.long + +* _battery.designed_capacity_ - The battery's designed capacity in mAh + +*dest_path* - keyword, text.text + +* _process_file_events.dest_path_ - The canonical path associated with the event + +*destination* - keyword, text.text + +* _cups_jobs.destination_ - The printer the job was sent to +* _docker_container_mounts.destination_ - Destination path inside container +* _routes.destination_ - Destination IP address + +*destination_id* - keyword, text.text + +* _time_machine_backups.destination_id_ - Time Machine destination ID +* _time_machine_destinations.destination_id_ - Time Machine destination ID + +*dev_id_enabled* - keyword, number.long + +* _gatekeeper.dev_id_enabled_ - 1 If a Gatekeeper allows execution from identified developers else 0 + +*developer_id* - keyword, text.text + +* _safari_extensions.developer_id_ - Optional developer identifier +* _xprotect_meta.developer_id_ - Developer identity (SHA1) of extension + +*development_region* - keyword, text.text + +* _apps.development_region_ - Info properties CFBundleDevelopmentRegion label +* _browser_plugins.development_region_ - Plugin language-localization + +*device* - keyword, text.text + +* _device_file.device_ - Absolute file path to device node +* _device_firmware.device_ - The device name +* _device_hash.device_ - Absolute file path to device node +* _device_partitions.device_ - Absolute file path to device node +* _disk_events.device_ - Disk event BSD name +* _file.device_ - Device ID (optional) +* _kernel_info.device_ - Kernel device identifier +* _lxd_instance_devices.device_ - Name of the device +* _mounts.device_ - Mounted device +* _process_memory_map.device_ - MA:MI Major/minor device ID + +*device_alias* - keyword, text.text + +* _mounts.device_alias_ - Mounted device alias + +*device_error_address* - keyword, text.text + +* _memory_error_info.device_error_address_ - 32 bit physical address of the error relative to the start of the failing memory address, in bytes + +*device_id* - keyword, text.text + +* _bitlocker_info.device_id_ - ID of the encrypted drive. +* _cpu_info.device_id_ - The DeviceID of the CPU. +* _drivers.device_id_ - Device ID +* _logical_drives.device_id_ - The drive id, usually the drive name, e.g., 'C:'. + +*device_locator* - keyword, text.text + +* _memory_devices.device_locator_ - String number of the string that identifies the physically-labeled socket or board position where the memory device is located + +*device_model* - keyword, text.text + +* _smart_drive_info.device_model_ - Device Model + +*device_name* - keyword, text.text + +* _drivers.device_name_ - Device name +* _md_devices.device_name_ - md device name +* _smart_drive_info.device_name_ - Name of block device + +*device_path* - keyword, text.text + +* _iokit_devicetree.device_path_ - Device tree path + +*device_type* - keyword, text.text + +* _lxd_instance_devices.device_type_ - Device type +* _shortcut_files.device_type_ - Device containing the target file. + +*dhcp_enabled* - keyword, number.long + +* _interface_details.dhcp_enabled_ - If TRUE, the dynamic host configuration protocol (DHCP) server automatically assigns an IP address to the computer system when establishing a network connection. + +*dhcp_lease_expires* - keyword, text.text + +* _interface_details.dhcp_lease_expires_ - Expiration date and time for a leased IP address that was assigned to the computer by the dynamic host configuration protocol (DHCP) server. + +*dhcp_lease_obtained* - keyword, text.text + +* _interface_details.dhcp_lease_obtained_ - Date and time the lease was obtained for the IP address assigned to the computer by the dynamic host configuration protocol (DHCP) server. + +*dhcp_server* - keyword, text.text + +* _interface_details.dhcp_server_ - IP address of the dynamic host configuration protocol (DHCP) server. + +*directory* - keyword, text.text + +* _extended_attributes.directory_ - Directory of file(s) +* _file.directory_ - Directory of file(s) +* _hash.directory_ - Must provide a path or directory +* _npm_packages.directory_ - Node module's directory where this package is located +* _python_packages.directory_ - Directory where Python modules are located +* _users.directory_ - User's home directory + +*disabled* - keyword + +* _browser_plugins.disabled_ - Is the plugin disabled. 1 = Disabled +* _firefox_addons.disabled_ - 1 If the addon is application-disabled else 0 +* _launchd.disabled_ - Skip loading this daemon or agent on boot +* _wifi_networks.disabled_ - 1 if this network is disabled, 0 otherwise + +*disc_sharing* - keyword, number.long + +* _sharing_preferences.disc_sharing_ - 1 If CD or DVD sharing is enabled else 0 + +*disconnected* - keyword, number.long + +* _connectivity.disconnected_ - True if the all interfaces are not connected to any network + +*discovery_cache_hits* - keyword, number.long + +* _osquery_packs.discovery_cache_hits_ - The number of times that the discovery query used cached values since the last time the config was reloaded + +*discovery_executions* - keyword, number.long + +* _osquery_packs.discovery_executions_ - The number of times that the discovery queries have been executed since the last time the config was reloaded + +*disk_bytes_read* - keyword, number.long + +* _processes.disk_bytes_read_ - Bytes read from disk + +*disk_bytes_written* - keyword, number.long + +* _processes.disk_bytes_written_ - Bytes written to disk + +*disk_id* - keyword, number.long + +* _smart_drive_info.disk_id_ - Physical slot number of device, only exists when hardware storage controller exists + +*disk_index* - keyword, number.long + +* _disk_info.disk_index_ - Physical drive number of the disk. + +*disk_read* - keyword, number.long + +* _docker_container_stats.disk_read_ - Total disk read bytes + +*disk_size* - keyword, number.long + +* _disk_info.disk_size_ - Size of the disk. + +*disk_write* - keyword, number.long + +* _docker_container_stats.disk_write_ - Total disk write bytes + +*display_name* - keyword, text.text + +* _apps.display_name_ - Info properties CFBundleDisplayName label +* _services.display_name_ - Service Display name + +*dns_domain* - keyword, text.text + +* _interface_details.dns_domain_ - Organization name followed by a period and an extension that indicates the type of organization, such as 'microsoft.com'. + +*dns_domain_name* - keyword, text.text + +* _logon_sessions.dns_domain_name_ - The DNS name for the owner of the logon session. + +*dns_domain_suffix_search_order* - keyword, text.text + +* _interface_details.dns_domain_suffix_search_order_ - Array of DNS domain suffixes to be appended to the end of host names during name resolution. + +*dns_forest_name* - keyword, text.text + +* _ntdomains.dns_forest_name_ - The name of the root of the DNS tree. + +*dns_host_name* - keyword, text.text + +* _interface_details.dns_host_name_ - Host name used to identify the local computer for authentication by some utilities. + +*dns_server_search_order* - keyword, text.text + +* _interface_details.dns_server_search_order_ - Array of server IP addresses to be used in querying for DNS servers. + +*domain* - keyword, text.text + +* _ad_config.domain_ - Active Directory trust domain +* _managed_policies.domain_ - System or manager-chosen domain key +* _preferences.domain_ - Application ID usually in com.name.product format + +*domain_controller_address* - keyword, text.text + +* _ntdomains.domain_controller_address_ - The IP Address of the discovered domain controller.. + +*domain_controller_name* - keyword, text.text + +* _ntdomains.domain_controller_name_ - The name of the discovered domain controller. + +*domain_name* - keyword, text.text + +* _ntdomains.domain_name_ - The name of the domain. + +*drive_letter* - keyword, text.text + +* _bitlocker_info.drive_letter_ - Drive letter of the encrypted drive. +* _ntfs_journal_events.drive_letter_ - The drive letter identifying the source journal + +*drive_name* - keyword, text.text + +* _md_drives.drive_name_ - Drive device name + +*driver* - keyword, text.text + +* _docker_container_mounts.driver_ - Driver providing the mount +* _docker_networks.driver_ - Network driver +* _docker_volumes.driver_ - Volume driver +* _hardware_events.driver_ - Driver claiming the device +* _lxd_storage_pools.driver_ - Storage driver +* _pci_devices.driver_ - PCI Device used driver +* _video_info.driver_ - The driver of the device. + +*driver_date* - keyword, number.long + +* _video_info.driver_date_ - The date listed on the installed driver. + +*driver_key* - keyword, text.text + +* _drivers.driver_key_ - Driver key + +*driver_type* - keyword, text.text + +* _smart_drive_info.driver_type_ - The explicit device type used to retrieve the SMART information + +*driver_version* - keyword, text.text + +* _video_info.driver_version_ - The version of the installed driver. + +*dst_ip* - keyword, text.text + +* _iptables.dst_ip_ - Destination IP address. + +*dst_mask* - keyword, text.text + +* _iptables.dst_mask_ - Destination IP address mask. + +*dst_port* - keyword, text.text + +* _iptables.dst_port_ - Protocol destination port(s). + +*dtime* - keyword, number.long + +* _shared_memory.dtime_ - Detached time + +*dump_certificate* - keyword, number.long + +* _curl_certificate.dump_certificate_ - Set this value to '1' to dump certificate + +*duration* - keyword, number.long + +* _bpf_process_events.duration_ - How much time was spent inside the syscall (nsecs) +* _bpf_socket_events.duration_ - How much time was spent inside the syscall (nsecs) + +*eapi* - keyword, number.long + +* _portage_packages.eapi_ - The eapi for the ebuild + +*egid* - keyword + +* _docker_container_processes.egid_ - Effective group ID +* _es_process_events.egid_ - Effective Group ID of the process +* _process_events.egid_ - Effective group ID at process start +* _process_file_events.egid_ - Effective group ID of the process using the file +* _processes.egid_ - Unsigned effective group ID + +*eid* - keyword, text.text + +* _apparmor_events.eid_ - Event ID +* _bpf_process_events.eid_ - Event ID +* _bpf_socket_events.eid_ - Event ID +* _disk_events.eid_ - Event ID +* _es_process_events.eid_ - Event ID +* _file_events.eid_ - Event ID +* _hardware_events.eid_ - Event ID +* _ntfs_journal_events.eid_ - Event ID +* _process_events.eid_ - Event ID +* _process_file_events.eid_ - Event ID +* _selinux_events.eid_ - Event ID +* _socket_events.eid_ - Event ID +* _syslog_events.eid_ - Event ID +* _user_events.eid_ - Event ID +* _windows_events.eid_ - Event ID +* _yara_events.eid_ - Event ID + +*ejectable* - keyword, number.long + +* _disk_events.ejectable_ - 1 if ejectable, 0 if not + +*elapsed_time* - keyword, number.long + +* _processes.elapsed_time_ - Elapsed time in seconds this process has been running. + +*element* - keyword, text.text + +* _apps.element_ - Does the app identify as a background agent + +*elevated_token* - keyword, number.long + +* _processes.elevated_token_ - Process uses elevated token yes=1, no=0 + +*enable_ipv6* - keyword, number.long + +* _docker_networks.enable_ipv6_ - 1 if IPv6 is enabled on this network. 0 otherwise + +*enabled* - keyword + +* _app_schemes.enabled_ - 1 if this handler is the OS default, else 0 +* _event_taps.enabled_ - Is the Event Tap enabled +* _interface_details.enabled_ - Indicates whether the adapter is enabled or not. +* _location_services.enabled_ - 1 if Location Services are enabled, else 0 +* _lxd_cluster.enabled_ - Whether clustering enabled (1) or not (0) on this node +* _sandboxes.enabled_ - Application sandboxings enabled on container +* _scheduled_tasks.enabled_ - Whether or not the scheduled task is enabled +* _screenlock.enabled_ - 1 If a password is required after sleep or the screensaver begins; else 0 +* _sip_config.enabled_ - 1 if this configuration is enabled, otherwise 0 +* _tpm_info.enabled_ - TPM is enabled +* _yum_sources.enabled_ - Whether the repository is used + +*enabled_nvram* - keyword, number.long + +* _sip_config.enabled_nvram_ - 1 if this configuration is enabled, otherwise 0 + +*encrypted* - keyword, number.long + +* _disk_encryption.encrypted_ - 1 If encrypted: true (disk is encrypted), else 0 +* _user_ssh_keys.encrypted_ - 1 if key is encrypted, 0 otherwise + +*encryption* - keyword, text.text + +* _time_machine_destinations.encryption_ - Last known encrypted state + +*encryption_method* - keyword, text.text + +* _bitlocker_info.encryption_method_ - The encryption type of the device. + +*encryption_status* - keyword, text.text + +* _disk_encryption.encryption_status_ - Disk encryption status with one of following values: encrypted | not encrypted | undefined + +*end* - keyword, text.text + +* _memory_map.end_ - End address of memory region +* _process_memory_map.end_ - Virtual end address (hex) + +*ending_address* - keyword, text.text + +* _memory_array_mapped_addresses.ending_address_ - Physical ending address of last kilobyte of a range of memory mapped to physical memory array +* _memory_device_mapped_addresses.ending_address_ - Physical ending address of last kilobyte of a range of memory mapped to physical memory array + +*endpoint_id* - keyword, text.text + +* _docker_container_networks.endpoint_id_ - Endpoint ID + +*entry* - keyword, text.text + +* _authorization_mechanisms.entry_ - The whole string entry +* _elf_info.entry_ - Entry point address +* _shimcache.entry_ - Execution order. + +*env* - keyword, text.text + +* _es_process_events.env_ - Environment variables delimited by spaces +* _process_events.env_ - Environment variables delimited by spaces + +*env_count* - keyword, number.long + +* _es_process_events.env_count_ - Number of environment variables +* _process_events.env_count_ - Number of environment variables + +*env_size* - keyword, number.long + +* _process_events.env_size_ - Actual size (bytes) of environment list + +*env_variables* - keyword, text.text + +* _docker_containers.env_variables_ - Container environmental variables + +*environment* - keyword, text.text + +* _apps.environment_ - Application-set environment variables + +*ephemeral* - keyword, number.long + +* _lxd_instances.ephemeral_ - Whether the instance is ephemeral(1) or not(0) + +*epoch* - keyword, number.long + +* _rpm_packages.epoch_ - Package epoch value + +*error* - keyword, text.text + +* _apparmor_events.error_ - Error information + +*error_granularity* - keyword, text.text + +* _memory_error_info.error_granularity_ - Granularity to which the error can be resolved + +*error_operation* - keyword, text.text + +* _memory_error_info.error_operation_ - Memory access operation that caused the error + +*error_resolution* - keyword, text.text + +* _memory_error_info.error_resolution_ - Range, in bytes, within which this error can be determined, when an error address is given + +*error_type* - keyword, text.text + +* _memory_error_info.error_type_ - type of error associated with current error status for array or device + +*euid* - keyword + +* _docker_container_processes.euid_ - Effective user ID +* _es_process_events.euid_ - Effective User ID of the process +* _process_events.euid_ - Effective user ID at process start +* _process_file_events.euid_ - Effective user ID of the process using the file +* _processes.euid_ - Unsigned effective user ID + +*event* - keyword, text.text + +* _crontab.event_ - The job @event name (rare) + +*event_queue* - keyword, number.long + +* _carbon_black_info.event_queue_ - Size in bytes of Carbon Black event files on disk + +*event_tap_id* - keyword, number.long + +* _event_taps.event_tap_id_ - Unique ID for the Tap + +*event_tapped* - keyword, text.text + +* _event_taps.event_tapped_ - The mask that identifies the set of events to be observed. + +*event_type* - keyword, text.text + +* _es_process_events.event_type_ - Type of EndpointSecurity event + +*eventid* - keyword, number.long + +* _windows_eventlog.eventid_ - Event ID of the event +* _windows_events.eventid_ - Event ID of the event + +*events* - keyword, number.long + +* _osquery_events.events_ - Number of events emitted or received since osquery started + +*exception_address* - keyword, text.text + +* _windows_crashes.exception_address_ - Address (in hex) where the exception occurred + +*exception_code* - keyword, text.text + +* _windows_crashes.exception_code_ - The Windows exception code + +*exception_codes* - keyword, text.text + +* _crashes.exception_codes_ - Exception codes from the crash + +*exception_message* - keyword, text.text + +* _windows_crashes.exception_message_ - The NTSTATUS error message associated with the exception code + +*exception_notes* - keyword, text.text + +* _crashes.exception_notes_ - Exception notes from the crash + +*exception_type* - keyword, text.text + +* _crashes.exception_type_ - Exception type of the crash + +*exe* - keyword, text.text + +* _seccomp_events.exe_ - The path to the executable that was used to invoke the analyzed process + +*executable* - keyword, text.text + +* _appcompat_shims.executable_ - Name of the executable that is being shimmed. This is pulled from the registry. +* _process_file_events.executable_ - The executable path + +*executable_path* - keyword, text.text + +* _wmi_cli_event_consumers.executable_path_ - Module to execute. The string can specify the full path and file name of the module to execute, or it can specify a partial name. If a partial name is specified, the current drive and current directory are assumed. + +*execution_flag* - keyword, number.long + +* _shimcache.execution_flag_ - Boolean Execution flag, 1 for execution, 0 for no execution, -1 for missing (this flag does not exist on Windows 10 and higher). + +*executions* - keyword, number.long + +* _osquery_schedule.executions_ - Number of times the query was executed + +*exit_code* - keyword, text.text + +* _bpf_process_events.exit_code_ - Exit code of the system call +* _bpf_socket_events.exit_code_ - Exit code of the system call +* _es_process_events.exit_code_ - Exit code of a process in case of an exit event + +*expand* - keyword, number.long + +* _default_environment.expand_ - 1 if the variable needs expanding, 0 otherwise + +*expire* - keyword, number.long + +* _shadow.expire_ - Number of days since UNIX epoch date until account is disabled + +*expires_at* - keyword, text.text + +* _lxd_images.expires_at_ - ISO time of image expiration + +*extended_key_usage* - keyword, text.text + +* _curl_certificate.extended_key_usage_ - Extended usage of key in certificate + +*extensions* - keyword, text.text + +* _osquery_info.extensions_ - osquery extensions status + +*external* - keyword, number.long + +* _app_schemes.external_ - 1 if this handler does NOT exist on OS X by default, else 0 + +*extra* - keyword, text.text + +* _asl.extra_ - Extra columns, in JSON format. Queries against this column are performed entirely in SQLite, so do not benefit from efficient querying via asl.h. +* _platform_info.extra_ - Platform-specific additional information + +*facility* - keyword, text.text + +* _asl.facility_ - Sender's facility. Default is 'user'. +* _syslog_events.facility_ - Syslog facility + +*fahrenheit* - keyword, number.double + +* _temperature_sensors.fahrenheit_ - Temperature in Fahrenheit + +*failed_disks* - keyword, number.long + +* _md_devices.failed_disks_ - Number of failed disks in array + +*failed_login_count* - keyword, number.long + +* _account_policy_data.failed_login_count_ - The number of failed login attempts using an incorrect password. Count resets after a correct password is entered. + +*failed_login_timestamp* - keyword, number.double + +* _account_policy_data.failed_login_timestamp_ - The time of the last failed login attempt. Resets after a correct password is entered + +*family* - keyword, number.long + +* _bpf_socket_events.family_ - The Internet protocol family ID +* _listening_ports.family_ - Network protocol (IPv4, IPv6) +* _process_open_sockets.family_ - Network protocol (IPv4, IPv6) +* _socket_events.family_ - The Internet protocol family ID + +*fan* - keyword, text.text + +* _fan_speed_sensors.fan_ - Fan number + +*faults* - keyword, number.long + +* _virtual_memory_info.faults_ - Total number of calls to vm_faults. + +*fd* - keyword, text.text + +* _bpf_socket_events.fd_ - The file description for the process socket +* _listening_ports.fd_ - Socket file descriptor number +* _process_open_files.fd_ - Process-specific file descriptor number +* _process_open_pipes.fd_ - File descriptor +* _process_open_sockets.fd_ - Socket file descriptor number +* _socket_events.fd_ - The file description for the process socket + +*feature* - keyword, text.text + +* _cpuid.feature_ - Present feature flags + +*feature_control* - keyword, number.long + +* _msr.feature_control_ - Bitfield controlling enabled features. + +*field_name* - keyword, text.text + +* _system_controls.field_name_ - Specific attribute of opaque type + +*file_attributes* - keyword, text.text + +* _ntfs_journal_events.file_attributes_ - File attributes + +*file_backed* - keyword, number.long + +* _virtual_memory_info.file_backed_ - Total number of file backed pages. + +*file_id* - keyword, text.text + +* _file.file_id_ - file ID + +*file_sharing* - keyword, number.long + +* _sharing_preferences.file_sharing_ - 1 If file sharing is enabled else 0 + +*file_system* - keyword, text.text + +* _logical_drives.file_system_ - The file system of the drive. + +*file_version* - keyword, text.text + +* _file.file_version_ - File version + +*filename* - keyword, text.text + +* _device_file.filename_ - Name portion of file path +* _file.filename_ - Name portion of file path +* _lxd_images.filename_ - Filename of the image file +* _prefetch.filename_ - Executable filename. +* _xprotect_entries.filename_ - Use this file name to match + +*filepath* - keyword, text.text + +* _package_bom.filepath_ - Package file or directory + +*filesystem* - keyword, text.text + +* _disk_events.filesystem_ - Filesystem if available + +*filetype* - keyword, text.text + +* _xprotect_entries.filetype_ - Use this file type to match + +*filevault_status* - keyword, text.text + +* _disk_encryption.filevault_status_ - FileVault status with one of following values: on | off | unknown + +*filter* - keyword, text.text + +* _wmi_filter_consumer_binding.filter_ - Reference to an instance of __EventFilter that represents the object path to an event filter which is a query that specifies the type of event to be received. + +*filter_name* - keyword, text.text + +* _iptables.filter_name_ - Packet matching filter table name. + +*fingerprint* - keyword, text.text + +* _lxd_certificates.fingerprint_ - SHA256 hash of the certificate + +*finished_at* - keyword, text.text + +* _docker_containers.finished_at_ - Container finish time as string + +*firewall* - keyword, text.text + +* _windows_security_center.firewall_ - The health of the monitored Firewall (see windows_security_products) + +*firewall_unload* - keyword, number.long + +* _alf.firewall_unload_ - 1 If firewall unloading enabled else 0 + +*firmware_version* - keyword, text.text + +* _ibridge_info.firmware_version_ - The build version of the firmware +* _smart_drive_info.firmware_version_ - Drive firmware version + +*fix_comments* - keyword, text.text + +* _patches.fix_comments_ - Additional comments about the patch. + +*flag* - keyword, number.long + +* _shadow.flag_ - Reserved + +*flags* - keyword + +* _device_partitions.flags_ - +* _dns_cache.flags_ - DNS record flags +* _elf_info.flags_ - ELF header flags +* _elf_sections.flags_ - Section attributes +* _elf_segments.flags_ - Segment attributes +* _interface_details.flags_ - Flags (netdevice) for the device +* _mounts.flags_ - Mounted device flags +* _pipes.flags_ - The flags indicating whether this pipe connection is a server or client end, and if the pipe for sending messages or bytes +* _routes.flags_ - Flags to describe route + +*flatsize* - keyword, number.long + +* _pkg_packages.flatsize_ - Package size in bytes + +*folder_id* - keyword, text.text + +* _ycloud_instance_metadata.folder_id_ - Folder identifier for the VM + +*following* - keyword, text.text + +* _systemd_units.following_ - The name of another unit that this unit follows in state + +*forced* - keyword, number.long + +* _preferences.forced_ - 1 if the value is forced/managed, else 0 + +*form_factor* - keyword, text.text + +* _memory_devices.form_factor_ - Implementation form factor for this memory device +* _smart_drive_info.form_factor_ - Form factor if reported + +*format* - keyword, text.text + +* _cups_jobs.format_ - The format of the print job + +*forwarding_enabled* - keyword, number.long + +* _interface_ipv6.forwarding_enabled_ - Enable IP forwarding + +*fragment_path* - keyword, text.text + +* _systemd_units.fragment_path_ - The unit file path this unit was read from, if there is any + +*frame_backtrace* - keyword, text.text + +* _kernel_panics.frame_backtrace_ - Backtrace of the crashed module + +*free* - keyword, number.long + +* _virtual_memory_info.free_ - Total number of free pages. + +*free_space* - keyword, number.long + +* _logical_drives.free_space_ - The amount of free space, in bytes, of the drive (-1 on failure). + +*friendly_name* - keyword, text.text + +* _interface_addresses.friendly_name_ - The friendly display name of the interface. +* _interface_details.friendly_name_ - The friendly display name of the interface. + +*from_webstore* - keyword, text.text + +* _chrome_extensions.from_webstore_ - True if this extension was installed from the web store + +*fs_id* - keyword, text.text + +* _quicklook_cache.fs_id_ - Quicklook file fs_id key + +*fsgid* - keyword + +* _process_events.fsgid_ - Filesystem group ID at process start +* _process_file_events.fsgid_ - Filesystem group ID of the process using the file + +*fsuid* - keyword + +* _apparmor_events.fsuid_ - Filesystem user ID +* _process_events.fsuid_ - Filesystem user ID at process start +* _process_file_events.fsuid_ - Filesystem user ID of the process using the file + +*gateway* - keyword, text.text + +* _docker_container_networks.gateway_ - Gateway +* _docker_networks.gateway_ - Network gateway +* _routes.gateway_ - Route gateway + +*gid* - keyword + +* _asl.gid_ - GID that sent the log message (set by the server). +* _bpf_process_events.gid_ - Group ID +* _bpf_socket_events.gid_ - Group ID +* _device_file.gid_ - Owning group ID +* _docker_container_processes.gid_ - Group ID +* _es_process_events.gid_ - Group ID of the process +* _file.gid_ - Owning group ID +* _file_events.gid_ - Owning group ID +* _groups.gid_ - Unsigned int64 group ID +* _package_bom.gid_ - Expected group of file or directory +* _process_events.gid_ - Group ID at process start +* _process_file_events.gid_ - The gid of the process performing the action +* _processes.gid_ - Unsigned group ID +* _seccomp_events.gid_ - Group ID of the user who started the analyzed process +* _user_groups.gid_ - Group ID +* _users.gid_ - Group ID (unsigned) + +*gid_signed* - keyword, number.long + +* _groups.gid_signed_ - A signed int64 version of gid +* _users.gid_signed_ - Default group ID as int64 signed (Apple) + +*git_commit* - keyword, text.text + +* _docker_version.git_commit_ - Docker build git commit + +*global_seq_num* - keyword, number.long + +* _es_process_events.global_seq_num_ - Global sequence number + +*global_state* - keyword, number.long + +* _alf.global_state_ - 1 If the firewall is enabled with exceptions, 2 if the firewall is configured to block all incoming connections, else 0 + +*go_version* - keyword, text.text + +* _docker_version.go_version_ - Go version + +*gpgcheck* - keyword, text.text + +* _yum_sources.gpgcheck_ - Whether packages are GPG checked + +*gpgkey* - keyword, text.text + +* _yum_sources.gpgkey_ - URL to GPG key + +*grace_period* - keyword, number.long + +* _screenlock.grace_period_ - The amount of time in seconds the screen must be asleep or the screensaver on before a password is required on-wake. 0 = immediately; -1 = no password is required on-wake + +*group_sid* - keyword, text.text + +* _groups.group_sid_ - Unique group ID + +*groupname* - keyword, text.text + +* _groups.groupname_ - Canonical local group name +* _launchd.groupname_ - Run this daemon or agent as this group +* _rpm_package_files.groupname_ - File default groupname from info DB +* _suid_bin.groupname_ - Binary owner group + +*guest* - keyword, number.long + +* _cpu_time.guest_ - Time spent running a virtual CPU for a guest OS under the control of the Linux kernel + +*guest_nice* - keyword, number.long + +* _cpu_time.guest_nice_ - Time spent running a niced guest + +*handle* - keyword, text.text + +* _memory_array_mapped_addresses.handle_ - Handle, or instance number, associated with the structure +* _memory_arrays.handle_ - Handle, or instance number, associated with the array +* _memory_device_mapped_addresses.handle_ - Handle, or instance number, associated with the structure +* _memory_devices.handle_ - Handle, or instance number, associated with the structure in SMBIOS +* _memory_error_info.handle_ - Handle, or instance number, associated with the structure +* _oem_strings.handle_ - Handle, or instance number, associated with the Type 11 structure +* _smbios_tables.handle_ - Table entry handle + +*handle_count* - keyword, number.long + +* _processes.handle_count_ - Total number of handles that the process has open. This number is the sum of the handles currently opened by each thread in the process. + +*handler* - keyword, text.text + +* _app_schemes.handler_ - Application label for the handler + +*hard_limit* - keyword, text.text + +* _ulimit_info.hard_limit_ - Maximum limit value + +*hard_links* - keyword, number.long + +* _device_file.hard_links_ - Number of hard links +* _file.hard_links_ - Number of hard links + +*hardware_model* - keyword, text.text + +* _disk_info.hardware_model_ - Hard drive model. +* _system_info.hardware_model_ - Hardware model + +*hardware_serial* - keyword, text.text + +* _system_info.hardware_serial_ - Device serial number + +*hardware_vendor* - keyword, text.text + +* _system_info.hardware_vendor_ - Hardware vendor + +*hardware_version* - keyword, text.text + +* _system_info.hardware_version_ - Hardware version + +*has_expired* - keyword, number.long + +* _curl_certificate.has_expired_ - 1 if the certificate has expired, 0 otherwise + +*hash* - keyword, text.text + +* _prefetch.hash_ - Prefetch CRC hash. + +*hash_alg* - keyword, text.text + +* _shadow.hash_alg_ - Password hashing algorithm + +*hash_resources* - keyword, number.long + +* _signature.hash_resources_ - Set to 1 to also hash resources, or 0 otherwise. Default is 1 + +*hashed* - keyword, number.long + +* _file_events.hashed_ - 1 if the file was hashed, 0 if not, -1 if hashing failed + +*header* - keyword, text.text + +* _sudoers.header_ - Symbol for given rule + +*header_size* - keyword, number.long + +* _smbios_tables.header_size_ - Header size in bytes + +*health* - keyword, text.text + +* _battery.health_ - One of the following: "Good" describes a well-performing battery, "Fair" describes a functional battery with limited capacity, or "Poor" describes a battery that's not capable of providing power + +*hidden* - keyword, number.long + +* _scheduled_tasks.hidden_ - Whether or not the task is visible in the UI +* _smc_keys.hidden_ - 1 if this key is normally hidden, otherwise 0 + +*history_file* - keyword, text.text + +* _shell_history.history_file_ - Path to the .*_history for this user + +*hit_count* - keyword, text.text + +* _quicklook_cache.hit_count_ - Number of cache hits on thumbnail + +*home_directory* - keyword, text.text + +* _logon_sessions.home_directory_ - The home directory for the logon session. + +*home_directory_drive* - keyword, text.text + +* _logon_sessions.home_directory_drive_ - The drive location of the home directory of the logon session. + +*homepage* - keyword, text.text + +* _atom_packages.homepage_ - Package supplied homepage + +*hop_limit* - keyword, number.long + +* _interface_ipv6.hop_limit_ - Current Hop Limit + +*hopcount* - keyword, number.long + +* _routes.hopcount_ - Max hops expected + +*host* - keyword, text.text + +* _asl.host_ - Sender's address (set by the server). +* _last.host_ - Entry hostname +* _logged_in_users.host_ - Remote hostname +* _preferences.host_ - 'current' or 'any' host, where 'current' takes precedence +* _syslog_events.host_ - Hostname configured for syslog + +*host_ip* - keyword, text.text + +* _docker_container_ports.host_ip_ - Host IP address on which public port is listening + +*host_port* - keyword, number.long + +* _docker_container_ports.host_port_ - Host port + +*hostname* - keyword, text.text + +* _curl_certificate.hostname_ - Hostname (domain[:port]) to CURL +* _shortcut_files.hostname_ - Optional hostname of the target file. +* _system_info.hostname_ - Network hostname including domain +* _ycloud_instance_metadata.hostname_ - Hostname of the VM + +*hostnames* - keyword, text.text + +* _etc_hosts.hostnames_ - Raw hosts mapping + +*hotfix_id* - keyword, text.text + +* _patches.hotfix_id_ - The KB ID of the patch. + +*hour* - keyword, text.text + +* _crontab.hour_ - The hour of the day for the job +* _time.hour_ - Current hour in the system + +*hours* - keyword, number.long + +* _uptime.hours_ - Hours of uptime + +*http_proxy* - keyword, text.text + +* _docker_info.http_proxy_ - HTTP proxy + +*https_proxy* - keyword, text.text + +* _docker_info.https_proxy_ - HTTPS proxy + +*hwaddr* - keyword, text.text + +* _lxd_networks.hwaddr_ - Hardware address for this network + +*iam_arn* - keyword, text.text + +* _ec2_instance_metadata.iam_arn_ - If there is an IAM role associated with the instance, contains instance profile ARN + +*ibrs_support_enabled* - keyword, number.long + +* _kva_speculative_info.ibrs_support_enabled_ - Windows uses IBRS. + +*ibytes* - keyword, number.long + +* _interface_details.ibytes_ - Input bytes + +*icon_mode* - keyword, number.long + +* _quicklook_cache.icon_mode_ - Thumbnail icon mode + +*icon_path* - keyword, text.text + +* _shortcut_files.icon_path_ - Lnk file icon location. + +*id* - keyword, text.text + +* _disk_info.id_ - The unique identifier of the drive on the system. +* _dns_resolvers.id_ - Address type index or order +* _docker_container_fs_changes.id_ - Container ID +* _docker_container_labels.id_ - Container ID +* _docker_container_mounts.id_ - Container ID +* _docker_container_networks.id_ - Container ID +* _docker_container_ports.id_ - Container ID +* _docker_container_processes.id_ - Container ID +* _docker_container_stats.id_ - Container ID +* _docker_containers.id_ - Container ID +* _docker_image_history.id_ - Image ID +* _docker_image_labels.id_ - Image ID +* _docker_image_layers.id_ - Image ID +* _docker_images.id_ - Image ID +* _docker_info.id_ - Docker system ID +* _docker_network_labels.id_ - Network ID +* _docker_networks.id_ - Network ID +* _example.id_ - An index of some sort +* _iokit_devicetree.id_ - IOKit internal registry ID +* _iokit_registry.id_ - IOKit internal registry ID +* _lxd_images.id_ - Image ID +* _systemd_units.id_ - Unique unit identifier + +*identifier* - keyword, text.text + +* _browser_plugins.identifier_ - Plugin identifier +* _chrome_extension_content_scripts.identifier_ - Extension identifier +* _chrome_extensions.identifier_ - Extension identifier, computed from its manifest. Empty in case of error. +* _crashes.identifier_ - Identifier of the crashed process +* _firefox_addons.identifier_ - Addon identifier +* _safari_extensions.identifier_ - Extension identifier +* _signature.identifier_ - The signing identifier sealed into the signature +* _system_extensions.identifier_ - Identifier name +* _xprotect_meta.identifier_ - Browser plugin or extension identifier + +*identifying_number* - keyword, text.text + +* _programs.identifying_number_ - Product identification such as a serial number on software, or a die number on a hardware chip. + +*identity* - keyword, text.text + +* _xprotect_entries.identity_ - XProtect identity (SHA1) of content + +*idle* - keyword, number.long + +* _cpu_time.idle_ - Time spent in the idle task + +*idrops* - keyword, number.long + +* _interface_details.idrops_ - Input drops + +*idx* - keyword, number.long + +* _kernel_extensions.idx_ - Extension load tag or index + +*ierrors* - keyword, number.long + +* _interface_details.ierrors_ - Input errors + +*image* - keyword, text.text + +* _docker_containers.image_ - Docker image (name) used to launch this container +* _drivers.image_ - Path to driver image file + +*image_id* - keyword, text.text + +* _docker_containers.image_id_ - Docker image ID + +*images* - keyword, number.long + +* _docker_info.images_ - Number of images + +*in_smartctl_db* - keyword, number.long + +* _smart_drive_info.in_smartctl_db_ - Boolean value for if drive is recognized + +*inactive* - keyword, number.long + +* _memory_info.inactive_ - The total amount of buffer or page cache memory, in bytes, that are free and available +* _shadow.inactive_ - Number of days after password expires until account is blocked +* _virtual_memory_info.inactive_ - Total number of inactive pages. + +*inetd_compatibility* - keyword, text.text + +* _launchd.inetd_compatibility_ - Run this daemon or agent as it was launched from inetd + +*inf* - keyword, text.text + +* _drivers.inf_ - Associated inf file + +*info* - keyword, text.text + +* _apparmor_events.info_ - Additional information + +*info_access* - keyword, text.text + +* _curl_certificate.info_access_ - Authority Information Access + +*info_string* - keyword, text.text + +* _apps.info_string_ - Info properties CFBundleGetInfoString label + +*inherited_from* - keyword, text.text + +* _ntfs_acl_permissions.inherited_from_ - The inheritance policy of the ACE. + +*iniface* - keyword, text.text + +* _iptables.iniface_ - Input interface for the rule. + +*iniface_mask* - keyword, text.text + +* _iptables.iniface_mask_ - Input interface mask for the rule. + +*inode* - keyword, number.long + +* _device_file.inode_ - Filesystem inode number +* _device_hash.inode_ - Filesystem inode number +* _file.inode_ - Filesystem inode number +* _file_events.inode_ - Filesystem inode number +* _process_memory_map.inode_ - Mapped path inode, 0 means uninitialized (BSS) +* _process_open_pipes.inode_ - Pipe inode number +* _quicklook_cache.inode_ - Parsed file ID (inode) from fs_id + +*inodes* - keyword, number.long + +* _device_partitions.inodes_ - Number of meta nodes +* _mounts.inodes_ - Mounted device used inodes + +*inodes_free* - keyword, number.long + +* _mounts.inodes_free_ - Mounted device free inodes + +*inodes_total* - keyword, number.long + +* _lxd_storage_pools.inodes_total_ - Total number of inodes available in this storage pool + +*inodes_used* - keyword, number.long + +* _lxd_storage_pools.inodes_used_ - Number of inodes used + +*input_eax* - keyword, text.text + +* _cpuid.input_eax_ - Value of EAX used + +*install_date* - keyword + +* _os_version.install_date_ - The install date of the OS. +* _patches.install_date_ - Indicates when the patch was installed. Lack of a value does not indicate that the patch was not installed. +* _programs.install_date_ - Date that this product was installed on the system. +* _shared_resources.install_date_ - Indicates when the object was installed. Lack of a value does not indicate that the object is not installed. + +*install_location* - keyword, text.text + +* _programs.install_location_ - The installation location directory of the product. + +*install_source* - keyword, text.text + +* _programs.install_source_ - The installation source of the product. + +*install_time* - keyword + +* _appcompat_shims.install_time_ - Install time of the SDB +* _chrome_extensions.install_time_ - Extension install time, in its original Webkit format +* _package_receipts.install_time_ - Timestamp of install time +* _rpm_packages.install_time_ - When the package was installed + +*install_timestamp* - keyword, number.long + +* _chrome_extensions.install_timestamp_ - Extension install time, converted to unix time + +*installed_by* - keyword, text.text + +* _patches.installed_by_ - The system context in which the patch as installed. + +*installed_on* - keyword, text.text + +* _patches.installed_on_ - The date when the patch was installed. + +*installer_name* - keyword, text.text + +* _package_receipts.installer_name_ - Name of installer process + +*instance_id* - keyword, text.text + +* _ec2_instance_metadata.instance_id_ - EC2 instance ID +* _ec2_instance_tags.instance_id_ - EC2 instance ID +* _osquery_info.instance_id_ - Unique, long-lived ID per instance of osquery +* _ycloud_instance_metadata.instance_id_ - Unique identifier for the VM + +*instance_identifier* - keyword, text.text + +* _hvci_status.instance_identifier_ - The instance ID of Device Guard. + +*instance_type* - keyword, text.text + +* _ec2_instance_metadata.instance_type_ - EC2 instance type + +*instances* - keyword, number.long + +* _pipes.instances_ - Number of instances of the named pipe + +*interface* - keyword, text.text + +* _arp_cache.interface_ - Interface of the network for the MAC +* _interface_addresses.interface_ - Interface name +* _interface_details.interface_ - Interface name +* _interface_ipv6.interface_ - Interface name +* _lldp_neighbors.interface_ - Interface name +* _routes.interface_ - Route local interface +* _wifi_status.interface_ - Name of the interface +* _wifi_survey.interface_ - Name of the interface + +*interleave_data_depth* - keyword, number.long + +* _memory_device_mapped_addresses.interleave_data_depth_ - The max number of consecutive rows from memory device that are accessed in a single interleave transfer; 0 indicates device is non-interleave + +*interleave_position* - keyword, number.long + +* _memory_device_mapped_addresses.interleave_position_ - The position of the device in a interleave, i.e. 0 indicates non-interleave, 1 indicates 1st interleave, 2 indicates 2nd interleave, etc. + +*internal* - keyword, number.long + +* _osquery_registry.internal_ - 1 If the plugin is internal else 0 + +*internet_settings* - keyword, text.text + +* _windows_security_center.internet_settings_ - The health of the Internet Settings + +*internet_sharing* - keyword, number.long + +* _sharing_preferences.internet_sharing_ - 1 If internet sharing is enabled else 0 + +*interval* - keyword, number.long + +* _docker_container_stats.interval_ - Difference between read and preread in nano-seconds +* _osquery_schedule.interval_ - The interval in seconds to run this query, not an exact interval + +*iowait* - keyword, number.long + +* _cpu_time.iowait_ - Time spent waiting for I/O to complete + +*ip* - keyword, text.text + +* _seccomp_events.ip_ - Instruction pointer value + +*ip_address* - keyword, text.text + +* _docker_container_networks.ip_address_ - IP address + +*ip_prefix_len* - keyword, number.long + +* _docker_container_networks.ip_prefix_len_ - IP subnet prefix length + +*ipackets* - keyword, number.long + +* _interface_details.ipackets_ - Input packets + +*ipc_namespace* - keyword, text.text + +* _docker_containers.ipc_namespace_ - IPC namespace +* _process_namespaces.ipc_namespace_ - ipc namespace inode + +*ipv4_address* - keyword, text.text + +* _lxd_networks.ipv4_address_ - IPv4 address + +*ipv4_forwarding* - keyword, number.long + +* _docker_info.ipv4_forwarding_ - 1 if IPv4 forwarding is enabled. 0 otherwise + +*ipv4_internet* - keyword, number.long + +* _connectivity.ipv4_internet_ - True if any interface is connected to the Internet via IPv4 + +*ipv4_local_network* - keyword, number.long + +* _connectivity.ipv4_local_network_ - True if any interface is connected to a routed network via IPv4 + +*ipv4_no_traffic* - keyword, number.long + +* _connectivity.ipv4_no_traffic_ - True if any interface is connected via IPv4, but has seen no traffic + +*ipv4_subnet* - keyword, number.long + +* _connectivity.ipv4_subnet_ - True if any interface is connected to the local subnet via IPv4 + +*ipv6_address* - keyword, text.text + +* _docker_container_networks.ipv6_address_ - IPv6 address +* _lxd_networks.ipv6_address_ - IPv6 address + +*ipv6_gateway* - keyword, text.text + +* _docker_container_networks.ipv6_gateway_ - IPv6 gateway + +*ipv6_internet* - keyword, number.long + +* _connectivity.ipv6_internet_ - True if any interface is connected to the Internet via IPv6 + +*ipv6_local_network* - keyword, number.long + +* _connectivity.ipv6_local_network_ - True if any interface is connected to a routed network via IPv6 + +*ipv6_no_traffic* - keyword, number.long + +* _connectivity.ipv6_no_traffic_ - True if any interface is connected via IPv6, but has seen no traffic + +*ipv6_prefix_len* - keyword, number.long + +* _docker_container_networks.ipv6_prefix_len_ - IPv6 subnet prefix length + +*ipv6_subnet* - keyword, number.long + +* _connectivity.ipv6_subnet_ - True if any interface is connected to the local subnet via IPv6 + +*irq* - keyword, number.long + +* _cpu_time.irq_ - Time spent servicing interrupts + +*is_active* - keyword, number.long + +* _running_apps.is_active_ - 1 if the application is in focus, 0 otherwise + +*is_hidden* - keyword, number.long + +* _groups.is_hidden_ - IsHidden attribute set in OpenDirectory +* _users.is_hidden_ - IsHidden attribute set in OpenDirectory + +*iso_8601* - keyword, text.text + +* _time.iso_8601_ - Current time (ISO format) in the system + +*issuer* - keyword, text.text + +* _certificates.issuer_ - Certificate issuer distinguished name + +*issuer_alternative_names* - keyword, text.text + +* _curl_certificate.issuer_alternative_names_ - Issuer Alternative Name + +*issuer_common_name* - keyword, text.text + +* _curl_certificate.issuer_common_name_ - Issuer common name + +*issuer_name* - keyword, text.text + +* _authenticode.issuer_name_ - The certificate issuer name + +*issuer_organization* - keyword, text.text + +* _curl_certificate.issuer_organization_ - Issuer organization + +*issuer_organization_unit* - keyword, text.text + +* _curl_certificate.issuer_organization_unit_ - Issuer organization unit + +*job_id* - keyword, number.long + +* _systemd_units.job_id_ - Next queued job id + +*job_path* - keyword, text.text + +* _systemd_units.job_path_ - The object path for the job + +*job_type* - keyword, text.text + +* _systemd_units.job_type_ - Job type + +*json_cmdline* - keyword, text.text + +* _bpf_process_events.json_cmdline_ - Command line arguments, in JSON format + +*keep_alive* - keyword, text.text + +* _launchd.keep_alive_ - Should the process be restarted if killed + +*kernel_memory* - keyword, number.long + +* _docker_info.kernel_memory_ - 1 if kernel memory limit support is enabled. 0 otherwise + +*kernel_version* - keyword, text.text + +* _docker_info.kernel_version_ - Kernel version +* _docker_version.kernel_version_ - Kernel version +* _kernel_panics.kernel_version_ - Version of the system kernel + +*key* - keyword, text.text + +* _authorized_keys.key_ - parsed authorized keys line +* _azure_instance_tags.key_ - The tag key +* _chrome_extensions.key_ - The extension key, from the manifest file +* _docker_container_labels.key_ - Label key +* _docker_image_labels.key_ - Label key +* _docker_network_labels.key_ - Label key +* _docker_volume_labels.key_ - Label key +* _ec2_instance_tags.key_ - Tag key +* _extended_attributes.key_ - Name of the value generated from the extended attribute +* _known_hosts.key_ - parsed authorized keys line +* _launchd_overrides.key_ - Name of the override key +* _lxd_instance_config.key_ - Configuration parameter name +* _lxd_instance_devices.key_ - Device info param name +* _mdls.key_ - Name of the metadata key +* _plist.key_ - Preference top-level key +* _power_sensors.key_ - The SMC key on OS X +* _preferences.key_ - Preference top-level key +* _process_envs.key_ - Environment variable name +* _registry.key_ - Name of the key to search for +* _selinux_settings.key_ - Key or class name. +* _smc_keys.key_ - 4-character key +* _temperature_sensors.key_ - The SMC key on OS X + +*key_algorithm* - keyword, text.text + +* _certificates.key_algorithm_ - Key algorithm used + +*key_file* - keyword, text.text + +* _authorized_keys.key_file_ - Path to the authorized_keys file +* _known_hosts.key_file_ - Path to known_hosts file + +*key_strength* - keyword, text.text + +* _certificates.key_strength_ - Key size used for RSA/DSA, or curve name + +*key_type* - keyword, text.text + +* _user_ssh_keys.key_type_ - The type of the private key. One of [rsa, dsa, dh, ec, hmac, cmac], or the empty string. + +*key_usage* - keyword, text.text + +* _certificates.key_usage_ - Certificate key usage and extended key usage +* _curl_certificate.key_usage_ - Usage of key in certificate + +*keychain_path* - keyword, text.text + +* _keychain_acls.keychain_path_ - The path of the keychain + +*keyword* - keyword, text.text + +* _portage_keywords.keyword_ - The keyword applied to the package + +*keywords* - keyword, text.text + +* _windows_eventlog.keywords_ - A bitmask of the keywords defined in the event +* _windows_events.keywords_ - A bitmask of the keywords defined in the event + +*kva_shadow_enabled* - keyword, number.long + +* _kva_speculative_info.kva_shadow_enabled_ - Kernel Virtual Address shadowing is enabled. + +*kva_shadow_inv_pcid* - keyword, number.long + +* _kva_speculative_info.kva_shadow_inv_pcid_ - Kernel VA INVPCID is enabled. + +*kva_shadow_pcid* - keyword, number.long + +* _kva_speculative_info.kva_shadow_pcid_ - Kernel VA PCID flushing optimization is enabled. + +*kva_shadow_user_global* - keyword, number.long + +* _kva_speculative_info.kva_shadow_user_global_ - User pages are marked as global. + +*label* - keyword, text.text + +* _apparmor_events.label_ - AppArmor label +* _augeas.label_ - The label of the configuration item +* _authorization_mechanisms.label_ - Label of the authorization right +* _authorizations.label_ - Item name, usually in reverse domain format +* _block_devices.label_ - Block device label string +* _device_partitions.label_ - +* _keychain_acls.label_ - An optional label tag that may be included with the keychain entry +* _keychain_items.label_ - Generic item name +* _launchd.label_ - Daemon or agent service name +* _launchd_overrides.label_ - Daemon or agent service name +* _quicklook_cache.label_ - Parsed version 'gen' field +* _sandboxes.label_ - UTI-format bundle or label ID + +*language* - keyword, text.text + +* _programs.language_ - The language of the product. + +*last_change* - keyword, number.long + +* _interface_details.last_change_ - Time of last device modification (optional) +* _shadow.last_change_ - Date of last password change (starting from UNIX epoch date) + +*last_connected* - keyword, number.long + +* _wifi_networks.last_connected_ - Last time this netword was connected to as a unix_time + +*last_executed* - keyword, number.long + +* _osquery_schedule.last_executed_ - UNIX time stamp in seconds of the last completed execution + +*last_execution_time* - keyword, number.long + +* _background_activities_moderator.last_execution_time_ - Most recent time application was executed. +* _userassist.last_execution_time_ - Most recent time application was executed. + +*last_hit_date* - keyword, number.long + +* _quicklook_cache.last_hit_date_ - Apple date format for last thumbnail cache hit + +*last_loaded* - keyword, text.text + +* _kernel_panics.last_loaded_ - Last loaded module before panic + +*last_opened_time* - keyword + +* _apps.last_opened_time_ - The time that the app was last used +* _office_mru.last_opened_time_ - Most recent opened time file was opened + +*last_run_code* - keyword, text.text + +* _scheduled_tasks.last_run_code_ - Exit status code of the last task run + +*last_run_message* - keyword, text.text + +* _scheduled_tasks.last_run_message_ - Exit status message of the last task run + +*last_run_time* - keyword, number.long + +* _prefetch.last_run_time_ - Most recent time application was run. +* _scheduled_tasks.last_run_time_ - Timestamp the task last ran + +*last_unloaded* - keyword, text.text + +* _kernel_panics.last_unloaded_ - Last unloaded module before panic + +*last_used_at* - keyword, text.text + +* _lxd_images.last_used_at_ - ISO time for the most recent use of this image in terms of container spawn + +*launch_type* - keyword, text.text + +* _xprotect_entries.launch_type_ - Launch services content type + +*layer_id* - keyword, text.text + +* _docker_image_layers.layer_id_ - Layer ID + +*layer_order* - keyword, number.long + +* _docker_image_layers.layer_order_ - Layer Order (1 = base layer) + +*level* - keyword, number.long + +* _asl.level_ - Log level number. See levels in asl.h. +* _windows_eventlog.level_ - Severity level associated with the event +* _windows_events.level_ - The severity level associated with the event + +*license* - keyword, text.text + +* _atom_packages.license_ - License for package +* _chocolatey_packages.license_ - License under which package is launched +* _npm_packages.license_ - License for package +* _python_packages.license_ - License under which package is launched + +*link* - keyword, text.text + +* _elf_sections.link_ - Link to other section + +*link_speed* - keyword, number.long + +* _interface_details.link_speed_ - Interface speed in Mb/s + +*linked_against* - keyword, text.text + +* _kernel_extensions.linked_against_ - Indexes of extensions this extension is linked against + +*load_state* - keyword, text.text + +* _systemd_units.load_state_ - Reflects whether the unit definition was properly loaded + +*local_address* - keyword, text.text + +* _bpf_socket_events.local_address_ - Local address associated with socket +* _process_open_sockets.local_address_ - Socket local address +* _socket_events.local_address_ - Local address associated with socket + +*local_hostname* - keyword, text.text + +* _ec2_instance_metadata.local_hostname_ - Private IPv4 DNS hostname of the first interface of this instance +* _system_info.local_hostname_ - Local hostname (optional) + +*local_ipv4* - keyword, text.text + +* _ec2_instance_metadata.local_ipv4_ - Private IPv4 address of the first interface of this instance + +*local_path* - keyword, text.text + +* _shortcut_files.local_path_ - Local system path to target file. + +*local_port* - keyword, number.long + +* _bpf_socket_events.local_port_ - Local network protocol port number +* _process_open_sockets.local_port_ - Socket local port +* _socket_events.local_port_ - Local network protocol port number + +*local_time* - keyword, number.long + +* _time.local_time_ - Current local UNIX time in the system + +*local_timezone* - keyword, text.text + +* _time.local_timezone_ - Current local timezone in the system + +*location* - keyword, text.text + +* _azure_instance_metadata.location_ - Azure Region the VM is running in +* _firefox_addons.location_ - Global, profile location +* _memory_arrays.location_ - Physical location of the memory array +* _package_receipts.location_ - Optional relative install path on volume + +*lock* - keyword, text.text + +* _chassis_info.lock_ - If TRUE, the frame is equipped with a lock. + +*lock_status* - keyword, number.long + +* _bitlocker_info.lock_status_ - The accessibility status of the drive from Windows. + +*locked* - keyword, number.long + +* _shared_memory.locked_ - 1 if segment is locked else 0 + +*log_file_disk_quota_mb* - keyword, number.long + +* _carbon_black_info.log_file_disk_quota_mb_ - Event file disk quota in MB + +*log_file_disk_quota_percentage* - keyword, number.long + +* _carbon_black_info.log_file_disk_quota_percentage_ - Event file disk quota in a percentage + +*logging_driver* - keyword, text.text + +* _docker_info.logging_driver_ - Logging driver + +*logging_enabled* - keyword, number.long + +* _alf.logging_enabled_ - 1 If logging mode is enabled else 0 + +*logging_option* - keyword, number.long + +* _alf.logging_option_ - Firewall logging option + +*logical_processors* - keyword, number.long + +* _cpu_info.logical_processors_ - The number of logical processors of the CPU. + +*logon_domain* - keyword, text.text + +* _logon_sessions.logon_domain_ - The name of the domain used to authenticate the owner of the logon session. + +*logon_id* - keyword, number.long + +* _logon_sessions.logon_id_ - A locally unique identifier (LUID) that identifies a logon session. + +*logon_script* - keyword, text.text + +* _logon_sessions.logon_script_ - The script used for logging on. + +*logon_server* - keyword, text.text + +* _logon_sessions.logon_server_ - The name of the server used to authenticate the owner of the logon session. + +*logon_sid* - keyword, text.text + +* _logon_sessions.logon_sid_ - The user's security identifier (SID). + +*logon_time* - keyword, number.long + +* _logon_sessions.logon_time_ - The time the session owner logged on. + +*logon_type* - keyword, text.text + +* _logon_sessions.logon_type_ - The logon method. + +*lu_wwn_device_id* - keyword, text.text + +* _smart_drive_info.lu_wwn_device_id_ - Device Identifier + +*mac* - keyword, text.text + +* _arp_cache.mac_ - MAC address of broadcasted address +* _ec2_instance_metadata.mac_ - MAC address for the first network interface of this EC2 instance +* _interface_details.mac_ - MAC of interface (optional) + +*mac_address* - keyword, text.text + +* _docker_container_networks.mac_address_ - MAC address + +*machine* - keyword, number.long + +* _elf_info.machine_ - Machine type + +*machine_name* - keyword, text.text + +* _windows_crashes.machine_name_ - Name of the machine where the crash happened + +*magic_db_files* - keyword, text.text + +* _magic.magic_db_files_ - Colon(:) separated list of files where the magic db file can be found. By default one of the following is used: /usr/share/file/magic/magic, /usr/share/misc/magic or /usr/share/misc/magic.mgc + +*maintainer* - keyword, text.text + +* _apt_sources.maintainer_ - Repository maintainer +* _deb_packages.maintainer_ - Package maintainer + +*major* - keyword, number.long + +* _os_version.major_ - Major release version + +*major_version* - keyword, number.long + +* _windows_crashes.major_version_ - Windows major version of the machine + +*managed* - keyword, number.long + +* _lxd_networks.managed_ - 1 if network created by LXD, 0 otherwise + +*manifest_hash* - keyword, text.text + +* _chrome_extensions.manifest_hash_ - The SHA256 hash of the manifest.json file + +*manifest_json* - keyword, text.text + +* _chrome_extensions.manifest_json_ - The manifest file of the extension + +*manual* - keyword, number.long + +* _managed_policies.manual_ - 1 if policy was loaded manually, otherwise 0 + +*manufacture_date* - keyword, number.long + +* _battery.manufacture_date_ - The date the battery was manufactured UNIX Epoch + +*manufacturer* - keyword, text.text + +* _battery.manufacturer_ - The battery manufacturer's name +* _chassis_info.manufacturer_ - The manufacturer of the chassis. +* _cpu_info.manufacturer_ - The manufacturer of the CPU. +* _disk_info.manufacturer_ - The manufacturer of the disk. +* _drivers.manufacturer_ - Device manufacturer +* _interface_details.manufacturer_ - Name of the network adapter's manufacturer. +* _memory_devices.manufacturer_ - Manufacturer ID string +* _video_info.manufacturer_ - The manufacturer of the gpu. + +*manufacturer_id* - keyword, number.long + +* _tpm_info.manufacturer_id_ - TPM manufacturers ID + +*manufacturer_name* - keyword, text.text + +* _tpm_info.manufacturer_name_ - TPM manufacturers name + +*manufacturer_version* - keyword, text.text + +* _tpm_info.manufacturer_version_ - TPM version + +*mask* - keyword, text.text + +* _interface_addresses.mask_ - Interface netmask +* _portage_keywords.mask_ - If the package is masked + +*match* - keyword, text.text + +* _chrome_extension_content_scripts.match_ - The pattern that the script is matched against +* _iptables.match_ - Matching rule that applies. + +*matches* - keyword, text.text + +* _yara.matches_ - List of YARA matches +* _yara_events.matches_ - List of YARA matches + +*max* - keyword, number.long + +* _fan_speed_sensors.max_ - Maximum speed +* _shadow.max_ - Maximum number of days between password changes + +*max_capacity* - keyword, number.long + +* _battery.max_capacity_ - The battery's actual capacity when it is fully charged in mAh +* _memory_arrays.max_capacity_ - Maximum capacity of array in gigabytes + +*max_clock_speed* - keyword, number.long + +* _cpu_info.max_clock_speed_ - The maximum possible frequency of the CPU. + +*max_instances* - keyword, number.long + +* _pipes.max_instances_ - The maximum number of instances creatable for this pipe + +*max_speed* - keyword, number.long + +* _memory_devices.max_speed_ - Max speed of memory device in megatransfers per second (MT/s) + +*max_voltage* - keyword, number.long + +* _memory_devices.max_voltage_ - Maximum operating voltage of device in millivolts + +*maximum_allowed* - keyword, number.long + +* _shared_resources.maximum_allowed_ - Limit on the maximum number of users allowed to use this resource concurrently. The value is only valid if the AllowMaximum property is set to FALSE. + +*md5* - keyword, text.text + +* _acpi_tables.md5_ - MD5 hash of table content +* _device_hash.md5_ - MD5 hash of provided inode data +* _file_events.md5_ - The MD5 of the file after change +* _hash.md5_ - MD5 hash of provided filesystem data +* _smbios_tables.md5_ - MD5 hash of table entry + +*md_device_name* - keyword, text.text + +* _md_drives.md_device_name_ - md device name + +*mdm_managed* - keyword, number.long + +* _system_extensions.mdm_managed_ - 1 if managed by MDM system extension payload configuration, 0 otherwise + +*mechanism* - keyword, text.text + +* _authorization_mechanisms.mechanism_ - Name of the mechanism that will be called + +*med_capability_capabilities* - keyword, number.long + +* _lldp_neighbors.med_capability_capabilities_ - Is MED capabilities enabled + +*med_capability_inventory* - keyword, number.long + +* _lldp_neighbors.med_capability_inventory_ - Is MED inventory capability enabled + +*med_capability_location* - keyword, number.long + +* _lldp_neighbors.med_capability_location_ - Is MED location capability enabled + +*med_capability_mdi_pd* - keyword, number.long + +* _lldp_neighbors.med_capability_mdi_pd_ - Is MED MDI PD capability enabled + +*med_capability_mdi_pse* - keyword, number.long + +* _lldp_neighbors.med_capability_mdi_pse_ - Is MED MDI PSE capability enabled + +*med_capability_policy* - keyword, number.long + +* _lldp_neighbors.med_capability_policy_ - Is MED policy capability enabled + +*med_device_type* - keyword, text.text + +* _lldp_neighbors.med_device_type_ - Chassis MED type + +*med_policies* - keyword, text.text + +* _lldp_neighbors.med_policies_ - Comma delimited list of MED policies + +*media_name* - keyword, text.text + +* _disk_events.media_name_ - Disk event media name string + +*mem* - keyword, number.double + +* _docker_container_processes.mem_ - Memory utilization as percentage + +*member_config_description* - keyword, text.text + +* _lxd_cluster.member_config_description_ - Config description + +*member_config_entity* - keyword, text.text + +* _lxd_cluster.member_config_entity_ - Type of configuration parameter for this node + +*member_config_key* - keyword, text.text + +* _lxd_cluster.member_config_key_ - Config key + +*member_config_name* - keyword, text.text + +* _lxd_cluster.member_config_name_ - Name of configuration parameter + +*member_config_value* - keyword, text.text + +* _lxd_cluster.member_config_value_ - Config value + +*memory* - keyword, number.long + +* _docker_info.memory_ - Total memory + +*memory_array_error_address* - keyword, text.text + +* _memory_error_info.memory_array_error_address_ - 32 bit physical address of the error based on the addressing of the bus to which the memory array is connected + +*memory_array_handle* - keyword, text.text + +* _memory_array_mapped_addresses.memory_array_handle_ - Handle of the memory array associated with this structure + +*memory_array_mapped_address_handle* - keyword, text.text + +* _memory_device_mapped_addresses.memory_array_mapped_address_handle_ - Handle of the memory array mapped address to which this device range is mapped to + +*memory_device_handle* - keyword, text.text + +* _memory_device_mapped_addresses.memory_device_handle_ - Handle of the memory device structure associated with this structure + +*memory_error_correction* - keyword, text.text + +* _memory_arrays.memory_error_correction_ - Primary hardware error correction or detection method supported + +*memory_error_info_handle* - keyword, text.text + +* _memory_arrays.memory_error_info_handle_ - Handle, or instance number, associated with any error that was detected for the array + +*memory_free* - keyword, number.long + +* _memory_info.memory_free_ - The amount of physical RAM, in bytes, left unused by the system + +*memory_limit* - keyword, number.long + +* _docker_container_stats.memory_limit_ - Memory limit +* _docker_info.memory_limit_ - 1 if memory limit support is enabled. 0 otherwise + +*memory_max_usage* - keyword, number.long + +* _docker_container_stats.memory_max_usage_ - Memory maximum usage + +*memory_total* - keyword, number.long + +* _memory_info.memory_total_ - Total amount of physical RAM, in bytes + +*memory_type* - keyword, text.text + +* _memory_devices.memory_type_ - Type of memory used + +*memory_type_details* - keyword, text.text + +* _memory_devices.memory_type_details_ - Additional details for memory device + +*memory_usage* - keyword, number.long + +* _docker_container_stats.memory_usage_ - Memory usage + +*message* - keyword, text.text + +* _apparmor_events.message_ - Raw audit message +* _asl.message_ - Message text. +* _lxd_cluster_members.message_ - Message from the node (Online/Offline) +* _selinux_events.message_ - Message +* _syslog_events.message_ - The syslog message +* _user_events.message_ - Message from the event + +*metadata_endpoint* - keyword, text.text + +* _ycloud_instance_metadata.metadata_endpoint_ - Endpoint used to fetch VM metadata + +*method* - keyword, text.text + +* _curl.method_ - The HTTP method for the request + +*metric* - keyword, number.long + +* _interface_details.metric_ - Metric based on the speed of the interface +* _routes.metric_ - Cost of route. Lowest is preferred + +*metric_name* - keyword, text.text + +* _prometheus_metrics.metric_name_ - Name of collected Prometheus metric + +*metric_value* - keyword, number.double + +* _prometheus_metrics.metric_value_ - Value of collected Prometheus metric + +*mft_entry* - keyword, number.long + +* _shellbags.mft_entry_ - Directory master file table entry. +* _shortcut_files.mft_entry_ - Target mft entry. + +*mft_sequence* - keyword, number.long + +* _shellbags.mft_sequence_ - Directory master file table sequence. +* _shortcut_files.mft_sequence_ - Target mft sequence. + +*mime_encoding* - keyword, text.text + +* _magic.mime_encoding_ - MIME encoding data from libmagic + +*mime_type* - keyword, text.text + +* _magic.mime_type_ - MIME type data from libmagic + +*min* - keyword, number.long + +* _fan_speed_sensors.min_ - Minimum speed +* _shadow.min_ - Minimal number of days between password changes + +*min_api_version* - keyword, text.text + +* _docker_version.min_api_version_ - Minimum API version supported + +*min_version* - keyword, text.text + +* _xprotect_meta.min_version_ - The minimum allowed plugin version. + +*min_voltage* - keyword, number.long + +* _memory_devices.min_voltage_ - Minimum operating voltage of device in millivolts + +*minimum_system_version* - keyword, text.text + +* _apps.minimum_system_version_ - Minimum version of OS X required for the app to run + +*minor* - keyword, number.long + +* _os_version.minor_ - Minor release version + +*minor_version* - keyword, number.long + +* _windows_crashes.minor_version_ - Windows minor version of the machine + +*minute* - keyword, text.text + +* _crontab.minute_ - The exact minute for the job + +*minutes* - keyword, number.long + +* _time.minutes_ - Current minutes in the system +* _uptime.minutes_ - Minutes of uptime + +*minutes_to_full_charge* - keyword, number.long + +* _battery.minutes_to_full_charge_ - The number of minutes until the battery is fully charged. This value is -1 if this time is still being calculated + +*minutes_until_empty* - keyword, number.long + +* _battery.minutes_until_empty_ - The number of minutes until the battery is fully depleted. This value is -1 if this time is still being calculated + +*mnt_namespace* - keyword, text.text + +* _docker_containers.mnt_namespace_ - Mount namespace +* _process_namespaces.mnt_namespace_ - mnt namespace inode + +*mode* - keyword, text.text + +* _apparmor_profiles.mode_ - How the policy is applied. +* _device_file.mode_ - Permission bits +* _docker_container_mounts.mode_ - Mount options (rw, ro) +* _file.mode_ - Permission bits +* _file_events.mode_ - Permission bits +* _package_bom.mode_ - Expected permissions +* _process_events.mode_ - File mode permissions +* _process_open_pipes.mode_ - Pipe open mode (r/w) +* _rpm_package_files.mode_ - File permissions mode from info DB +* _wifi_status.mode_ - The current operating mode for the Wi-Fi interface + +*model* - keyword, text.text + +* _battery.model_ - The battery's model number +* _block_devices.model_ - Block device model string identifier +* _chassis_info.model_ - The model of the chassis. +* _cpu_info.model_ - The model of the CPU. +* _hardware_events.model_ - Hardware device model +* _pci_devices.model_ - PCI Device model +* _usb_devices.model_ - USB Device model string +* _video_info.model_ - The model of the gpu. + +*model_family* - keyword, text.text + +* _smart_drive_info.model_family_ - Drive model family + +*model_id* - keyword, text.text + +* _hardware_events.model_id_ - Hex encoded Hardware model identifier +* _pci_devices.model_id_ - Hex encoded PCI Device model identifier +* _usb_devices.model_id_ - Hex encoded USB Device model identifier + +*modified* - keyword, text.text + +* _authorizations.modified_ - Label top-level key +* _keychain_items.modified_ - Date of last modification + +*modified_time* - keyword, number.long + +* _package_bom.modified_time_ - Timestamp the file was installed +* _shellbags.modified_time_ - Directory Modified time. +* _shimcache.modified_time_ - File Modified time. + +*module* - keyword, text.text + +* _windows_crashes.module_ - Path of the crashed module within the process + +*module_backtrace* - keyword, text.text + +* _kernel_panics.module_backtrace_ - Modules appearing in the crashed module's backtrace + +*module_path* - keyword, text.text + +* _services.module_path_ - Path to ServiceDll + +*month* - keyword, text.text + +* _crontab.month_ - The month of the year for the job +* _time.month_ - Current month in the system + +*mount_namespace_id* - keyword, text.text + +* _deb_packages.mount_namespace_id_ - Mount namespace id +* _file.mount_namespace_id_ - Mount namespace id +* _hash.mount_namespace_id_ - Mount namespace id +* _npm_packages.mount_namespace_id_ - Mount namespace id +* _os_version.mount_namespace_id_ - Mount namespace id +* _rpm_packages.mount_namespace_id_ - Mount namespace id + +*mount_point* - keyword, text.text + +* _docker_volumes.mount_point_ - Mount point + +*mountable* - keyword, number.long + +* _disk_events.mountable_ - 1 if mountable, 0 if not + +*msize* - keyword, number.long + +* _elf_segments.msize_ - Segment offset in memory + +*mtime* - keyword + +* _device_file.mtime_ - Last modification time +* _file.mtime_ - Last modification time +* _file_events.mtime_ - Last modification time +* _gatekeeper_approved_apps.mtime_ - Last modification time +* _process_events.mtime_ - File modification in UNIX time +* _quicklook_cache.mtime_ - Parsed version date field +* _registry.mtime_ - timestamp of the most recent registry write + +*mtu* - keyword, number.long + +* _interface_details.mtu_ - Network MTU +* _lxd_networks.mtu_ - MTU size +* _routes.mtu_ - Maximum Transmission Unit for the route + +*name* - keyword, text.text + +* _acpi_tables.name_ - ACPI table name +* _ad_config.name_ - The OS X-specific configuration name +* _apparmor_events.name_ - Process name +* _apparmor_profiles.name_ - Policy name. +* _apps.name_ - Name of the Name.app folder +* _apt_sources.name_ - Repository name +* _atom_packages.name_ - Package display name +* _autoexec.name_ - Name of the program +* _azure_instance_metadata.name_ - Name of the VM +* _block_devices.name_ - Block device name +* _browser_plugins.name_ - Plugin display name +* _chocolatey_packages.name_ - Package display name +* _chrome_extensions.name_ - Extension display name +* _cups_destinations.name_ - Name of the printer +* _deb_packages.name_ - Package name +* _disk_encryption.name_ - Disk name +* _disk_events.name_ - Disk event name +* _disk_info.name_ - The label of the disk object. +* _dns_cache.name_ - DNS record name +* _docker_container_mounts.name_ - Optional mount name +* _docker_container_networks.name_ - Network name +* _docker_container_processes.name_ - The process path or shorthand argv[0] +* _docker_container_stats.name_ - Container name +* _docker_containers.name_ - Container name +* _docker_info.name_ - Name of the docker host +* _docker_networks.name_ - Network name +* _docker_volume_labels.name_ - Volume name +* _docker_volumes.name_ - Volume name +* _elf_sections.name_ - Section name +* _elf_segments.name_ - Segment type/name +* _elf_symbols.name_ - Symbol name +* _etc_protocols.name_ - Protocol name +* _etc_services.name_ - Service name +* _example.name_ - Description for name column +* _fan_speed_sensors.name_ - Fan name +* _fbsd_kmods.name_ - Module name +* _firefox_addons.name_ - Addon display name +* _homebrew_packages.name_ - Package name +* _ie_extensions.name_ - Extension display name +* _iokit_devicetree.name_ - Device node name +* _iokit_registry.name_ - Default name of the node +* _kernel_extensions.name_ - Extension label +* _kernel_modules.name_ - Module name +* _kernel_panics.name_ - Process name corresponding to crashed thread +* _launchd.name_ - File name of plist (used by launchd) +* _lxd_certificates.name_ - Name of the certificate +* _lxd_instance_config.name_ - Instance name +* _lxd_instance_devices.name_ - Instance name +* _lxd_instances.name_ - Instance name +* _lxd_networks.name_ - Name of the network +* _lxd_storage_pools.name_ - Name of the storage pool +* _managed_policies.name_ - Policy key name +* _md_personalities.name_ - Name of personality supported by kernel +* _memory_map.name_ - Region name +* _npm_packages.name_ - Package display name +* _ntdomains.name_ - The label by which the object is known. +* _nvram.name_ - Variable name +* _os_version.name_ - Distribution or product name +* _osquery_events.name_ - Event publisher or subscriber name +* _osquery_extensions.name_ - Extension's name +* _osquery_flags.name_ - Flag name +* _osquery_packs.name_ - The given name for this query pack +* _osquery_registry.name_ - Name of the plugin item +* _osquery_schedule.name_ - The given name for this query +* _package_install_history.name_ - Package display name +* _physical_disk_performance.name_ - Name of the physical disk +* _pipes.name_ - Name of the pipe +* _pkg_packages.name_ - Package name +* _power_sensors.name_ - Name of power source +* _processes.name_ - The process path or shorthand argv[0] +* _programs.name_ - Commonly used product name. +* _python_packages.name_ - Package display name +* _registry.name_ - Name of the registry value entry +* _rpm_packages.name_ - RPM package name +* _safari_extensions.name_ - Extension display name +* _scheduled_tasks.name_ - Name of the scheduled task +* _services.name_ - Service name +* _shared_folders.name_ - The shared name of the folder as it appears to other users +* _shared_resources.name_ - Alias given to a path set up as a share on a computer system running Windows. +* _startup_items.name_ - Name of startup item +* _system_controls.name_ - Full sysctl MIB name +* _temperature_sensors.name_ - Name of temperature source +* _windows_optional_features.name_ - Name of the feature +* _windows_security_products.name_ - Name of product +* _wmi_bios_info.name_ - Name of the Bios setting +* _wmi_cli_event_consumers.name_ - Unique name of a consumer. +* _wmi_event_filters.name_ - Unique identifier of an event filter. +* _wmi_script_event_consumers.name_ - Unique identifier for the event consumer. +* _xprotect_entries.name_ - Description of XProtected malware +* _xprotect_reports.name_ - Description of XProtected malware +* _ycloud_instance_metadata.name_ - Name of the VM +* _yum_sources.name_ - Repository name + +*name_constraints* - keyword, text.text + +* _curl_certificate.name_constraints_ - Name Constraints + +*namespace* - keyword, text.text + +* _apparmor_events.namespace_ - AppArmor namespace + +*native* - keyword, number.long + +* _browser_plugins.native_ - Plugin requires native execution +* _firefox_addons.native_ - 1 If the addon includes binary components else 0 + +*net_namespace* - keyword, text.text + +* _docker_containers.net_namespace_ - Network namespace +* _listening_ports.net_namespace_ - The inode number of the network namespace +* _process_namespaces.net_namespace_ - net namespace inode +* _process_open_sockets.net_namespace_ - The inode number of the network namespace + +*netmask* - keyword, text.text + +* _dns_resolvers.netmask_ - Address (sortlist) netmask length +* _routes.netmask_ - Netmask length + +*network_id* - keyword, text.text + +* _docker_container_networks.network_id_ - Network ID + +*network_name* - keyword, text.text + +* _wifi_networks.network_name_ - Name of the network +* _wifi_status.network_name_ - Name of the network +* _wifi_survey.network_name_ - Name of the network + +*network_rx_bytes* - keyword, number.long + +* _docker_container_stats.network_rx_bytes_ - Total network bytes read + +*network_tx_bytes* - keyword, number.long + +* _docker_container_stats.network_tx_bytes_ - Total network bytes transmitted + +*next_run_time* - keyword, number.long + +* _scheduled_tasks.next_run_time_ - Timestamp the task is scheduled to run next + +*nice* - keyword, number.long + +* _cpu_time.nice_ - Time spent in user mode with low priority (nice) +* _docker_container_processes.nice_ - Process nice level (-20 to 20, default 0) +* _processes.nice_ - Process nice level (-20 to 20, default 0) + +*no_proxy* - keyword, text.text + +* _docker_info.no_proxy_ - Comma-separated list of domain extensions proxy should not be used for + +*node* - keyword, text.text + +* _augeas.node_ - The node path of the configuration item + +*node_ref_number* - keyword, text.text + +* _ntfs_journal_events.node_ref_number_ - The ordinal that associates a journal record with a filename + +*noise* - keyword, number.long + +* _wifi_status.noise_ - The current noise measurement (dBm) +* _wifi_survey.noise_ - The current noise measurement (dBm) + +*not_valid_after* - keyword, text.text + +* _certificates.not_valid_after_ - Certificate expiration data + +*not_valid_before* - keyword, text.text + +* _certificates.not_valid_before_ - Lower bound of valid date + +*nr_raid_disks* - keyword, number.long + +* _md_devices.nr_raid_disks_ - Number of partitions or disk devices to comprise the array + +*ntime* - keyword, text.text + +* _bpf_process_events.ntime_ - The nsecs uptime timestamp as obtained from BPF +* _bpf_socket_events.ntime_ - The nsecs uptime timestamp as obtained from BPF + +*num_procs* - keyword, number.long + +* _docker_container_stats.num_procs_ - Number of processors + +*number* - keyword, number.long + +* _etc_protocols.number_ - Protocol number +* _oem_strings.number_ - The string index of the structure +* _smbios_tables.number_ - Table entry number + +*number_memory_devices* - keyword, number.long + +* _memory_arrays.number_memory_devices_ - Number of memory devices on array + +*number_of_cores* - keyword, text.text + +* _cpu_info.number_of_cores_ - The number of cores of the CPU. + +*object_name* - keyword, text.text + +* _winbaseobj.object_name_ - Object Name + +*object_path* - keyword, text.text + +* _systemd_units.object_path_ - The object path for this unit + +*object_type* - keyword, text.text + +* _winbaseobj.object_type_ - Object Type + +*obytes* - keyword, number.long + +* _interface_details.obytes_ - Output bytes + +*odrops* - keyword, number.long + +* _interface_details.odrops_ - Output drops + +*oerrors* - keyword, number.long + +* _interface_details.oerrors_ - Output errors + +*offer* - keyword, text.text + +* _azure_instance_metadata.offer_ - Offer information for the VM image (Azure image gallery VMs only) + +*offset* - keyword, number.long + +* _device_partitions.offset_ - +* _elf_sections.offset_ - Offset of section in file +* _elf_segments.offset_ - Segment offset in file +* _elf_symbols.offset_ - Section table index +* _process_memory_map.offset_ - Offset into mapped path + +*oid* - keyword, text.text + +* _system_controls.oid_ - Control MIB + +*old_path* - keyword, text.text + +* _ntfs_journal_events.old_path_ - Old path (renames only) + +*on_demand* - keyword, text.text + +* _launchd.on_demand_ - Deprecated key, replaced by keep_alive + +*on_disk* - keyword, number.long + +* _processes.on_disk_ - The process path exists yes=1, no=0, unknown=-1 + +*online_cpus* - keyword, number.long + +* _docker_container_stats.online_cpus_ - Online CPUs + +*oom_kill_disable* - keyword, number.long + +* _docker_info.oom_kill_disable_ - 1 if Out-of-memory kill is disabled. 0 otherwise + +*opackets* - keyword, number.long + +* _interface_details.opackets_ - Output packets + +*opaque_version* - keyword, text.text + +* _gatekeeper.opaque_version_ - Version of Gatekeeper's gkopaque.bundle + +*operation* - keyword, text.text + +* _apparmor_events.operation_ - Permission requested by the process +* _process_file_events.operation_ - Operation type + +*option* - keyword, text.text + +* _ad_config.option_ - Canonical name of option +* _ssh_configs.option_ - The option and value + +*option_name* - keyword, text.text + +* _cups_destinations.option_name_ - Option name + +*option_value* - keyword, text.text + +* _cups_destinations.option_value_ - Option value + +*optional* - keyword, number.long + +* _xprotect_entries.optional_ - Match any of the identities/patterns for this XProtect name + +*optional_permissions* - keyword, text.text + +* _chrome_extensions.optional_permissions_ - The permissions optionally required by the extensions + +*optional_permissions_json* - keyword, text.text + +* _chrome_extensions.optional_permissions_json_ - The JSON-encoded permissions optionally required by the extensions + +*options* - keyword + +* _dns_resolvers.options_ - Resolver options +* _nfs_shares.options_ - Options string set on the export share + +*organization* - keyword, text.text + +* _curl_certificate.organization_ - Organization issued to + +*organization_unit* - keyword, text.text + +* _curl_certificate.organization_unit_ - Organization unit issued to + +*original_parent* - keyword, number.long + +* _es_process_events.original_parent_ - Original parent process ID in case of reparenting + +*original_program_name* - keyword, text.text + +* _authenticode.original_program_name_ - The original program name that the publisher has signed + +*os* - keyword, text.text + +* _docker_info.os_ - Operating system +* _docker_version.os_ - Operating system +* _lxd_images.os_ - OS on which image is based +* _lxd_instances.os_ - The OS of this instance + +*os_type* - keyword, text.text + +* _azure_instance_metadata.os_type_ - Linux or Windows +* _docker_info.os_type_ - Operating system type + +*os_version* - keyword, text.text + +* _kernel_panics.os_version_ - Version of the operating system + +*other* - keyword, text.text + +* _md_devices.other_ - Other information associated with array from /proc/mdstat + +*other_run_times* - keyword, text.text + +* _prefetch.other_run_times_ - Other execution times in prefetch file. + +*ouid* - keyword, number.long + +* _apparmor_events.ouid_ - Object owner's user ID + +*outiface* - keyword, text.text + +* _iptables.outiface_ - Output interface for the rule. + +*outiface_mask* - keyword, text.text + +* _iptables.outiface_mask_ - Output interface mask for the rule. + +*output_bit* - keyword, number.long + +* _cpuid.output_bit_ - Bit in register value for feature value + +*output_register* - keyword, text.text + +* _cpuid.output_register_ - Register used to for feature value + +*output_size* - keyword, number.long + +* _osquery_schedule.output_size_ - Total number of bytes generated by the query + +*overflows* - keyword, text.text + +* _process_events.overflows_ - List of structures that overflowed + +*owned* - keyword, number.long + +* _tpm_info.owned_ - TPM is ownned + +*owner_gid* - keyword, number.long + +* _process_events.owner_gid_ - File owner group ID + +*owner_uid* - keyword, number.long + +* _process_events.owner_uid_ - File owner user ID +* _shared_memory.owner_uid_ - User ID of owning process + +*owner_uuid* - keyword, number.long + +* _osquery_registry.owner_uuid_ - Extension route UUID (0 for core) + +*package* - keyword, text.text + +* _portage_keywords.package_ - Package name +* _portage_packages.package_ - Package name +* _portage_use.package_ - Package name +* _rpm_package_files.package_ - RPM package name + +*package_filename* - keyword, text.text + +* _package_receipts.package_filename_ - Filename of original .pkg file + +*package_group* - keyword, text.text + +* _rpm_packages.package_group_ - Package group + +*package_id* - keyword, text.text + +* _package_install_history.package_id_ - Label packageIdentifiers +* _package_receipts.package_id_ - Package domain identifier + +*packet_device_type* - keyword, text.text + +* _smart_drive_info.packet_device_type_ - Packet device type + +*packets* - keyword, number.long + +* _iptables.packets_ - Number of matching packets for this rule. + +*packets_received* - keyword, number.long + +* _lxd_networks.packets_received_ - Number of packets received on this network + +*packets_sent* - keyword, number.long + +* _lxd_networks.packets_sent_ - Number of packets sent on this network + +*page_ins* - keyword, number.long + +* _virtual_memory_info.page_ins_ - The total number of requests for pages from a pager. + +*page_outs* - keyword, number.long + +* _virtual_memory_info.page_outs_ - Total number of pages paged out. + +*parent* - keyword + +* _apparmor_events.parent_ - Parent process PID +* _block_devices.parent_ - Block device parent name +* _bpf_process_events.parent_ - Parent process ID +* _bpf_socket_events.parent_ - Parent process ID +* _crashes.parent_ - Parent PID of the crashed process +* _docker_container_processes.parent_ - Process parent's PID +* _es_process_events.parent_ - Parent process ID +* _iokit_devicetree.parent_ - Parent device registry ID +* _iokit_registry.parent_ - Parent registry ID +* _process_events.parent_ - Process parent's PID, or -1 if cannot be determined. +* _processes.parent_ - Process parent's PID + +*parent_ref_number* - keyword, text.text + +* _ntfs_journal_events.parent_ref_number_ - The ordinal that associates a journal record with a filename's parent directory + +*part_number* - keyword, text.text + +* _memory_devices.part_number_ - Manufacturer specific serial number of memory device + +*partial* - keyword + +* _ntfs_journal_events.partial_ - Set to 1 if either path or old_path only contains the file or folder name +* _process_file_events.partial_ - True if this is a partial event (i.e.: this process existed before we started osquery) + +*partition* - keyword, text.text + +* _device_file.partition_ - A partition number +* _device_hash.partition_ - A partition number +* _device_partitions.partition_ - A partition number or description + +*partition_row_position* - keyword, number.long + +* _memory_device_mapped_addresses.partition_row_position_ - Identifies the position of the referenced memory device in a row of the address partition + +*partition_width* - keyword, number.long + +* _memory_array_mapped_addresses.partition_width_ - Number of memory devices that form a single row of memory for the address partition of this structure + +*partitions* - keyword, number.long + +* _disk_info.partitions_ - Number of detected partitions on disk. + +*partner_fd* - keyword, number.long + +* _process_open_pipes.partner_fd_ - File descriptor of shared pipe at partner's end + +*partner_mode* - keyword, text.text + +* _process_open_pipes.partner_mode_ - Mode of shared pipe at partner's end + +*partner_pid* - keyword, number.long + +* _process_open_pipes.partner_pid_ - Process ID of partner process sharing a particular pipe + +*passpoint* - keyword, number.long + +* _wifi_networks.passpoint_ - 1 if Passpoint is supported, 0 otherwise + +*password_last_set_time* - keyword, number.double + +* _account_policy_data.password_last_set_time_ - The time the password was last changed + +*password_status* - keyword, text.text + +* _shadow.password_status_ - Password status + +*patch* - keyword, number.long + +* _os_version.patch_ - Optional patch release + +*path* - keyword, text.text + +* _alf_exceptions.path_ - Path to the executable that is excepted +* _apparmor_profiles.path_ - Unique, aa-status compatible, policy identifier. +* _appcompat_shims.path_ - This is the path to the SDB database. +* _apps.path_ - Absolute and full Name.app path +* _atom_packages.path_ - Package's package.json path +* _augeas.path_ - The path to the configuration file +* _authenticode.path_ - Must provide a path or directory +* _autoexec.path_ - Path to the executable +* _background_activities_moderator.path_ - Application file path. +* _bpf_process_events.path_ - Binary path +* _bpf_socket_events.path_ - Path of executed file +* _browser_plugins.path_ - Path to plugin bundle +* _carves.path_ - The path of the requested carve +* _certificates.path_ - Path to Keychain or PEM bundle +* _chocolatey_packages.path_ - Path at which this package resides +* _chrome_extension_content_scripts.path_ - Path to extension folder +* _chrome_extensions.path_ - Path to extension folder +* _crashes.path_ - Path to the crashed process +* _crontab.path_ - File parsed +* _device_file.path_ - A logical path within the device node +* _disk_events.path_ - Path of the DMG file accessed +* _docker_container_fs_changes.path_ - FIle or directory path relative to rootfs +* _docker_containers.path_ - Container path +* _elf_dynamic.path_ - Path to ELF file +* _elf_info.path_ - Path to ELF file +* _elf_sections.path_ - Path to ELF file +* _elf_segments.path_ - Path to ELF file +* _elf_symbols.path_ - Path to ELF file +* _es_process_events.path_ - Path of executed file +* _example.path_ - Path of example +* _extended_attributes.path_ - Absolute file path +* _file.path_ - Absolute file path +* _firefox_addons.path_ - Path to plugin bundle +* _gatekeeper_approved_apps.path_ - Path of executable allowed to run +* _hardware_events.path_ - Local device path assigned (optional) +* _hash.path_ - Must provide a path or directory +* _homebrew_packages.path_ - Package install path +* _ie_extensions.path_ - Path to executable +* _kernel_extensions.path_ - Optional path to extension bundle +* _kernel_info.path_ - Kernel path +* _kernel_panics.path_ - Location of log file +* _keychain_acls.path_ - The path of the authorized application +* _keychain_items.path_ - Path to keychain containing item +* _launchd.path_ - Path to daemon or agent plist +* _launchd_overrides.path_ - Path to daemon or agent plist +* _listening_ports.path_ - Path for UNIX domain sockets +* _magic.path_ - Absolute path to target file +* _mdfind.path_ - Path of the file returned from spotlight +* _mdls.path_ - Path of the file +* _mounts.path_ - Mounted device path +* _npm_packages.path_ - Module's package.json path +* _ntfs_acl_permissions.path_ - Path to the file or directory. +* _ntfs_journal_events.path_ - Path +* _office_mru.path_ - File path +* _osquery_extensions.path_ - Path of the extension's Thrift connection or library path +* _package_bom.path_ - Path of package bom +* _package_receipts.path_ - Path of receipt plist +* _plist.path_ - (required) read preferences from a plist +* _prefetch.path_ - Prefetch file path. +* _process_events.path_ - Path of executed file +* _process_file_events.path_ - The path associated with the event +* _process_memory_map.path_ - Path to mapped file or mapped type +* _process_open_files.path_ - Filesystem path of descriptor +* _process_open_sockets.path_ - For UNIX sockets (family=AF_UNIX), the domain path +* _processes.path_ - Path to executed binary +* _python_packages.path_ - Path at which this module resides +* _quicklook_cache.path_ - Path of file +* _registry.path_ - Full path to the value +* _rpm_package_files.path_ - File path within the package +* _safari_extensions.path_ - Path to extension XAR bundle +* _sandboxes.path_ - Path to sandbox container directory +* _scheduled_tasks.path_ - Path to the executable to be run +* _services.path_ - Path to Service Executable +* _shared_folders.path_ - Absolute path of shared folder on the local system +* _shared_resources.path_ - Local path of the Windows share. +* _shellbags.path_ - Directory name. +* _shimcache.path_ - This is the path to the executed file. +* _shortcut_files.path_ - Directory name. +* _signature.path_ - Must provide a path or directory +* _socket_events.path_ - Path of executed file +* _startup_items.path_ - Path of startup item +* _suid_bin.path_ - Binary path +* _system_extensions.path_ - Original path of system extension +* _user_events.path_ - Supplied path from event +* _user_ssh_keys.path_ - Path to key file +* _userassist.path_ - Application file path. +* _windows_crashes.path_ - Path of the executable file for the crashed process +* _yara.path_ - The path scanned + +*pci_class* - keyword, text.text + +* _pci_devices.pci_class_ - PCI Device class + +*pci_class_id* - keyword, text.text + +* _pci_devices.pci_class_id_ - PCI Device class ID in hex format + +*pci_slot* - keyword, text.text + +* _interface_details.pci_slot_ - PCI slot number +* _pci_devices.pci_slot_ - PCI Device used slot + +*pci_subclass* - keyword, text.text + +* _pci_devices.pci_subclass_ - PCI Device subclass + +*pci_subclass_id* - keyword, text.text + +* _pci_devices.pci_subclass_id_ - PCI Device subclass in hex format + +*pem* - keyword, text.text + +* _curl_certificate.pem_ - Certificate PEM format + +*percent_disk_read_time* - keyword, number.long + +* _physical_disk_performance.percent_disk_read_time_ - Percentage of elapsed time that the selected disk drive is busy servicing read requests + +*percent_disk_time* - keyword, number.long + +* _physical_disk_performance.percent_disk_time_ - Percentage of elapsed time that the selected disk drive is busy servicing read or write requests + +*percent_disk_write_time* - keyword, number.long + +* _physical_disk_performance.percent_disk_write_time_ - Percentage of elapsed time that the selected disk drive is busy servicing write requests + +*percent_idle_time* - keyword, number.long + +* _physical_disk_performance.percent_idle_time_ - Percentage of time during the sample interval that the disk was idle + +*percent_processor_time* - keyword, number.long + +* _processes.percent_processor_time_ - Returns elapsed time that all of the threads of this process used the processor to execute instructions in 100 nanoseconds ticks. + +*percent_remaining* - keyword, number.long + +* _battery.percent_remaining_ - The percentage of battery remaining before it is drained + +*percentage_encrypted* - keyword, number.long + +* _bitlocker_info.percentage_encrypted_ - The percentage of the drive that is encrypted. + +*perf_ctl* - keyword, number.long + +* _msr.perf_ctl_ - Performance setting for the processor. + +*perf_status* - keyword, number.long + +* _msr.perf_status_ - Performance status for the processor. + +*period* - keyword, text.text + +* _load_average.period_ - Period over which the average is calculated. + +*permanent* - keyword, text.text + +* _arp_cache.permanent_ - 1 for true, 0 for false + +*permissions* - keyword, text.text + +* _chrome_extensions.permissions_ - The permissions required by the extension +* _process_memory_map.permissions_ - r=read, w=write, x=execute, p=private (cow) +* _shared_memory.permissions_ - Memory segment permissions +* _suid_bin.permissions_ - Binary permissions + +*permissions_json* - keyword, text.text + +* _chrome_extensions.permissions_json_ - The JSON-encoded permissions required by the extension + +*persistent* - keyword, number.long + +* _chrome_extensions.persistent_ - 1 If extension is persistent across all tabs else 0 + +*persistent_volume_id* - keyword, text.text + +* _bitlocker_info.persistent_volume_id_ - Persistent ID of the drive. + +*pgroup* - keyword, number.long + +* _docker_container_processes.pgroup_ - Process group +* _processes.pgroup_ - Process group + +*physical_adapter* - keyword, number.long + +* _interface_details.physical_adapter_ - Indicates whether the adapter is a physical or a logical adapter. + +*physical_memory* - keyword, number.long + +* _system_info.physical_memory_ - Total physical memory in bytes + +*physical_presence_version* - keyword, text.text + +* _tpm_info.physical_presence_version_ - Version of the Physical Presence Interface + +*pid* - keyword, number.long + +* _apparmor_events.pid_ - Process ID +* _asl.pid_ - Sending process ID encoded as a string. Set automatically. +* _bpf_process_events.pid_ - Process ID +* _bpf_socket_events.pid_ - Process ID +* _crashes.pid_ - Process (or thread) ID of the crashed process +* _docker_container_processes.pid_ - Process ID +* _docker_containers.pid_ - Identifier of the initial process +* _es_process_events.pid_ - Process (or thread) ID +* _last.pid_ - Process (or thread) ID +* _listening_ports.pid_ - Process (or thread) ID +* _logged_in_users.pid_ - Process (or thread) ID +* _lxd_instances.pid_ - Instance's process ID +* _osquery_info.pid_ - Process (or thread/handle) ID +* _pipes.pid_ - Process ID of the process to which the pipe belongs +* _process_envs.pid_ - Process (or thread) ID +* _process_events.pid_ - Process (or thread) ID +* _process_file_events.pid_ - Process ID +* _process_memory_map.pid_ - Process (or thread) ID +* _process_namespaces.pid_ - Process (or thread) ID +* _process_open_files.pid_ - Process (or thread) ID +* _process_open_pipes.pid_ - Process ID +* _process_open_sockets.pid_ - Process (or thread) ID +* _processes.pid_ - Process (or thread) ID +* _running_apps.pid_ - The pid of the application +* _seccomp_events.pid_ - Process ID +* _services.pid_ - the Process ID of the service +* _shared_memory.pid_ - Process ID to last use the segment +* _socket_events.pid_ - Process (or thread) ID +* _user_events.pid_ - Process (or thread) ID +* _windows_crashes.pid_ - Process ID of the crashed process +* _windows_eventlog.pid_ - Process ID which emitted the event record + +*pid_namespace* - keyword, text.text + +* _docker_containers.pid_namespace_ - PID namespace +* _process_namespaces.pid_namespace_ - pid namespace inode + +*pid_with_namespace* - keyword, number.long + +* _apt_sources.pid_with_namespace_ - Pids that contain a namespace +* _authorized_keys.pid_with_namespace_ - Pids that contain a namespace +* _crontab.pid_with_namespace_ - Pids that contain a namespace +* _deb_packages.pid_with_namespace_ - Pids that contain a namespace +* _dns_resolvers.pid_with_namespace_ - Pids that contain a namespace +* _etc_hosts.pid_with_namespace_ - Pids that contain a namespace +* _file.pid_with_namespace_ - Pids that contain a namespace +* _groups.pid_with_namespace_ - Pids that contain a namespace +* _hash.pid_with_namespace_ - Pids that contain a namespace +* _npm_packages.pid_with_namespace_ - Pids that contain a namespace +* _os_version.pid_with_namespace_ - Pids that contain a namespace +* _python_packages.pid_with_namespace_ - Pids that contain a namespace +* _rpm_packages.pid_with_namespace_ - Pids that contain a namespace +* _suid_bin.pid_with_namespace_ - Pids that contain a namespace +* _user_ssh_keys.pid_with_namespace_ - Pids that contain a namespace +* _users.pid_with_namespace_ - Pids that contain a namespace +* _yum_sources.pid_with_namespace_ - Pids that contain a namespace + +*pids* - keyword + +* _docker_container_stats.pids_ - Number of processes +* _lldp_neighbors.pids_ - Comma delimited list of PIDs + +*placement_group_id* - keyword, text.text + +* _azure_instance_metadata.placement_group_id_ - Placement group for the VM scale set + +*platform* - keyword, text.text + +* _os_version.platform_ - OS Platform or ID +* _osquery_packs.platform_ - Platforms this query is supported on + +*platform_binary* - keyword, number.long + +* _es_process_events.platform_binary_ - Indicates if the binary is Apple signed binary (1) or not (0) + +*platform_fault_domain* - keyword, text.text + +* _azure_instance_metadata.platform_fault_domain_ - Fault domain the VM is running in + +*platform_info* - keyword, number.long + +* _msr.platform_info_ - Platform information. + +*platform_like* - keyword, text.text + +* _os_version.platform_like_ - Closely related platforms + +*platform_mask* - keyword, number.long + +* _osquery_info.platform_mask_ - The osquery platform bitmask + +*platform_update_domain* - keyword, text.text + +* _azure_instance_metadata.platform_update_domain_ - Update domain the VM is running in + +*plugin* - keyword, text.text + +* _authorization_mechanisms.plugin_ - Authorization plugin name + +*pnp_device_id* - keyword, text.text + +* _disk_info.pnp_device_id_ - The unique identifier of the drive on the system. + +*point_to_point* - keyword, text.text + +* _interface_addresses.point_to_point_ - PtP address for the interface + +*points* - keyword, number.long + +* _example.points_ - This is a signed SQLite int column + +*policies* - keyword, text.text + +* _curl_certificate.policies_ - Certificate Policies + +*policy* - keyword, text.text + +* _iptables.policy_ - Policy that applies for this rule. + +*policy_constraints* - keyword, text.text + +* _curl_certificate.policy_constraints_ - Policy Constraints + +*policy_mappings* - keyword, text.text + +* _curl_certificate.policy_mappings_ - Policy Mappings + +*port* - keyword, number.long + +* _docker_container_ports.port_ - Port inside the container +* _etc_services.port_ - Service port number +* _listening_ports.port_ - Transport layer port + +*port_aggregation_id* - keyword, text.text + +* _lldp_neighbors.port_aggregation_id_ - Port aggregation ID + +*port_autoneg_1000baset_fd_enabled* - keyword, number.long + +* _lldp_neighbors.port_autoneg_1000baset_fd_enabled_ - 1000Base-T FD auto negotiation enabled + +*port_autoneg_1000baset_hd_enabled* - keyword, number.long + +* _lldp_neighbors.port_autoneg_1000baset_hd_enabled_ - 1000Base-T HD auto negotiation enabled + +*port_autoneg_1000basex_fd_enabled* - keyword, number.long + +* _lldp_neighbors.port_autoneg_1000basex_fd_enabled_ - 1000Base-X FD auto negotiation enabled + +*port_autoneg_1000basex_hd_enabled* - keyword, number.long + +* _lldp_neighbors.port_autoneg_1000basex_hd_enabled_ - 1000Base-X HD auto negotiation enabled + +*port_autoneg_100baset2_fd_enabled* - keyword, number.long + +* _lldp_neighbors.port_autoneg_100baset2_fd_enabled_ - 100Base-T2 FD auto negotiation enabled + +*port_autoneg_100baset2_hd_enabled* - keyword, number.long + +* _lldp_neighbors.port_autoneg_100baset2_hd_enabled_ - 100Base-T2 HD auto negotiation enabled + +*port_autoneg_100baset4_fd_enabled* - keyword, number.long + +* _lldp_neighbors.port_autoneg_100baset4_fd_enabled_ - 100Base-T4 FD auto negotiation enabled + +*port_autoneg_100baset4_hd_enabled* - keyword, number.long + +* _lldp_neighbors.port_autoneg_100baset4_hd_enabled_ - 100Base-T4 HD auto negotiation enabled + +*port_autoneg_100basetx_fd_enabled* - keyword, number.long + +* _lldp_neighbors.port_autoneg_100basetx_fd_enabled_ - 100Base-TX FD auto negotiation enabled + +*port_autoneg_100basetx_hd_enabled* - keyword, number.long + +* _lldp_neighbors.port_autoneg_100basetx_hd_enabled_ - 100Base-TX HD auto negotiation enabled + +*port_autoneg_10baset_fd_enabled* - keyword, number.long + +* _lldp_neighbors.port_autoneg_10baset_fd_enabled_ - 10Base-T FD auto negotiation enabled + +*port_autoneg_10baset_hd_enabled* - keyword, number.long + +* _lldp_neighbors.port_autoneg_10baset_hd_enabled_ - 10Base-T HD auto negotiation enabled + +*port_autoneg_enabled* - keyword, number.long + +* _lldp_neighbors.port_autoneg_enabled_ - Is auto negotiation enabled + +*port_autoneg_supported* - keyword, number.long + +* _lldp_neighbors.port_autoneg_supported_ - Auto negotiation supported + +*port_description* - keyword, text.text + +* _lldp_neighbors.port_description_ - Port description + +*port_id* - keyword, text.text + +* _lldp_neighbors.port_id_ - Port ID value + +*port_id_type* - keyword, text.text + +* _lldp_neighbors.port_id_type_ - Port ID type + +*port_mau_type* - keyword, text.text + +* _lldp_neighbors.port_mau_type_ - MAU type + +*port_mfs* - keyword, number.long + +* _lldp_neighbors.port_mfs_ - Port max frame size + +*port_ttl* - keyword, number.long + +* _lldp_neighbors.port_ttl_ - Age of neighbor port + +*possibly_hidden* - keyword, number.long + +* _wifi_networks.possibly_hidden_ - 1 if network is possibly a hidden network, 0 otherwise + +*power_8023at_enabled* - keyword, number.long + +* _lldp_neighbors.power_8023at_enabled_ - Is 802.3at enabled + +*power_8023at_power_allocated* - keyword, text.text + +* _lldp_neighbors.power_8023at_power_allocated_ - 802.3at power allocated + +*power_8023at_power_priority* - keyword, text.text + +* _lldp_neighbors.power_8023at_power_priority_ - 802.3at power priority + +*power_8023at_power_requested* - keyword, text.text + +* _lldp_neighbors.power_8023at_power_requested_ - 802.3at power requested + +*power_8023at_power_source* - keyword, text.text + +* _lldp_neighbors.power_8023at_power_source_ - 802.3at power source + +*power_8023at_power_type* - keyword, text.text + +* _lldp_neighbors.power_8023at_power_type_ - 802.3at power type + +*power_class* - keyword, text.text + +* _lldp_neighbors.power_class_ - Power class + +*power_device_type* - keyword, text.text + +* _lldp_neighbors.power_device_type_ - Dot3 power device type + +*power_mdi_enabled* - keyword, number.long + +* _lldp_neighbors.power_mdi_enabled_ - Is MDI power enabled + +*power_mdi_supported* - keyword, number.long + +* _lldp_neighbors.power_mdi_supported_ - MDI power supported + +*power_mode* - keyword, text.text + +* _smart_drive_info.power_mode_ - Device power mode + +*power_paircontrol_enabled* - keyword, number.long + +* _lldp_neighbors.power_paircontrol_enabled_ - Is power pair control enabled + +*power_pairs* - keyword, text.text + +* _lldp_neighbors.power_pairs_ - Dot3 power pairs + +*ppid* - keyword, number.long + +* _process_file_events.ppid_ - Parent process ID + +*ppvids_enabled* - keyword, text.text + +* _lldp_neighbors.ppvids_enabled_ - Comma delimited list of enabled PPVIDs + +*ppvids_supported* - keyword, text.text + +* _lldp_neighbors.ppvids_supported_ - Comma delimited list of supported PPVIDs + +*pre_cpu_kernelmode_usage* - keyword, number.long + +* _docker_container_stats.pre_cpu_kernelmode_usage_ - Last read CPU kernel mode usage + +*pre_cpu_total_usage* - keyword, number.long + +* _docker_container_stats.pre_cpu_total_usage_ - Last read total CPU usage + +*pre_cpu_usermode_usage* - keyword, number.long + +* _docker_container_stats.pre_cpu_usermode_usage_ - Last read CPU user mode usage + +*pre_online_cpus* - keyword, number.long + +* _docker_container_stats.pre_online_cpus_ - Last read online CPUs + +*pre_system_cpu_usage* - keyword, number.long + +* _docker_container_stats.pre_system_cpu_usage_ - Last read CPU system usage + +*prefix* - keyword, text.text + +* _homebrew_packages.prefix_ - Homebrew install prefix + +*preread* - keyword, number.long + +* _docker_container_stats.preread_ - UNIX time when stats were last read + +*principal* - keyword, text.text + +* _ntfs_acl_permissions.principal_ - User or group to which the ACE applies. + +*printer_sharing* - keyword, number.long + +* _sharing_preferences.printer_sharing_ - 1 If printer sharing is enabled else 0 + +*priority* - keyword, text.text + +* _deb_packages.priority_ - Package priority + +*privileged* - keyword, text.text + +* _authorization_mechanisms.privileged_ - If privileged it will run as root, else as an anonymous user +* _docker_containers.privileged_ - Is the container privileged + +*probe_error* - keyword, number.long + +* _bpf_process_events.probe_error_ - Set to 1 if one or more buffers could not be captured +* _bpf_socket_events.probe_error_ - Set to 1 if one or more buffers could not be captured + +*process* - keyword, text.text + +* _alf_explicit_auths.process_ - Process name explicitly allowed + +*process_being_tapped* - keyword, number.long + +* _event_taps.process_being_tapped_ - The process ID of the target application + +*process_type* - keyword, text.text + +* _launchd.process_type_ - Key describes the intended purpose of the job + +*process_uptime* - keyword, number.long + +* _windows_crashes.process_uptime_ - Uptime of the process in seconds + +*processes* - keyword, number.long + +* _lxd_instances.processes_ - Number of processes running inside this instance + +*processing_time* - keyword, number.long + +* _cups_jobs.processing_time_ - How long the job took to process + +*processor_number* - keyword, number.long + +* _msr.processor_number_ - The processor number as reported in /proc/cpuinfo + +*processor_type* - keyword, text.text + +* _cpu_info.processor_type_ - The processor type, such as Central, Math, or Video. + +*product_name* - keyword, text.text + +* _tpm_info.product_name_ - Product name of the TPM + +*product_version* - keyword, text.text + +* _file.product_version_ - File product version + +*profile* - keyword, text.text + +* _apparmor_events.profile_ - Apparmor profile name +* _chrome_extensions.profile_ - The name of the Chrome profile that contains this extension + +*profile_path* - keyword, text.text + +* _chrome_extension_content_scripts.profile_path_ - The profile path +* _chrome_extensions.profile_path_ - The profile path +* _logon_sessions.profile_path_ - The home directory for the logon session. + +*program* - keyword, text.text + +* _launchd.program_ - Path to target program + +*program_arguments* - keyword, text.text + +* _launchd.program_arguments_ - Command line arguments passed to program + +*propagation* - keyword, text.text + +* _docker_container_mounts.propagation_ - Mount propagation + +*protected* - keyword, number.long + +* _app_schemes.protected_ - 1 if this handler is protected (reserved) by OS X, else 0 + +*protection_disabled* - keyword, number.long + +* _carbon_black_info.protection_disabled_ - If the sensor is configured to report tamper events + +*protection_status* - keyword, number.long + +* _bitlocker_info.protection_status_ - The bitlocker protection status of the drive. + +*protection_type* - keyword, text.text + +* _processes.protection_type_ - The protection type of the process + +*protocol* - keyword + +* _bpf_socket_events.protocol_ - The network protocol ID +* _etc_services.protocol_ - Transport protocol (TCP/UDP) +* _iptables.protocol_ - Protocol number identification. +* _listening_ports.protocol_ - Transport protocol (TCP/UDP) +* _process_open_sockets.protocol_ - Transport protocol (TCP/UDP) +* _socket_events.protocol_ - The network protocol ID +* _usb_devices.protocol_ - USB Device protocol + +*provider* - keyword, text.text + +* _drivers.provider_ - Driver provider + +*provider_guid* - keyword, text.text + +* _windows_eventlog.provider_guid_ - Provider guid of the event +* _windows_events.provider_guid_ - Provider guid of the event + +*provider_name* - keyword, text.text + +* _windows_eventlog.provider_name_ - Provider name of the event +* _windows_events.provider_name_ - Provider name of the event + +*pseudo* - keyword, number.long + +* _process_memory_map.pseudo_ - 1 If path is a pseudo path, else 0 + +*psize* - keyword, number.long + +* _elf_segments.psize_ - Size of segment in file + +*public* - keyword, number.long + +* _lxd_images.public_ - Whether image is public (1) or not (0) + +*publisher* - keyword, text.text + +* _azure_instance_metadata.publisher_ - Publisher of the VM image +* _osquery_events.publisher_ - Name of the associated publisher +* _programs.publisher_ - Name of the product supplier. + +*purgeable* - keyword, number.long + +* _virtual_memory_info.purgeable_ - Total number of purgeable pages. + +*purged* - keyword, number.long + +* _virtual_memory_info.purged_ - Total number of purged pages. + +*pvid* - keyword, text.text + +* _lldp_neighbors.pvid_ - Primary VLAN id + +*query* - keyword, text.text + +* _mdfind.query_ - The query that was run to find the file +* _osquery_schedule.query_ - The exact query to run +* _wmi_event_filters.query_ - Windows Management Instrumentation Query Language (WQL) event query that specifies the set of events for consumer notification, and the specific conditions for notification. + +*query_language* - keyword, text.text + +* _wmi_event_filters.query_language_ - Query language that the query is written in. + +*queue_directories* - keyword, text.text + +* _launchd.queue_directories_ - Similar to watch_paths but only with non-empty directories + +*raid_disks* - keyword, number.long + +* _md_devices.raid_disks_ - Number of configured RAID disks in array + +*raid_level* - keyword, number.long + +* _md_devices.raid_level_ - Current raid level of the array + +*rapl_energy_status* - keyword, number.long + +* _msr.rapl_energy_status_ - Run Time Average Power Limiting energy status. + +*rapl_power_limit* - keyword, number.long + +* _msr.rapl_power_limit_ - Run Time Average Power Limiting power limit. + +*rapl_power_units* - keyword, number.long + +* _msr.rapl_power_units_ - Run Time Average Power Limiting power units. + +*reactivated* - keyword, number.long + +* _virtual_memory_info.reactivated_ - Total number of reactivated pages. + +*read* - keyword, number.long + +* _docker_container_stats.read_ - UNIX time when stats were read + +*read_device_identity_failure* - keyword, text.text + +* _smart_drive_info.read_device_identity_failure_ - Error string for device id read, if any + +*readonly* - keyword, number.long + +* _nfs_shares.readonly_ - 1 if the share is exported readonly else 0 + +*readonly_rootfs* - keyword, number.long + +* _docker_containers.readonly_rootfs_ - Is the root filesystem mounted as read only + +*record_timestamp* - keyword, text.text + +* _ntfs_journal_events.record_timestamp_ - Journal record timestamp + +*record_usn* - keyword, text.text + +* _ntfs_journal_events.record_usn_ - The update sequence number that identifies the journal record + +*recovery_finish* - keyword, text.text + +* _md_devices.recovery_finish_ - Estimated duration of recovery activity + +*recovery_progress* - keyword, text.text + +* _md_devices.recovery_progress_ - Progress of the recovery activity + +*recovery_speed* - keyword, text.text + +* _md_devices.recovery_speed_ - Speed of recovery activity + +*redirect_accept* - keyword, number.long + +* _interface_ipv6.redirect_accept_ - Accept ICMP redirect messages + +*ref_pid* - keyword, number.long + +* _asl.ref_pid_ - Reference PID for messages proxied by launchd + +*ref_proc* - keyword, text.text + +* _asl.ref_proc_ - Reference process for messages proxied by launchd + +*referenced* - keyword, number.long + +* _chrome_extension_content_scripts.referenced_ - 1 if this extension is referenced by the Preferences file of the profile +* _chrome_extensions.referenced_ - 1 if this extension is referenced by the Preferences file of the profile + +*referenced_identifier* - keyword, text.text + +* _chrome_extensions.referenced_identifier_ - Extension identifier, as specified by the preferences file. Empty if the extension is not in the profile. + +*refreshes* - keyword, number.long + +* _osquery_events.refreshes_ - Publisher only: number of runloop restarts + +*refs* - keyword, number.long + +* _fbsd_kmods.refs_ - Module reverse dependencies +* _kernel_extensions.refs_ - Reference count + +*region* - keyword, text.text + +* _ec2_instance_metadata.region_ - AWS region in which this instance launched + +*registers* - keyword, text.text + +* _crashes.registers_ - The value of the system registers +* _kernel_panics.registers_ - A space delimited line of register:value pairs +* _windows_crashes.registers_ - The values of the system registers + +*registry* - keyword, text.text + +* _osquery_registry.registry_ - Name of the osquery registry + +*registry_hive* - keyword, text.text + +* _logged_in_users.registry_hive_ - HKEY_USERS registry hive + +*registry_path* - keyword, text.text + +* _ie_extensions.registry_path_ - Extension identifier + +*relative_path* - keyword, text.text + +* _shortcut_files.relative_path_ - Relative path to target file from lnk file. +* _wmi_cli_event_consumers.relative_path_ - Relative path to the class or instance. +* _wmi_event_filters.relative_path_ - Relative path to the class or instance. +* _wmi_filter_consumer_binding.relative_path_ - Relative path to the class or instance. +* _wmi_script_event_consumers.relative_path_ - Relative path to the class or instance. + +*release* - keyword, text.text + +* _apt_sources.release_ - Release name +* _lxd_images.release_ - OS release version on which the image is based +* _rpm_packages.release_ - Package release + +*remediation_path* - keyword, text.text + +* _windows_security_products.remediation_path_ - Remediation path + +*remote_address* - keyword, text.text + +* _bpf_socket_events.remote_address_ - Remote address associated with socket +* _process_open_sockets.remote_address_ - Socket remote address +* _socket_events.remote_address_ - Remote address associated with socket + +*remote_apple_events* - keyword, number.long + +* _sharing_preferences.remote_apple_events_ - 1 If remote apple events are enabled else 0 + +*remote_login* - keyword, number.long + +* _sharing_preferences.remote_login_ - 1 If remote login is enabled else 0 + +*remote_management* - keyword, number.long + +* _sharing_preferences.remote_management_ - 1 If remote management is enabled else 0 + +*remote_port* - keyword, number.long + +* _bpf_socket_events.remote_port_ - Remote network protocol port number +* _process_open_sockets.remote_port_ - Socket remote port +* _socket_events.remote_port_ - Remote network protocol port number + +*removable* - keyword, number.long + +* _usb_devices.removable_ - 1 If USB device is removable else 0 + +*repository* - keyword, text.text + +* _portage_packages.repository_ - From which repository the ebuild was used + +*request_id* - keyword, text.text + +* _carves.request_id_ - Identifying value of the carve request (e.g., scheduled query name, distributed request, etc) + +*requested_mask* - keyword, text.text + +* _apparmor_events.requested_mask_ - Requested access mask + +*requirement* - keyword, text.text + +* _gatekeeper_approved_apps.requirement_ - Code signing requirement language + +*reservation_id* - keyword, text.text + +* _ec2_instance_metadata.reservation_id_ - ID of the reservation + +*reshape_finish* - keyword, text.text + +* _md_devices.reshape_finish_ - Estimated duration of reshape activity + +*reshape_progress* - keyword, text.text + +* _md_devices.reshape_progress_ - Progress of the reshape activity + +*reshape_speed* - keyword, text.text + +* _md_devices.reshape_speed_ - Speed of reshape activity + +*resident_size* - keyword, number.long + +* _docker_container_processes.resident_size_ - Bytes of private memory used by process +* _processes.resident_size_ - Bytes of private memory used by process + +*resource_group_name* - keyword, text.text + +* _azure_instance_metadata.resource_group_name_ - Resource group for the VM + +*response_code* - keyword, number.long + +* _curl.response_code_ - The HTTP status code for the response + +*responsible* - keyword, text.text + +* _crashes.responsible_ - Process responsible for the crashed process + +*result* - keyword, text.text + +* _authenticode.result_ - The signature check result +* _curl.result_ - The HTTP response body + +*resync_finish* - keyword, text.text + +* _md_devices.resync_finish_ - Estimated duration of resync activity + +*resync_progress* - keyword, text.text + +* _md_devices.resync_progress_ - Progress of the resync activity + +*resync_speed* - keyword, text.text + +* _md_devices.resync_speed_ - Speed of resync activity + +*retain_count* - keyword, number.long + +* _iokit_devicetree.retain_count_ - The device reference count +* _iokit_registry.retain_count_ - The node reference count + +*revision* - keyword, text.text + +* _deb_packages.revision_ - Package revision +* _hardware_events.revision_ - Device revision (optional) +* _platform_info.revision_ - BIOS major and minor revision + +*rid* - keyword, number.long + +* _lldp_neighbors.rid_ - Neighbor chassis index + +*roaming* - keyword, number.long + +* _wifi_networks.roaming_ - 1 if roaming is supported, 0 otherwise + +*roaming_profile* - keyword, text.text + +* _wifi_networks.roaming_profile_ - Describe the roaming profile, usually one of Single, Dual or Multi + +*root* - keyword, text.text + +* _processes.root_ - Process virtual root directory + +*root_dir* - keyword, text.text + +* _docker_info.root_dir_ - Docker root directory + +*root_directory* - keyword, text.text + +* _launchd.root_directory_ - Key used to specify a directory to chroot to before launch + +*root_volume_uuid* - keyword, text.text + +* _time_machine_destinations.root_volume_uuid_ - Root UUID of backup volume + +*rotation_rate* - keyword, text.text + +* _smart_drive_info.rotation_rate_ - Drive RPM + +*round_trip_time* - keyword, number.long + +* _curl.round_trip_time_ - Time taken to complete the request + +*rowid* - keyword, number.long + +* _quicklook_cache.rowid_ - Quicklook file rowid key + +*rssi* - keyword, number.long + +* _wifi_status.rssi_ - The current received signal strength indication (dbm) +* _wifi_survey.rssi_ - The current received signal strength indication (dbm) + +*rtadv_accept* - keyword, number.long + +* _interface_ipv6.rtadv_accept_ - Accept ICMP Router Advertisement + +*rule_details* - keyword, text.text + +* _sudoers.rule_details_ - Rule definition + +*run_at_load* - keyword, text.text + +* _launchd.run_at_load_ - Should the program run on launch load + +*run_count* - keyword, number.long + +* _prefetch.run_count_ - Number of times the application has been run. + +*rw* - keyword, number.long + +* _docker_container_mounts.rw_ - 1 if read/write. 0 otherwise + +*sata_version* - keyword, text.text + +* _smart_drive_info.sata_version_ - SATA version, if any + +*scheme* - keyword, text.text + +* _app_schemes.scheme_ - Name of the scheme/protocol + +*scope* - keyword, text.text + +* _selinux_settings.scope_ - Where the key is located inside the SELinuxFS mount point. + +*screen_sharing* - keyword, number.long + +* _sharing_preferences.screen_sharing_ - 1 If screen sharing is enabled else 0 + +*script* - keyword, text.text + +* _chrome_extension_content_scripts.script_ - The content script used by the extension + +*script_block_count* - keyword, number.long + +* _powershell_events.script_block_count_ - The total number of script blocks for this script + +*script_block_id* - keyword, text.text + +* _powershell_events.script_block_id_ - The unique GUID of the powershell script to which this block belongs + +*script_file_name* - keyword, text.text + +* _wmi_script_event_consumers.script_file_name_ - Name of the file from which the script text is read, intended as an alternative to specifying the text of the script in the ScriptText property. + +*script_name* - keyword, text.text + +* _powershell_events.script_name_ - The name of the Powershell script + +*script_path* - keyword, text.text + +* _powershell_events.script_path_ - The path for the Powershell script + +*script_text* - keyword, text.text + +* _powershell_events.script_text_ - The text content of the Powershell script +* _wmi_script_event_consumers.script_text_ - Text of the script that is expressed in a language known to the scripting engine. This property must be NULL if the ScriptFileName property is not NULL. + +*scripting_engine* - keyword, text.text + +* _wmi_script_event_consumers.scripting_engine_ - Name of the scripting engine to use, for example, 'VBScript'. This property cannot be NULL. + +*sdb_id* - keyword, text.text + +* _appcompat_shims.sdb_id_ - Unique GUID of the SDB. + +*sdk* - keyword, text.text + +* _browser_plugins.sdk_ - Build SDK used to compile plugin +* _safari_extensions.sdk_ - Bundle SDK used to compile extension + +*sdk_version* - keyword, text.text + +* _osquery_extensions.sdk_version_ - osquery SDK version used to build the extension + +*seconds* - keyword, number.long + +* _time.seconds_ - Current seconds in the system +* _uptime.seconds_ - Seconds of uptime + +*section* - keyword, text.text + +* _deb_packages.section_ - Package section + +*sector_sizes* - keyword, text.text + +* _smart_drive_info.sector_sizes_ - Bytes of drive sector sizes + +*secure_boot* - keyword, number.long + +* _secureboot.secure_boot_ - Whether secure boot is enabled + +*secure_process* - keyword, number.long + +* _processes.secure_process_ - Process is secure (IUM) yes=1, no=0 + +*security_breach* - keyword, text.text + +* _chassis_info.security_breach_ - The physical status of the chassis such as Breach Successful, Breach Attempted, etc. + +*security_groups* - keyword, text.text + +* _ec2_instance_metadata.security_groups_ - Comma separated list of security group names + +*security_options* - keyword, text.text + +* _docker_containers.security_options_ - List of container security options + +*security_type* - keyword, text.text + +* _wifi_networks.security_type_ - Type of security on this network +* _wifi_status.security_type_ - Type of security on this network + +*self_signed* - keyword, number.long + +* _certificates.self_signed_ - 1 if self-signed, else 0 + +*sender* - keyword, text.text + +* _asl.sender_ - Sender's identification string. Default is process name. + +*sensor_backend_server* - keyword, text.text + +* _carbon_black_info.sensor_backend_server_ - Carbon Black server + +*sensor_id* - keyword, number.long + +* _carbon_black_info.sensor_id_ - Sensor ID of the Carbon Black sensor + +*sensor_ip_addr* - keyword, text.text + +* _carbon_black_info.sensor_ip_addr_ - IP address of the sensor + +*seq_num* - keyword, number.long + +* _es_process_events.seq_num_ - Per event sequence number + +*serial* - keyword, text.text + +* _certificates.serial_ - Certificate serial number +* _chassis_info.serial_ - The serial number of the chassis. +* _disk_info.serial_ - The serial number of the disk. +* _hardware_events.serial_ - Device serial (optional) +* _usb_devices.serial_ - USB Device serial connection + +*serial_number* - keyword, text.text + +* _authenticode.serial_number_ - The certificate serial number +* _battery.serial_number_ - The battery's unique serial number +* _curl_certificate.serial_number_ - Certificate serial number +* _memory_devices.serial_number_ - Serial number of memory device +* _smart_drive_info.serial_number_ - Device serial number + +*serial_port_enabled* - keyword, text.text + +* _ycloud_instance_metadata.serial_port_enabled_ - Indicates if serial port is enabled for the VM + +*series* - keyword, text.text + +* _video_info.series_ - The series of the gpu. + +*server_name* - keyword, text.text + +* _lxd_cluster.server_name_ - Name of the LXD server node +* _lxd_cluster_members.server_name_ - Name of the LXD server node + +*server_version* - keyword, text.text + +* _docker_info.server_version_ - Server version + +*service* - keyword, text.text + +* _drivers.service_ - Driver service name, if one exists +* _interface_details.service_ - The name of the service the network adapter uses. +* _iokit_devicetree.service_ - 1 if the device conforms to IOService else 0 + +*service_exit_code* - keyword, number.long + +* _services.service_exit_code_ - The service-specific error code that the service returns when an error occurs while the service is starting or stopping + +*service_key* - keyword, text.text + +* _drivers.service_key_ - Driver service registry key + +*service_type* - keyword, text.text + +* _services.service_type_ - Service Type: OWN_PROCESS, SHARE_PROCESS and maybe Interactive (can interact with the desktop) + +*ses* - keyword, number.long + +* _seccomp_events.ses_ - Session ID of the session from which the analyzed process was invoked + +*session_id* - keyword, number.long + +* _logon_sessions.session_id_ - The Terminal Services session identifier. +* _winbaseobj.session_id_ - Terminal Services Session Id + +*session_owner* - keyword, text.text + +* _authorizations.session_owner_ - Label top-level key + +*set* - keyword, number.long + +* _memory_devices.set_ - Identifies if memory device is one of a set of devices. A value of 0 indicates no set affiliation. + +*setup_mode* - keyword, number.long + +* _secureboot.setup_mode_ - Whether setup mode is enabled + +*severity* - keyword, number.long + +* _syslog_events.severity_ - Syslog severity + +*sgid* - keyword + +* _docker_container_processes.sgid_ - Saved group ID +* _process_events.sgid_ - Saved group ID at process start +* _process_file_events.sgid_ - Saved group ID of the process using the file +* _processes.sgid_ - Unsigned saved group ID + +*sha1* - keyword, text.text + +* _apparmor_profiles.sha1_ - A unique hash that identifies this policy. +* _certificates.sha1_ - SHA1 hash of the raw certificate contents +* _device_hash.sha1_ - SHA1 hash of provided inode data +* _file_events.sha1_ - The SHA1 of the file after change +* _hash.sha1_ - SHA1 hash of provided filesystem data +* _rpm_packages.sha1_ - SHA1 hash of the package contents + +*sha1_fingerprint* - keyword, text.text + +* _curl_certificate.sha1_fingerprint_ - SHA1 fingerprint + +*sha256* - keyword, text.text + +* _carves.sha256_ - A SHA256 sum of the carved archive +* _device_hash.sha256_ - SHA256 hash of provided inode data +* _file_events.sha256_ - The SHA256 of the file after change +* _hash.sha256_ - SHA256 hash of provided filesystem data +* _rpm_package_files.sha256_ - SHA256 file digest from RPM info DB + +*sha256_fingerprint* - keyword, text.text + +* _curl_certificate.sha256_fingerprint_ - SHA-256 fingerprint + +*shard* - keyword, number.long + +* _osquery_packs.shard_ - Shard restriction limit, 1-100, 0 meaning no restriction + +*share* - keyword, text.text + +* _nfs_shares.share_ - Filesystem path to the share + +*share_name* - keyword, text.text + +* _shortcut_files.share_name_ - Share name of the target file. + +*shared* - keyword, text.text + +* _authorizations.shared_ - Label top-level key + +*shell* - keyword, text.text + +* _users.shell_ - User's configured default shell + +*shell_only* - keyword, number.long + +* _osquery_flags.shell_only_ - Is the flag shell only? + +*shmid* - keyword, number.long + +* _shared_memory.shmid_ - Shared memory segment ID + +*sid* - keyword, text.text + +* _background_activities_moderator.sid_ - User SID. +* _certificates.sid_ - SID +* _logged_in_users.sid_ - The user's unique security identifier +* _office_mru.sid_ - User SID +* _shellbags.sid_ - User SID +* _userassist.sid_ - User SID. + +*sig* - keyword, number.long + +* _seccomp_events.sig_ - Signal value sent to process by seccomp + +*sig_group* - keyword, text.text + +* _yara.sig_group_ - Signature group used + +*sigfile* - keyword, text.text + +* _yara.sigfile_ - Signature file used + +*signature* - keyword, text.text + +* _curl_certificate.signature_ - Signature + +*signature_algorithm* - keyword, text.text + +* _curl_certificate.signature_algorithm_ - Signature Algorithm + +*signatures_up_to_date* - keyword, number.long + +* _windows_security_products.signatures_up_to_date_ - 1 if product signatures are up to date, else 0 + +*signed* - keyword, number.long + +* _drivers.signed_ - Whether the driver is signed or not +* _signature.signed_ - 1 If the file is signed else 0 + +*signing_algorithm* - keyword, text.text + +* _certificates.signing_algorithm_ - Signing algorithm used + +*signing_id* - keyword, text.text + +* _es_process_events.signing_id_ - Signature identifier of the process + +*sigrule* - keyword, text.text + +* _yara.sigrule_ - Signature strings used + +*sigurl* - keyword, text.text + +* _yara.sigurl_ - Signature url + +*size* - keyword + +* _acpi_tables.size_ - Size of compiled table data +* _block_devices.size_ - Block device size in blocks +* _carves.size_ - Size of the carved archive +* _cups_jobs.size_ - The size of the print job +* _deb_packages.size_ - Package size in bytes +* _device_file.size_ - Size of file in bytes +* _disk_events.size_ - Size of partition in bytes +* _docker_image_history.size_ - Size of instruction in bytes +* _elf_sections.size_ - Size of section +* _elf_symbols.size_ - Size of object +* _example.size_ - This is a signed SQLite bigint column +* _fbsd_kmods.size_ - Size of module content +* _file.size_ - Size of file in bytes +* _file_events.size_ - Size of file in bytes +* _kernel_extensions.size_ - Bytes of wired memory used by extension +* _kernel_modules.size_ - Size of module content +* _logical_drives.size_ - The total amount of space, in bytes, of the drive (-1 on failure). +* _lxd_images.size_ - Size of image in bytes +* _lxd_storage_pools.size_ - Size of the storage pool +* _md_devices.size_ - size of the array in blocks +* _memory_devices.size_ - Size of memory device in Megabyte +* _package_bom.size_ - Expected file size +* _platform_info.size_ - Size in bytes of firmware +* _portage_packages.size_ - The size of the package +* _prefetch.size_ - Application file size. +* _quicklook_cache.size_ - Parsed version size field +* _rpm_package_files.size_ - Expected file size in bytes from RPM info DB +* _rpm_packages.size_ - Package size in bytes +* _shared_memory.size_ - Size in bytes +* _smbios_tables.size_ - Table entry size in bytes +* _smc_keys.size_ - Reported size of data in bytes + +*size_bytes* - keyword, number.long + +* _docker_images.size_bytes_ - Size of image in bytes + +*sku* - keyword, text.text + +* _azure_instance_metadata.sku_ - SKU for the VM image +* _chassis_info.sku_ - The Stock Keeping Unit number if available. + +*slot* - keyword + +* _md_drives.slot_ - Slot position of disk +* _portage_packages.slot_ - The slot used by package + +*smart_enabled* - keyword, text.text + +* _smart_drive_info.smart_enabled_ - SMART enabled status + +*smart_supported* - keyword, text.text + +* _smart_drive_info.smart_supported_ - SMART support status + +*smbios_tag* - keyword, text.text + +* _chassis_info.smbios_tag_ - The assigned asset tag number of the chassis. + +*socket* - keyword + +* _listening_ports.socket_ - Socket handle or inode number +* _process_open_sockets.socket_ - Socket handle or inode number +* _socket_events.socket_ - The local path (UNIX domain socket only) + +*socket_designation* - keyword, text.text + +* _cpu_info.socket_designation_ - The assigned socket on the board for the given CPU. + +*soft_limit* - keyword, text.text + +* _ulimit_info.soft_limit_ - Current limit value + +*softirq* - keyword, number.long + +* _cpu_time.softirq_ - Time spent servicing softirqs + +*source* - keyword, text.text + +* _apt_sources.source_ - Source file +* _autoexec.source_ - Source table of the autoexec item +* _deb_packages.source_ - Package source +* _docker_container_mounts.source_ - Source path on host +* _lxd_storage_pools.source_ - Storage pool source +* _package_install_history.source_ - Install source: usually the installer process name +* _routes.source_ - Route source +* _rpm_packages.source_ - Source RPM package name (optional) +* _shellbags.source_ - Shellbags source Registry file +* _startup_items.source_ - Directory or plist containing startup item +* _sudoers.source_ - Source file containing the given rule +* _windows_events.source_ - Source or channel of the event + +*source_path* - keyword, text.text + +* _systemd_units.source_path_ - Path to the (possibly generated) unit configuration file + +*source_url* - keyword, text.text + +* _firefox_addons.source_url_ - URL that installed the addon + +*space_total* - keyword, number.long + +* _lxd_storage_pools.space_total_ - Total available storage space in bytes for this storage pool + +*space_used* - keyword, number.long + +* _lxd_storage_pools.space_used_ - Storage space used in bytes + +*spare_disks* - keyword, number.long + +* _md_devices.spare_disks_ - Number of idle disks in array + +*spec_version* - keyword, text.text + +* _tpm_info.spec_version_ - Trusted Computing Group specification that the TPM supports + +*speculative* - keyword, number.long + +* _virtual_memory_info.speculative_ - Total number of speculative pages. + +*speed* - keyword, number.long + +* _interface_details.speed_ - Estimate of the current bandwidth in bits per second. + +*src_ip* - keyword, text.text + +* _iptables.src_ip_ - Source IP address. + +*src_mask* - keyword, text.text + +* _iptables.src_mask_ - Source IP address mask. + +*src_port* - keyword, text.text + +* _iptables.src_port_ - Protocol source port(s). + +*ssdeep* - keyword, text.text + +* _hash.ssdeep_ - ssdeep hash of provided filesystem data + +*ssh_config_file* - keyword, text.text + +* _ssh_configs.ssh_config_file_ - Path to the ssh_config file + +*ssh_public_key* - keyword, text.text + +* _ec2_instance_metadata.ssh_public_key_ - SSH public key. Only available if supplied at instance launch time +* _ycloud_instance_metadata.ssh_public_key_ - SSH public key. Only available if supplied at instance launch time + +*ssid* - keyword, text.text + +* _wifi_networks.ssid_ - SSID octets of the network +* _wifi_status.ssid_ - SSID octets of the network +* _wifi_survey.ssid_ - SSID octets of the network + +*stack_trace* - keyword, text.text + +* _crashes.stack_trace_ - Most recent frame from the stack trace +* _windows_crashes.stack_trace_ - Multiple stack frames from the stack trace + +*start* - keyword, text.text + +* _memory_map.start_ - Start address of memory region +* _process_memory_map.start_ - Virtual start address (hex) + +*start_interval* - keyword, text.text + +* _launchd.start_interval_ - Frequency to run in seconds + +*start_on_mount* - keyword, text.text + +* _launchd.start_on_mount_ - Run daemon or agent every time a filesystem is mounted + +*start_time* - keyword, number.long + +* _docker_container_processes.start_time_ - Process start in seconds since boot (non-sleeping) +* _osquery_info.start_time_ - UNIX time in seconds when the process started +* _processes.start_time_ - Process start time in seconds since Epoch, in case of error -1 + +*start_type* - keyword, text.text + +* _services.start_type_ - Service start type: BOOT_START, SYSTEM_START, AUTO_START, DEMAND_START, DISABLED + +*started_at* - keyword, text.text + +* _docker_containers.started_at_ - Container start time as string + +*starting_address* - keyword, text.text + +* _memory_array_mapped_addresses.starting_address_ - Physical stating address, in kilobytes, of a range of memory mapped to physical memory array +* _memory_device_mapped_addresses.starting_address_ - Physical stating address, in kilobytes, of a range of memory mapped to physical memory array + +*state* - keyword + +* _alf_exceptions.state_ - Firewall exception state +* _battery.state_ - One of the following: "AC Power" indicates the battery is connected to an external power source, "Battery Power" indicates that the battery is drawing internal power, "Off Line" indicates the battery is off-line or no longer connected +* _chrome_extensions.state_ - 1 if this extension is enabled +* _docker_container_processes.state_ - Process state +* _docker_containers.state_ - Container state (created, restarting, running, removing, paused, exited, dead) +* _lxd_networks.state_ - Network status +* _md_drives.state_ - State of the drive +* _process_open_sockets.state_ - TCP socket state +* _processes.state_ - Process state +* _scheduled_tasks.state_ - State of the scheduled task +* _system_extensions.state_ - System extension state +* _windows_optional_features.state_ - Installation state value. 1 == Enabled, 2 == Disabled, 3 == Absent +* _windows_security_products.state_ - State of protection + +*state_timestamp* - keyword, text.text + +* _windows_security_products.state_timestamp_ - Timestamp for the product state + +*stateful* - keyword, number.long + +* _lxd_instances.stateful_ - Whether the instance is stateful(1) or not(0) + +*statename* - keyword, text.text + +* _windows_optional_features.statename_ - Installation state name. 'Enabled','Disabled','Absent' + +*status* - keyword, text.text + +* _carves.status_ - Status of the carve, can be STARTING, PENDING, SUCCESS, or FAILED +* _chassis_info.status_ - If available, gives various operational or nonoperational statuses such as OK, Degraded, and Pred Fail. +* _deb_packages.status_ - Package status +* _docker_containers.status_ - Container status information +* _kernel_modules.status_ - Kernel module status +* _lxd_cluster_members.status_ - Status of the node (Online/Offline) +* _lxd_instances.status_ - Instance state (running, stopped, etc.) +* _md_devices.status_ - Current state of the array +* _ntdomains.status_ - The current status of the domain object. +* _process_events.status_ - OpenBSM Attribute: Status of the process +* _services.status_ - Service Current status: STOPPED, START_PENDING, STOP_PENDING, RUNNING, CONTINUE_PENDING, PAUSE_PENDING, PAUSED +* _shared_memory.status_ - Destination/attach status +* _shared_resources.status_ - String that indicates the current status of the object. +* _socket_events.status_ - Either 'succeeded', 'failed', 'in_progress' (connect() on non-blocking socket) or 'no_client' (null accept() on non-blocking socket) +* _startup_items.status_ - Startup status; either enabled or disabled + +*stderr_path* - keyword, text.text + +* _launchd.stderr_path_ - Pipe stderr to a target path + +*stdout_path* - keyword, text.text + +* _launchd.stdout_path_ - Pipe stdout to a target path + +*steal* - keyword, number.long + +* _cpu_time.steal_ - Time spent in other operating systems when running in a virtualized environment + +*stealth_enabled* - keyword, number.long + +* _alf.stealth_enabled_ - 1 If stealth mode is enabled else 0 + +*stibp_support_enabled* - keyword, number.long + +* _kva_speculative_info.stibp_support_enabled_ - Windows uses STIBP. + +*storage_driver* - keyword, text.text + +* _docker_info.storage_driver_ - Storage driver + +*store* - keyword, text.text + +* _certificates.store_ - Certificate system store + +*store_id* - keyword, text.text + +* _certificates.store_id_ - Exists for service/user stores. Contains raw store id provided by WinAPI. + +*store_location* - keyword, text.text + +* _certificates.store_location_ - Certificate system store location + +*strings* - keyword, text.text + +* _yara.strings_ - Matching strings +* _yara_events.strings_ - Matching strings + +*sub_state* - keyword, text.text + +* _systemd_units.sub_state_ - The low-level unit activation state, values depend on unit type + +*subclass* - keyword, text.text + +* _usb_devices.subclass_ - USB Device subclass + +*subject* - keyword, text.text + +* _certificates.subject_ - Certificate distinguished name + +*subject_alternative_names* - keyword, text.text + +* _curl_certificate.subject_alternative_names_ - Subject Alternative Name + +*subject_info_access* - keyword, text.text + +* _curl_certificate.subject_info_access_ - Subject Information Access + +*subject_key_id* - keyword, text.text + +* _certificates.subject_key_id_ - SKID an optionally included SHA1 + +*subject_key_identifier* - keyword, text.text + +* _curl_certificate.subject_key_identifier_ - Subject Key Identifier + +*subject_name* - keyword, text.text + +* _authenticode.subject_name_ - The certificate subject name + +*subkey* - keyword, text.text + +* _plist.subkey_ - Intermediate key path, includes lists/dicts +* _preferences.subkey_ - Intemediate key path, includes lists/dicts + +*subnet* - keyword, text.text + +* _docker_networks.subnet_ - Network subnet + +*subscription_id* - keyword, text.text + +* _azure_instance_metadata.subscription_id_ - Azure subscription for the VM + +*subscriptions* - keyword, number.long + +* _osquery_events.subscriptions_ - Number of subscriptions the publisher received or subscriber used + +*subsystem* - keyword, text.text + +* _system_controls.subsystem_ - Subsystem ID, control type + +*subsystem_model* - keyword, text.text + +* _pci_devices.subsystem_model_ - Device description of PCI device subsystem + +*subsystem_model_id* - keyword, text.text + +* _pci_devices.subsystem_model_id_ - Model ID of PCI device subsystem + +*subsystem_vendor* - keyword, text.text + +* _pci_devices.subsystem_vendor_ - Vendor of PCI device subsystem + +*subsystem_vendor_id* - keyword, text.text + +* _pci_devices.subsystem_vendor_id_ - Vendor ID of PCI device subsystem + +*success* - keyword, number.long + +* _socket_events.success_ - Deprecated. Use the 'status' column instead + +*suid* - keyword + +* _docker_container_processes.suid_ - Saved user ID +* _process_events.suid_ - Saved user ID at process start +* _process_file_events.suid_ - Saved user ID of the process using the file +* _processes.suid_ - Unsigned saved user ID + +*summary* - keyword, text.text + +* _chocolatey_packages.summary_ - Package-supplied summary +* _python_packages.summary_ - Package-supplied summary + +*superblock_state* - keyword, text.text + +* _md_devices.superblock_state_ - State of the superblock + +*superblock_update_time* - keyword, number.long + +* _md_devices.superblock_update_time_ - Unix timestamp of last update + +*superblock_version* - keyword, text.text + +* _md_devices.superblock_version_ - Version of the superblock + +*swap_cached* - keyword, number.long + +* _memory_info.swap_cached_ - The amount of swap, in bytes, used as cache memory + +*swap_free* - keyword, number.long + +* _memory_info.swap_free_ - The total amount of swap free, in bytes + +*swap_ins* - keyword, number.long + +* _virtual_memory_info.swap_ins_ - The total number of compressed pages that have been swapped out to disk. + +*swap_limit* - keyword, number.long + +* _docker_info.swap_limit_ - 1 if swap limit support is enabled. 0 otherwise + +*swap_outs* - keyword, number.long + +* _virtual_memory_info.swap_outs_ - The total number of compressed pages that have been swapped back in from disk. + +*swap_total* - keyword, number.long + +* _memory_info.swap_total_ - The total amount of swap available, in bytes + +*symlink* - keyword, number.long + +* _file.symlink_ - 1 if the path is a symlink, otherwise 0 + +*syscall* - keyword, text.text + +* _bpf_process_events.syscall_ - System call name +* _bpf_socket_events.syscall_ - System call name +* _process_events.syscall_ - Syscall name: fork, vfork, clone, execve, execveat +* _seccomp_events.syscall_ - Type of the system call + +*system* - keyword, number.long + +* _cpu_time.system_ - Time spent in system mode + +*system_cpu_usage* - keyword, number.long + +* _docker_container_stats.system_cpu_usage_ - CPU system usage + +*system_model* - keyword, text.text + +* _kernel_panics.system_model_ - Physical system model, for example 'MacBookPro12,1 (Mac-E43C1C25D4880AD6)' + +*system_time* - keyword, number.long + +* _osquery_schedule.system_time_ - Total system time spent executing +* _processes.system_time_ - CPU time in milliseconds spent in kernel space + +*table* - keyword, text.text + +* _elf_symbols.table_ - Table name containing symbol + +*tag* - keyword + +* _elf_dynamic.tag_ - Tag ID +* _syslog_events.tag_ - The syslog tag + +*tags* - keyword, text.text + +* _docker_image_history.tags_ - Comma-separated list of tags +* _docker_images.tags_ - Comma-separated list of repository tags +* _yara.tags_ - Matching tags +* _yara_events.tags_ - Matching tags + +*tapping_process* - keyword, number.long + +* _event_taps.tapping_process_ - The process ID of the application that created the event tap. + +*target* - keyword + +* _fan_speed_sensors.target_ - Target speed +* _iptables.target_ - Target that applies for this rule. + +*target_accessed* - keyword, number.long + +* _shortcut_files.target_accessed_ - Target Accessed time. + +*target_created* - keyword, number.long + +* _shortcut_files.target_created_ - Target Created time. + +*target_modified* - keyword, number.long + +* _shortcut_files.target_modified_ - Target Modified time. + +*target_name* - keyword, text.text + +* _prometheus_metrics.target_name_ - Address of prometheus target + +*target_path* - keyword, text.text + +* _file_events.target_path_ - The path associated with the event +* _shortcut_files.target_path_ - Target file path +* _yara_events.target_path_ - The path scanned + +*target_size* - keyword, number.long + +* _shortcut_files.target_size_ - Size of target file. + +*task* - keyword, number.long + +* _windows_eventlog.task_ - Task value associated with the event +* _windows_events.task_ - Task value associated with the event + +*team* - keyword, text.text + +* _system_extensions.team_ - Signing team ID + +*team_id* - keyword, text.text + +* _es_process_events.team_id_ - Team identifier of thd process + +*team_identifier* - keyword, text.text + +* _signature.team_identifier_ - The team signing identifier sealed into the signature + +*temporarily_disabled* - keyword, number.long + +* _wifi_networks.temporarily_disabled_ - 1 if this network is temporarily disabled, 0 otherwise + +*terminal* - keyword, text.text + +* _user_events.terminal_ - The network protocol ID + +*threads* - keyword, number.long + +* _docker_container_processes.threads_ - Number of threads used by process +* _processes.threads_ - Number of threads used by process + +*throttled* - keyword, number.long + +* _virtual_memory_info.throttled_ - Total number of throttled pages. + +*tid* - keyword, number.long + +* _bpf_process_events.tid_ - Thread ID +* _bpf_socket_events.tid_ - Thread ID +* _windows_crashes.tid_ - Thread ID of the crashed thread +* _windows_eventlog.tid_ - Thread ID which emitted the event record + +*time* - keyword + +* _apparmor_events.time_ - Time of execution in UNIX time +* _asl.time_ - Unix timestamp. Set automatically +* _bpf_process_events.time_ - Time of execution in UNIX time +* _bpf_socket_events.time_ - Time of execution in UNIX time +* _carves.time_ - Time at which the carve was kicked off +* _disk_events.time_ - Time of appearance/disappearance in UNIX time +* _docker_container_processes.time_ - Cumulative CPU time. [DD-]HH:MM:SS format +* _es_process_events.time_ - Time of execution in UNIX time +* _file_events.time_ - Time of file event +* _hardware_events.time_ - Time of hardware event +* _kernel_panics.time_ - Formatted time of the event +* _last.time_ - Entry timestamp +* _logged_in_users.time_ - Time entry was made +* _ntfs_journal_events.time_ - Time of file event +* _package_install_history.time_ - Label date as UNIX timestamp +* _powershell_events.time_ - Timestamp the event was received by the osquery event publisher +* _process_events.time_ - Time of execution in UNIX time +* _process_file_events.time_ - Time of execution in UNIX time +* _seccomp_events.time_ - Time of execution in UNIX time +* _selinux_events.time_ - Time of execution in UNIX time +* _shell_history.time_ - Entry timestamp. It could be absent, default value is 0. +* _socket_events.time_ - Time of execution in UNIX time +* _syslog_events.time_ - Current unix epoch time +* _user_events.time_ - Time of execution in UNIX time +* _user_interaction_events.time_ - Time +* _windows_events.time_ - Timestamp the event was received +* _xprotect_reports.time_ - Quarantine alert time +* _yara_events.time_ - Time of the scan + +*time_nano_sec* - keyword, number.long + +* _asl.time_nano_sec_ - Nanosecond time. + +*time_range* - keyword, text.text + +* _windows_eventlog.time_range_ - System time to selectively filter the events + +*timeout* - keyword, text.text + +* _authorizations.timeout_ - Label top-level key +* _curl_certificate.timeout_ - Set this value to the timeout in seconds to complete the TLS handshake (default 4s, use 0 for no timeout) + +*timestamp* - keyword, text.text + +* _time.timestamp_ - Current timestamp (log format) in the system +* _windows_eventlog.timestamp_ - Timestamp to selectively filter the events + +*timestamp_ms* - keyword, number.long + +* _prometheus_metrics.timestamp_ms_ - Unix timestamp of collected data in MS + +*timezone* - keyword, text.text + +* _time.timezone_ - Current timezone in the system + +*title* - keyword, text.text + +* _cups_jobs.title_ - Title of the printed job + +*total_seconds* - keyword, number.long + +* _uptime.total_seconds_ - Total uptime seconds + +*total_size* - keyword, number.long + +* _docker_container_processes.total_size_ - Total virtual memory size +* _processes.total_size_ - Total virtual memory size + +*total_width* - keyword, number.long + +* _memory_devices.total_width_ - Total width, in bits, of this memory device, including any check or error-correction bits + +*transaction_id* - keyword, number.long + +* _file_events.transaction_id_ - ID used during bulk update +* _yara_events.transaction_id_ - ID used during bulk update + +*transmit_rate* - keyword, text.text + +* _wifi_status.transmit_rate_ - The current transmit rate + +*transport_type* - keyword, text.text + +* _smart_drive_info.transport_type_ - Drive transport type + +*tries* - keyword, text.text + +* _authorizations.tries_ - Label top-level key + +*tty* - keyword, text.text + +* _last.tty_ - Entry terminal +* _logged_in_users.tty_ - Device name + +*turbo_disabled* - keyword, number.long + +* _msr.turbo_disabled_ - Whether the turbo feature is disabled. + +*turbo_ratio_limit* - keyword, number.long + +* _msr.turbo_ratio_limit_ - The turbo feature ratio limit. + +*type* - keyword, text.text + +* _apparmor_events.type_ - Event type +* _appcompat_shims.type_ - Type of the SDB database. +* _block_devices.type_ - Block device type string +* _bpf_socket_events.type_ - The socket type +* _crashes.type_ - Type of crash log +* _device_file.type_ - File status +* _device_firmware.type_ - Type of device +* _device_partitions.type_ - +* _disk_encryption.type_ - Description of cipher type and mode if available +* _disk_info.type_ - The interface type of the disk. +* _dns_cache.type_ - DNS record type +* _dns_resolvers.type_ - Address type: sortlist, nameserver, search +* _docker_container_mounts.type_ - Type of mount (bind, volume) +* _docker_container_ports.type_ - Protocol (tcp, udp) +* _docker_volumes.type_ - Volume type +* _elf_info.type_ - Offset of section in file +* _elf_sections.type_ - Section type +* _elf_symbols.type_ - Symbol type +* _file.type_ - File status +* _firefox_addons.type_ - Extension, addon, webapp +* _hardware_events.type_ - Type of hardware and hardware event +* _interface_addresses.type_ - Type of address. One of dhcp, manual, auto, other, unknown +* _interface_details.type_ - Interface type (includes virtual) +* _keychain_items.type_ - Keychain item type (class) +* _last.type_ - Entry type, according to ut_type types (utmp.h) +* _logged_in_users.type_ - Login type +* _logical_drives.type_ - Deprecated (always 'Unknown'). +* _lxd_certificates.type_ - Type of the certificate +* _lxd_networks.type_ - Type of network +* _mounts.type_ - Mounted device type +* _ntfs_acl_permissions.type_ - Type of access mode for the access control entry. +* _nvram.type_ - Data type (CFData, CFString, etc) +* _osquery_events.type_ - Either publisher or subscriber +* _osquery_extensions.type_ - SDK extension type: extension or module +* _osquery_flags.type_ - Flag type +* _process_open_pipes.type_ - Pipe Type: named vs unnamed/anonymous +* _registry.type_ - Type of the registry value, or 'subkey' if item is a subkey +* _routes.type_ - Type of route +* _selinux_events.type_ - Event type +* _shared_resources.type_ - Type of resource being shared. Types include: disk drives, print queues, interprocess communications (IPC), and general devices. +* _smbios_tables.type_ - Table entry type +* _smc_keys.type_ - SMC-reported type literal type +* _startup_items.type_ - Startup Item or Login Item +* _system_controls.type_ - Data type +* _ulimit_info.type_ - System resource to be limited +* _user_events.type_ - The file description for the process socket +* _users.type_ - Whether the account is roaming (domain), local, or a system profile +* _windows_crashes.type_ - Type of crash log +* _windows_security_products.type_ - Type of security product +* _xprotect_meta.type_ - Either plugin or extension + +*type_name* - keyword, text.text + +* _last.type_name_ - Entry type name, according to ut_type types (utmp.h) + +*uid* - keyword + +* _account_policy_data.uid_ - User ID +* _asl.uid_ - UID that sent the log message (set by the server). +* _atom_packages.uid_ - The local user that owns the plugin +* _authorized_keys.uid_ - The local owner of authorized_keys file +* _bpf_process_events.uid_ - User ID +* _bpf_socket_events.uid_ - User ID +* _browser_plugins.uid_ - The local user that owns the plugin +* _chrome_extension_content_scripts.uid_ - The local user that owns the extension +* _chrome_extensions.uid_ - The local user that owns the extension +* _crashes.uid_ - User ID of the crashed process +* _device_file.uid_ - Owning user ID +* _disk_encryption.uid_ - Currently authenticated user if available +* _docker_container_processes.uid_ - User ID +* _es_process_events.uid_ - User ID of the process +* _file.uid_ - Owning user ID +* _file_events.uid_ - Owning user ID +* _firefox_addons.uid_ - The local user that owns the addon +* _known_hosts.uid_ - The local user that owns the known_hosts file +* _launchd_overrides.uid_ - User ID applied to the override, 0 applies to all +* _package_bom.uid_ - Expected user of file or directory +* _process_events.uid_ - User ID at process start +* _process_file_events.uid_ - The uid of the process performing the action +* _processes.uid_ - Unsigned user ID +* _safari_extensions.uid_ - The local user that owns the extension +* _seccomp_events.uid_ - User ID of the user who started the analyzed process +* _shell_history.uid_ - Shell history owner +* _ssh_configs.uid_ - The local owner of the ssh_config file +* _user_events.uid_ - User ID +* _user_groups.uid_ - User ID +* _user_ssh_keys.uid_ - The local user that owns the key file +* _users.uid_ - User ID + +*uid_signed* - keyword, number.long + +* _users.uid_signed_ - User ID as int64 signed (Apple) + +*umci_policy_status* - keyword, text.text + +* _hvci_status.umci_policy_status_ - The status of the User Mode Code Integrity security settings. Returns UNKNOWN if an error is encountered. + +*uncompressed* - keyword, number.long + +* _virtual_memory_info.uncompressed_ - Total number of uncompressed pages. + +*uninstall_string* - keyword, text.text + +* _programs.uninstall_string_ - Path and filename of the uninstaller. + +*unique_chip_id* - keyword, text.text + +* _ibridge_info.unique_chip_id_ - Unique id of the iBridge controller + +*unix_time* - keyword, number.long + +* _time.unix_time_ - Current UNIX time in the system, converted to UTC if --utc enabled + +*unmask* - keyword, number.long + +* _portage_keywords.unmask_ - If the package is unmasked + +*unused_devices* - keyword, text.text + +* _md_devices.unused_devices_ - Unused devices + +*update_source_alias* - keyword, text.text + +* _lxd_images.update_source_alias_ - Alias of image at update source server + +*update_source_certificate* - keyword, text.text + +* _lxd_images.update_source_certificate_ - Certificate for update source server + +*update_source_protocol* - keyword, text.text + +* _lxd_images.update_source_protocol_ - Protocol used for image information update and image import from source server + +*update_source_server* - keyword, text.text + +* _lxd_images.update_source_server_ - Server for image update + +*update_url* - keyword, text.text + +* _chrome_extensions.update_url_ - Extension-supplied update URI +* _safari_extensions.update_url_ - Extension-supplied update URI + +*upid* - keyword, number.long + +* _processes.upid_ - A 64bit pid that is never reused. Returns -1 if we couldn't gather them from the system. + +*uploaded_at* - keyword, text.text + +* _lxd_images.uploaded_at_ - ISO time of image upload + +*upn* - keyword, text.text + +* _logon_sessions.upn_ - The user principal name (UPN) for the owner of the logon session. + +*uppid* - keyword, number.long + +* _processes.uppid_ - The 64bit parent pid that is never reused. Returns -1 if we couldn't gather them from the system. + +*uptime* - keyword, number.long + +* _apparmor_events.uptime_ - Time of execution in system uptime +* _kernel_panics.uptime_ - System uptime at kernel panic in nanoseconds +* _process_events.uptime_ - Time of execution in system uptime +* _process_file_events.uptime_ - Time of execution in system uptime +* _seccomp_events.uptime_ - Time of execution in system uptime +* _selinux_events.uptime_ - Time of execution in system uptime +* _socket_events.uptime_ - Time of execution in system uptime +* _user_events.uptime_ - Time of execution in system uptime + +*url* - keyword, text.text + +* _curl.url_ - The url for the request +* _lxd_cluster_members.url_ - URL of the node + +*usb_address* - keyword, number.long + +* _usb_devices.usb_address_ - USB Device used address + +*usb_port* - keyword, number.long + +* _usb_devices.usb_port_ - USB Device used port + +*use* - keyword, text.text + +* _memory_arrays.use_ - Function for which the array is used +* _portage_use.use_ - USE flag which has been enabled for package + +*used_by* - keyword, text.text + +* _kernel_modules.used_by_ - Module reverse dependencies +* _lxd_networks.used_by_ - URLs for containers using this network + +*user* - keyword + +* _cpu_time.user_ - Time spent in user mode +* _cups_jobs.user_ - The user who printed the job +* _docker_container_processes.user_ - User name +* _logged_in_users.user_ - User login name +* _logon_sessions.user_ - The account name of the security principal that owns the logon session. +* _sandboxes.user_ - Sandbox owner +* _systemd_units.user_ - The configured user, if any + +*user_account* - keyword, text.text + +* _services.user_account_ - The name of the account that the service process will be logged on as when it runs. This name can be of the form Domain\UserName. If the account belongs to the built-in domain, the name can be of the form .\UserName. + +*user_account_control* - keyword, text.text + +* _windows_security_center.user_account_control_ - The health of the User Account Control (UAC) capability in Windows + +*user_action* - keyword, text.text + +* _xprotect_reports.user_action_ - Action taken by user after prompted + +*user_agent* - keyword, text.text + +* _curl.user_agent_ - The user-agent string to use for the request + +*user_capacity* - keyword, text.text + +* _smart_drive_info.user_capacity_ - Bytes of drive capacity + +*user_namespace* - keyword, text.text + +* _docker_containers.user_namespace_ - User namespace +* _process_namespaces.user_namespace_ - user namespace inode + +*user_time* - keyword, number.long + +* _osquery_schedule.user_time_ - Total user time spent executing +* _processes.user_time_ - CPU time in milliseconds spent in user space + +*user_uuid* - keyword, text.text + +* _disk_encryption.user_uuid_ - UUID of authenticated user if available + +*username* - keyword, text.text + +* _certificates.username_ - Username +* _es_process_events.username_ - Username +* _last.username_ - Entry username +* _launchd.username_ - Run this daemon or agent as this username +* _managed_policies.username_ - Policy applies only this user +* _preferences.username_ - (optional) read preferences for a specific user +* _rpm_package_files.username_ - File default username from info DB +* _shadow.username_ - Username +* _startup_items.username_ - The user associated with the startup item +* _suid_bin.username_ - Binary owner username +* _users.username_ - Username +* _windows_crashes.username_ - Username of the user who ran the crashed process + +*uses_pattern* - keyword, number.long + +* _xprotect_entries.uses_pattern_ - Uses a match pattern instead of identity + +*uts_namespace* - keyword, text.text + +* _docker_containers.uts_namespace_ - UTS namespace +* _process_namespaces.uts_namespace_ - uts namespace inode + +*uuid* - keyword, text.text + +* _block_devices.uuid_ - Block device Universally Unique Identifier +* _disk_encryption.uuid_ - Disk Universally Unique Identifier +* _disk_events.uuid_ - UUID of the volume inside DMG if available +* _managed_policies.uuid_ - Optional UUID assigned to policy set +* _osquery_extensions.uuid_ - The transient ID assigned for communication +* _osquery_info.uuid_ - Unique ID provided by the system +* _system_info.uuid_ - Unique ID provided by the system +* _users.uuid_ - User's UUID (Apple) or SID (Windows) + +*vaddr* - keyword, number.long + +* _elf_sections.vaddr_ - Section virtual address in memory +* _elf_segments.vaddr_ - Segment virtual address in memory + +*valid_from* - keyword, text.text + +* _curl_certificate.valid_from_ - Period of validity start date + +*valid_to* - keyword, text.text + +* _curl_certificate.valid_to_ - Period of validity end date + +*value* - keyword, text.text + +* _ad_config.value_ - Variable typed option value +* _augeas.value_ - The value of the configuration item +* _azure_instance_tags.value_ - The tag value +* _cpuid.value_ - Bit value or string +* _default_environment.value_ - Value of the environment variable +* _docker_container_labels.value_ - Optional label value +* _docker_image_labels.value_ - Optional label value +* _docker_network_labels.value_ - Optional label value +* _docker_volume_labels.value_ - Optional label value +* _ec2_instance_tags.value_ - Tag value +* _elf_dynamic.value_ - Tag value +* _extended_attributes.value_ - The parsed information from the attribute +* _launchd_overrides.value_ - Overridden value +* _lxd_instance_config.value_ - Configuration parameter value +* _lxd_instance_devices.value_ - Device info param value +* _managed_policies.value_ - Policy value +* _mdls.value_ - Value stored in the metadata key +* _nvram.value_ - Raw variable data +* _oem_strings.value_ - The value of the OEM string +* _osquery_flags.value_ - Flag value +* _plist.value_ - String value of most CF types +* _power_sensors.value_ - Power in Watts +* _preferences.value_ - String value of most CF types +* _process_envs.value_ - Environment variable value +* _selinux_settings.value_ - Active value. +* _smc_keys.value_ - A type-encoded representation of the key value +* _wmi_bios_info.value_ - Value of the Bios setting + +*valuetype* - keyword, text.text + +* _mdls.valuetype_ - CoreFoundation type of data stored in value + +*variable* - keyword, text.text + +* _default_environment.variable_ - Name of the environment variable + +*vbs_status* - keyword, text.text + +* _hvci_status.vbs_status_ - The status of the virtualization based security settings. Returns UNKNOWN if an error is encountered. + +*vendor* - keyword, text.text + +* _block_devices.vendor_ - Block device vendor string +* _disk_events.vendor_ - Disk event vendor string +* _hardware_events.vendor_ - Hardware device vendor +* _pci_devices.vendor_ - PCI Device vendor +* _platform_info.vendor_ - Platform code vendor +* _rpm_packages.vendor_ - Package vendor +* _usb_devices.vendor_ - USB Device vendor string + +*vendor_id* - keyword, text.text + +* _hardware_events.vendor_id_ - Hex encoded Hardware vendor identifier +* _pci_devices.vendor_id_ - Hex encoded PCI Device vendor identifier +* _usb_devices.vendor_id_ - Hex encoded USB Device vendor identifier + +*vendor_syndrome* - keyword, text.text + +* _memory_error_info.vendor_syndrome_ - Vendor specific ECC syndrome or CRC data associated with the erroneous access + +*version* - keyword, text.text + +* _alf.version_ - Application Layer Firewall version +* _apt_sources.version_ - Repository source version +* _atom_packages.version_ - Package supplied version +* _authorizations.version_ - Label top-level key +* _azure_instance_metadata.version_ - Version of the VM image +* _bitlocker_info.version_ - The FVE metadata version of the drive. +* _browser_plugins.version_ - Plugin short version +* _chocolatey_packages.version_ - Package-supplied version +* _chrome_extension_content_scripts.version_ - Extension-supplied version +* _chrome_extensions.version_ - Extension-supplied version +* _crashes.version_ - Version info of the crashed process +* _curl_certificate.version_ - Version Number +* _deb_packages.version_ - Package version +* _device_firmware.version_ - Firmware version +* _docker_version.version_ - Docker version +* _drivers.version_ - Driver version +* _elf_info.version_ - Object file version +* _es_process_events.version_ - Version of EndpointSecurity event +* _firefox_addons.version_ - Addon-supplied version string +* _gatekeeper.version_ - Version of Gatekeeper's gke.bundle +* _homebrew_packages.version_ - Current 'linked' version +* _hvci_status.version_ - The version number of the Device Guard build. +* _ie_extensions.version_ - Version of the executable +* _intel_me_info.version_ - Intel ME version +* _kernel_extensions.version_ - Extension version +* _kernel_info.version_ - Kernel version +* _npm_packages.version_ - Package supplied version +* _office_mru.version_ - Office application version number +* _os_version.version_ - Pretty, suitable for presentation, OS version +* _osquery_extensions.version_ - Extension's version +* _osquery_info.version_ - osquery toolkit version +* _osquery_packs.version_ - Minimum osquery version that this query will run on +* _package_install_history.version_ - Package display version +* _package_receipts.version_ - Installed package version +* _pkg_packages.version_ - Package version +* _platform_info.version_ - Platform code version +* _portage_keywords.version_ - The version which are affected by the use flags, empty means all +* _portage_packages.version_ - The version which are affected by the use flags, empty means all +* _portage_use.version_ - The version of the installed package +* _programs.version_ - Product version information. +* _python_packages.version_ - Package-supplied version +* _rpm_packages.version_ - Package version +* _safari_extensions.version_ - Extension long version +* _system_extensions.version_ - System extension version +* _usb_devices.version_ - USB Device version number +* _windows_crashes.version_ - File version info of the crashed process + +*video_mode* - keyword, text.text + +* _video_info.video_mode_ - The current resolution of the display. + +*virtual_process* - keyword, number.long + +* _processes.virtual_process_ - Process is virtual (e.g. System, Registry, vmmem) yes=1, no=0 + +*visible* - keyword, number.long + +* _firefox_addons.visible_ - 1 If the addon is shown in browser else 0 + +*visible_alarm* - keyword, text.text + +* _chassis_info.visible_alarm_ - If TRUE, the frame is equipped with a visual alarm. + +*vlans* - keyword, text.text + +* _lldp_neighbors.vlans_ - Comma delimited list of vlan ids + +*vm_id* - keyword, text.text + +* _azure_instance_metadata.vm_id_ - Unique identifier for the VM +* _azure_instance_tags.vm_id_ - Unique identifier for the VM + +*vm_scale_set_name* - keyword, text.text + +* _azure_instance_metadata.vm_scale_set_name_ - VM scale set name + +*vm_size* - keyword, text.text + +* _azure_instance_metadata.vm_size_ - VM size + +*voltage* - keyword, number.long + +* _battery.voltage_ - The battery's current voltage in mV + +*volume_creation* - keyword, text.text + +* _prefetch.volume_creation_ - Volume creation time. + +*volume_id* - keyword, number.long + +* _quicklook_cache.volume_id_ - Parsed volume ID from fs_id + +*volume_serial* - keyword, text.text + +* _file.volume_serial_ - Volume serial number +* _prefetch.volume_serial_ - Volume serial number. +* _shortcut_files.volume_serial_ - Volume serial number. + +*volume_size* - keyword, number.long + +* _platform_info.volume_size_ - (Optional) size of firmware volume + +*wall_time* - keyword, number.long + +* _osquery_schedule.wall_time_ - Total wall time spent executing + +*warning* - keyword, number.long + +* _shadow.warning_ - Number of days before password expires to warn user about it + +*warnings* - keyword, text.text + +* _smart_drive_info.warnings_ - Warning messages from SMART controller + +*watch_paths* - keyword, text.text + +* _launchd.watch_paths_ - Key that launches daemon or agent if path is modified + +*watcher* - keyword, number.long + +* _osquery_info.watcher_ - Process (or thread/handle) ID of optional watcher process + +*weekday* - keyword, text.text + +* _time.weekday_ - Current weekday in the system + +*win32_exit_code* - keyword, number.long + +* _services.win32_exit_code_ - The error code that the service uses to report an error that occurs when it is starting or stopping + +*win_timestamp* - keyword, number.long + +* _time.win_timestamp_ - Timestamp value in 100 nanosecond units. + +*windows_security_center_service* - keyword, text.text + +* _windows_security_center.windows_security_center_service_ - The health of the Windows Security Center Service + +*wired* - keyword, number.long + +* _virtual_memory_info.wired_ - Total number of wired down pages. + +*wired_size* - keyword, number.long + +* _docker_container_processes.wired_size_ - Bytes of unpageable memory used by process +* _processes.wired_size_ - Bytes of unpageable memory used by process + +*working_directory* - keyword, text.text + +* _launchd.working_directory_ - Key used to specify a directory to chdir to before launch + +*working_disks* - keyword, number.long + +* _md_devices.working_disks_ - Number of working disks in array + +*working_path* - keyword, text.text + +* _shortcut_files.working_path_ - Target file directory. + +*world* - keyword, number.long + +* _portage_packages.world_ - If package is in the world file + +*writable* - keyword, number.long + +* _disk_events.writable_ - 1 if writable, 0 if not + +*xpath* - keyword, text.text + +* _windows_eventlog.xpath_ - The custom query to filter events + +*year* - keyword, number.long + +* _time.year_ - Current year in the system + +*zero_fill* - keyword, number.long + +* _virtual_memory_info.zero_fill_ - Total number of zero filled pages. + +*zone* - keyword, text.text + +* _azure_instance_metadata.zone_ - Availability zone of the VM +* _ycloud_instance_metadata.zone_ - Availability zone of the VM + diff --git a/docs/osquery/osquery.asciidoc b/docs/osquery/osquery.asciidoc index ab8058027934e..e450bcbcb7d6f 100644 --- a/docs/osquery/osquery.asciidoc +++ b/docs/osquery/osquery.asciidoc @@ -16,7 +16,7 @@ With Osquery in {kib}, you can: * View a history of past queries and their results * Save queries and build a library of queries for specific use cases -Osquery is powered by the *Osquery Manager* integration. +Osquery in {kib} is powered by the *Osquery Manager* integration. For information on how to set up *Osquery Manager*, refer to <>. [float] @@ -119,6 +119,51 @@ image::images/scheduled-pack.png[Shows queries in the pack and details about eac . View scheduled query results in <> or the drag-and-drop <> editor. +[float] +[[osquery-prebuilt-packs]] +== Prebuilt Elastic packs + +The Osquery Manager integration includes a set of prebuilt Osquery packs that you can optionally load. Once added, you can then activate and schedule the packs. + +You can modify the scheduled agent policies for a prebuilt pack, but you cannot edit queries in the pack. To edit the queries, you must first create a copy of the pack. + +[float] +[[load-prebuilt-packs]] +=== Load and activate prebuilt Elastic packs + +. Go to *Packs*, and then click *Load Elastic prebuilt packs*. ++ +NOTE: This option is only available if new or updated prebuilt packs are available. + +. For each pack that you want to schedule: + +* Enable the option to make the pack *Active*. + +* Click the pack name, then *Edit*. + +* Update the *Scheduled agent policies* to specify the policies where this pack should run. + +. Click *Update pack*. + +[float] +[[copy-prebuilt-packs]] +=== Copy prebuilt Elastic packs + +To modify queries in prebuilt packs, you must first make a copy of the pack. + +. Go to *Stack Management* -> *Saved Objects*. + +. Search for the Osquery packs you want to modify by name. + +. Select the checkboxes of the packs to export. + +. Click *Export x objects*. + +. Click *Import*. + +. Select the import option *Create new objects with random IDs*, then click *Import* to import the pack. This creates a copy of the pack that you can edit. + + [float] [[osquery-manage-query]] == Save queries @@ -157,9 +202,110 @@ To add or edit saved queries from the *Saved queries* tab: . Click *Save* or *Update*. --- -include::advanced-osquery.asciidoc[] +[float] +[[osquery-map-fields]] +== Map result fields to ECS + +When you save queries or add queries to a pack, you can optionally map Osquery results or static values to fields in +the {ecs-ref}/ecs-reference.html[Elastic Common Schema] (ECS). +This standardizes your Osquery data for use across detections, machine learning, +and any other areas that rely on ECS-compliant data. +When the query is run, the results include the original `osquery.` +and the mapped ECS fields. For example, if you update a query to map `osquery.name` to `user.name`, the query results include both fields. + +. Edit saved queries or queries in a pack to map fields: + +* For *Saved queries*: Open the *Saved queries* tab, and then click the edit icon for the query that you want to map. + +* For *packs*: Open the *Packs* tab, edit a pack, and then click the edit icon for the query that you want to map. + +. In the **ECS mapping** section, select an **ECS field** to map. + +. In the **Value** column, use the dropdown on the left to choose what type of value to map to the ECS field: + +** **Osquery value**: Select an Osquery field. The fields available are based on the SQL query entered, and only include fields that the query returns. When the query runs, the ECS field is set dynamically to the value of the Osquery field selected. + +** **Static value**: Enter a static value. When the query runs, the ECS field is set to the value entered. For example, static fields can be used to apply `tags` or your preferred `event.category` to the query results. + +. Map more fields, as needed. To remove any mapped rows, click the delete icon. + +. Save your changes. + +[NOTE] +========================= + +* Some ECS fields are restricted and cannot be mapped. These are not available in the ECS dropdown. + +* Some ECS fields are restricted to a set of allowed values, like {ecs-ref}/ecs-event.html#field-event-category[event.category]. Use the {ecs-ref}/ecs-field-reference.html[ECS Field Reference] for help when mapping fields. + +* Osquery date fields have a variety of data types (including integer, text, or bigint). When mapping an Osquery date field to an ECS date field, you might need to use SQL operators in the query to get an {es}-compatible +{ref}/date.html[date] type. +========================= + + +[float] +[[osquery-extended-tables]] +== Extended tables for Kubernetes queries +In addition to the Osquery schema, the Elastic-provided version of Osquery also includes the following tables to support Kubernetes containers. These can be queried with live or scheduled queries. + +* `host_users` + +* `host_groups` + +* `host_processes` + +When querying these tables, the expectation is that the `/etc/passwd`, `/etc/group`, and `/proc` are available in the container under `/hostfs` as: +`/hostfs/etc/passwd`, `/hostfs/etc/group`, and `/hostfs/proc`. For information about the fields available in these tables, see the +https://docs.elastic.co/en/integrations/osquery_manager#exported-fields[exported fields] reference. + +[float] +[[osquery-status]] +== Osquery status + +A query can have the following status: + +[cols="2*<"] +|=== +| Successful | The query successfully completed. +| Failed | The query encountered a problem, such as an issue with the query or the agent was disconnected, and might have failed. +| Not yet responded | The query has not been sent to the agent. +| Expired | The action request timed out. The agent may be offline. +|=== + +NOTE: If an agent is offline, the request status remains **pending** as {kib} retries the request. +By default, a query request times out after five minutes. The time out applies to the time it takes +to deliver the action request to an agent to run a query. If the action completes after the timeout period, +the results are still returned. + + +[float] +[[osquery-results]] +== Osquery results +When you run live or scheduled queries, the results are automatically +stored in an {es} index, so that you can search, analyze, and visualize this data in {kib}. +For a list of the Osquery fields that can be returned in query results, +refer to https://docs.elastic.co/en/integrations/osquery_manager#exported-fields[exported fields]. +Query results can also include ECS fields, if the query has a defined ECS mapping. + +Osquery responses include the following information: + +* Everything prefaced with `osquery.` is part of the query response. These fields are not mapped to ECS by default. + +* Results include some ECS fields by default, such as `host.*` and `agent.*`, which provide information about the host that was queried. + +* For live queries, the `action_data.query` is the query that was sent. + +* For scheduled queries in a pack, the `action_id` has the format `pack__`. You can use this information to look up the query that was run. + +* By default, all query results are https://osquery.readthedocs.io/en/stable/deployment/logging/#snapshot-logs[snapshot logs] +that represent a point in time with a set of results, with no +https://osquery.readthedocs.io/en/stable/deployment/logging/#differential-logs[differentials]. + +* Osquery data is stored in the `logs-osquery_manager.result-` datastream, and the result row data is under the `osquery` property in the document. + + +-- include::manage-integration.asciidoc[] diff --git a/docs/redirects.asciidoc b/docs/redirects.asciidoc index 9a96eec55db32..934ebfc3e4b08 100644 --- a/docs/redirects.asciidoc +++ b/docs/redirects.asciidoc @@ -410,3 +410,8 @@ This page has been deleted. Refer to <>. == View a document This page has been deleted. Refer to <>. + +[role="exclude",id="advanced-osquery"] +== Advanced Osquery + +This page has been deleted. Refer to <>. diff --git a/docs/settings/alert-action-settings.asciidoc b/docs/settings/alert-action-settings.asciidoc index 3d15c3cc5e368..33c97373a76c4 100644 --- a/docs/settings/alert-action-settings.asciidoc +++ b/docs/settings/alert-action-settings.asciidoc @@ -125,6 +125,11 @@ The contents of a PEM-encoded certificate file, or multiple files appended into a single string. This configuration can be used for environments where the files cannot be made available. +[[action-config-email-domain-allowlist]] `xpack.actions.email.domain_allowlist` {ess-icon}:: +A list of allowed email domains which can be used with the email connector. When this setting is not used, all email domains are allowed. When this setting is used, if any email is attempted to be sent that (a) includes an addressee with an email domain that is not in the allowlist, or (b) includes a from address domain that is not in the allowlist, it will fail with a message indicating the email is not allowed. + +WARNING: This feature is available in {kib} 7.17.4 and 8.3.0 onwards but is not supported in {kib} 8.0, 8.1 or 8.2. As such, this setting should be removed before upgrading from 7.17 to 8.0, 8.1 or 8.2. It is possible to configure the settings in 7.17.4 and then upgrade to 8.3.0 directly. + `xpack.actions.enabledActionTypes` {ess-icon}:: A list of action types that are enabled. It defaults to `[*]`, enabling all types. The names for built-in {kib} action types are prefixed with a `.` and include: `.email`, `.index`, `.jira`, `.pagerduty`, `.resilient`, `.server-log`, `.servicenow`, .`servicenow-itom`, `.servicenow-sir`, `.slack`, `.swimlane`, `.teams`, `.xmatters`, and `.webhook`. An empty list `[]` will disable all action types. + @@ -211,13 +216,26 @@ For example, `20m`, `24h`, `7d`, `1w`. Default: `5m`. `xpack.alerting.rules.run.ruleTypeOverrides`:: Overrides the configs under `xpack.alerting.rules.run` for the rule type with the given ID. List the rule identifier and its settings in an array of objects. + --- For example: -``` +[source,yaml] +-- xpack.alerting.rules.run: timeout: '5m' ruleTypeOverrides: - id: '.index-threshold' timeout: '15m' -``` --- \ No newline at end of file +-- + +`xpack.alerting.rules.run.actions.connectorTypeOverrides`:: +Overrides the configs under `xpack.alerting.rules.run.actions` for the connector type with the given ID. List the connector type identifier and its settings in an array of objects. ++ +For example: +[source,yaml] +-- +xpack.alerting.rules.run: + actions: + max: 10 + connectorTypeOverrides: + - id: '.server-log' + max: 5 +-- diff --git a/docs/settings/general-infra-logs-ui-settings.asciidoc b/docs/settings/general-infra-logs-ui-settings.asciidoc index 91a6c2ef91a23..af84b92829dfd 100644 --- a/docs/settings/general-infra-logs-ui-settings.asciidoc +++ b/docs/settings/general-infra-logs-ui-settings.asciidoc @@ -1,28 +1,7 @@ -`xpack.infra.sources.default.logAlias`:: -Index pattern for matching indices that contain log data. Defaults to `filebeat-*,kibana_sample_data_logs*`. To match multiple wildcard patterns, use a comma to separate the names, with no space after the comma. For example, `logstash-app1-*,default-logs-*`. - -`xpack.infra.sources.default.metricAlias`:: -Index pattern for matching indices that contain Metricbeat data. Defaults to `metricbeat-*`. To match multiple wildcard patterns, use a comma to separate the names, with no space after the comma. For example, `logstash-app1-*,default-logs-*`. - -`xpack.infra.sources.default.fields.timestamp`:: -Timestamp used to sort log entries. Defaults to `@timestamp`. - `xpack.infra.sources.default.fields.message`:: Fields used to display messages in the Logs app. Defaults to `['message', '@message']`. -`xpack.infra.sources.default.fields.tiebreaker`:: -Field used to break ties between two entries with the same timestamp. Defaults to `_doc`. - -`xpack.infra.sources.default.fields.host`:: -Field used to identify hosts. Defaults to `host.name`. - -`xpack.infra.sources.default.fields.container`:: -Field used to identify Docker containers. Defaults to `container.id`. - -`xpack.infra.sources.default.fields.pod`:: -Field used to identify Kubernetes pods. Defaults to `kubernetes.pod.uid`. - `xpack.infra.alerting.inventory_threshold.group_by_page_size`:: Controls the size of the composite aggregations used by the Inventory Threshold to retrieve all the hosts. Defaults to `10_000`. diff --git a/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc index f5dca28a7da1c..79421e1ac90b5 100644 --- a/docs/setup/settings.asciidoc +++ b/docs/setup/settings.asciidoc @@ -289,11 +289,11 @@ is an alternative to `elasticsearch.username` and `elasticsearch.password`. | `interpreter.enableInVisualize` | Enables use of interpreter in Visualize. *Default: `true`* -| `data.autocomplete.valueSuggestions.timeout:` {ess-icon} +| `unifiedSearch.autocomplete.valueSuggestions.timeout:` {ess-icon} | Time in milliseconds to wait for autocomplete suggestions from {es}. This value must be a whole number greater than zero. *Default: `"1000"`* -| `data.autocomplete.valueSuggestions.terminateAfter:` {ess-icon} +| `unifiedSearch.autocomplete.valueSuggestions.terminateAfter:` {ess-icon} | Maximum number of documents loaded by each shard to generate autocomplete suggestions. This value must be a whole number greater than zero. *Default: `"100000"`* @@ -500,7 +500,7 @@ send on all responses to the client from the {kib} server. *Default: `{}`* |[[server-host]] `server.host:` | This setting specifies the host of the -back end server. To allow remote users to connect, set the value to the IP address or DNS name of the {kib} server. *Default: `"localhost"`* +back end server. To allow remote users to connect, set the value to the IP address or DNS name of the {kib} server. Use `0.0.0.0` to make Kibana listen on all IPs (public and private). *Default: `"localhost"`* | `server.keepaliveTimeout:` | The number of milliseconds to wait for additional data before restarting @@ -543,10 +543,6 @@ inactive socket. *Default: `"120000"`* | Paths to a PEM-encoded X.509 server certificate and its corresponding private key. These are used by {kib} to establish trust when receiving inbound SSL/TLS connections from users. -|[[server-uuid]] `server.uuid:` - | The unique identifier for this {kib} instance. - - |=== [NOTE] @@ -627,6 +623,9 @@ all http requests to https over the port configured as <> + +Before retrying the migration, inspect the output of the `_cluster/allocation/explain?index=${targetIndex}` API to identify why the index isn't yellow: + +[source,sh] +-------------------------------------------- +GET _cluster/allocation/explain +{ + "index": ".kibana_8.1.0_001", + "shard": 0, + "primary": true, +} +-------------------------------------------- +If the cluster exceeded the low watermark for disk usage, the output should contain a message similar to this: + +[source,sh] +-------------------------------------------- +"The node is above the low watermark cluster setting [cluster.routing.allocation.disk.watermark.low=85%], using more disk space than the maximum allowed [85.0%], actual free: [11.692661332965082%]" +-------------------------------------------- +Refer to the {es} guide for how to {ref}/fix-common-cluster-issues.html#_error_disk_usage_exceeded_flood_stage_watermark_index_has_read_only_allow_delete_block[fix common cluster issues]. + +If routing allocation is the issue, the `_cluster/allocation/explain` API will return an entry similar to this: + +[source,sh] +-------------------------------------------- +"allocate_explanation" : "cannot allocate because allocation is not permitted to any of the nodes" +-------------------------------------------- + +[float] +[[routing-allocation-disabled]] +==== Routing allocation disabled or restricted +Upgrade migrations fail because routing allocation is disabled or restricted (`cluster.routing.allocation.enable: none/primaries/new_primaries`), which causes {kib} to log errors such as: + +[source,sh] +-------------------------------------------- +Unable to complete saved object migrations for the [.kibana] index: [unsupported_cluster_routing_allocation] The elasticsearch cluster has cluster routing allocation incorrectly set for migrations to continue. To proceed, please remove the cluster routing allocation settings with PUT /_cluster/settings {"transient": {"cluster.routing.allocation.enable": null}, "persistent": {"cluster.routing.allocation.enable": null}} +-------------------------------------------- + +To get around the issue, remove the transient and persisted routing allocation settings: +[source,sh] +-------------------------------------------- +PUT /_cluster/settings +{ + "transient": { + "cluster.routing.allocation.enable": null + }, + "persistent": { + "cluster.routing.allocation.enable": null + } +} +-------------------------------------------- diff --git a/docs/user/alerting/troubleshooting/testing-connectors.asciidoc b/docs/user/alerting/troubleshooting/testing-connectors.asciidoc index f90a7ebc35614..64ba106655321 100644 --- a/docs/user/alerting/troubleshooting/testing-connectors.asciidoc +++ b/docs/user/alerting/troubleshooting/testing-connectors.asciidoc @@ -39,6 +39,7 @@ $ kbn-action ls "service": null }, "isPreconfigured": false, + "isDeprecated": false, "referencedByCount": 0 } ] diff --git a/docs/user/dashboard/vega-reference.asciidoc b/docs/user/dashboard/vega-reference.asciidoc index b593eacf703fb..95b1ffb27b476 100644 --- a/docs/user/dashboard/vega-reference.asciidoc +++ b/docs/user/dashboard/vega-reference.asciidoc @@ -242,12 +242,17 @@ experimental[] Access the Elastic Map Service files via the same mechanism: url: { // "type" defaults to "elasticsearch" otherwise %type%: emsfile - // Name of the file, exactly as in the Region map visualization + // Name of the file, exactly as in https://maps.elastic.co name: World Countries } -// The result is a geojson file, get its features to use -// this data source with the "shape" marks +// The result is either a topojson file or a geojson file. +// Refer to the Default format for the file at https://maps.elastic.co +// Get its features to use this data source with the "shape" marks // https://vega.github.io/vega/docs/marks/shape/ +// For a topojson file use +format: {type: "topojson", feature: "data"} + +// For a geojson file use format: {property: "features"} ---- @@ -310,16 +315,28 @@ experimental[] You can use the *Vega* https://vega.github.io/vega/docs/data/[dat [source,yaml] ---- -url: { - // "type" defaults to "elasticsearch" otherwise - %type%: emsfile - // Name of the file, exactly as in the Region map visualization - name: World Countries -} -// The result is a geojson file, get its features to use -// this data source with the "shape" marks -// https://vega.github.io/vega/docs/marks/shape/ -format: {property: "features"} + "data": [ + { + "name": "countries", + "url": { + // "type" defaults to "elasticsearch" otherwise + %type%: emsfile + // Name of the file, exactly as in the Region map visualization + name: World Countries + }, + // The result is a topojson file, get its features to use + // this data source with the "shape" marks + // https://vega.github.io/vega/docs/marks/shape/ + "format": {"type": "topojson", "feature": "data"}, + } + ], + "marks": [ + { + "type": "shape", + "from": {"data": "countries"}, + "transform": [{"type": "geoshape", "projection": "projection"}] + } + ] ---- [float] diff --git a/examples/screenshot_mode_example/server/routes.ts b/examples/screenshot_mode_example/server/routes.ts index adf4c2e2b6fc5..44515abc48c70 100644 --- a/examples/screenshot_mode_example/server/routes.ts +++ b/examples/screenshot_mode_example/server/routes.ts @@ -14,7 +14,7 @@ export const registerRoutes = ({ router, log, screenshotMode }: RouteDependencie { path: `${BASE_API_ROUTE}/check_is_screenshot`, validate: false }, async (ctx, req, res) => { log.info(`Reading screenshot mode from a request: ${screenshotMode.isScreenshotMode(req)}`); - log.info(`Reading is screenshot mode from ctx: ${ctx.screenshotMode.isScreenshot}`); + log.info(`Reading is screenshot mode from ctx: ${(await ctx.screenshotMode).isScreenshot}`); return res.ok(); } ); diff --git a/examples/search_examples/server/routes/server_search_route.ts b/examples/search_examples/server/routes/server_search_route.ts index d7464561a0abb..632952b6c4617 100644 --- a/examples/search_examples/server/routes/server_search_route.ts +++ b/examples/search_examples/server/routes/server_search_route.ts @@ -33,8 +33,9 @@ export function registerServerSearchRoute(router: IRouter=2.0.0 <4.0.0", - "@types/selenium-webdriver": "^4.0.18", + "@types/selenium-webdriver": "^4.0.19", "@types/semver": "^7", "@types/set-value": "^2.0.0", "@types/sinon": "^7.0.13", @@ -755,7 +753,7 @@ "@types/tempy": "^0.2.0", "@types/testing-library__jest-dom": "^5.14.3", "@types/tinycolor2": "^1.4.1", - "@types/tough-cookie": "^4.0.1", + "@types/tough-cookie": "^4.0.2", "@types/type-detect": "^4.0.1", "@types/use-resize-observer": "^6.0.0", "@types/uuid": "^3.4.4", @@ -772,9 +770,9 @@ "@types/yargs": "^15.0.0", "@types/yauzl": "^2.9.1", "@types/zen-observable": "^0.8.0", - "@typescript-eslint/eslint-plugin": "^5.17.0", - "@typescript-eslint/parser": "^5.17.0", - "@typescript-eslint/typescript-estree": "^5.17.0", + "@typescript-eslint/eslint-plugin": "^5.20.0", + "@typescript-eslint/parser": "^5.20.0", + "@typescript-eslint/typescript-estree": "^5.20.0", "@yarnpkg/lockfile": "^1.1.0", "abab": "^2.0.4", "aggregate-error": "^3.1.0", @@ -912,7 +910,7 @@ "postcss": "^7.0.32", "postcss-loader": "^3.0.0", "postcss-prefix-selector": "^1.7.2", - "prettier": "^2.6.1", + "prettier": "^2.6.2", "pretty-format": "^27.5.1", "q": "^1.5.1", "react-test-renderer": "^16.12.0", diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel index 567e5dd65d664..43c80fc882159 100644 --- a/packages/BUILD.bazel +++ b/packages/BUILD.bazel @@ -26,7 +26,6 @@ filegroup( "//packages/kbn-babel-preset:build", "//packages/kbn-bazel-packages:build", "//packages/kbn-bazel-runner:build", - "//packages/kbn-ci-stats-client:build", "//packages/kbn-ci-stats-core:build", "//packages/kbn-ci-stats-reporter:build", "//packages/kbn-cli-dev-mode:build", @@ -126,7 +125,6 @@ filegroup( "//packages/kbn-axe-config:build_types", "//packages/kbn-bazel-packages:build_types", "//packages/kbn-bazel-runner:build_types", - "//packages/kbn-ci-stats-client:build_types", "//packages/kbn-ci-stats-core:build_types", "//packages/kbn-ci-stats-reporter:build_types", "//packages/kbn-cli-dev-mode:build_types", diff --git a/packages/analytics/client/src/analytics_client/analytics_client.test.ts b/packages/analytics/client/src/analytics_client/analytics_client.test.ts index 08515ecae8d1e..1e8d5aa5445c0 100644 --- a/packages/analytics/client/src/analytics_client/analytics_client.test.ts +++ b/packages/analytics/client/src/analytics_client/analytics_client.test.ts @@ -19,7 +19,8 @@ import { TelemetryCounterType } from '../events'; const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); -describe('AnalyticsClient', () => { +// FLAKY: https://github.com/elastic/kibana/issues/131369 +describe.skip('AnalyticsClient', () => { let analyticsClient: AnalyticsClient; let logger: MockedLogger; diff --git a/packages/kbn-bazel-runner/jest.config.js b/packages/kbn-bazel-runner/jest.config.js deleted file mode 100644 index 4d4f77a8f43f3..0000000000000 --- a/packages/kbn-bazel-runner/jest.config.js +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -module.exports = { - preset: '@kbn/test/jest_node', - rootDir: '../..', - roots: ['/packages/kbn-bazel-runner'], -}; diff --git a/packages/kbn-ci-stats-client/BUILD.bazel b/packages/kbn-ci-stats-client/BUILD.bazel deleted file mode 100644 index 7017adc604416..0000000000000 --- a/packages/kbn-ci-stats-client/BUILD.bazel +++ /dev/null @@ -1,120 +0,0 @@ -load("@npm//@bazel/typescript:index.bzl", "ts_config") -load("@build_bazel_rules_nodejs//:index.bzl", "js_library") -load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") - -PKG_DIRNAME = "kbn-ci-stats-client" -PKG_REQUIRE_NAME = "@kbn/ci-stats-client" - -SOURCE_FILES = glob( - [ - "src/**/*.ts", - ], - exclude = [ - "**/*.test.*", - ], -) - -SRCS = SOURCE_FILES - -filegroup( - name = "srcs", - srcs = SRCS, -) - -NPM_MODULE_EXTRA_FILES = [ - "package.json", -] - -# In this array place runtime dependencies, including other packages and NPM packages -# which must be available for this code to run. -# -# To reference other packages use: -# "//repo/relative/path/to/package" -# eg. "//packages/kbn-utils" -# -# To reference a NPM package use: -# "@npm//name-of-package" -# eg. "@npm//lodash" -RUNTIME_DEPS = [ - "@npm//axios", - "//packages/kbn-ci-stats-core", - "//packages/kbn-tooling-log", -] - -# In this array place dependencies necessary to build the types, which will include the -# :npm_module_types target of other packages and packages from NPM, including @types/* -# packages. -# -# To reference the types for another package use: -# "//repo/relative/path/to/package:npm_module_types" -# eg. "//packages/kbn-utils:npm_module_types" -# -# References to NPM packages work the same as RUNTIME_DEPS -TYPES_DEPS = [ - "@npm//@types/node", - "@npm//@types/jest", - "@npm//axios", - "//packages/kbn-ci-stats-core:npm_module_types", - "//packages/kbn-tooling-log:npm_module_types", -] - -jsts_transpiler( - name = "target_node", - srcs = SRCS, - build_pkg_name = package_name(), -) - -ts_config( - name = "tsconfig", - src = "tsconfig.json", - deps = [ - "//:tsconfig.base.json", - "//:tsconfig.bazel.json", - ], -) - -ts_project( - name = "tsc_types", - args = ['--pretty'], - srcs = SRCS, - deps = TYPES_DEPS, - declaration = True, - emit_declaration_only = True, - out_dir = "target_types", - root_dir = "src", - tsconfig = ":tsconfig", -) - -js_library( - name = PKG_DIRNAME, - srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node"], - package_name = PKG_REQUIRE_NAME, - visibility = ["//visibility:public"], -) - -pkg_npm( - name = "npm_module", - deps = [":" + PKG_DIRNAME], -) - -filegroup( - name = "build", - srcs = [":npm_module"], - visibility = ["//visibility:public"], -) - -pkg_npm_types( - name = "npm_module_types", - srcs = SRCS, - deps = [":tsc_types"], - package_name = PKG_REQUIRE_NAME, - tsconfig = ":tsconfig", - visibility = ["//visibility:public"], -) - -filegroup( - name = "build_types", - srcs = [":npm_module_types"], - visibility = ["//visibility:public"], -) diff --git a/packages/kbn-ci-stats-client/README.md b/packages/kbn-ci-stats-client/README.md deleted file mode 100644 index d1f6c59e978c9..0000000000000 --- a/packages/kbn-ci-stats-client/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# @kbn/ci-stats-client - -Client for reading data stored at https://ci-stats.kibana.dev \ No newline at end of file diff --git a/packages/kbn-ci-stats-client/jest.config.js b/packages/kbn-ci-stats-client/jest.config.js deleted file mode 100644 index d855d7886d0d7..0000000000000 --- a/packages/kbn-ci-stats-client/jest.config.js +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -module.exports = { - preset: '@kbn/test/jest_node', - rootDir: '../..', - roots: ['/packages/kbn-ci-stats-client'], -}; diff --git a/packages/kbn-ci-stats-client/package.json b/packages/kbn-ci-stats-client/package.json deleted file mode 100644 index 709f6a3454d59..0000000000000 --- a/packages/kbn-ci-stats-client/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "@kbn/ci-stats-client", - "private": true, - "version": "1.0.0", - "main": "./target_node/index.js", - "license": "SSPL-1.0 OR Elastic License 2.0", - "kibana": { - "devOnly": true - } -} diff --git a/packages/kbn-ci-stats-client/src/ci_stats_client.ts b/packages/kbn-ci-stats-client/src/ci_stats_client.ts deleted file mode 100644 index a7ab6f1cc4cb8..0000000000000 --- a/packages/kbn-ci-stats-client/src/ci_stats_client.ts +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import Axios from 'axios'; -import { ToolingLog } from '@kbn/tooling-log'; - -import { parseConfig, Config, CiStatsMetadata } from '@kbn/ci-stats-core'; - -interface LatestTestGroupStatsOptions { - /** The Kibana branch to get stats for, eg "main" */ - branch: string; - /** The CI job names to filter builds by, eg "kibana-hourly" */ - ciJobNames: string[]; - /** Filter test groups by group type */ - testGroupType?: string; -} - -interface CompleteSuccessBuildSource { - jobName: string; - jobRunner: string; - completedAt: string; - commit: string; - startedAt: string; - branch: string; - result: 'SUCCESS'; - jobId: string; - targetBranch: string | null; - fromKibanaCiProduction: boolean; - requiresValidMetrics: boolean | null; - jobUrl: string; - mergeBase: string | null; -} - -interface TestGroupSource { - '@timestamp': string; - buildId: string; - name: string; - type: string; - startTime: string; - durationMs: number; - meta: CiStatsMetadata; -} - -interface LatestTestGroupStatsResp { - build: CompleteSuccessBuildSource & { id: string }; - testGroups: Array; -} - -export class CiStatsClient { - /** - * Create a CiStatsReporter by inspecting the ENV for the necessary config - */ - static fromEnv(log: ToolingLog) { - return new CiStatsClient(parseConfig(log)); - } - - constructor(private readonly config?: Config) {} - - isEnabled() { - return !!this.config?.apiToken; - } - - async getLatestTestGroupStats(options: LatestTestGroupStatsOptions) { - if (!this.config || !this.config.apiToken) { - throw new Error('No ciStats config available, call `isEnabled()` before using the client'); - } - - const resp = await Axios.request({ - baseURL: 'https://ci-stats.kibana.dev', - url: '/v1/test_group_stats', - params: { - branch: options.branch, - ci_job_name: options.ciJobNames.join(','), - test_group_type: options.testGroupType, - }, - headers: { - Authentication: `token ${this.config.apiToken}`, - }, - }); - - return resp.data; - } -} diff --git a/packages/kbn-ci-stats-client/src/index.ts b/packages/kbn-ci-stats-client/src/index.ts deleted file mode 100644 index ac32c69b9f7b7..0000000000000 --- a/packages/kbn-ci-stats-client/src/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export { CiStatsClient } from './ci_stats_client'; diff --git a/packages/kbn-ci-stats-client/tsconfig.json b/packages/kbn-ci-stats-client/tsconfig.json deleted file mode 100644 index a8cfc2cceb08b..0000000000000 --- a/packages/kbn-ci-stats-client/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "extends": "../../tsconfig.bazel.json", - "compilerOptions": { - "declaration": true, - "emitDeclarationOnly": true, - "outDir": "target_types", - "rootDir": "src", - "stripInternal": false, - "types": [ - "jest", - "node" - ] - }, - "include": [ - "src/**/*" - ] -} diff --git a/packages/kbn-ci-stats-core/README.md b/packages/kbn-ci-stats-core/README.md index b2e34a492b745..741728394aa83 100644 --- a/packages/kbn-ci-stats-core/README.md +++ b/packages/kbn-ci-stats-core/README.md @@ -1,3 +1,3 @@ # @kbn/ci-stats-core -Config and types used by `@kbn/ci-stats-client` and `@kbn/ci-stats-reporter`. \ No newline at end of file +Config and types used by `@kbn/ci-stats-reporter`. \ No newline at end of file diff --git a/packages/kbn-ci-stats-core/jest.config.js b/packages/kbn-ci-stats-core/jest.config.js deleted file mode 100644 index 0feb7b4e1b872..0000000000000 --- a/packages/kbn-ci-stats-core/jest.config.js +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -module.exports = { - preset: '@kbn/test/jest_node', - rootDir: '../..', - roots: ['/packages/kbn-ci-stats-core'], -}; diff --git a/packages/kbn-ci-stats-reporter/jest.config.js b/packages/kbn-ci-stats-reporter/jest.config.js deleted file mode 100644 index bf58324f440a3..0000000000000 --- a/packages/kbn-ci-stats-reporter/jest.config.js +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -module.exports = { - preset: '@kbn/test/jest_node', - rootDir: '../..', - roots: ['/packages/kbn-ci-stats-reporter'], -}; diff --git a/packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts b/packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts index d709927787b0e..5d3f17a76f687 100644 --- a/packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts +++ b/packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts @@ -22,6 +22,20 @@ import { parseConfig, Config, CiStatsMetadata } from '@kbn/ci-stats-core'; import type { CiStatsTestGroupInfo, CiStatsTestRun } from './ci_stats_test_group_types'; const BASE_URL = 'https://ci-stats.kibana.dev'; +const SECOND = 1000; +const MINUTE = 60 * SECOND; + +function limitMetaStrings(meta: CiStatsMetadata) { + return Object.fromEntries( + Object.entries(meta).map(([key, value]) => { + if (typeof value === 'string' && value.length > 2000) { + return [key, value.slice(0, 2000)]; + } + + return [key, value]; + }) + ); +} /** A ci-stats metric record */ export interface CiStatsMetric { @@ -84,10 +98,8 @@ export interface CiStatsReportTestsOptions { } /* @internal */ -interface ReportTestsResponse { - buildId: string; +interface ReportTestGroupResponse { groupId: string; - testRunCount: number; } /* @internal */ @@ -97,6 +109,7 @@ interface ReqOptions { body: any; bodyDesc: string; query?: AxiosRequestConfig['params']; + timeout?: number; } /** Object that helps report data to the ci-stats service */ @@ -138,7 +151,14 @@ export class CiStatsReporter { } const buildId = this.config?.buildId; - const timings = options.timings; + const timings = options.timings.map((timing) => + timing.meta + ? { + ...timing, + meta: limitMetaStrings(timing.meta), + } + : timing + ); const upstreamBranch = options.upstreamBranch ?? this.getUpstreamBranch(); const kibanaUuid = options.kibanaUuid === undefined ? this.getKibanaUuid() : options.kibanaUuid; let email; @@ -238,18 +258,52 @@ export class CiStatsReporter { ); } - return await this.req({ + const groupResp = await this.req({ auth: true, - path: '/v1/test_group', + path: '/v2/test_group', query: { buildId: this.config?.buildId, }, - bodyDesc: `[${group.name}/${group.type}] test groups with ${testRuns.length} tests`, - body: [ - JSON.stringify({ group }), - ...testRuns.map((testRun) => JSON.stringify({ testRun })), - ].join('\n'), + bodyDesc: `[${group.name}/${group.type}] test group`, + body: group, }); + + if (!groupResp) { + return; + } + + let bufferBytes = 0; + const buffer: string[] = []; + const flushBuffer = async () => { + await this.req<{ testRunCount: number }>({ + auth: true, + path: '/v2/test_runs', + query: { + buildId: this.config?.buildId, + groupId: groupResp.groupId, + groupType: group.type, + }, + bodyDesc: `[${group.name}/${group.type}] Chunk of ${bufferBytes} bytes`, + body: buffer.join('\n'), + timeout: 5 * MINUTE, + }); + buffer.length = 0; + bufferBytes = 0; + }; + + // send test runs in chunks of ~500kb + for (const testRun of testRuns) { + const json = JSON.stringify(testRun); + bufferBytes += json.length; + buffer.push(json); + if (bufferBytes >= 450000) { + await flushBuffer(); + } + } + + if (bufferBytes) { + await flushBuffer(); + } } /** @@ -286,7 +340,7 @@ export class CiStatsReporter { } } - private async req({ auth, body, bodyDesc, path, query }: ReqOptions) { + private async req({ auth, body, bodyDesc, path, query, timeout = 60 * SECOND }: ReqOptions) { let attempt = 0; const maxAttempts = 5; @@ -315,6 +369,7 @@ export class CiStatsReporter { // if it can be serialized into a string, send it maxBodyLength: Infinity, maxContentLength: Infinity, + timeout, }); return resp.data; diff --git a/packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts b/packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts index 223273ca82cd3..298b46498aff4 100644 --- a/packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts +++ b/packages/kbn-ci-stats-reporter/src/ci_stats_test_group_types.ts @@ -83,6 +83,10 @@ export interface CiStatsTestGroupInfo { * The name of this specific group (within the "type") */ name: string; + /** + * Overall result of this test group + */ + result: 'fail' | 'pass' | 'skip'; /** * Arbitrary metadata associated with this group. We currently look for a ciGroup metadata property for highlighting that when appropriate */ diff --git a/packages/kbn-cli-dev-mode/src/dev_server.test.ts b/packages/kbn-cli-dev-mode/src/dev_server.test.ts index 772ba097fc31a..959a47ac80803 100644 --- a/packages/kbn-cli-dev-mode/src/dev_server.test.ts +++ b/packages/kbn-cli-dev-mode/src/dev_server.test.ts @@ -72,6 +72,7 @@ const defaultOptions: Options = { processExit$, sigint$, sigterm$, + forceColor: true, }; expect.addSnapshotSerializer(extendedEnvSerializer); @@ -80,7 +81,6 @@ beforeEach(() => { jest.clearAllMocks(); log.messages.length = 0; process.execArgv = ['--inheritted', '--exec', '--argv']; - process.env.FORCE_COLOR = process.env.FORCE_COLOR || '1'; currentProc = undefined; }); diff --git a/packages/kbn-cli-dev-mode/src/dev_server.ts b/packages/kbn-cli-dev-mode/src/dev_server.ts index bed1afe126c15..cf89d2c00d16f 100644 --- a/packages/kbn-cli-dev-mode/src/dev_server.ts +++ b/packages/kbn-cli-dev-mode/src/dev_server.ts @@ -34,6 +34,7 @@ export interface Options { sigint$?: Rx.Observable; sigterm$?: Rx.Observable; mapLogLine?: DevServer['mapLogLine']; + forceColor?: boolean; } export class DevServer { @@ -50,6 +51,7 @@ export class DevServer { private readonly argv: string[]; private readonly gracefulTimeout: number; private readonly mapLogLine?: (line: string) => string | null; + private readonly forceColor: boolean; constructor(options: Options) { this.log = options.log; @@ -62,6 +64,7 @@ export class DevServer { this.sigint$ = options.sigint$ ?? Rx.fromEvent(process, 'SIGINT'); this.sigterm$ = options.sigterm$ ?? Rx.fromEvent(process, 'SIGTERM'); this.mapLogLine = options.mapLogLine; + this.forceColor = options.forceColor ?? !!process.stdout.isTTY; } isReady$() { @@ -141,8 +144,13 @@ export class DevServer { }) ); + const serverOptions = { + script: this.script, + argv: this.argv, + forceColor: this.forceColor, + }; const runServer = () => - usingServerProcess(this.script, this.argv, (proc) => { + usingServerProcess(serverOptions, (proc) => { this.phase$.next('starting'); this.ready$.next(false); diff --git a/packages/kbn-cli-dev-mode/src/using_server_process.ts b/packages/kbn-cli-dev-mode/src/using_server_process.ts index eb997295035d8..690ba250cbcbc 100644 --- a/packages/kbn-cli-dev-mode/src/using_server_process.ts +++ b/packages/kbn-cli-dev-mode/src/using_server_process.ts @@ -18,14 +18,19 @@ interface ProcResource extends Rx.Unsubscribable { unsubscribe(): void; } +interface Options { + script: string; + argv: string[]; + forceColor: boolean; +} + export function usingServerProcess( - script: string, - argv: string[], + options: Options, fn: (proc: execa.ExecaChildProcess) => Rx.Observable ) { return Rx.using( (): ProcResource => { - const proc = execa.node(script, argv, { + const proc = execa.node(options.script, options.argv, { stdio: 'pipe', nodeOptions: [ ...process.execArgv, @@ -36,7 +41,7 @@ export function usingServerProcess( NODE_OPTIONS: process.env.NODE_OPTIONS, isDevCliChild: 'true', ELASTIC_APM_SERVICE_NAME: 'kibana', - ...(process.stdout.isTTY ? { FORCE_COLOR: 'true' } : {}), + ...(options.forceColor ? { FORCE_COLOR: 'true' } : {}), }, }); diff --git a/packages/kbn-doc-links/src/get_doc_links.ts b/packages/kbn-doc-links/src/get_doc_links.ts index f4d01b8f12353..14fd80c3a8552 100644 --- a/packages/kbn-doc-links/src/get_doc_links.ts +++ b/packages/kbn-doc-links/src/get_doc_links.ts @@ -387,6 +387,7 @@ export const getDocLinks = ({ kibanaBranch }: GetDocLinkOptions): DocLinks => { regressionEvaluation: `${ELASTIC_WEBSITE_URL}guide/en/machine-learning/${DOC_LINK_VERSION}/ml-dfa-regression.html#ml-dfanalytics-regression-evaluation`, classificationAucRoc: `${ELASTIC_WEBSITE_URL}guide/en/machine-learning/${DOC_LINK_VERSION}/ml-dfa-classification.html#ml-dfanalytics-class-aucroc`, setUpgradeMode: `${ELASTICSEARCH_DOCS}ml-set-upgrade-mode.html`, + trainedModels: `${ELASTIC_WEBSITE_URL}guide/en/machine-learning/${DOC_LINK_VERSION}/ml-trained-models.html`, }, transforms: { guide: `${ELASTICSEARCH_DOCS}transforms.html`, @@ -458,6 +459,9 @@ export const getDocLinks = ({ kibanaBranch }: GetDocLinkOptions): DocLinks => { monitorLogstash: `${ELASTIC_WEBSITE_URL}guide/en/logstash/${DOC_LINK_VERSION}/monitoring-with-metricbeat.html`, troubleshootKibana: `${KIBANA_DOCS}monitor-troubleshooting.html`, }, + reporting: { + cloudMinimumRequirements: `${KIBANA_DOCS}reporting-getting-started.html#reporting-on-cloud-resource-requirements`, + }, security: { apiKeyServiceSettings: `${ELASTICSEARCH_DOCS}security-settings.html#api-key-service-settings`, clusterPrivileges: `${ELASTICSEARCH_DOCS}security-privileges.html#privileges-list-cluster`, @@ -642,5 +646,10 @@ export const getDocLinks = ({ kibanaBranch }: GetDocLinkOptions): DocLinks => { legal: { privacyStatement: `${ELASTIC_WEBSITE_URL}legal/privacy-statement`, }, + kibanaUpgradeSavedObjects: { + resolveMigrationFailures: `${KIBANA_DOCS}resolve-migrations-failures.html`, + repeatedTimeoutRequests: `${KIBANA_DOCS}resolve-migrations-failures.html#_repeated_time_out_requests_that_eventually_fail`, + routingAllocationDisabled: `${KIBANA_DOCS}resolve-migrations-failures.html#routing-allocation-disabled`, + }, }); }; diff --git a/packages/kbn-doc-links/src/types.ts b/packages/kbn-doc-links/src/types.ts index e51ef91ac43b1..4a5a9fdeb9576 100644 --- a/packages/kbn-doc-links/src/types.ts +++ b/packages/kbn-doc-links/src/types.ts @@ -310,6 +310,9 @@ export interface DocLinks { gdalTutorial: string; }>; readonly monitoring: Record; + readonly reporting: Readonly<{ + cloudMinimumRequirements: string; + }>; readonly security: Readonly<{ apiKeyServiceSettings: string; clusterPrivileges: string; @@ -398,4 +401,9 @@ export interface DocLinks { readonly legal: { readonly privacyStatement: string; }; + readonly kibanaUpgradeSavedObjects: { + readonly resolveMigrationFailures: string; + readonly repeatedTimeoutRequests: string; + readonly routingAllocationDisabled: string; + }; } diff --git a/packages/kbn-docs-utils/src/api_docs/build_api_declarations/buid_api_declaration.test.ts b/packages/kbn-docs-utils/src/api_docs/build_api_declarations/buid_api_declaration.test.ts index 9b86db445c225..527ce59011a8b 100644 --- a/packages/kbn-docs-utils/src/api_docs/build_api_declarations/buid_api_declaration.test.ts +++ b/packages/kbn-docs-utils/src/api_docs/build_api_declarations/buid_api_declaration.test.ts @@ -53,6 +53,24 @@ it('Test number primitive doc def', () => { expect(def.type).toBe(TypeKind.NumberKind); }); +it('Test a constructor type declaration inside an interface', () => { + const node = nodes.find((n) => getNodeName(n) === 'ClassConstructorWithStaticProperties'); + expect(node).toBeDefined(); + const def = buildApiDeclarationTopNode(node!, { + plugins, + log, + currentPluginId: plugins[0].manifest.id, + scope: ApiScope.CLIENT, + captureReferences: false, + }); + + expect(def.type).toBe(TypeKind.InterfaceKind); + expect(def.children).toHaveLength(2); + expect(def.children![1].type).toBe(TypeKind.FunctionKind); + expect(def.children![1].label).toBe('new'); + expect(def.children![1].id).toBe('def-public.ClassConstructorWithStaticProperties.new'); +}); + it('Function type is exported as type with signature', () => { const node = nodes.find((n) => getNodeName(n) === 'FnWithGeneric'); expect(node).toBeDefined(); diff --git a/packages/kbn-docs-utils/src/api_docs/build_api_declarations/build_api_declaration.ts b/packages/kbn-docs-utils/src/api_docs/build_api_declarations/build_api_declaration.ts index 809097ee73818..2e167c7a0a783 100644 --- a/packages/kbn-docs-utils/src/api_docs/build_api_declarations/build_api_declaration.ts +++ b/packages/kbn-docs-utils/src/api_docs/build_api_declarations/build_api_declaration.ts @@ -65,12 +65,17 @@ export function buildApiDeclaration(node: Node, opts: BuildApiDecOpts): ApiDecla Node.isMethodSignature(node) || Node.isFunctionDeclaration(node) || Node.isMethodDeclaration(node) || + Node.isConstructSignatureDeclaration(node) || Node.isConstructorDeclaration(node) ) { return buildFunctionDec(node, { ...opts, // Use "Constructor" if applicable, instead of the default "Unnamed" - name: Node.isConstructorDeclaration(node) ? 'Constructor' : node.getName() || 'Unnamed', + name: Node.isConstructSignatureDeclaration(node) + ? 'new' + : Node.isConstructorDeclaration(node) + ? 'Constructor' + : node.getName() || 'Unnamed', }); } else if ( Node.isPropertySignature(node) || diff --git a/packages/kbn-docs-utils/src/api_docs/build_api_declarations/build_function_dec.ts b/packages/kbn-docs-utils/src/api_docs/build_api_declarations/build_function_dec.ts index 3ba688f1ee284..020ffd402366a 100644 --- a/packages/kbn-docs-utils/src/api_docs/build_api_declarations/build_function_dec.ts +++ b/packages/kbn-docs-utils/src/api_docs/build_api_declarations/build_function_dec.ts @@ -11,6 +11,7 @@ import { MethodDeclaration, ConstructorDeclaration, MethodSignature, + ConstructSignatureDeclaration, } from 'ts-morph'; import { buildApiDecsForParameters } from './build_parameter_decs'; @@ -23,7 +24,12 @@ import { BuildApiDecOpts } from './types'; * Takes the various function-like node declaration types and converts them into an ApiDeclaration. */ export function buildFunctionDec( - node: FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | MethodSignature, + node: + | ConstructSignatureDeclaration + | FunctionDeclaration + | MethodDeclaration + | ConstructorDeclaration + | MethodSignature, opts: BuildApiDecOpts ): ApiDeclaration { const fn = { diff --git a/packages/kbn-docs-utils/src/api_docs/build_api_declarations/utils.ts b/packages/kbn-docs-utils/src/api_docs/build_api_declarations/utils.ts index a57b1790b27a8..76328a314b066 100644 --- a/packages/kbn-docs-utils/src/api_docs/build_api_declarations/utils.ts +++ b/packages/kbn-docs-utils/src/api_docs/build_api_declarations/utils.ts @@ -46,7 +46,11 @@ export function buildParentApiId(parentName: string, parentsParentApiId?: string } export function getOptsForChild(node: Node, parentOpts: BuildApiDecOpts): BuildApiDecOpts { - const name = isNamedNode(node) ? node.getName() : 'Unnamed'; + const name = Node.isConstructSignatureDeclaration(node) + ? 'new' + : isNamedNode(node) + ? node.getName() + : 'Unnamed'; return getOptsForChildWithName(name, parentOpts); } diff --git a/packages/kbn-docs-utils/src/api_docs/build_api_docs_cli.ts b/packages/kbn-docs-utils/src/api_docs/build_api_docs_cli.ts index 0617e35a88615..41bb6400b92ab 100644 --- a/packages/kbn-docs-utils/src/api_docs/build_api_docs_cli.ts +++ b/packages/kbn-docs-utils/src/api_docs/build_api_docs_cli.ts @@ -65,11 +65,16 @@ export function runBuildApiDocsCli() { // Delete all files except the README that warns about the auto-generated nature of // the folder. const files = Fs.readdirSync(outputFolder); - files.forEach((file) => { - if (file.indexOf('README.md') < 0) { - Fs.rmSync(Path.resolve(outputFolder, file)); - } - }); + await Promise.all( + files + .filter((file) => file.indexOf('README.md') < 0) + .map( + (file) => + new Promise((resolve, reject) => + Fs.rm(Path.resolve(outputFolder, file), (err) => (err ? reject(err) : resolve())) + ) + ) + ); } const collectReferences = flags.references as boolean; diff --git a/packages/kbn-docs-utils/src/api_docs/mdx/split_apis_by_folder.test.ts b/packages/kbn-docs-utils/src/api_docs/mdx/split_apis_by_folder.test.ts index b1862f9bc2165..1a1ecb8ec3e67 100644 --- a/packages/kbn-docs-utils/src/api_docs/mdx/split_apis_by_folder.test.ts +++ b/packages/kbn-docs-utils/src/api_docs/mdx/split_apis_by_folder.test.ts @@ -38,7 +38,7 @@ beforeAll(() => { }); test('foo service has all exports', () => { - expect(doc?.client.length).toBe(37); + expect(doc?.client.length).toBe(38); const split = splitApisByFolder(doc); expect(split.length).toBe(2); @@ -47,5 +47,5 @@ test('foo service has all exports', () => { expect(fooDoc?.common.length).toBe(1); expect(fooDoc?.client.length).toBe(2); - expect(mainDoc?.client.length).toBe(35); + expect(mainDoc?.client.length).toBe(36); }); diff --git a/packages/kbn-docs-utils/src/api_docs/tests/__fixtures__/src/plugin_a/public/index.ts b/packages/kbn-docs-utils/src/api_docs/tests/__fixtures__/src/plugin_a/public/index.ts index 345e85bc044b7..ad3d1204aeda9 100644 --- a/packages/kbn-docs-utils/src/api_docs/tests/__fixtures__/src/plugin_a/public/index.ts +++ b/packages/kbn-docs-utils/src/api_docs/tests/__fixtures__/src/plugin_a/public/index.ts @@ -24,6 +24,11 @@ export interface InterfaceWithIndexSignature { [key: string]: { foo: string }; } +export interface ClassConstructorWithStaticProperties { + staticProperty1: string; + new (config: { foo: string }): InterfaceWithIndexSignature; +} + export function plugin() { return new PluginA(); } diff --git a/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_a.devdocs.json b/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_a.devdocs.json index ff977517cb5a7..88e4043442e88 100644 --- a/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_a.devdocs.json +++ b/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_a.devdocs.json @@ -712,6 +712,67 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "pluginA", + "id": "def-public.ClassConstructorWithStaticProperties", + "type": "Interface", + "tags": [], + "label": "ClassConstructorWithStaticProperties", + "description": [], + "path": "packages/kbn-docs-utils/src/api_docs/tests/__fixtures__/src/plugin_a/public/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "pluginA", + "id": "def-public.ClassConstructorWithStaticProperties.staticProperty1", + "type": "string", + "tags": [], + "label": "staticProperty1", + "description": [], + "path": "packages/kbn-docs-utils/src/api_docs/tests/__fixtures__/src/plugin_a/public/index.ts", + "deprecated": false + }, + { + "parentPluginId": "pluginA", + "id": "def-public.ClassConstructorWithStaticProperties.new", + "type": "Function", + "tags": [], + "label": "new", + "description": [], + "signature": [ + "any" + ], + "path": "packages/kbn-docs-utils/src/api_docs/tests/__fixtures__/src/plugin_a/public/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "pluginA", + "id": "def-public.ClassConstructorWithStaticProperties.new.$1", + "type": "Object", + "tags": [], + "label": "config", + "description": [], + "path": "packages/kbn-docs-utils/src/api_docs/tests/__fixtures__/src/plugin_a/public/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "pluginA", + "id": "def-public.ClassConstructorWithStaticProperties.new.$1.foo", + "type": "string", + "tags": [], + "label": "foo", + "description": [], + "path": "packages/kbn-docs-utils/src/api_docs/tests/__fixtures__/src/plugin_a/public/index.ts", + "deprecated": false + } + ] + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + }, { "parentPluginId": "pluginA", "id": "def-public.ExampleInterface", diff --git a/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_a.mdx b/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_a.mdx index ab80f1f02d0ac..6a66fa74f7c01 100644 --- a/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_a.mdx +++ b/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_a.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/pluginA title: "pluginA" image: https://source.unsplash.com/400x175/?github summary: API docs for the pluginA plugin -date: 2022-02-14 +date: 2022-04-30 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'pluginA'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact Kibana Core for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 131 | 1 | 71 | 2 | +| 136 | 1 | 76 | 2 | ## Client diff --git a/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_a_foo.mdx b/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_a_foo.mdx index e9873f8223017..4082de6306895 100644 --- a/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_a_foo.mdx +++ b/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_a_foo.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/pluginA-foo title: "pluginA.foo" image: https://source.unsplash.com/400x175/?github summary: API docs for the pluginA.foo plugin -date: 2022-02-14 +date: 2022-04-30 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'pluginA.foo'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact Kibana Core for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 131 | 1 | 71 | 2 | +| 136 | 1 | 76 | 2 | ## Client diff --git a/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_b.mdx b/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_b.mdx index 1671cd7a529d3..d69da971f7e3e 100644 --- a/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_b.mdx +++ b/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_b.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/pluginB title: "pluginB" image: https://source.unsplash.com/400x175/?github summary: API docs for the pluginB plugin -date: 2022-02-14 +date: 2022-04-30 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'pluginB'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/packages/kbn-eslint-plugin-imports/jest.integration.config.js b/packages/kbn-eslint-plugin-imports/jest.integration.config.js deleted file mode 100644 index e7d05a6222c88..0000000000000 --- a/packages/kbn-eslint-plugin-imports/jest.integration.config.js +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -module.exports = { - preset: '@kbn/test/jest_integration_node', - rootDir: '../..', - roots: ['/packages/kbn-eslint-plugin-imports'], -}; diff --git a/packages/kbn-generate/jest.config.js b/packages/kbn-generate/jest.config.js deleted file mode 100644 index b72f891cfb1a7..0000000000000 --- a/packages/kbn-generate/jest.config.js +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -module.exports = { - preset: '@kbn/test/jest_node', - rootDir: '../..', - roots: ['/packages/kbn-generate'], -}; diff --git a/packages/kbn-jest-serializers/jest.config.js b/packages/kbn-jest-serializers/jest.config.js deleted file mode 100644 index 23fad67c028bf..0000000000000 --- a/packages/kbn-jest-serializers/jest.config.js +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -module.exports = { - preset: '@kbn/test/jest_node', - rootDir: '../..', - roots: ['/packages/kbn-jest-serializers'], -}; diff --git a/packages/kbn-kibana-json-schema/jest.config.js b/packages/kbn-kibana-json-schema/jest.config.js deleted file mode 100644 index 00bc8f55adc57..0000000000000 --- a/packages/kbn-kibana-json-schema/jest.config.js +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -module.exports = { - preset: '@kbn/test/jest_node', - rootDir: '../..', - roots: ['/packages/kbn-kibana-json-schema'], -}; diff --git a/packages/kbn-mapbox-gl/src/index.ts b/packages/kbn-mapbox-gl/src/index.ts index 3b31aec0011f3..481702b15771b 100644 --- a/packages/kbn-mapbox-gl/src/index.ts +++ b/packages/kbn-mapbox-gl/src/index.ts @@ -8,51 +8,56 @@ import type { Map, + LayerSpecification, + Source, GeoJSONSource, - VectorSource, - Layer, - AnyLayer, - FeatureIdentifier, - Style, - MapboxOptions, + VectorTileSource, + StyleSpecification, + MapEvent, + MapOptions, MapMouseEvent, MapSourceDataEvent, LngLat, LngLatBounds, + Point2D, PointLike, - MapboxGeoJSONFeature, - Point, + MapGeoJSONFeature, CustomLayerInterface, + FilterSpecification, + FeatureIdentifier, } from 'maplibre-gl'; + // @ts-expect-error -import mapboxglDist from 'maplibre-gl/dist/maplibre-gl-csp'; +import maplibreglDist from 'maplibre-gl/dist/maplibre-gl-csp'; // @ts-expect-error import mbRtlPlugin from '!!file-loader!@mapbox/mapbox-gl-rtl-text/mapbox-gl-rtl-text.min.js'; // @ts-expect-error import mbWorkerUrl from '!!file-loader!maplibre-gl/dist/maplibre-gl-csp-worker'; import 'maplibre-gl/dist/maplibre-gl.css'; -const mapboxgl: any = mapboxglDist; -mapboxgl.workerUrl = mbWorkerUrl; -mapboxgl.setRTLTextPlugin(mbRtlPlugin); +const maplibregl: any = maplibreglDist; +maplibregl.workerUrl = mbWorkerUrl; +maplibregl.setRTLTextPlugin(mbRtlPlugin); -export { mapboxgl }; +export { maplibregl }; export type { Map, + LayerSpecification, + StyleSpecification, + Source, GeoJSONSource, - VectorSource, - Layer, - AnyLayer, - FeatureIdentifier, - Style, - MapboxOptions, + VectorTileSource, + MapEvent, + MapOptions, MapMouseEvent, MapSourceDataEvent, LngLat, LngLatBounds, + Point2D, PointLike, - MapboxGeoJSONFeature, - Point, + MapGeoJSONFeature, CustomLayerInterface, + FilterSpecification, + FeatureIdentifier, }; diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index 5ec1645d368a6..9f73dcd620d30 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -1,5 +1,6 @@ pageLoadAssetSize: advancedSettings: 27596 + actions: 20000 alerting: 106936 apm: 64385 canvas: 1066647 @@ -103,8 +104,7 @@ pageLoadAssetSize: fieldFormats: 65209 kibanaReact: 74422 share: 71239 - uiActions: 35121 - dataEnhanced: 24980 + uiActions: 35121 embeddable: 87309 embeddableEnhanced: 22107 uiActionsEnhanced: 38494 @@ -122,9 +122,9 @@ pageLoadAssetSize: sessionView: 77750 cloudSecurityPosture: 19109 visTypeGauge: 24113 - unifiedSearch: 49195 + unifiedSearch: 71059 data: 454087 - expressionXY: 44598 eventAnnotation: 19334 screenshotting: 22870 synthetics: 40958 + expressionXY: 29000 diff --git a/packages/kbn-optimizer/src/babel_runtime_helpers/find_node_libs_browser_polyfills_in_entry_bundles.ts b/packages/kbn-optimizer/src/babel_runtime_helpers/find_node_libs_browser_polyfills_in_entry_bundles.ts new file mode 100644 index 0000000000000..06ad13da2b2f2 --- /dev/null +++ b/packages/kbn-optimizer/src/babel_runtime_helpers/find_node_libs_browser_polyfills_in_entry_bundles.ts @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import Path from 'path'; + +import { run } from '@kbn/dev-utils'; +import { REPO_ROOT } from '@kbn/utils'; + +import { OptimizerConfig } from '../optimizer'; +import { parseStats, inAnyEntryChunk } from './parse_stats'; + +export async function runFindNodeLibsBrowserPolyfillsInEntryBundlesCli() { + run(async ({ log }) => { + const config = OptimizerConfig.create({ + includeCoreBundle: true, + repoRoot: REPO_ROOT, + }); + + const paths = config.bundles.map((b) => Path.resolve(b.outputDir, 'stats.json')); + + log.info('analyzing', paths.length, 'stats files'); + log.verbose(paths); + + const imports = new Set(); + for (const path of paths) { + const stats = parseStats(path); + + for (const module of stats.modules) { + if (!inAnyEntryChunk(stats, module)) { + continue; + } + + // Relying on module name instead of actual imports because these are usual polyfills that assume the global + // Node.js environment when development (i.e.: Buffer doesn't require an import to be used). + if (module.name.includes('node-libs-browser/node_modules/')) { + imports.add(module.name); + } + } + } + + log.success('found', imports.size, 'node-libs-browser/* imports in entry bundles'); + log.write( + Array.from(imports, (i) => `'${i}',`) + .sort() + .join('\n') + ); + }); +} diff --git a/packages/kbn-optimizer/src/babel_runtime_helpers/index.ts b/packages/kbn-optimizer/src/babel_runtime_helpers/index.ts index 58a3ddf263a1d..3a7987f867bc5 100644 --- a/packages/kbn-optimizer/src/babel_runtime_helpers/index.ts +++ b/packages/kbn-optimizer/src/babel_runtime_helpers/index.ts @@ -7,3 +7,4 @@ */ export * from './find_babel_runtime_helpers_in_entry_bundles'; +export * from './find_node_libs_browser_polyfills_in_entry_bundles'; diff --git a/packages/kbn-optimizer/src/babel_runtime_helpers/parse_stats.ts b/packages/kbn-optimizer/src/babel_runtime_helpers/parse_stats.ts index fac0b099b5195..9b9ba11f90c9a 100644 --- a/packages/kbn-optimizer/src/babel_runtime_helpers/parse_stats.ts +++ b/packages/kbn-optimizer/src/babel_runtime_helpers/parse_stats.ts @@ -20,6 +20,7 @@ const partialObject =

(props: P) => { export type Module = TypeOf; const moduleSchema = partialObject({ identifier: schema.string(), + name: schema.string(), chunks: schema.arrayOf(schema.oneOf([schema.string(), schema.number()])), reasons: schema.arrayOf( partialObject({ diff --git a/packages/kbn-plugin-discovery/jest.config.js b/packages/kbn-plugin-discovery/jest.config.js deleted file mode 100644 index 37d7a4f2b63a2..0000000000000 --- a/packages/kbn-plugin-discovery/jest.config.js +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -module.exports = { - preset: '@kbn/test/jest_node', - rootDir: '../..', - roots: ['/packages/kbn-plugin-discovery'], -}; diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js index 32171e030d91a..6638acfef5ef4 100644 --- a/packages/kbn-pm/dist/index.js +++ b/packages/kbn-pm/dist/index.js @@ -1580,8 +1580,21 @@ var _ciStatsCore = __webpack_require__("../../node_modules/@kbn/ci-stats-core/ta */ // @ts-expect-error not "public", but necessary to prevent Jest shimming from breaking things const BASE_URL = 'https://ci-stats.kibana.dev'; +const SECOND = 1000; +const MINUTE = 60 * SECOND; + +function limitMetaStrings(meta) { + return Object.fromEntries(Object.entries(meta).map(([key, value]) => { + if (typeof value === 'string' && value.length > 2000) { + return [key, value.slice(0, 2000)]; + } + + return [key, value]; + })); +} /** A ci-stats metric record */ + /** Object that helps report data to the ci-stats service */ class CiStatsReporter { /** @@ -1631,7 +1644,9 @@ class CiStatsReporter { } const buildId = (_this$config3 = this.config) === null || _this$config3 === void 0 ? void 0 : _this$config3.buildId; - const timings = options.timings; + const timings = options.timings.map(timing => timing.meta ? { ...timing, + meta: limitMetaStrings(timing.meta) + } : timing); const upstreamBranch = (_options$upstreamBran = options.upstreamBranch) !== null && _options$upstreamBran !== void 0 ? _options$upstreamBran : this.getUpstreamBranch(); const kibanaUuid = options.kibanaUuid === undefined ? this.getKibanaUuid() : options.kibanaUuid; let email; @@ -1740,19 +1755,56 @@ class CiStatsReporter { throw new Error('unable to report tests unless buildId is configured and auth config available'); } - return await this.req({ + const groupResp = await this.req({ auth: true, - path: '/v1/test_group', + path: '/v2/test_group', query: { buildId: (_this$config7 = this.config) === null || _this$config7 === void 0 ? void 0 : _this$config7.buildId }, - bodyDesc: `[${group.name}/${group.type}] test groups with ${testRuns.length} tests`, - body: [JSON.stringify({ - group - }), ...testRuns.map(testRun => JSON.stringify({ - testRun - }))].join('\n') + bodyDesc: `[${group.name}/${group.type}] test group`, + body: group }); + + if (!groupResp) { + return; + } + + let bufferBytes = 0; + const buffer = []; + + const flushBuffer = async () => { + var _this$config8; + + await this.req({ + auth: true, + path: '/v2/test_runs', + query: { + buildId: (_this$config8 = this.config) === null || _this$config8 === void 0 ? void 0 : _this$config8.buildId, + groupId: groupResp.groupId, + groupType: group.type + }, + bodyDesc: `[${group.name}/${group.type}] Chunk of ${bufferBytes} bytes`, + body: buffer.join('\n'), + timeout: 5 * MINUTE + }); + buffer.length = 0; + bufferBytes = 0; + }; // send test runs in chunks of ~500kb + + + for (const testRun of testRuns) { + const json = JSON.stringify(testRun); + bufferBytes += json.length; + buffer.push(json); + + if (bufferBytes >= 450000) { + await flushBuffer(); + } + } + + if (bufferBytes) { + await flushBuffer(); + } } /** * In order to allow this code to run before @kbn/utils is built, @kbn/pm will pass @@ -1802,7 +1854,8 @@ class CiStatsReporter { body, bodyDesc, path, - query + query, + timeout = 60 * SECOND }) { let attempt = 0; const maxAttempts = 5; @@ -1830,7 +1883,8 @@ class CiStatsReporter { adapter: _http.default, // if it can be serialized into a string, send it maxBodyLength: Infinity, - maxContentLength: Infinity + maxContentLength: Infinity, + timeout }); return resp.data; } catch (error) { diff --git a/packages/kbn-securitysolution-autocomplete/src/field_value_match/index.tsx b/packages/kbn-securitysolution-autocomplete/src/field_value_match/index.tsx index 096058fcc0aa3..bfede3a8fcc4d 100644 --- a/packages/kbn-securitysolution-autocomplete/src/field_value_match/index.tsx +++ b/packages/kbn-securitysolution-autocomplete/src/field_value_match/index.tsx @@ -21,7 +21,7 @@ import { uniq } from 'lodash'; import { ListOperatorTypeEnum as OperatorTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; // TODO: I have to use any here for now, but once this is available below, we should use the correct types, https://github.com/elastic/kibana/issues/100715 -// import { AutocompleteStart } from '../../../../../../../src/plugins/data/public'; +// import { AutocompleteStart } from '../../../../../../../src/plugins/unified_search/public'; type AutocompleteStart = any; import * as i18n from '../translations'; diff --git a/packages/kbn-securitysolution-autocomplete/src/field_value_match_any/index.tsx b/packages/kbn-securitysolution-autocomplete/src/field_value_match_any/index.tsx index 5a36e155c548f..8f5afbbc86629 100644 --- a/packages/kbn-securitysolution-autocomplete/src/field_value_match_any/index.tsx +++ b/packages/kbn-securitysolution-autocomplete/src/field_value_match_any/index.tsx @@ -13,7 +13,7 @@ import { ListOperatorTypeEnum as OperatorTypeEnum } from '@kbn/securitysolution- import { DataViewBase, DataViewFieldBase } from '@kbn/es-query'; // TODO: I have to use any here for now, but once this is available below, we should use the correct types, https://github.com/elastic/kibana/issues/100715 -// import { AutocompleteStart } from '../../../../../../../src/plugins/data/public'; +// import { AutocompleteStart } from '../../../../../../../src/plugins/unified_search/public'; type AutocompleteStart = any; import * as i18n from '../translations'; diff --git a/packages/kbn-securitysolution-autocomplete/src/field_value_wildcard/index.tsx b/packages/kbn-securitysolution-autocomplete/src/field_value_wildcard/index.tsx index 82b9cb029d8dc..82d36aef83728 100644 --- a/packages/kbn-securitysolution-autocomplete/src/field_value_wildcard/index.tsx +++ b/packages/kbn-securitysolution-autocomplete/src/field_value_wildcard/index.tsx @@ -15,7 +15,7 @@ import { uniq } from 'lodash'; import { ListOperatorTypeEnum as OperatorTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; // TODO: I have to use any here for now, but once this is available below, we should use the correct types, https://github.com/elastic/kibana/issues/100715 -// import { AutocompleteStart } from '../../../../../../../src/plugins/data/public'; +// import { AutocompleteStart } from '../../../../../../../src/plugins/unified_search/public'; type AutocompleteStart = any; import * as i18n from '../translations'; diff --git a/packages/kbn-securitysolution-autocomplete/src/hooks/use_field_value_autocomplete/index.ts b/packages/kbn-securitysolution-autocomplete/src/hooks/use_field_value_autocomplete/index.ts index ca0868e5056a6..1b2de4567fe2a 100644 --- a/packages/kbn-securitysolution-autocomplete/src/hooks/use_field_value_autocomplete/index.ts +++ b/packages/kbn-securitysolution-autocomplete/src/hooks/use_field_value_autocomplete/index.ts @@ -12,7 +12,7 @@ import { ListOperatorTypeEnum as OperatorTypeEnum } from '@kbn/securitysolution- import { DataViewBase, DataViewFieldBase, getDataViewFieldSubtypeNested } from '@kbn/es-query'; // TODO: I have to use any here for now, but once this is available below, we should use the correct types, https://github.com/elastic/kibana/issues/100715 -// import { AutocompleteStart } from '../../../../../../../../src/plugins/data/public'; +// import { AutocompleteStart } from '../../../../../../../../src/plugins/unified_search/public'; type AutocompleteStart = any; interface FuncArgs { diff --git a/packages/kbn-shared-ux-components/src/empty_state/index.ts b/packages/kbn-shared-ux-components/src/empty_state/index.ts new file mode 100644 index 0000000000000..68defa5269344 --- /dev/null +++ b/packages/kbn-shared-ux-components/src/empty_state/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { NoDataViews, NoDataViewsComponent } from './no_data_views'; +export { KibanaNoDataPage } from './kibana_no_data_page'; diff --git a/packages/kbn-shared-ux-components/src/empty_state/index.tsx b/packages/kbn-shared-ux-components/src/empty_state/index.tsx deleted file mode 100644 index 902a9cd3614d5..0000000000000 --- a/packages/kbn-shared-ux-components/src/empty_state/index.tsx +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export { NoDataViews, NoDataViewsComponent } from './no_data_views'; diff --git a/packages/kbn-shared-ux-components/src/empty_state/kibana_no_data_page.mdx b/packages/kbn-shared-ux-components/src/empty_state/kibana_no_data_page.mdx new file mode 100644 index 0000000000000..c3571d1dd9d82 --- /dev/null +++ b/packages/kbn-shared-ux-components/src/empty_state/kibana_no_data_page.mdx @@ -0,0 +1,23 @@ +--- +id: sharedUX/Components/KibanaNoDataPage +slug: /shared-ux-components/kibana_no_data_page +title: Kibana No Data Page +summary: A page to be displayed when there is no data in Elasticsearch, or no data views +tags: ['shared-ux', 'component'] +date: 2022-04-20 +--- + +## Description + +Many plugins display "no data" page, either when there is no data in Elasticsearch, or there haven't been any data views created yet. This component is meant +to be used in those scenarios. It displays an appropriate message to the user and facilitate addition of integrations and creation of data views. + +## Component: `KibanaNoDataPage` + +- uses `hasUserDataView` and `hasData` API from `HasData` service in `data_views` plugin to check for existence of data / data views +- uses `onDataViewCreated` callback to be called once the data view has been created +- receives (noDataConfig)[https://github.com/elastic/kibana/blob/main/packages/kbn-shared-ux-components/src/page_template/no_data_page/types.ts] as configuration for the page in case of no data +- needs to be wrapped in `ServicesContext` provided by the start contract of the `shared_ux` plugin to be used + +## EUI Promotion Status +This component is not currently considered for promotion to EUI. \ No newline at end of file diff --git a/packages/kbn-shared-ux-components/src/empty_state/kibana_no_data_page.stories.tsx b/packages/kbn-shared-ux-components/src/empty_state/kibana_no_data_page.stories.tsx new file mode 100644 index 0000000000000..6d0c240dd4c05 --- /dev/null +++ b/packages/kbn-shared-ux-components/src/empty_state/kibana_no_data_page.stories.tsx @@ -0,0 +1,72 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { action } from '@storybook/addon-actions'; +import React from 'react'; +import { servicesFactory, DataServiceFactoryConfig } from '@kbn/shared-ux-storybook'; +import { SharedUxServicesProvider } from '@kbn/shared-ux-services'; +import mdx from './kibana_no_data_page.mdx'; +import { NoDataPageProps } from '../page_template'; +import { KibanaNoDataPage } from './kibana_no_data_page'; + +export default { + title: 'No Data/Kibana No Data Page', + description: 'A component to display when there is no data available', + parameters: { + docs: { + page: mdx, + }, + }, +}; + +const noDataConfig = { + solution: 'Analytics', + logo: 'logoKibana', + action: { + elasticAgent: { + title: 'Add Integrations', + }, + }, + docsLink: 'http://www.docs.com', +}; + +type Params = Pick & DataServiceFactoryConfig; + +export const PureComponent = (params: Params) => { + const { solution, logo, hasESData, hasUserDataView } = params; + const serviceParams = { hasESData, hasUserDataView, hasDataViews: false }; + const services = servicesFactory(serviceParams); + return ( + + + + ); +}; + +PureComponent.argTypes = { + solution: { + control: 'text', + defaultValue: 'Observability', + }, + logo: { + control: { type: 'radio' }, + options: ['logoElastic', 'logoKibana', 'logoCloud', undefined], + defaultValue: undefined, + }, + hasESData: { + control: 'boolean', + defaultValue: false, + }, + hasUserDataView: { + control: 'boolean', + defaultValue: false, + }, +}; diff --git a/packages/kbn-shared-ux-components/src/empty_state/kibana_no_data_page.test.tsx b/packages/kbn-shared-ux-components/src/empty_state/kibana_no_data_page.test.tsx new file mode 100644 index 0000000000000..82fbd222b3640 --- /dev/null +++ b/packages/kbn-shared-ux-components/src/empty_state/kibana_no_data_page.test.tsx @@ -0,0 +1,71 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; +import { act } from 'react-dom/test-utils'; + +import { mountWithIntl } from '@kbn/test-jest-helpers'; +import { SharedUxServicesProvider, mockServicesFactory } from '@kbn/shared-ux-services'; + +import { KibanaNoDataPage } from './kibana_no_data_page'; +import { NoDataConfigPage } from '../page_template'; +import { NoDataViews } from './no_data_views'; + +describe('Kibana No Data Page', () => { + const noDataConfig = { + solution: 'Analytics', + pageTitle: 'Analytics', + logo: 'logoKibana', + action: { + elasticAgent: { + title: 'Add Integrations', + }, + }, + docsLink: 'http://www.docs.com', + }; + const onDataViewCreated = jest.fn(); + const config = { + hasESData: false, + hasDataView: false, + hasUserDataView: false, + }; + + afterEach(() => { + jest.resetAllMocks(); + }); + + test('renders NoDataConfigPage', async () => { + const services = mockServicesFactory({ config: { ...config, hasESData: false } }); + const component = mountWithIntl( + + + + ); + + await act(() => new Promise(setImmediate)); + component.update(); + + expect(component.find(NoDataConfigPage).length).toBe(1); + expect(component.find(NoDataViews).length).toBe(0); + }); + + test('renders NoDataViews', async () => { + const services = mockServicesFactory({ config: { ...config, hasESData: true } }); + const component = mountWithIntl( + + + + ); + + await act(() => new Promise(setImmediate)); + component.update(); + + expect(component.find(NoDataViews).length).toBe(1); + expect(component.find(NoDataConfigPage).length).toBe(0); + }); +}); diff --git a/packages/kbn-shared-ux-components/src/empty_state/kibana_no_data_page.tsx b/packages/kbn-shared-ux-components/src/empty_state/kibana_no_data_page.tsx new file mode 100644 index 0000000000000..2e54d0d9f6a67 --- /dev/null +++ b/packages/kbn-shared-ux-components/src/empty_state/kibana_no_data_page.tsx @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import React, { useEffect, useState } from 'react'; +import { useData } from '@kbn/shared-ux-services'; +import { NoDataConfigPage, NoDataPageProps } from '../page_template'; +import { NoDataViews } from './no_data_views'; + +export interface Props { + onDataViewCreated: (dataView: unknown) => void; + noDataConfig: NoDataPageProps; +} + +export const KibanaNoDataPage = ({ onDataViewCreated, noDataConfig }: Props) => { + const { hasESData, hasUserDataView } = useData(); + const [dataExists, setDataExists] = useState(false); + const [hasUserDataViews, setHasUserDataViews] = useState(false); + + useEffect(() => { + const checkData = async () => { + setDataExists(await hasESData()); + setHasUserDataViews(await hasUserDataView()); + }; + // TODO: add error handling + // https://github.com/elastic/kibana/issues/130913 + checkData().catch(() => {}); + }, [hasESData, hasUserDataView]); + + if (!dataExists) { + return ; + } + + if (!hasUserDataViews) { + return ; + } + + return null; +}; diff --git a/packages/kbn-shared-ux-components/src/empty_state/no_data_views/no_data_views.stories.tsx b/packages/kbn-shared-ux-components/src/empty_state/no_data_views/no_data_views.stories.tsx index f40a04d8d4d2b..bee7c87d2841b 100644 --- a/packages/kbn-shared-ux-components/src/empty_state/no_data_views/no_data_views.stories.tsx +++ b/packages/kbn-shared-ux-components/src/empty_state/no_data_views/no_data_views.stories.tsx @@ -18,7 +18,7 @@ import mdx from './no_data_views.mdx'; const services = servicesFactory({}); export default { - title: 'No Data Views', + title: 'No Data/No Data Views', description: 'A component to display when there are no user-created data views available.', parameters: { docs: { diff --git a/packages/kbn-shared-ux-components/src/index.ts b/packages/kbn-shared-ux-components/src/index.ts index 98bd3ad1ac7e9..05afc94f782c8 100644 --- a/packages/kbn-shared-ux-components/src/index.ts +++ b/packages/kbn-shared-ux-components/src/index.ts @@ -30,53 +30,36 @@ export const ToolbarButton = withSuspense(LazyToolbarButton); export { AddFromLibraryButton, ToolbarPopover } from './toolbar'; /** - * The Lazily-loaded `NoDataViews` component. Consumers should use `React.Suspense` or the + * The Lazily-loaded `IconButtonGroup` component. Consumers should use `React.Suspense` or the * `withSuspense` HOC to load this component. */ -export const LazyNoDataViews = React.lazy(() => - import('./empty_state/no_data_views').then(({ NoDataViews }) => ({ - default: NoDataViews, +export const LazyIconButtonGroup = React.lazy(() => + import('./toolbar').then(({ IconButtonGroup }) => ({ + default: IconButtonGroup, })) ); /** - * A `NoDataViews` component that is wrapped by the `withSuspense` HOC. This component can - * be used directly by consumers and will load the `LazyNoDataViews` component lazily with - * a predefined fallback and error boundary. + * The IconButtonGroup component that is wrapped by the `withSuspence` HOC. */ -export const NoDataViews = withSuspense(LazyNoDataViews); +export const IconButtonGroup = withSuspense(LazyIconButtonGroup); /** - * A pure `NoDataViews` component, with no services hooks. Consumers should use `React.Suspense` or the + * A `KibanaNoDataPage` component, with service hooks. Consumers should use `React.Suspennse` or the * `withSuspense` HOC to load this component. */ -export const LazyNoDataViewsComponent = React.lazy(() => - import('./empty_state/no_data_views').then(({ NoDataViewsComponent }) => ({ - default: NoDataViewsComponent, +export const KibanaNoDataPageLazy = React.lazy(() => + import('./empty_state').then(({ KibanaNoDataPage }) => ({ + default: KibanaNoDataPage, })) ); /** - * A pure `NoDataViews` component, with no services hooks. The component is wrapped by the `withSuspense` HOC. - * This component can be used directly by consumers and will load the `LazyNoDataViewsComponent` lazily with + * A `KibanaNoDataPage` component. The component is wrapped by the `withSuspense` HOC. + * This component can be used directly by consumers and will load the `KibanaNoDataPageLazy` lazily with * a predefined fallback and error boundary. */ -export const NoDataViewsComponent = withSuspense(LazyNoDataViewsComponent); - -/** - * The Lazily-loaded `IconButtonGroup` component. Consumers should use `React.Suspense` or the - * `withSuspense` HOC to load this component. - */ -export const LazyIconButtonGroup = React.lazy(() => - import('./toolbar').then(({ IconButtonGroup }) => ({ - default: IconButtonGroup, - })) -); - -/** - * The IconButtonGroup component that is wrapped by the `withSuspence` HOC. - */ -export const IconButtonGroup = withSuspense(LazyIconButtonGroup); +export const KibanaNoDataPage = withSuspense(KibanaNoDataPageLazy); /** * The lazily loaded `KibanaPageTemplate` component that is wrapped by the `withSuspense` HOC. Consumers should use @@ -95,6 +78,11 @@ export const KibanaPageTemplateLazy = React.lazy(() => */ export const KibanaPageTemplate = withSuspense(KibanaPageTemplateLazy); +/** + * A `KibanaPageTemplateProps` type. + */ +export type { KibanaPageTemplateProps } from './page_template'; + /** * The lazily loaded `KibanaPageTemplateSolutionNav` component that is wrapped by the `withSuspense` HOC. Consumers should use * `React.Suspense` or `withSuspense` HOC to load this component. @@ -128,3 +116,37 @@ export const KibanaSolutionAvatarLazy = React.lazy(() => * a predefined fallback and error boundary. */ export const KibanaSolutionAvatar = withSuspense(KibanaSolutionAvatarLazy); + +/** + * The Lazily-loaded `NoDataViews` component. Consumers should use `React.Suspennse` or the + * `withSuspense` HOC to load this component. + */ +export const NoDataViewsLazy = React.lazy(() => + import('./empty_state/no_data_views').then(({ NoDataViews }) => ({ + default: NoDataViews, + })) +); + +/** + * A `NoDataViews` component that is wrapped by the `withSuspense` HOC. This component can + * be used directly by consumers and will load the `LazyNoDataViews` component lazily with + * a predefined fallback and error boundary. + */ +export const NoDataViews = withSuspense(NoDataViewsLazy); + +/** + * A pure `NoDataViews` component, with no services hooks. Consumers should use `React.Suspennse` or the + * `withSuspense` HOC to load this component. + */ +export const NoDataViewsComponentLazy = React.lazy(() => + import('./empty_state/no_data_views').then(({ NoDataViewsComponent }) => ({ + default: NoDataViewsComponent, + })) +); + +/** + * A pure `NoDataViews` component, with no services hooks. The component is wrapped by the `withSuspense` HOC. + * This component can be used directly by consumers and will load the `LazyNoDataViewsComponent` lazily with + * a predefined fallback and error boundary. + */ +export const NoDataViewsComponent = withSuspense(NoDataViewsComponentLazy); diff --git a/packages/kbn-shared-ux-components/src/page_template/index.ts b/packages/kbn-shared-ux-components/src/page_template/index.ts index caed703e5d656..671f720972fc9 100644 --- a/packages/kbn-shared-ux-components/src/page_template/index.ts +++ b/packages/kbn-shared-ux-components/src/page_template/index.ts @@ -5,8 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ - -export { NoDataCard, ElasticAgentCard } from './no_data_page'; -export { NoDataPage } from './no_data_page'; +export { NoDataCard, ElasticAgentCard, NoDataPage, NoDataConfigPage } from './no_data_page'; export { KibanaPageTemplate } from './page_template'; export type { KibanaPageTemplateProps } from './types'; +export type { NoDataPageProps } from './no_data_page'; diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.test.tsx.snap b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.test.tsx.snap index cac139bbb9035..79c0ea245b6cb 100644 --- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.test.tsx.snap +++ b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.test.tsx.snap @@ -8,6 +8,13 @@ exports[`ElasticAgentCard renders 1`] = ` "navigateToUrl": [Function], } } + data={ + Object { + "hasDataView": [Function], + "hasESData": [Function], + "hasUserDataView": [Function], + } + } docLinks={ Object { "dataViewsDocLink": "dummy link", @@ -20,7 +27,19 @@ exports[`ElasticAgentCard renders 1`] = ` } http={ Object { - "addBasePath": [MockFunction], + "addBasePath": [MockFunction] { + "calls": Array [ + Array [ + "/app/integrations/browse", + ], + ], + "results": Array [ + Object { + "type": "return", + "value": "/app/integrations/browse", + }, + ], + }, } } intl={ diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.stories.tsx b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.stories.tsx index ea890c265b5cd..77c41cddde6da 100644 --- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.stories.tsx +++ b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.stories.tsx @@ -15,7 +15,7 @@ import { } from './elastic_agent_card.component'; export default { - title: 'Page Template/No Data Page/Elastic Agent Data Card', + title: 'Page Template/No Data/Elastic Agent Data Card', description: 'A solution-specific wrapper around NoDataCard, to be used on NoData page', }; diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.tsx b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.tsx index d917514a96ccc..42d42dd805650 100644 --- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.tsx +++ b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/elastic_agent_card.tsx @@ -27,7 +27,7 @@ export const ElasticAgentCard = (props: ElasticAgentCardProps) => { if (category) { return addBasePath(`${prefix}/${category}`); } - return prefix; + return addBasePath(prefix); }; return ( diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/no_data_card.stories.tsx b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/no_data_card.stories.tsx index 4cea040af5f3c..9c1b2d0322074 100644 --- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/no_data_card.stories.tsx +++ b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_card/no_data_card.stories.tsx @@ -11,7 +11,7 @@ import { NoDataCard } from './no_data_card'; import type { NoDataCardProps } from './types'; export default { - title: 'Page Template/No Data Page/No Data Card', + title: 'Page Template/No Data/No Data Card', description: 'A wrapper around EuiCard, to be used on NoData page', }; diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_config_page/index.ts b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_config_page/index.ts new file mode 100644 index 0000000000000..f8c272c8f9875 --- /dev/null +++ b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_config_page/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +export { NoDataConfigPage, NoDataConfigPageWithSolutionNavBar } from './no_data_config_page'; diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_config_page/index.tsx b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_config_page/index.tsx deleted file mode 100644 index 0bdde40021398..0000000000000 --- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_config_page/index.tsx +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export { NoDataConfigPage, NoDataConfigPageWithSolutionNavBar } from './no_data_config_page'; diff --git a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_page.stories.tsx b/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_page.stories.tsx deleted file mode 100644 index cbb8ef6b0446f..0000000000000 --- a/packages/kbn-shared-ux-components/src/page_template/no_data_page/no_data_page.stories.tsx +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React from 'react'; -import { servicesFactory } from '@kbn/shared-ux-storybook'; -import { NoDataPageProps } from './types'; -import { NoDataPage } from './no_data_page'; - -const services = servicesFactory({}); - -export default { - title: 'Page Template/No Data Page/No Data Page', - description: 'No Data Page of PageTemplate', -}; -const action = { - elasticAgent: {}, -}; -type Params = Pick; - -export const PureComponent = (params: Params) => { - return ; -}; - -PureComponent.argTypes = { - solution: { - control: 'text', - defaultValue: 'Observability', - }, - logo: { - control: { type: 'radio' }, - options: ['logoElastic', 'logoKibana', 'logoCloud', undefined], - defaultValue: undefined, - }, -}; diff --git a/packages/kbn-shared-ux-components/src/toolbar/buttons/icon_button_group/__snapshots__/icon_button_group.test.tsx.snap b/packages/kbn-shared-ux-components/src/toolbar/buttons/icon_button_group/__snapshots__/icon_button_group.test.tsx.snap index 60a49e521ab07..c3b7dc63bce94 100644 --- a/packages/kbn-shared-ux-components/src/toolbar/buttons/icon_button_group/__snapshots__/icon_button_group.test.tsx.snap +++ b/packages/kbn-shared-ux-components/src/toolbar/buttons/icon_button_group/__snapshots__/icon_button_group.test.tsx.snap @@ -8,6 +8,13 @@ exports[` is rendered 1`] = ` "navigateToUrl": [Function], } } + data={ + Object { + "hasDataView": [Function], + "hasESData": [Function], + "hasUserDataView": [Function], + } + } docLinks={ Object { "dataViewsDocLink": "dummy link", diff --git a/packages/kbn-shared-ux-components/src/toolbar/buttons/primary/__snapshots__/primary.test.tsx.snap b/packages/kbn-shared-ux-components/src/toolbar/buttons/primary/__snapshots__/primary.test.tsx.snap index 8b7b51f228740..9dc8913562d2b 100644 --- a/packages/kbn-shared-ux-components/src/toolbar/buttons/primary/__snapshots__/primary.test.tsx.snap +++ b/packages/kbn-shared-ux-components/src/toolbar/buttons/primary/__snapshots__/primary.test.tsx.snap @@ -8,6 +8,13 @@ exports[` is rendered 1`] = ` "navigateToUrl": [Function], } } + data={ + Object { + "hasDataView": [Function], + "hasESData": [Function], + "hasUserDataView": [Function], + } + } docLinks={ Object { "dataViewsDocLink": "dummy link", diff --git a/packages/kbn-shared-ux-services/jest.config.js b/packages/kbn-shared-ux-services/jest.config.js deleted file mode 100755 index f1ef008d0f62d..0000000000000 --- a/packages/kbn-shared-ux-services/jest.config.js +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -module.exports = { - preset: '@kbn/test', - rootDir: '../..', - roots: ['/packages/kbn-shared-ux-services'], -}; diff --git a/packages/kbn-shared-ux-services/src/context.tsx b/packages/kbn-shared-ux-services/src/context.tsx index 55d05c57a08fb..6131c23e27370 100644 --- a/packages/kbn-shared-ux-services/src/context.tsx +++ b/packages/kbn-shared-ux-services/src/context.tsx @@ -63,3 +63,8 @@ export const useDocLinks = () => useSharedUxServices().docLinks; export const useHttp = () => useSharedUxServices().http; export const useApplication = () => useSharedUxServices().application; + +/** + * React hook for accessing the pre-wired `SharedUxDataService`. + */ +export const useData = () => useSharedUxServices().data; diff --git a/packages/kbn-shared-ux-services/src/index.ts b/packages/kbn-shared-ux-services/src/index.ts index d9ea2c670c9c5..744718a63b42d 100755 --- a/packages/kbn-shared-ux-services/src/index.ts +++ b/packages/kbn-shared-ux-services/src/index.ts @@ -14,6 +14,7 @@ export type { SharedUxHttpService, SharedUxPlatformService, SharedUxUserPermissionsService, + SharedUxDataService, } from './services'; export { @@ -24,6 +25,7 @@ export { useHttp, usePermissions, usePlatformService, + useData, useSharedUxServices, } from './context'; diff --git a/packages/kbn-shared-ux-services/src/services/data.ts b/packages/kbn-shared-ux-services/src/services/data.ts new file mode 100644 index 0000000000000..2750c9bd32085 --- /dev/null +++ b/packages/kbn-shared-ux-services/src/services/data.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/** + * A service providing data information. Typically used for handling of empty state.. + */ +export interface SharedUxDataService { + /** True if the cluster contains data, false otherwise. */ + hasESData: () => Promise; + /** True if Kibana instance contains user-created data view, false otherwise. */ + hasUserDataView: () => Promise; + /** True if Kibana instance contains any data view, including system-created ones. */ + hasDataView: () => Promise; +} diff --git a/packages/kbn-shared-ux-services/src/services/index.ts b/packages/kbn-shared-ux-services/src/services/index.ts index 485264353feb2..cf0e211ef492e 100644 --- a/packages/kbn-shared-ux-services/src/services/index.ts +++ b/packages/kbn-shared-ux-services/src/services/index.ts @@ -12,6 +12,7 @@ export type { SharedUxEditorsService } from './editors'; export type { SharedUxHttpService } from './http'; export type { SharedUxUserPermissionsService } from './permissions'; export type { SharedUxPlatformService } from './platform'; +export type { SharedUxDataService } from './data'; export { mockServicesFactory, mockServiceFactories } from './mock'; export { stubServicesFactory, stubServiceFactories } from './stub'; diff --git a/packages/kbn-shared-ux-services/src/services/mock/data.mock.ts b/packages/kbn-shared-ux-services/src/services/mock/data.mock.ts new file mode 100644 index 0000000000000..bb9d59643348d --- /dev/null +++ b/packages/kbn-shared-ux-services/src/services/mock/data.mock.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { ServiceFactory } from '../../types'; +import { SharedUxDataService } from '../data'; + +/** + * A factory function for creating a Jest-based implementation of `SharedUxDataService`. + */ +export type MockDataServiceFactory = ServiceFactory; + +export interface MockDataServiceFactoryConfig { + hasESData: boolean; + hasDataView: boolean; + hasUserDataView: boolean; +} + +/** + * A factory function for creating a Jest-based implementation of `SharedUxDataService`. + */ +export const dataServiceFactory: (config?: MockDataServiceFactoryConfig) => SharedUxDataService = ( + config?: MockDataServiceFactoryConfig +) => ({ + hasESData: () => Promise.resolve(config?.hasESData || false), + hasDataView: () => Promise.resolve(config?.hasDataView || false), + hasUserDataView: () => Promise.resolve(config?.hasUserDataView || false), +}); diff --git a/packages/kbn-shared-ux-services/src/services/mock/index.ts b/packages/kbn-shared-ux-services/src/services/mock/index.ts index 63256345d1bba..604a8ae677b9d 100644 --- a/packages/kbn-shared-ux-services/src/services/mock/index.ts +++ b/packages/kbn-shared-ux-services/src/services/mock/index.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import type { SharedUxServices, ServiceFactory } from '../../types'; +import type { SharedUxServices } from '../../types'; import { applicationServiceFactory } from './application.mock'; import { docLinksServiceFactory } from './doc_links.mock'; @@ -14,6 +14,7 @@ import { editorsServiceFactory } from './editors.mock'; import { httpServiceFactory } from './http.mock'; import { userPermissionsServiceFactory } from './permissions.mock'; import { platformServiceFactory } from './platform.mock'; +import { dataServiceFactory, MockDataServiceFactoryConfig } from './data.mock'; export type { MockApplicationServiceFactory } from './application.mock'; export type { MockDocLinksServiceFactory } from './doc_links.mock'; @@ -28,17 +29,25 @@ export { editorsServiceFactory } from './editors.mock'; export { httpServiceFactory } from './http.mock'; export { userPermissionsServiceFactory } from './permissions.mock'; export { platformServiceFactory } from './platform.mock'; +export { dataServiceFactory } from './data.mock'; + +export interface MockServicesFactoryParams { + config: MockDataServiceFactoryConfig; +} /** * A factory function for creating a Jest-based implementation of `SharedUxServices`. */ -export const mockServicesFactory: ServiceFactory = () => ({ +export const mockServicesFactory: (params?: MockServicesFactoryParams) => SharedUxServices = ( + params?: MockServicesFactoryParams +) => ({ application: applicationServiceFactory(), docLinks: docLinksServiceFactory(), editors: editorsServiceFactory(), http: httpServiceFactory(), permissions: userPermissionsServiceFactory(), platform: platformServiceFactory(), + data: dataServiceFactory(params?.config), }); /** @@ -51,4 +60,5 @@ export const mockServiceFactories = { httpServiceFactory, platformServiceFactory, userPermissionsServiceFactory, + dataServiceFactory, }; diff --git a/packages/kbn-shared-ux-services/src/services/stub/data.ts b/packages/kbn-shared-ux-services/src/services/stub/data.ts new file mode 100644 index 0000000000000..833c64e1f9d8d --- /dev/null +++ b/packages/kbn-shared-ux-services/src/services/stub/data.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { ServiceFactory } from '../../types'; +import { SharedUxDataService } from '../data'; + +/** + * A factory function for creating a simple stubbed implementation of `SharedUxDataSevice`. + */ +export type DataServiceFactory = ServiceFactory; + +/** + * A factory function for creating a simple stubbed implementation of `SharedUxDataSevice`. + */ +export const dataServiceFactory: DataServiceFactory = () => ({ + hasESData: () => Promise.resolve(true), + hasDataView: () => Promise.resolve(false), + hasUserDataView: () => Promise.resolve(false), +}); diff --git a/packages/kbn-shared-ux-services/src/services/stub/index.ts b/packages/kbn-shared-ux-services/src/services/stub/index.ts index 10323b7db8762..ab8b0ca3f4d9c 100644 --- a/packages/kbn-shared-ux-services/src/services/stub/index.ts +++ b/packages/kbn-shared-ux-services/src/services/stub/index.ts @@ -14,6 +14,7 @@ import { editorsServiceFactory } from './editors'; import { httpServiceFactory } from './http'; import { platformServiceFactory } from './platform'; import { userPermissionsServiceFactory } from './permissions'; +import { dataServiceFactory } from './data'; /** * A factory function for creating simple stubbed implementations of all `SharedUxServices`. @@ -25,6 +26,7 @@ export const stubServicesFactory: ServiceFactory = () => ({ http: httpServiceFactory(), permissions: userPermissionsServiceFactory(), platform: platformServiceFactory(), + data: dataServiceFactory(), }); /** @@ -37,4 +39,5 @@ export const stubServiceFactories = { httpServiceFactory, platformServiceFactory, userPermissionsServiceFactory, + dataServiceFactory, }; diff --git a/packages/kbn-shared-ux-services/src/types.ts b/packages/kbn-shared-ux-services/src/types.ts index 2bfbafb880e80..a0a4ec32c0e75 100755 --- a/packages/kbn-shared-ux-services/src/types.ts +++ b/packages/kbn-shared-ux-services/src/types.ts @@ -10,6 +10,7 @@ import { FC } from 'react'; import { SharedUxApplicationService, + SharedUxDataService, SharedUxDocLinksService, SharedUxEditorsService, SharedUxHttpService, @@ -32,6 +33,7 @@ export interface SharedUxServices { http: SharedUxHttpService; permissions: SharedUxUserPermissionsService; platform: SharedUxPlatformService; + data: SharedUxDataService; } /** diff --git a/packages/kbn-shared-ux-storybook/jest.config.js b/packages/kbn-shared-ux-storybook/jest.config.js deleted file mode 100644 index 91285e025f069..0000000000000 --- a/packages/kbn-shared-ux-storybook/jest.config.js +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -module.exports = { - preset: '@kbn/test', - rootDir: '../..', - roots: ['/packages/kbn-shared-ux-storybook'], -}; diff --git a/packages/kbn-shared-ux-storybook/src/index.ts b/packages/kbn-shared-ux-storybook/src/index.ts index 51f1c61165020..6b310673eb00d 100755 --- a/packages/kbn-shared-ux-storybook/src/index.ts +++ b/packages/kbn-shared-ux-storybook/src/index.ts @@ -16,4 +16,7 @@ export { platformServiceFactory, servicesFactory, userPermissionsServiceFactory, + dataServiceFactory, } from './services'; + +export type { DataServiceFactoryConfig } from './services'; diff --git a/packages/kbn-shared-ux-storybook/src/services/data.ts b/packages/kbn-shared-ux-storybook/src/services/data.ts new file mode 100644 index 0000000000000..dbfd2fceb4210 --- /dev/null +++ b/packages/kbn-shared-ux-storybook/src/services/data.ts @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { ServiceFactory, SharedUxDataService } from '@kbn/shared-ux-services'; + +export interface DataServiceFactoryConfig { + hasESData: boolean; + hasDataView: boolean; + hasUserDataView: boolean; +} + +/** + * A factory function for creating a Storybook implementation of `SharedUxDataService`. + */ +export type SharedUxDataServiceFactory = ServiceFactory< + SharedUxDataService, + DataServiceFactoryConfig +>; + +/** + * A factory function for creating a Storybook implementation of `SharedUxDataService`. + */ +export const dataServiceFactory: SharedUxDataServiceFactory = (params) => { + return { + hasESData: () => Promise.resolve(params.hasESData || false), + hasDataView: () => Promise.resolve(params.hasDataView || false), + hasUserDataView: () => Promise.resolve(params.hasUserDataView || false), + }; +}; diff --git a/packages/kbn-shared-ux-storybook/src/services/doc_links.ts b/packages/kbn-shared-ux-storybook/src/services/doc_links.ts index 5ae1dcccc3664..eff942989956f 100644 --- a/packages/kbn-shared-ux-storybook/src/services/doc_links.ts +++ b/packages/kbn-shared-ux-storybook/src/services/doc_links.ts @@ -18,4 +18,5 @@ export type SharedUxDocLinksServiceFactory = ServiceFactory ({ dataViewsDocLink: 'https://www.elastic.co/guide/en/kibana/master/data-views.html', + kibanaGuideDocLink: 'https://www.elastic.co/guide/en/kibana/master/index.html', }); diff --git a/packages/kbn-shared-ux-storybook/src/services/index.ts b/packages/kbn-shared-ux-storybook/src/services/index.ts index 2de34f3392312..ff6ad1f1f2913 100644 --- a/packages/kbn-shared-ux-storybook/src/services/index.ts +++ b/packages/kbn-shared-ux-storybook/src/services/index.ts @@ -14,6 +14,7 @@ import { editorsServiceFactory } from './editors'; import { httpServiceFactory } from './http'; import { platformServiceFactory } from './platform'; import { userPermissionsServiceFactory } from './permissions'; +import { dataServiceFactory, DataServiceFactoryConfig } from './data'; export { applicationServiceFactory } from './application'; export { docLinksServiceFactory } from './doc_links'; @@ -21,6 +22,7 @@ export { editorsServiceFactory } from './editors'; export { httpServiceFactory } from './http'; export { platformServiceFactory } from './platform'; export { userPermissionsServiceFactory } from './permissions'; +export { dataServiceFactory } from './data'; /** * A factory function for creating a Storybook implementation of `SharedUxServices`. @@ -32,4 +34,7 @@ export const servicesFactory: ServiceFactory = (params) => http: httpServiceFactory(params), permissions: userPermissionsServiceFactory(), platform: platformServiceFactory(params), + data: dataServiceFactory(params as DataServiceFactoryConfig), }); + +export type { DataServiceFactoryConfig } from './data'; diff --git a/packages/kbn-sort-package-json/jest.config.js b/packages/kbn-sort-package-json/jest.config.js deleted file mode 100644 index ae0651be19e61..0000000000000 --- a/packages/kbn-sort-package-json/jest.config.js +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -module.exports = { - preset: '@kbn/test/jest_node', - rootDir: '../..', - roots: ['/packages/kbn-sort-package-json'], -}; diff --git a/packages/kbn-stdio-dev-helpers/jest.config.js b/packages/kbn-stdio-dev-helpers/jest.config.js deleted file mode 100644 index 31a8aab16c7e5..0000000000000 --- a/packages/kbn-stdio-dev-helpers/jest.config.js +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -module.exports = { - preset: '@kbn/test/jest_node', - rootDir: '../..', - roots: ['/packages/kbn-stdio-dev-helpers'], -}; diff --git a/packages/kbn-storybook/src/lib/default_config.ts b/packages/kbn-storybook/src/lib/default_config.ts index 3caf879c48cbb..0f0b8070ff8b0 100644 --- a/packages/kbn-storybook/src/lib/default_config.ts +++ b/packages/kbn-storybook/src/lib/default_config.ts @@ -14,6 +14,12 @@ import { REPO_ROOT } from './constants'; import { default as WebpackConfig } from '../webpack.config'; const toPath = (_path: string) => path.join(REPO_ROOT, _path); + +// This ignore pattern excludes all of node_modules EXCEPT for `@kbn`. This allows for +// changes to packages to cause a refresh in Storybook. +const IGNORE_PATTERN = + /[/\\]node_modules[/\\](?!@kbn[/\\][^/\\]+[/\\](?!node_modules)([^/\\]+))([^/\\]+[/\\][^/\\]+)/; + export const defaultConfig: StorybookConfig = { addons: ['@kbn/storybook/preset', '@storybook/addon-a11y', '@storybook/addon-essentials'], stories: ['../**/*.stories.tsx', '../**/*.stories.mdx'], @@ -45,6 +51,11 @@ export const defaultConfig: StorybookConfig = { } config.node = { fs: 'empty' }; + config.watch = true; + config.watchOptions = { + ...config.watchOptions, + ignored: [IGNORE_PATTERN], + }; // Remove when @storybook has moved to @emotion v11 // https://github.com/storybookjs/storybook/issues/13145 diff --git a/packages/kbn-test/jest-preset.js b/packages/kbn-test/jest-preset.js index 6245532b00e44..fb535c2766cc4 100644 --- a/packages/kbn-test/jest-preset.js +++ b/packages/kbn-test/jest-preset.js @@ -63,12 +63,16 @@ module.exports = { rootDirectory: '.', }, ], - [ - '@kbn/test/target_node/jest/ci_stats_jest_reporter', - { - testGroupType: 'Jest Unit Tests', - }, - ], + ...(process.env.TEST_GROUP_TYPE_UNIT + ? [ + [ + '@kbn/test/target_node/jest/ci_stats_jest_reporter', + { + testGroupType: process.env.TEST_GROUP_TYPE_UNIT, + }, + ], + ] + : []), ], // The paths to modules that run some code to configure or set up the testing environment before each test diff --git a/packages/kbn-test/jest_integration/jest-preset.js b/packages/kbn-test/jest_integration/jest-preset.js index f5593e3f57fb6..1f2626aef532e 100644 --- a/packages/kbn-test/jest_integration/jest-preset.js +++ b/packages/kbn-test/jest_integration/jest-preset.js @@ -28,12 +28,16 @@ module.exports = { reportName: 'Jest Integration Tests', }, ], - [ - '@kbn/test/target_node/jest/ci_stats_jest_reporter', - { - testGroupType: 'Jest Integration Tests', - }, - ], + ...(process.env.TEST_GROUP_TYPE_INTEGRATION + ? [ + [ + '@kbn/test/target_node/jest/ci_stats_jest_reporter', + { + testGroupType: process.env.TEST_GROUP_TYPE_INTEGRATION, + }, + ], + ] + : []), ], coverageReporters: !!process.env.CI ? [['json', { file: 'jest-integration.json' }]] diff --git a/packages/kbn-test/src/functional_test_runner/lib/mocha/reporter/ci_stats_ftr_reporter.ts b/packages/kbn-test/src/functional_test_runner/lib/mocha/reporter/ci_stats_ftr_reporter.ts index 838b8ee9b9aa5..ee993122d7d9c 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/mocha/reporter/ci_stats_ftr_reporter.ts +++ b/packages/kbn-test/src/functional_test_runner/lib/mocha/reporter/ci_stats_ftr_reporter.ts @@ -80,6 +80,7 @@ export function setupCiStatsFtrTestGroupReporter({ durationMs: 0, type: config.path.startsWith('x-pack') ? 'X-Pack Functional Tests' : 'Functional Tests', name: Path.relative(REPO_ROOT, config.path), + result: 'skip', meta: { ciGroup: config.get('suiteTags.include').find((t: string) => t.startsWith('ciGroup')), tags: [ @@ -117,6 +118,11 @@ export function setupCiStatsFtrTestGroupReporter({ errors.set(test, error); }); + let passCount = 0; + let failCount = 0; + runner.on('pass', () => (passCount += 1)); + runner.on('fail', () => (failCount += 1)); + runner.on('hook end', (hook: Runnable) => { if (hook.isFailed()) { const error = errors.get(hook); @@ -150,6 +156,7 @@ export function setupCiStatsFtrTestGroupReporter({ // update the durationMs group.durationMs = Date.now() - startMs; + group.result = failCount ? 'fail' : passCount ? 'pass' : 'skip'; }); lifecycle.cleanup.add(async () => { diff --git a/packages/kbn-test/src/jest/ci_stats_jest_reporter.ts b/packages/kbn-test/src/jest/ci_stats_jest_reporter.ts index 6294594ff6cf5..3ac4a64c1f3f7 100644 --- a/packages/kbn-test/src/jest/ci_stats_jest_reporter.ts +++ b/packages/kbn-test/src/jest/ci_stats_jest_reporter.ts @@ -39,6 +39,8 @@ export default class CiStatsJestReporter extends BaseReporter { private readonly reportName: string; private readonly rootDir: string; private startTime: number | undefined; + private passCount = 0; + private failCount = 0; private group: CiStatsReportTestsOptions['group'] | undefined; private readonly testRuns: CiStatsReportTestsOptions['testRuns'] = []; @@ -79,6 +81,7 @@ export default class CiStatsJestReporter extends BaseReporter { startTime: new Date(this.startTime).toJSON(), meta: {}, durationMs: 0, + result: 'skip', }; } @@ -89,6 +92,14 @@ export default class CiStatsJestReporter extends BaseReporter { let elapsedTime = 0; for (const t of testResult.testResults) { + const result = t.status === 'failed' ? 'fail' : t.status === 'passed' ? 'pass' : 'skip'; + + if (result === 'fail') { + this.failCount += 1; + } else if (result === 'pass') { + this.passCount += 1; + } + const startTime = new Date(testResult.perfStats.start + elapsedTime).toJSON(); elapsedTime += t.duration ?? 0; this.testRuns.push({ @@ -97,7 +108,7 @@ export default class CiStatsJestReporter extends BaseReporter { seq: this.testRuns.length + 1, file: Path.relative(this.rootDir, testResult.testFilePath), name: t.title, - result: t.status === 'failed' ? 'fail' : t.status === 'passed' ? 'pass' : 'skip', + result, suites: t.ancestorTitles, type: 'test', error: t.failureMessages.join('\n\n'), @@ -107,11 +118,12 @@ export default class CiStatsJestReporter extends BaseReporter { } async onRunComplete() { - if (!this.reporter || !this.group || !this.testRuns.length || !this.startTime) { + if (!this.reporter || !this.group || !this.startTime) { return; } this.group.durationMs = Date.now() - this.startTime; + this.group.result = this.failCount ? 'fail' : this.passCount ? 'pass' : 'skip'; await this.reporter.reportTests({ group: this.group, diff --git a/packages/kbn-test/src/jest/run_check_jest_configs_cli.ts b/packages/kbn-test/src/jest/run_check_jest_configs_cli.ts index 42766ad3f5a31..7a50e88b3396d 100644 --- a/packages/kbn-test/src/jest/run_check_jest_configs_cli.ts +++ b/packages/kbn-test/src/jest/run_check_jest_configs_cli.ts @@ -17,14 +17,14 @@ import { getAllRepoRelativeBazelPackageDirs } from '@kbn/bazel-packages'; import { JestConfigs, CONFIG_NAMES } from './configs'; const unitTestingTemplate: string = `module.exports = { - preset: '@kbn/test', + preset: '@kbn/test/jest_node', rootDir: '{{{relToRoot}}}', roots: ['/{{{modulePath}}}'], }; `; const integrationTestingTemplate: string = `module.exports = { - preset: '@kbn/test/jest_integration', + preset: '@kbn/test/jest_integration_node', rootDir: '{{{relToRoot}}}', roots: ['/{{{modulePath}}}'], }; diff --git a/packages/kbn-test/src/jest/setup/polyfills.jsdom.js b/packages/kbn-test/src/jest/setup/polyfills.jsdom.js index ebe6178dbdd91..5857ca9b99b8a 100644 --- a/packages/kbn-test/src/jest/setup/polyfills.jsdom.js +++ b/packages/kbn-test/src/jest/setup/polyfills.jsdom.js @@ -14,7 +14,3 @@ require('whatwg-fetch'); if (!global.URL.hasOwnProperty('createObjectURL')) { Object.defineProperty(global.URL, 'createObjectURL', { value: () => '' }); } - -// Will be replaced with a better solution in EUI -// https://github.com/elastic/eui/issues/3713 -global._isJest = true; diff --git a/packages/kbn-tooling-log/BUILD.bazel b/packages/kbn-tooling-log/BUILD.bazel index a4953521171cb..e5d196bd4649c 100644 --- a/packages/kbn-tooling-log/BUILD.bazel +++ b/packages/kbn-tooling-log/BUILD.bazel @@ -54,6 +54,7 @@ TYPES_DEPS = [ "@npm//tslib", "@npm//@types/node", "@npm//@types/jest", + "//packages/kbn-jest-serializers:npm_module_types" # needed for windows development, only used in tests ] jsts_transpiler( diff --git a/packages/kbn-ui-shared-deps-npm/webpack.config.js b/packages/kbn-ui-shared-deps-npm/webpack.config.js index 0a709181b04d2..ddcb71fdb2c86 100644 --- a/packages/kbn-ui-shared-deps-npm/webpack.config.js +++ b/packages/kbn-ui-shared-deps-npm/webpack.config.js @@ -37,6 +37,10 @@ module.exports = (_, argv) => { 'regenerator-runtime/runtime', 'whatwg-fetch', 'symbol-observable', + // Parts of node-libs-browser that are used in many places across Kibana + 'buffer', + 'punycode', + 'util', /** * babel runtime helpers referenced from entry chunks diff --git a/packages/kbn-utility-types/src/index.ts b/packages/kbn-utility-types/src/index.ts index 277b4a70e415a..50741bbd96954 100644 --- a/packages/kbn-utility-types/src/index.ts +++ b/packages/kbn-utility-types/src/index.ts @@ -26,6 +26,13 @@ export type MaybePromise = T | Promise; */ export type ShallowPromise = T extends Promise ? Promise : Promise; +/** + * Unwrap all promise attributes of the given type + */ +export type AwaitedProperties = { + [K in keyof T]: Awaited; +}; + /** * Minimal interface for an object resembling an `Observable`. */ diff --git a/scripts/find_node_libs_browser_polyfills_in_use.js b/scripts/find_node_libs_browser_polyfills_in_use.js new file mode 100644 index 0000000000000..4e53e5e551075 --- /dev/null +++ b/scripts/find_node_libs_browser_polyfills_in_use.js @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +require('../src/setup_node_env/no_transpilation'); +require('@kbn/optimizer').runFindNodeLibsBrowserPolyfillsInEntryBundlesCli(); diff --git a/src/cli_encryption_keys/encryption_config.test.js b/src/cli_encryption_keys/encryption_config.test.js index 9629cfcafe78a..dba1967f4f6b1 100644 --- a/src/cli_encryption_keys/encryption_config.test.js +++ b/src/cli_encryption_keys/encryption_config.test.js @@ -14,7 +14,7 @@ describe('encryption key configuration', () => { let encryptionConfig = null; beforeEach(() => { - jest.spyOn(fs, 'readFileSync').mockReturnValue('xpack.security.encryptionKey: foo'); + jest.spyOn(fs, 'readFileSync').mockReturnValueOnce('xpack.security.encryptionKey: foo'); jest.spyOn(crypto, 'randomBytes').mockReturnValue('random-key'); encryptionConfig = new EncryptionConfig(); }); diff --git a/src/core/public/i18n/__snapshots__/i18n_service.test.tsx.snap b/src/core/public/i18n/__snapshots__/i18n_service.test.tsx.snap index 69439d1927745..a3e3ca7a7c207 100644 --- a/src/core/public/i18n/__snapshots__/i18n_service.test.tsx.snap +++ b/src/core/public/i18n/__snapshots__/i18n_service.test.tsx.snap @@ -141,6 +141,8 @@ exports[`#start() returns \`Context\` component 1`] = ` "euiImage.openImage": [Function], "euiLink.external.ariaLabel": "External link", "euiLink.newTarget.screenReaderOnlyText": "(opens in a new tab or window)", + "euiMark.highlightEnd": "highlight end", + "euiMark.highlightStart": "highlight start", "euiMarkdownEditorFooter.closeButton": "Close", "euiMarkdownEditorFooter.errorsTitle": "Errors", "euiMarkdownEditorFooter.mdSyntaxLink": "GitHub flavored markdown", diff --git a/src/core/public/i18n/i18n_eui_mapping.tsx b/src/core/public/i18n/i18n_eui_mapping.tsx index 9969f4ee23f57..5344fddc4fe2e 100644 --- a/src/core/public/i18n/i18n_eui_mapping.tsx +++ b/src/core/public/i18n/i18n_eui_mapping.tsx @@ -618,6 +618,12 @@ export const getEuiContextMapping = (): EuiTokensObject => { defaultMessage: '(opens in a new tab or window)', } ), + 'euiMark.highlightStart': i18n.translate('core.euiMark.highlightStart', { + defaultMessage: 'highlight start', + }), + 'euiMark.highlightEnd': i18n.translate('core.euiMark.highlightEnd', { + defaultMessage: 'highlight end', + }), 'euiMarkdownEditorFooter.closeButton': i18n.translate( 'core.euiMarkdownEditorFooter.closeButton', { diff --git a/src/core/server/context/container/context.test.ts b/src/core/server/context/container/context.test.ts index 25fab2e3f0bfb..17a04531dedd1 100644 --- a/src/core/server/context/container/context.test.ts +++ b/src/core/server/context/container/context.test.ts @@ -7,7 +7,7 @@ */ import { ContextContainer } from './context'; -import { PluginOpaqueId } from '../..'; +import type { PluginOpaqueId, RequestHandlerContextBase } from '../..'; import { httpServerMock } from '../../http/http_server.mocks'; const pluginA = Symbol('pluginA'); @@ -22,7 +22,7 @@ const plugins: ReadonlyMap = new Map([ ]); const coreId = Symbol(); -interface MyContext { +interface MyContext extends RequestHandlerContextBase { core: any; core1: string; core2: number; @@ -32,31 +32,47 @@ interface MyContext { ctxFromD: object; } +type TestContext = T & RequestHandlerContextBase; + describe('ContextContainer', () => { - it('does not allow the same context to be registered twice', () => { - const contextContainer = new ContextContainer(plugins, coreId); - contextContainer.registerContext<{ ctxFromA: string; core: any }, 'ctxFromA'>( - coreId, - 'ctxFromA', - () => 'aString' - ); - - expect(() => - contextContainer.registerContext<{ ctxFromA: string; core: any }, 'ctxFromA'>( + describe('registerContext', () => { + it('throws an error if the same context is registered twice', () => { + const contextContainer = new ContextContainer(plugins, coreId); + contextContainer.registerContext, 'ctxFromA'>( coreId, 'ctxFromA', () => 'aString' - ) - ).toThrowErrorMatchingInlineSnapshot( - `"Context provider for ctxFromA has already been registered."` - ); - }); + ); + + expect(() => + contextContainer.registerContext, 'ctxFromA'>( + coreId, + 'ctxFromA', + () => 'aString' + ) + ).toThrowErrorMatchingInlineSnapshot( + `"Context provider for ctxFromA has already been registered."` + ); + }); + + it('throws an error if a `resolve` context is registered', () => { + const contextContainer = new ContextContainer(plugins, coreId); + expect(() => + contextContainer.registerContext, 'ctxFromA'>( + coreId, + // @ts-expect-error protected with typing too + 'resolve', + () => 'aString' + ) + ).toThrowErrorMatchingInlineSnapshot( + `"Cannot register a provider for resolve, it is a reserved keyword."` + ); + }); - describe('registerContext', () => { it('throws error if called with an unknown symbol', async () => { const contextContainer = new ContextContainer(plugins, coreId); await expect(() => - contextContainer.registerContext<{ ctxFromA: string; core: any }, 'ctxFromA'>( + contextContainer.registerContext, 'ctxFromA'>( Symbol('unknown'), 'ctxFromA', jest.fn() @@ -69,7 +85,7 @@ describe('ContextContainer', () => { it('reports a TS error if returned contract does not satisfy the Context interface', async () => { const contextContainer = new ContextContainer(plugins, coreId); await expect(() => - contextContainer.registerContext<{ ctxFromA: string; core: any }, 'ctxFromA'>( + contextContainer.registerContext, 'ctxFromA'>( pluginA, 'ctxFromA', // @ts-expect-error expected string, returned number @@ -82,7 +98,7 @@ describe('ContextContainer', () => { const contextContainer = new ContextContainer(plugins, coreId); await expect(() => // @ts-expect-error expects ctxFromB, but given ctxFromC - contextContainer.registerContext<{ ctxFromB: string; core: any }, 'ctxFromC'>( + contextContainer.registerContext, 'ctxFromC'>( pluginB, 'ctxFromC', async () => 1 @@ -92,39 +108,216 @@ describe('ContextContainer', () => { }); describe('context building', () => { + const resolveAllContexts = async (ctx: Record): Promise => { + const resolved = {} as Record; + for (const key of Object.getOwnPropertyNames(ctx)) { + if (key === 'resolve') { + continue; + } + resolved[key] = await ctx[key]; + } + return resolved; + }; + + it('lazily loads the providers when accessed', async () => { + const contextContainer = new ContextContainer(plugins, coreId); + + const core1provider = jest.fn().mockReturnValue('core1'); + const ctxFromAProvider = jest.fn().mockReturnValue('ctxFromA'); + + contextContainer.registerContext, 'core1'>( + coreId, + 'core1', + core1provider + ); + + contextContainer.registerContext, 'ctxFromA'>( + pluginA, + 'ctxFromA', + ctxFromAProvider + ); + + let context: any; + const rawHandler1 = jest.fn((ctx) => { + context = ctx; + return 'rawHandler1' as any; + }); + const handler1 = contextContainer.createHandler(pluginC, rawHandler1); + + const request = httpServerMock.createKibanaRequest(); + const response = httpServerMock.createResponseFactory(); + await handler1(request, response); + + expect(core1provider).not.toHaveBeenCalled(); + expect(ctxFromAProvider).not.toHaveBeenCalled(); + + await context!.core1; + + expect(core1provider).toHaveBeenCalledTimes(1); + expect(ctxFromAProvider).not.toHaveBeenCalled(); + + await context!.ctxFromA; + + expect(core1provider).toHaveBeenCalledTimes(1); + expect(ctxFromAProvider).toHaveBeenCalledTimes(1); + }); + + it(`does not eagerly loads a provider's dependencies`, async () => { + const contextContainer = new ContextContainer(plugins, coreId); + + const core1provider = jest.fn().mockReturnValue('core1'); + const ctxFromAProvider = jest.fn().mockReturnValue('ctxFromA'); + + contextContainer.registerContext, 'core1'>( + coreId, + 'core1', + core1provider + ); + + contextContainer.registerContext, 'ctxFromA'>( + pluginA, + 'ctxFromA', + ctxFromAProvider + ); + + let context: any; + const rawHandler1 = jest.fn((ctx) => { + context = ctx; + return 'rawHandler1' as any; + }); + const handler1 = contextContainer.createHandler(pluginC, rawHandler1); + + const request = httpServerMock.createKibanaRequest(); + const response = httpServerMock.createResponseFactory(); + await handler1(request, response); + + expect(core1provider).not.toHaveBeenCalled(); + expect(ctxFromAProvider).not.toHaveBeenCalled(); + + await context!.ctxFromA; + + expect(core1provider).not.toHaveBeenCalled(); + expect(ctxFromAProvider).toHaveBeenCalledTimes(1); + }); + + it(`allows to load a dependency from a provider`, async () => { + const contextContainer = new ContextContainer(plugins, coreId); + + const core1provider = jest.fn().mockReturnValue('core1'); + const ctxFromAProvider = jest.fn().mockImplementation(async (ctx: any) => { + const core1 = await ctx.core1; + return `${core1}-ctxFromA`; + }); + + contextContainer.registerContext, 'core1'>( + coreId, + 'core1', + core1provider + ); + + contextContainer.registerContext, 'ctxFromA'>( + pluginA, + 'ctxFromA', + ctxFromAProvider + ); + + let context: any; + const rawHandler1 = jest.fn((ctx) => { + context = ctx; + return 'rawHandler1' as any; + }); + const handler1 = contextContainer.createHandler(pluginC, rawHandler1); + + const request = httpServerMock.createKibanaRequest(); + const response = httpServerMock.createResponseFactory(); + await handler1(request, response); + + expect(core1provider).not.toHaveBeenCalled(); + expect(ctxFromAProvider).not.toHaveBeenCalled(); + + const contextValue = await context!.ctxFromA; + + expect(contextValue).toEqual('core1-ctxFromA'); + expect(core1provider).toHaveBeenCalledTimes(1); + expect(ctxFromAProvider).toHaveBeenCalledTimes(1); + }); + + it(`only calls a provider once and caches the returned value`, async () => { + const contextContainer = new ContextContainer(plugins, coreId); + + const core1provider = jest.fn().mockReturnValue('core1'); + const ctxFromAProvider = jest.fn().mockImplementation(async (ctx: any) => { + const core1 = await ctx.core1; + return `${core1}-ctxFromA`; + }); + + contextContainer.registerContext, 'core1'>( + coreId, + 'core1', + core1provider + ); + + contextContainer.registerContext, 'ctxFromA'>( + pluginA, + 'ctxFromA', + ctxFromAProvider + ); + + let context: any; + const rawHandler1 = jest.fn((ctx) => { + context = ctx; + return 'rawHandler1' as any; + }); + const handler1 = contextContainer.createHandler(pluginC, rawHandler1); + + const request = httpServerMock.createKibanaRequest(); + const response = httpServerMock.createResponseFactory(); + await handler1(request, response); + + expect(core1provider).not.toHaveBeenCalled(); + expect(ctxFromAProvider).not.toHaveBeenCalled(); + + await context!.core1; + await context!.ctxFromA; + await context!.core1; + + expect(core1provider).toHaveBeenCalledTimes(1); + expect(ctxFromAProvider).toHaveBeenCalledTimes(1); + }); + it('resolves dependencies', async () => { const contextContainer = new ContextContainer(plugins, coreId); - expect.assertions(8); - contextContainer.registerContext<{ core1: string; core: any }, 'core1'>( + expect.assertions(10); + contextContainer.registerContext, 'core1'>( coreId, 'core1', - (context) => { - expect(context).toEqual({}); + async (context) => { + expect(await resolveAllContexts(context)).toEqual({}); return 'core'; } ); - contextContainer.registerContext<{ ctxFromA: string; core: any }, 'ctxFromA'>( + contextContainer.registerContext, 'ctxFromA'>( pluginA, 'ctxFromA', - (context) => { - expect(context).toEqual({ core1: 'core' }); + async (context) => { + expect(await resolveAllContexts(context)).toEqual({ core1: 'core' }); return 'aString'; } ); - contextContainer.registerContext<{ ctxFromB: number; core: any }, 'ctxFromB'>( + contextContainer.registerContext, 'ctxFromB'>( pluginB, 'ctxFromB', - (context) => { - expect(context).toEqual({ core1: 'core', ctxFromA: 'aString' }); + async (context) => { + expect(await resolveAllContexts(context)).toEqual({ core1: 'core', ctxFromA: 'aString' }); return 299; } ); - contextContainer.registerContext<{ ctxFromC: boolean; core: any }, 'ctxFromC'>( + contextContainer.registerContext, 'ctxFromC'>( pluginC, 'ctxFromC', - (context) => { - expect(context).toEqual({ + async (context) => { + expect(await resolveAllContexts(context)).toEqual({ core1: 'core', ctxFromA: 'aString', ctxFromB: 299, @@ -132,19 +325,34 @@ describe('ContextContainer', () => { return false; } ); - contextContainer.registerContext<{ ctxFromD: {}; core: any }, 'ctxFromD'>( + contextContainer.registerContext, 'ctxFromD'>( pluginD, 'ctxFromD', - (context) => { - expect(context).toEqual({ core1: 'core' }); + async (context) => { + expect(await resolveAllContexts(context)).toEqual({ core1: 'core' }); return {}; } ); - const rawHandler1 = jest.fn(() => 'handler1' as any); + const rawHandler1 = jest.fn(async (context) => { + expect(await resolveAllContexts(context)).toEqual({ + core1: 'core', + ctxFromA: 'aString', + ctxFromB: 299, + ctxFromC: false, + }); + return 'handler1' as any; + }); const handler1 = contextContainer.createHandler(pluginC, rawHandler1); - const rawHandler2 = jest.fn(() => 'handler2' as any); + const rawHandler2 = jest.fn(async (context) => { + expect(await resolveAllContexts(context)).toEqual({ + core1: 'core', + ctxFromD: {}, + }); + return 'handler2' as any; + }); + const handler2 = contextContainer.createHandler(pluginD, rawHandler2); const request = httpServerMock.createKibanaRequest(); @@ -154,41 +362,25 @@ describe('ContextContainer', () => { await handler2(request, response); // Should have context from pluginC, its deps, and core - expect(rawHandler1).toHaveBeenCalledWith( - { - core1: 'core', - ctxFromA: 'aString', - ctxFromB: 299, - ctxFromC: false, - }, - request, - response - ); + expect(rawHandler1).toHaveBeenCalledWith(expect.any(Object), request, response); // Should have context from pluginD, and core - expect(rawHandler2).toHaveBeenCalledWith( - { - core1: 'core', - ctxFromD: {}, - }, - request, - response - ); + expect(rawHandler2).toHaveBeenCalledWith(expect.any(Object), request, response); }); it('exposes all core context to all providers regardless of registration order', async () => { - expect.assertions(4); + expect.assertions(5); const contextContainer = new ContextContainer(plugins, coreId); contextContainer - .registerContext(pluginA, 'ctxFromA', (context) => { - expect(context).toEqual({ core1: 'core', core2: 101 }); - return `aString ${context.core1} ${context.core2}`; + .registerContext(pluginA, 'ctxFromA', async (context) => { + expect(await resolveAllContexts(context)).toEqual({ core1: 'core', core2: 101 }); + return `aString ${await context.core1} ${await context.core2}`; }) .registerContext(coreId, 'core1', () => 'core') .registerContext(coreId, 'core2', () => 101) - .registerContext(pluginB, 'ctxFromB', (context) => { - expect(context).toEqual({ + .registerContext(pluginB, 'ctxFromB', async (context) => { + expect(await resolveAllContexts(context)).toEqual({ core1: 'core', core2: 101, ctxFromA: 'aString core 101', @@ -196,40 +388,45 @@ describe('ContextContainer', () => { return 277; }); - const rawHandler1 = jest.fn(() => 'handler1' as any); + const rawHandler1 = jest.fn(async (context) => { + expect(await resolveAllContexts(context)).toEqual({ + core1: 'core', + core2: 101, + ctxFromA: 'aString core 101', + ctxFromB: 277, + }); + return 'handler1' as any; + }); const handler1 = contextContainer.createHandler(pluginB, rawHandler1); const request = httpServerMock.createKibanaRequest(); const response = httpServerMock.createResponseFactory(); expect(await handler1(request, response)).toEqual('handler1'); - expect(rawHandler1).toHaveBeenCalledWith( - { - core1: 'core', - core2: 101, - ctxFromA: 'aString core 101', - ctxFromB: 277, - }, - request, - response - ); + expect(rawHandler1).toHaveBeenCalledWith(expect.any(Object), request, response); }); it('exposes all core context to core providers', async () => { - expect.assertions(4); + expect.assertions(5); const contextContainer = new ContextContainer(plugins, coreId); contextContainer - .registerContext(coreId, 'core1', (context) => { - expect(context).toEqual({}); + .registerContext(coreId, 'core1', async (context) => { + expect(await resolveAllContexts(context)).toEqual({}); return 'core'; }) - .registerContext(coreId, 'core2', (context) => { - expect(context).toEqual({ core1: 'core' }); + .registerContext(coreId, 'core2', async (context) => { + expect(await resolveAllContexts(context)).toEqual({ core1: 'core' }); return 101; }); - const rawHandler1 = jest.fn(() => 'handler1' as any); + const rawHandler1 = jest.fn(async (context) => { + expect(await resolveAllContexts(context)).toEqual({ + core1: 'core', + core2: 101, + }); + return 'handler1' as any; + }); const handler1 = contextContainer.createHandler(pluginA, rawHandler1); const request = httpServerMock.createKibanaRequest(); @@ -237,14 +434,7 @@ describe('ContextContainer', () => { expect(await handler1(request, response)).toEqual('handler1'); // If no context is registered for pluginA, only core contexts should be exposed - expect(rawHandler1).toHaveBeenCalledWith( - { - core1: 'core', - core2: 101, - }, - request, - response - ); + expect(rawHandler1).toHaveBeenCalledWith(expect.any(Object), request, response); }); it('does not expose plugin contexts to core handler', async () => { @@ -254,24 +444,24 @@ describe('ContextContainer', () => { .registerContext(coreId, 'core1', (context) => 'core') .registerContext(pluginA, 'ctxFromA', (context) => 'aString'); - const rawHandler1 = jest.fn(() => 'handler1' as any); + const rawHandler1 = jest.fn(async (context) => { + // pluginA context should not be present in a core handler + expect(await resolveAllContexts(context)).toEqual({ + core1: 'core', + }); + return 'handler1' as any; + }); const handler1 = contextContainer.createHandler(coreId, rawHandler1); const request = httpServerMock.createKibanaRequest(); const response = httpServerMock.createResponseFactory(); expect(await handler1(request, response)).toEqual('handler1'); - // pluginA context should not be present in a core handler - expect(rawHandler1).toHaveBeenCalledWith( - { - core1: 'core', - }, - request, - response - ); + + expect(rawHandler1).toHaveBeenCalledWith(expect.any(Object), request, response); }); it('passes additional arguments to providers', async () => { - expect.assertions(6); + expect.assertions(7); const contextContainer = new ContextContainer(plugins, coreId); const request = httpServerMock.createKibanaRequest(); @@ -292,19 +482,102 @@ describe('ContextContainer', () => { } ); - const rawHandler1 = jest.fn(() => 'handler1' as any); + const rawHandler1 = jest.fn(async (context) => { + expect(await resolveAllContexts(context)).toEqual({ + core1: 'core', + ctxFromB: 77, + }); + return 'handler1' as any; + }); const handler1 = contextContainer.createHandler(pluginD, rawHandler1); expect(await handler1(request, response)).toEqual('handler1'); - expect(rawHandler1).toHaveBeenCalledWith( - { - core1: 'core', - ctxFromB: 77, - }, - request, - response - ); + expect(rawHandler1).toHaveBeenCalledWith(expect.any(Object), request, response); + }); + + describe('#resolve', () => { + it('resolves dependencies', async () => { + const contextContainer = new ContextContainer(plugins, coreId); + expect.assertions(10); + contextContainer.registerContext(coreId, 'core1', async (context) => { + expect(await context.resolve([])).toEqual({}); + return 'core'; + }); + + contextContainer.registerContext( + pluginA, + 'ctxFromA', + async (context) => { + expect(await context.resolve(['core1'])).toEqual({ core1: 'core' }); + return 'aString'; + } + ); + contextContainer.registerContext( + pluginB, + 'ctxFromB', + async (context) => { + expect(await context.resolve(['core1', 'ctxFromA'])).toEqual({ + core1: 'core', + ctxFromA: 'aString', + }); + return 299; + } + ); + contextContainer.registerContext( + pluginC, + 'ctxFromC', + async (context) => { + expect(await context.resolve(['core1', 'ctxFromA', 'ctxFromB'])).toEqual({ + core1: 'core', + ctxFromA: 'aString', + ctxFromB: 299, + }); + return false; + } + ); + contextContainer.registerContext( + pluginD, + 'ctxFromD', + async (context) => { + expect(await context.resolve(['core1'])).toEqual({ core1: 'core' }); + return {}; + } + ); + + const rawHandler1 = jest.fn(async (context) => { + expect(await context.resolve(['core1', 'ctxFromA', 'ctxFromB', 'ctxFromC'])).toEqual({ + core1: 'core', + ctxFromA: 'aString', + ctxFromB: 299, + ctxFromC: false, + }); + return 'handler1' as any; + }); + const handler1 = contextContainer.createHandler(pluginC, rawHandler1); + + const rawHandler2 = jest.fn(async (context) => { + expect(await context.resolve(['core1', 'ctxFromD'])).toEqual({ + core1: 'core', + ctxFromD: {}, + }); + return 'handler2' as any; + }); + + const handler2 = contextContainer.createHandler(pluginD, rawHandler2); + + const request = httpServerMock.createKibanaRequest(); + const response = httpServerMock.createResponseFactory(); + + await handler1(request, response); + await handler2(request, response); + + // Should have context from pluginC, its deps, and core + expect(rawHandler1).toHaveBeenCalledWith(expect.any(Object), request, response); + + // Should have context from pluginD, and core + expect(rawHandler2).toHaveBeenCalledWith(expect.any(Object), request, response); + }); }); }); @@ -337,7 +610,11 @@ describe('ContextContainer', () => { const request = httpServerMock.createKibanaRequest(); const response = httpServerMock.createResponseFactory(); await handler1(request, response); - expect(rawHandler1).toHaveBeenCalledWith({}, request, response); + expect(rawHandler1).toHaveBeenCalledWith( + { resolve: expect.any(Function) }, + request, + response + ); }); }); }); diff --git a/src/core/server/context/container/context.ts b/src/core/server/context/container/context.ts index 2650c21853604..4bc9a70a7afbb 100644 --- a/src/core/server/context/container/context.ts +++ b/src/core/server/context/container/context.ts @@ -7,8 +7,7 @@ */ import { flatten } from 'lodash'; -import { ShallowPromise } from '@kbn/utility-types'; -import { pick } from 'lodash'; +import { ShallowPromise, MaybePromise } from '@kbn/utility-types'; import type { CoreId, PluginOpaqueId, RequestHandler, RequestHandlerContext } from '../..'; /** @@ -31,7 +30,7 @@ export type IContextProvider< // context.core will always be available, but plugin contexts are typed as optional context: Omit, ...rest: HandlerParameters -) => Promise | Context[ContextName]; +) => MaybePromise>; /** * A function that accepts a context object and an optional number of additional arguments. Used for the generic types @@ -202,6 +201,9 @@ export class ContextContainer implements IContextContainer { provider: IContextProvider ): this => { const contextName = name as string; + if (contextName === 'resolve') { + throw new Error(`Cannot register a provider for ${contextName}, it is a reserved keyword.`); + } if (this.contextProviders.has(contextName)) { throw new Error(`Context provider for ${contextName} has already been registered.`); } @@ -224,36 +226,51 @@ export class ContextContainer implements IContextContainer { } return (async (...args: HandlerParameters) => { - const context = await this.buildContext(source, ...args); + const context = this.buildContext(source, ...args); return handler(context, ...args); }) as ( ...args: HandlerParameters ) => ShallowPromise>; }; - private async buildContext( + private buildContext( source: symbol, ...contextArgs: HandlerParameters - ): Promise> { + ): HandlerContextType { const contextsToBuild = new Set(this.getContextNamesForSource(source)); + const builtContextPromises: Record> = {}; + + const builtContext = {} as HandlerContextType; + (builtContext as unknown as RequestHandlerContext).resolve = async (keys) => { + const resolved = await Promise.all( + keys.map(async (key) => { + return [key, await builtContext[key]]; + }) + ); + return Object.fromEntries(resolved); + }; return [...this.contextProviders] .sort(sortByCoreFirst(this.coreId)) .filter(([contextName]) => contextsToBuild.has(contextName)) - .reduce(async (contextPromise, [contextName, { provider, source: providerSource }]) => { - const resolvedContext = await contextPromise; - - // For the next provider, only expose the context available based on the dependencies of the plugin that - // registered that provider. - const exposedContext = pick(resolvedContext, [ - ...this.getContextNamesForSource(providerSource), - ]); + .reduce((contextAccessors, [contextName, { provider, source: providerSource }]) => { + const exposedContext = createExposedContext({ + currentContextName: contextName, + exposedContextNames: [...this.getContextNamesForSource(providerSource)], + contextAccessors, + }); + Object.defineProperty(contextAccessors, contextName, { + get: async () => { + const contextKey = contextName as keyof HandlerContextType; + if (!builtContextPromises[contextKey]) { + builtContextPromises[contextKey] = provider(exposedContext, ...contextArgs); + } + return await builtContextPromises[contextKey]; + }, + }); - return { - ...resolvedContext, - [contextName]: await provider(exposedContext, ...contextArgs), - }; - }, Promise.resolve({}) as Promise>); + return contextAccessors; + }, builtContext); } private getContextNamesForSource(source: symbol): ReadonlySet { @@ -299,3 +316,28 @@ const sortByCoreFirst = return rightProvider.source === coreId ? 1 : 0; } }; + +const createExposedContext = ({ + currentContextName, + exposedContextNames, + contextAccessors, +}: { + currentContextName: string; + exposedContextNames: string[]; + contextAccessors: Partial>; +}) => { + const exposedContext: Partial> = {}; + exposedContext.resolve = contextAccessors.resolve; + + for (const contextName of exposedContextNames) { + if (contextName === currentContextName) { + continue; + } + const descriptor = Object.getOwnPropertyDescriptor(contextAccessors, contextName); + if (descriptor) { + Object.defineProperty(exposedContext, contextName, descriptor); + } + } + + return exposedContext; +}; diff --git a/src/core/server/core_app/core_app.ts b/src/core/server/core_app/core_app.ts index bd7de6b20226c..28c52775b2d20 100644 --- a/src/core/server/core_app/core_app.ts +++ b/src/core/server/core_app/core_app.ts @@ -89,7 +89,8 @@ export class CoreApp { const resources = coreSetup.httpResources.createRegistrar(router); router.get({ path: '/', validate: false }, async (context, req, res) => { - const defaultRoute = await context.core.uiSettings.client.get('defaultRoute'); + const { uiSettings } = await context.core; + const defaultRoute = await uiSettings.client.get('defaultRoute'); const basePath = httpSetup.basePath.get(req); const url = `${basePath}${defaultRoute}`; diff --git a/src/core/server/deprecations/routes/get.ts b/src/core/server/deprecations/routes/get.ts index cce9369db6171..88965505488f9 100644 --- a/src/core/server/deprecations/routes/get.ts +++ b/src/core/server/deprecations/routes/get.ts @@ -15,7 +15,7 @@ export const registerGetRoute = (router: IRouter) => { validate: false, }, async (context, req, res) => { - const deprecationsClient = context.core.deprecations.client; + const deprecationsClient = (await context.core).deprecations.client; const body: DeprecationsGetResponse = { deprecations: await deprecationsClient.getAllDeprecations(), diff --git a/src/core/server/execution_context/integration_tests/tracing.test.ts b/src/core/server/execution_context/integration_tests/tracing.test.ts index 15813529c358b..2634c81833735 100644 --- a/src/core/server/execution_context/integration_tests/tracing.test.ts +++ b/src/core/server/execution_context/integration_tests/tracing.test.ts @@ -65,10 +65,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - const { headers } = await context.core.elasticsearch.client.asInternalUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asInternalUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -90,10 +88,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asCurrentUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -115,10 +111,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - const { headers } = await context.core.elasticsearch.client.asInternalUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asInternalUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -136,10 +130,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asCurrentUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -157,7 +149,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - const { headers } = await context.core.elasticsearch.client.asInternalUser.ping( + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asInternalUser.ping( {}, { opaqueId: 'new-opaque-id', @@ -203,10 +196,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asCurrentUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -229,10 +220,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { executionContext.set(parentContext); - const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asCurrentUser.ping({}, { meta: true }); return res.ok({ body: { context: executionContext.get()?.toJSON(), @@ -345,10 +334,8 @@ describe('trace', () => { router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { executionContext.set(parentContext); await delay(id-- * 100); - const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asCurrentUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -397,10 +384,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asCurrentUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -487,10 +472,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asCurrentUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -511,10 +494,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - const { headers } = await context.core.elasticsearch.client.asInternalUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asInternalUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -535,10 +516,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asCurrentUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -561,10 +540,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { executionContext.set(parentContext); - const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asCurrentUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -593,10 +570,8 @@ describe('trace', () => { }; router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { executionContext.set(ctx); - const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asCurrentUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -663,9 +638,10 @@ describe('trace', () => { description: 'new-description', }; router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - const { headers } = await executionContext.withContext(newContext, () => - context.core.elasticsearch.client.asCurrentUser.ping({}, { meta: true }) - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await executionContext.withContext(newContext, () => { + return esClient.asCurrentUser.ping({}, { meta: true }); + }); return res.ok({ body: headers || {} }); }); diff --git a/src/core/server/http/types.ts b/src/core/server/http/types.ts index e6d9514107798..27f240af48e01 100644 --- a/src/core/server/http/types.ts +++ b/src/core/server/http/types.ts @@ -366,7 +366,7 @@ export interface HttpServiceSetup { */ registerRouteHandlerContext: < Context extends RequestHandlerContext, - ContextName extends keyof Context + ContextName extends keyof Omit >( contextName: ContextName, provider: RequestHandlerContextProvider @@ -393,7 +393,7 @@ export interface InternalHttpServiceSetup authRequestHeaders: IAuthHeadersStorage; registerRouteHandlerContext: < Context extends RequestHandlerContext, - ContextName extends keyof Context + ContextName extends keyof Omit >( pluginOpaqueId: PluginOpaqueId, contextName: ContextName, diff --git a/src/core/server/http_resources/http_resources_service.test.ts b/src/core/server/http_resources/http_resources_service.test.ts index 0a661f25d3141..c74fde4d2e2a7 100644 --- a/src/core/server/http_resources/http_resources_service.test.ts +++ b/src/core/server/http_resources/http_resources_service.test.ts @@ -27,7 +27,7 @@ describe('HttpResources service', () => { let setupDeps: SetupDeps; let router: jest.Mocked; const kibanaRequest = httpServerMock.createKibanaRequest(); - const context = { core: coreMock.createRequestHandlerContext() }; + const context = coreMock.createCustomRequestHandlerContext({}); const apmConfig = { mockApmConfig: true }; beforeEach(() => { @@ -71,7 +71,7 @@ describe('HttpResources service', () => { await routeHandler(context, kibanaRequest, responseFactory); expect(getDeps().rendering.render).toHaveBeenCalledWith( kibanaRequest, - context.core.uiSettings.client, + (await context.core).uiSettings.client, { isAnonymousPage: false, vars: { @@ -117,7 +117,7 @@ describe('HttpResources service', () => { await routeHandler(context, kibanaRequest, responseFactory); expect(getDeps().rendering.render).toHaveBeenCalledWith( kibanaRequest, - context.core.uiSettings.client, + (await context.core).uiSettings.client, { isAnonymousPage: true, vars: { diff --git a/src/core/server/http_resources/http_resources_service.ts b/src/core/server/http_resources/http_resources_service.ts index 692b248752df9..2d49cb17cf4c0 100644 --- a/src/core/server/http_resources/http_resources_service.ts +++ b/src/core/server/http_resources/http_resources_service.ts @@ -93,7 +93,8 @@ export class HttpResourcesService implements CoreService>( + parts: T[] + ) => Promise>>; +} + /** - * Plugin specific context passed to a route handler. + * Base context passed to a route handler. + * + * @public + */ +export interface RequestHandlerContext extends RequestHandlerContextBase { + core: Promise; +} + +/** @public */ +export type CustomRequestHandlerContext = RequestHandlerContext & { + [Key in keyof T]: T[Key] extends Promise ? T[Key] : Promise; +}; + +/** + * The `core` context provided to route handler. * * Provides the following clients and services: * - {@link SavedObjectsClient | savedObjects.client} - Saved Objects client @@ -477,27 +509,24 @@ export { TelemetryCounterType } from './analytics'; * data client which uses the credentials of the incoming request * - {@link IUiSettingsClient | uiSettings.client} - uiSettings client * which uses the credentials of the incoming request - * * @public */ -export interface RequestHandlerContext { - core: { - savedObjects: { - client: SavedObjectsClientContract; - typeRegistry: ISavedObjectTypeRegistry; - getClient: (options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract; - getExporter: (client: SavedObjectsClientContract) => ISavedObjectsExporter; - getImporter: (client: SavedObjectsClientContract) => ISavedObjectsImporter; - }; - elasticsearch: { - client: IScopedClusterClient; - }; - uiSettings: { - client: IUiSettingsClient; - }; - deprecations: { - client: DeprecationsClient; - }; +export interface CoreRequestHandlerContext { + savedObjects: { + client: SavedObjectsClientContract; + typeRegistry: ISavedObjectTypeRegistry; + getClient: (options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract; + getExporter: (client: SavedObjectsClientContract) => ISavedObjectsExporter; + getImporter: (client: SavedObjectsClientContract) => ISavedObjectsImporter; + }; + elasticsearch: { + client: IScopedClusterClient; + }; + uiSettings: { + client: IUiSettingsClient; + }; + deprecations: { + client: DeprecationsClient; }; } diff --git a/src/core/server/mocks.ts b/src/core/server/mocks.ts index 0e5821bcc1c23..cb7010808fe32 100644 --- a/src/core/server/mocks.ts +++ b/src/core/server/mocks.ts @@ -9,6 +9,7 @@ import { of } from 'rxjs'; import { duration } from 'moment'; import { ByteSizeValue } from '@kbn/config-schema'; +import { isPromise } from '@kbn/std'; import type { MockedKeys } from '@kbn/utility-types/jest'; import type { PluginInitializerContext, @@ -66,7 +67,11 @@ export { executionContextServiceMock } from './execution_context/execution_conte export { docLinksServiceMock } from './doc_links/doc_links_service.mock'; export { analyticsServiceMock } from './analytics/analytics_service.mock'; -export type { ElasticsearchClientMock } from './elasticsearch/client/mocks'; +export type { + ElasticsearchClientMock, + ClusterClientMock, + ScopedClusterClientMock, +} from './elasticsearch/client/mocks'; type MockedPluginInitializerConfig = jest.Mocked['config']>; @@ -280,6 +285,40 @@ function createCoreRequestHandlerContextMock() { }; } +export type CustomRequestHandlerMock = { + core: Promise>; + resolve: jest.MockedFunction; +} & { + [Key in keyof T]: T[Key] extends Promise ? T[Key] : Promise; +}; + +const createCustomRequestHandlerContextMock = (contextParts: T): CustomRequestHandlerMock => { + const mock = Object.entries(contextParts).reduce( + (context, [key, value]) => { + // @ts-expect-error type matching from inferred types is hard + context[key] = isPromise(value) ? value : Promise.resolve(value); + return context; + }, + { + core: Promise.resolve(createCoreRequestHandlerContextMock()), + } as CustomRequestHandlerMock + ); + + mock.resolve = jest.fn().mockImplementation(async () => { + const resolved = {}; + for (const propName of Object.keys(mock)) { + if (propName === 'resolve') { + continue; + } + // @ts-expect-error type matching from inferred types is hard + resolved[propName] = await mock[propName]; + } + return resolved; + }); + + return mock; +}; + export const coreMock = { createPreboot: createCorePrebootMock, createSetup: createCoreSetupMock, @@ -289,4 +328,5 @@ export const coreMock = { createInternalStart: createInternalCoreStartMock, createPluginInitializerContext: pluginInitializerContextMock, createRequestHandlerContext: createCoreRequestHandlerContextMock, + createCustomRequestHandlerContext: createCustomRequestHandlerContextMock, }; diff --git a/src/core/server/plugins/plugin_context.ts b/src/core/server/plugins/plugin_context.ts index 1566fd5bbe07b..81e3b3a107c72 100644 --- a/src/core/server/plugins/plugin_context.ts +++ b/src/core/server/plugins/plugin_context.ts @@ -185,7 +185,7 @@ export function createPluginSetupContext( createCookieSessionStorageFactory: deps.http.createCookieSessionStorageFactory, registerRouteHandlerContext: < Context extends RequestHandlerContext, - ContextName extends keyof Context + ContextName extends keyof Omit >( contextName: ContextName, provider: RequestHandlerContextProvider diff --git a/src/core/server/rendering/bootstrap/register_bootstrap_route.ts b/src/core/server/rendering/bootstrap/register_bootstrap_route.ts index 6be537dce1981..06f4100a01576 100644 --- a/src/core/server/rendering/bootstrap/register_bootstrap_route.ts +++ b/src/core/server/rendering/bootstrap/register_bootstrap_route.ts @@ -25,7 +25,7 @@ export const registerBootstrapRoute = ({ validate: false, }, async (ctx, req, res) => { - const uiSettingsClient = ctx.core.uiSettings.client; + const uiSettingsClient = (await ctx.core).uiSettings.client; const { body, etag } = await renderer({ uiSettingsClient, request: req }); return res.ok({ @@ -48,7 +48,7 @@ export const registerBootstrapRoute = ({ validate: false, }, async (ctx, req, res) => { - const uiSettingsClient = ctx.core.uiSettings.client; + const uiSettingsClient = (await ctx.core).uiSettings.client; const { body, etag } = await renderer({ uiSettingsClient, request: req, diff --git a/src/core/server/saved_objects/import/import_saved_objects.ts b/src/core/server/saved_objects/import/import_saved_objects.ts index 0631d97b58a72..9e9f5f8b050dc 100644 --- a/src/core/server/saved_objects/import/import_saved_objects.ts +++ b/src/core/server/saved_objects/import/import_saved_objects.ts @@ -35,6 +35,8 @@ export interface ImportSavedObjectsOptions { objectLimit: number; /** If true, will override existing object if present. Note: this has no effect when used with the `createNewCopies` option. */ overwrite: boolean; + /** Refresh setting, defaults to `wait_for` */ + refresh?: boolean | 'wait_for'; /** {@link SavedObjectsClientContract | client} to use to perform the import operation */ savedObjectsClient: SavedObjectsClientContract; /** The registry of all known saved object types */ @@ -62,6 +64,7 @@ export async function importSavedObjectsFromStream({ typeRegistry, importHooks, namespace, + refresh, }: ImportSavedObjectsOptions): Promise { let errorAccumulator: SavedObjectsImportFailure[] = []; const supportedTypes = typeRegistry.getImportableAndExportableTypes().map((type) => type.name); @@ -141,6 +144,7 @@ export async function importSavedObjectsFromStream({ importStateMap, overwrite, namespace, + refresh, }; const createSavedObjectsResult = await createSavedObjects(createSavedObjectsParams); errorAccumulator = [...errorAccumulator, ...createSavedObjectsResult.errors]; diff --git a/src/core/server/saved_objects/import/lib/create_saved_objects.ts b/src/core/server/saved_objects/import/lib/create_saved_objects.ts index bf58b2bb4b00e..d6c7cbe934b51 100644 --- a/src/core/server/saved_objects/import/lib/create_saved_objects.ts +++ b/src/core/server/saved_objects/import/lib/create_saved_objects.ts @@ -18,6 +18,7 @@ export interface CreateSavedObjectsParams { importStateMap: ImportStateMap; namespace?: string; overwrite?: boolean; + refresh?: boolean | 'wait_for'; } export interface CreateSavedObjectsResult { createdObjects: Array>; @@ -35,6 +36,7 @@ export const createSavedObjects = async ({ importStateMap, namespace, overwrite, + refresh, }: CreateSavedObjectsParams): Promise> => { // filter out any objects that resulted in errors const errorSet = accumulatedErrors.reduce( @@ -87,6 +89,7 @@ export const createSavedObjects = async ({ const bulkCreateResponse = await savedObjectsClient.bulkCreate(objectsToCreate, { namespace, overwrite, + refresh, }); expectedResults = bulkCreateResponse.saved_objects; } diff --git a/src/core/server/saved_objects/import/saved_objects_importer.ts b/src/core/server/saved_objects/import/saved_objects_importer.ts index f4572e58d6fad..e9c54f7b44deb 100644 --- a/src/core/server/saved_objects/import/saved_objects_importer.ts +++ b/src/core/server/saved_objects/import/saved_objects_importer.ts @@ -66,12 +66,14 @@ export class SavedObjectsImporter { createNewCopies, namespace, overwrite, + refresh, }: SavedObjectsImportOptions): Promise { return importSavedObjectsFromStream({ readStream, createNewCopies, namespace, overwrite, + refresh, objectLimit: this.#importSizeLimit, savedObjectsClient: this.#savedObjectsClient, typeRegistry: this.#typeRegistry, diff --git a/src/core/server/saved_objects/import/types.ts b/src/core/server/saved_objects/import/types.ts index ccf58c99f1ad8..d3a38b48e92cb 100644 --- a/src/core/server/saved_objects/import/types.ts +++ b/src/core/server/saved_objects/import/types.ts @@ -155,6 +155,8 @@ export interface SavedObjectsImportOptions { namespace?: string; /** If true, will create new copies of import objects, each with a random `id` and undefined `originId`. */ createNewCopies: boolean; + /** Refresh setting, defaults to `wait_for` */ + refresh?: boolean | 'wait_for'; } /** diff --git a/src/core/server/saved_objects/migrations/README.md b/src/core/server/saved_objects/migrations/README.md index d8382e4f0e061..7dd5dacffcee6 100644 --- a/src/core/server/saved_objects/migrations/README.md +++ b/src/core/server/saved_objects/migrations/README.md @@ -181,7 +181,11 @@ and the migration source index is the index the `.kibana` alias points to. Create the target index. This operation is idempotent, if the index already exist, we wait until its status turns yellow ### New control state - → `MARK_VERSION_INDEX_READY` +1. If the action succeeds + → `MARK_VERSION_INDEX_READY` +2. If the action fails with a `index_not_yellow_timeout` + → `CREATE_NEW_TARGET` + ## LEGACY_SET_WRITE_BLOCK ### Next action @@ -209,8 +213,10 @@ Create a new `.kibana_pre6.5.0_001` index into which we can reindex the legacy index. (Since the task manager index was converted from a data index into a saved objects index in 7.4 it will be reindexed into `.kibana_pre7.4.0_001`) ### New control state +1. If the index creation succeeds → `LEGACY_REINDEX` - +2. If the index creation task failed with a `index_not_yellow_timeout` + → `LEGACY_REINDEX_WAIT_FOR_TASK` ## LEGACY_REINDEX ### Next action `reindex` @@ -257,7 +263,10 @@ Wait for the Elasticsearch cluster to be in "yellow" state. It means the index's We don't have as much data redundancy as we could have, but it's enough to start the migration. ### New control state +1. If the action succeeds → `SET_SOURCE_WRITE_BLOCK` +2. If the action fails with a `index_not_yellow_timeout` + → `WAIT_FOR_YELLOW_SOURCE` ## SET_SOURCE_WRITE_BLOCK ### Next action @@ -278,7 +287,10 @@ This operation is idempotent, if the index already exist, we wait until its stat - (Since we never query the temporary index we can potentially disable refresh to speed up indexing performance. Profile to see if gains justify complexity) ### New control state +1. If the action succeeds → `REINDEX_SOURCE_TO_TEMP_OPEN_PIT` +2. If the action fails with a `index_not_yellow_timeout` + → `CREATE_REINDEX_TEMP` ## REINDEX_SOURCE_TO_TEMP_OPEN_PIT ### Next action @@ -357,7 +369,10 @@ Ask elasticsearch to clone the temporary index into the target index. If the tar We can’t use the temporary index as our target index because one instance can complete the migration, delete a document, and then a second instance starts the reindex operation and re-creates the deleted document. By cloning the temporary index and only accepting writes/deletes from the cloned target index, we prevent lost acknowledged deletes. ### New control state +1. If the action succeeds → `OUTDATED_DOCUMENTS_SEARCH` +2. If the action fails with a `index_not_yellow_timeout` + → `CLONE_TEMP_TO_TARGET` ## OUTDATED_DOCUMENTS_SEARCH ### Next action diff --git a/src/core/server/saved_objects/migrations/__snapshots__/migrations_state_action_machine.test.ts.snap b/src/core/server/saved_objects/migrations/__snapshots__/migrations_state_action_machine.test.ts.snap index 0ad6f18104685..d26021d28b0e5 100644 --- a/src/core/server/saved_objects/migrations/__snapshots__/migrations_state_action_machine.test.ts.snap +++ b/src/core/server/saved_objects/migrations/__snapshots__/migrations_state_action_machine.test.ts.snap @@ -32,6 +32,11 @@ Object { }, ], "maxBatchSizeBytes": 100000000, + "migrationDocLinks": Object { + "repeatedTimeoutRequests": "https://www.elastic.co/guide/en/kibana/test-branch/resolve-migrations-failures.html#_repeated_time_out_requests_that_eventually_fail", + "resolveMigrationFailures": "https://www.elastic.co/guide/en/kibana/test-branch/resolve-migrations-failures.html", + "routingAllocationDisabled": "https://www.elastic.co/guide/en/kibana/test-branch/resolve-migrations-failures.html#routing-allocation-disabled", + }, "outdatedDocuments": Array [], "outdatedDocumentsQuery": Object { "bool": Object { @@ -193,6 +198,11 @@ Object { }, ], "maxBatchSizeBytes": 100000000, + "migrationDocLinks": Object { + "repeatedTimeoutRequests": "https://www.elastic.co/guide/en/kibana/test-branch/resolve-migrations-failures.html#_repeated_time_out_requests_that_eventually_fail", + "resolveMigrationFailures": "https://www.elastic.co/guide/en/kibana/test-branch/resolve-migrations-failures.html", + "routingAllocationDisabled": "https://www.elastic.co/guide/en/kibana/test-branch/resolve-migrations-failures.html#routing-allocation-disabled", + }, "outdatedDocuments": Array [], "outdatedDocumentsQuery": Object { "bool": Object { @@ -358,6 +368,11 @@ Object { }, ], "maxBatchSizeBytes": 100000000, + "migrationDocLinks": Object { + "repeatedTimeoutRequests": "https://www.elastic.co/guide/en/kibana/test-branch/resolve-migrations-failures.html#_repeated_time_out_requests_that_eventually_fail", + "resolveMigrationFailures": "https://www.elastic.co/guide/en/kibana/test-branch/resolve-migrations-failures.html", + "routingAllocationDisabled": "https://www.elastic.co/guide/en/kibana/test-branch/resolve-migrations-failures.html#routing-allocation-disabled", + }, "outdatedDocuments": Array [], "outdatedDocumentsQuery": Object { "bool": Object { @@ -527,6 +542,11 @@ Object { }, ], "maxBatchSizeBytes": 100000000, + "migrationDocLinks": Object { + "repeatedTimeoutRequests": "https://www.elastic.co/guide/en/kibana/test-branch/resolve-migrations-failures.html#_repeated_time_out_requests_that_eventually_fail", + "resolveMigrationFailures": "https://www.elastic.co/guide/en/kibana/test-branch/resolve-migrations-failures.html", + "routingAllocationDisabled": "https://www.elastic.co/guide/en/kibana/test-branch/resolve-migrations-failures.html#routing-allocation-disabled", + }, "outdatedDocuments": Array [], "outdatedDocumentsQuery": Object { "bool": Object { @@ -722,6 +742,11 @@ Object { }, ], "maxBatchSizeBytes": 100000000, + "migrationDocLinks": Object { + "repeatedTimeoutRequests": "https://www.elastic.co/guide/en/kibana/test-branch/resolve-migrations-failures.html#_repeated_time_out_requests_that_eventually_fail", + "resolveMigrationFailures": "https://www.elastic.co/guide/en/kibana/test-branch/resolve-migrations-failures.html", + "routingAllocationDisabled": "https://www.elastic.co/guide/en/kibana/test-branch/resolve-migrations-failures.html#routing-allocation-disabled", + }, "outdatedDocuments": Array [ Object { "_id": "1234", @@ -894,6 +919,11 @@ Object { }, ], "maxBatchSizeBytes": 100000000, + "migrationDocLinks": Object { + "repeatedTimeoutRequests": "https://www.elastic.co/guide/en/kibana/test-branch/resolve-migrations-failures.html#_repeated_time_out_requests_that_eventually_fail", + "resolveMigrationFailures": "https://www.elastic.co/guide/en/kibana/test-branch/resolve-migrations-failures.html", + "routingAllocationDisabled": "https://www.elastic.co/guide/en/kibana/test-branch/resolve-migrations-failures.html#routing-allocation-disabled", + }, "outdatedDocuments": Array [ Object { "_id": "1234", diff --git a/src/core/server/saved_objects/migrations/actions/clone_index.ts b/src/core/server/saved_objects/migrations/actions/clone_index.ts index b5aedb11b36fa..c9496ec6915ca 100644 --- a/src/core/server/saved_objects/migrations/actions/clone_index.ts +++ b/src/core/server/saved_objects/migrations/actions/clone_index.ts @@ -15,7 +15,7 @@ import { catchRetryableEsClientErrors, RetryableEsClientError, } from './catch_retryable_es_client_errors'; -import type { IndexNotFound, AcknowledgeResponse } from '.'; +import type { IndexNotFound, AcknowledgeResponse, IndexNotYellowTimeout } from '.'; import { waitForIndexStatusYellow } from './wait_for_index_status_yellow'; import { DEFAULT_TIMEOUT, @@ -49,7 +49,7 @@ export const cloneIndex = ({ target, timeout = DEFAULT_TIMEOUT, }: CloneIndexParams): TaskEither.TaskEither< - RetryableEsClientError | IndexNotFound, + RetryableEsClientError | IndexNotFound | IndexNotYellowTimeout, CloneIndexResponse > => { const cloneTask: TaskEither.TaskEither< @@ -122,7 +122,7 @@ export const cloneIndex = ({ return pipe( cloneTask, - TaskEither.chain((res) => { + TaskEither.chainW((res) => { if (res.acknowledged && res.shardsAcknowledged) { // If the cluster state was updated and all shards ackd we're done return TaskEither.right(res); diff --git a/src/core/server/saved_objects/migrations/actions/create_index.ts b/src/core/server/saved_objects/migrations/actions/create_index.ts index b0be80d1b74b6..69d47077c0606 100644 --- a/src/core/server/saved_objects/migrations/actions/create_index.ts +++ b/src/core/server/saved_objects/migrations/actions/create_index.ts @@ -22,7 +22,7 @@ import { INDEX_AUTO_EXPAND_REPLICAS, WAIT_FOR_ALL_SHARDS_TO_BE_ACTIVE, } from './constants'; -import { waitForIndexStatusYellow } from './wait_for_index_status_yellow'; +import { IndexNotYellowTimeout, waitForIndexStatusYellow } from './wait_for_index_status_yellow'; function aliasArrayToRecord(aliases: string[]): Record { const result: Record = {}; @@ -54,7 +54,10 @@ export const createIndex = ({ indexName, mappings, aliases = [], -}: CreateIndexParams): TaskEither.TaskEither => { +}: CreateIndexParams): TaskEither.TaskEither< + RetryableEsClientError | IndexNotYellowTimeout, + 'create_index_succeeded' +> => { const createIndexTask: TaskEither.TaskEither< RetryableEsClientError, AcknowledgeResponse diff --git a/src/core/server/saved_objects/migrations/actions/index.ts b/src/core/server/saved_objects/migrations/actions/index.ts index 0915a73f0d531..4db260d4c139b 100644 --- a/src/core/server/saved_objects/migrations/actions/index.ts +++ b/src/core/server/saved_objects/migrations/actions/index.ts @@ -35,8 +35,11 @@ export { removeWriteBlock } from './remove_write_block'; export type { CloneIndexResponse, CloneIndexParams } from './clone_index'; export { cloneIndex } from './clone_index'; -export type { WaitForIndexStatusYellowParams } from './wait_for_index_status_yellow'; -import { waitForIndexStatusYellow } from './wait_for_index_status_yellow'; +export type { + WaitForIndexStatusYellowParams, + IndexNotYellowTimeout, +} from './wait_for_index_status_yellow'; +import { IndexNotYellowTimeout, waitForIndexStatusYellow } from './wait_for_index_status_yellow'; export type { WaitForTaskResponse, WaitForTaskCompletionTimeout } from './wait_for_task'; import { waitForTask, WaitForTaskCompletionTimeout } from './wait_for_task'; @@ -149,6 +152,7 @@ export interface ActionErrorTypeMap { request_entity_too_large_exception: RequestEntityTooLargeException; unknown_docs_found: UnknownDocsFound; unsupported_cluster_routing_allocation: UnsupportedClusterRoutingAllocation; + index_not_yellow_timeout: IndexNotYellowTimeout; } /** diff --git a/src/core/server/saved_objects/migrations/actions/initialize_action.ts b/src/core/server/saved_objects/migrations/actions/initialize_action.ts index 73502382c9ca0..281e3a0a4f3e0 100644 --- a/src/core/server/saved_objects/migrations/actions/initialize_action.ts +++ b/src/core/server/saved_objects/migrations/actions/initialize_action.ts @@ -29,6 +29,7 @@ export interface InitActionParams { export interface UnsupportedClusterRoutingAllocation { type: 'unsupported_cluster_routing_allocation'; + message: string; } export const checkClusterRoutingAllocationEnabledTask = @@ -53,7 +54,11 @@ export const checkClusterRoutingAllocationEnabledTask = [...clusterRoutingAllocations].every((s: string) => s === 'all'); // if set, only allow 'all' if (!clusterRoutingAllocationEnabled) { - return Either.left({ type: 'unsupported_cluster_routing_allocation' as const }); + return Either.left({ + type: 'unsupported_cluster_routing_allocation' as const, + message: + '[unsupported_cluster_routing_allocation] The elasticsearch cluster has cluster routing allocation incorrectly set for migrations to continue.', + }); } else { return Either.right({}); } diff --git a/src/core/server/saved_objects/migrations/actions/integration_tests/actions.test.ts b/src/core/server/saved_objects/migrations/actions/integration_tests/actions.test.ts index 331958e88ce83..9846e5f48dc21 100644 --- a/src/core/server/saved_objects/migrations/actions/integration_tests/actions.test.ts +++ b/src/core/server/saved_objects/migrations/actions/integration_tests/actions.test.ts @@ -167,6 +167,7 @@ describe('migration actions', () => { Object { "_tag": "Left", "left": Object { + "message": "[unsupported_cluster_routing_allocation] The elasticsearch cluster has cluster routing allocation incorrectly set for migrations to continue.", "type": "unsupported_cluster_routing_allocation", }, } @@ -187,6 +188,7 @@ describe('migration actions', () => { Object { "_tag": "Left", "left": Object { + "message": "[unsupported_cluster_routing_allocation] The elasticsearch cluster has cluster routing allocation incorrectly set for migrations to continue.", "type": "unsupported_cluster_routing_allocation", }, } @@ -207,6 +209,7 @@ describe('migration actions', () => { Object { "_tag": "Left", "left": Object { + "message": "[unsupported_cluster_routing_allocation] The elasticsearch cluster has cluster routing allocation incorrectly set for migrations to continue.", "type": "unsupported_cluster_routing_allocation", }, } @@ -321,8 +324,13 @@ describe('migration actions', () => { }); describe('waitForIndexStatusYellow', () => { - afterAll(async () => { - await client.indices.delete({ index: 'red_then_yellow_index' }); + afterEach(async () => { + try { + await client.indices.delete({ index: 'red_then_yellow_index' }); + await client.indices.delete({ index: 'red_index' }); + } catch (e) { + /** ignore */ + } }); it('resolves right after waiting for an index status to be yellow if the index already existed', async () => { // Create a red index @@ -366,6 +374,39 @@ describe('migration actions', () => { const yellowStatusResponse = await client.cluster.health({ index: 'red_then_yellow_index' }); expect(yellowStatusResponse.status).toBe('yellow'); }); + it('resolves left with "index_not_yellow_timeout" after waiting for an index status to be yellow timeout', async () => { + // Create a red index + await client.indices + .create({ + index: 'red_index', + timeout: '5s', + body: { + mappings: { properties: {} }, + settings: { + // Allocate no replicas so that this index stays red + number_of_replicas: '0', + // Disable all shard allocation so that the index status is red + index: { routing: { allocation: { enable: 'none' } } }, + }, + }, + }) + .catch((e) => {}); + // try to wait for index status yellow: + const task = waitForIndexStatusYellow({ + client, + index: 'red_index', + timeout: '1s', + }); + await expect(task()).resolves.toMatchInlineSnapshot(` + Object { + "_tag": "Left", + "left": Object { + "message": "[index_not_yellow_timeout] Timeout waiting for the status of the [red_index] index to become 'yellow'", + "type": "index_not_yellow_timeout", + }, + } + `); + }); }); describe('cloneIndex', () => { @@ -384,14 +425,14 @@ describe('migration actions', () => { }); expect.assertions(1); await expect(task()).resolves.toMatchInlineSnapshot(` - Object { - "_tag": "Right", - "right": Object { - "acknowledged": true, - "shardsAcknowledged": true, - }, - } - `); + Object { + "_tag": "Right", + "right": Object { + "acknowledged": true, + "shardsAcknowledged": true, + }, + } + `); }); it('resolves right after waiting for index status to be yellow if clone target already existed', async () => { expect.assertions(2); @@ -450,16 +491,16 @@ describe('migration actions', () => { expect.assertions(1); const task = cloneIndex({ client, source: 'no_such_index', target: 'clone_target_3' }); await expect(task()).resolves.toMatchInlineSnapshot(` - Object { - "_tag": "Left", - "left": Object { - "index": "no_such_index", - "type": "index_not_found_exception", - }, - } - `); + Object { + "_tag": "Left", + "left": Object { + "index": "no_such_index", + "type": "index_not_found_exception", + }, + } + `); }); - it('resolves left with a retryable_es_client_error if clone target already exists but takes longer than the specified timeout before turning yellow', async () => { + it('resolves left with a index_not_yellow_timeout if clone target already exists but takes longer than the specified timeout before turning yellow', async () => { // Create a red index await client.indices .create({ @@ -486,14 +527,14 @@ describe('migration actions', () => { })(); await expect(cloneIndexPromise).resolves.toMatchInlineSnapshot(` - Object { - "_tag": "Left", - "left": Object { - "message": "Timeout waiting for the status of the [clone_red_index] index to become 'yellow'", - "type": "retryable_es_client_error", - }, - } - `); + Object { + "_tag": "Left", + "left": Object { + "message": "[index_not_yellow_timeout] Timeout waiting for the status of the [clone_red_index] index to become 'yellow'", + "type": "index_not_yellow_timeout", + }, + } + `); // Now that we know timeouts work, make the index yellow again and call cloneIndex a second time to verify that it completes @@ -514,14 +555,14 @@ describe('migration actions', () => { })(); await expect(cloneIndexPromise2).resolves.toMatchInlineSnapshot(` - Object { - "_tag": "Right", - "right": Object { - "acknowledged": true, - "shardsAcknowledged": true, - }, - } - `); + Object { + "_tag": "Right", + "right": Object { + "acknowledged": true, + "shardsAcknowledged": true, + }, + } + `); }); }); @@ -539,11 +580,11 @@ describe('migration actions', () => { })()) as Either.Right; const task = waitForReindexTask({ client, taskId: res.right.taskId, timeout: '10s' }); await expect(task()).resolves.toMatchInlineSnapshot(` - Object { - "_tag": "Right", - "right": "reindex_succeeded", - } - `); + Object { + "_tag": "Right", + "right": "reindex_succeeded", + } + `); const results = ( (await searchForOutdatedDocuments(client, { @@ -579,11 +620,11 @@ describe('migration actions', () => { })()) as Either.Right; const task = waitForReindexTask({ client, taskId: res.right.taskId, timeout: '10s' }); await expect(task()).resolves.toMatchInlineSnapshot(` - Object { - "_tag": "Right", - "right": "reindex_succeeded", - } - `); + Object { + "_tag": "Right", + "right": "reindex_succeeded", + } + `); const results = ( (await searchForOutdatedDocuments(client, { @@ -612,11 +653,11 @@ describe('migration actions', () => { })()) as Either.Right; const task = waitForReindexTask({ client, taskId: res.right.taskId, timeout: '10s' }); await expect(task()).resolves.toMatchInlineSnapshot(` - Object { - "_tag": "Right", - "right": "reindex_succeeded", - } - `); + Object { + "_tag": "Right", + "right": "reindex_succeeded", + } + `); const results = ( (await searchForOutdatedDocuments(client, { batchSize: 1000, @@ -647,11 +688,11 @@ describe('migration actions', () => { })()) as Either.Right; let task = waitForReindexTask({ client, taskId: res.right.taskId, timeout: '10s' }); await expect(task()).resolves.toMatchInlineSnapshot(` - Object { - "_tag": "Right", - "right": "reindex_succeeded", - } - `); + Object { + "_tag": "Right", + "right": "reindex_succeeded", + } + `); // reindex without a script res = (await reindex({ @@ -664,11 +705,11 @@ describe('migration actions', () => { })()) as Either.Right; task = waitForReindexTask({ client, taskId: res.right.taskId, timeout: '10s' }); await expect(task()).resolves.toMatchInlineSnapshot(` - Object { - "_tag": "Right", - "right": "reindex_succeeded", - } - `); + Object { + "_tag": "Right", + "right": "reindex_succeeded", + } + `); // Assert that documents weren't overridden by the second, unscripted reindex const results = ( @@ -723,11 +764,11 @@ describe('migration actions', () => { })()) as Either.Right; const task = waitForReindexTask({ client, taskId: res.right.taskId, timeout: '10s' }); await expect(task()).resolves.toMatchInlineSnapshot(` - Object { - "_tag": "Right", - "right": "reindex_succeeded", - } - `); + Object { + "_tag": "Right", + "right": "reindex_succeeded", + } + `); // Assert that existing documents weren't overridden, but that missing // documents were added by the reindex const results = ( @@ -780,13 +821,13 @@ describe('migration actions', () => { const task = waitForReindexTask({ client, taskId: reindexTaskId, timeout: '10s' }); await expect(task()).resolves.toMatchInlineSnapshot(` - Object { - "_tag": "Left", - "left": Object { - "type": "incompatible_mapping_exception", - }, - } - `); + Object { + "_tag": "Left", + "left": Object { + "type": "incompatible_mapping_exception", + }, + } + `); }); it('resolves left incompatible_mapping_exception if all reindex failures are due to a mapper_parsing_exception', async () => { expect.assertions(1); @@ -819,13 +860,13 @@ describe('migration actions', () => { const task = waitForReindexTask({ client, taskId: reindexTaskId, timeout: '10s' }); await expect(task()).resolves.toMatchInlineSnapshot(` - Object { - "_tag": "Left", - "left": Object { - "type": "incompatible_mapping_exception", - }, - } - `); + Object { + "_tag": "Left", + "left": Object { + "type": "incompatible_mapping_exception", + }, + } + `); }); it('resolves left index_not_found_exception if source index does not exist', async () => { expect.assertions(1); @@ -841,14 +882,14 @@ describe('migration actions', () => { })()) as Either.Right; const task = waitForReindexTask({ client, taskId: res.right.taskId, timeout: '10s' }); await expect(task()).resolves.toMatchInlineSnapshot(` - Object { - "_tag": "Left", - "left": Object { - "index": "no_such_index", - "type": "index_not_found_exception", - }, - } - `); + Object { + "_tag": "Left", + "left": Object { + "index": "no_such_index", + "type": "index_not_found_exception", + }, + } + `); }); it('resolves left target_index_had_write_block if all failures are due to a write block', async () => { expect.assertions(1); @@ -864,13 +905,13 @@ describe('migration actions', () => { const task = waitForReindexTask({ client, taskId: res.right.taskId, timeout: '10s' }); await expect(task()).resolves.toMatchInlineSnapshot(` - Object { - "_tag": "Left", - "left": Object { - "type": "target_index_had_write_block", - }, - } - `); + Object { + "_tag": "Left", + "left": Object { + "type": "target_index_had_write_block", + }, + } + `); }); it('resolves left if requireAlias=true and the target is not an alias', async () => { expect.assertions(1); @@ -886,14 +927,14 @@ describe('migration actions', () => { const task = waitForReindexTask({ client, taskId: res.right.taskId, timeout: '10s' }); await expect(task()).resolves.toMatchInlineSnapshot(` - Object { - "_tag": "Left", - "left": Object { - "index": "existing_index_with_write_block", - "type": "index_not_found_exception", - }, - } - `); + Object { + "_tag": "Left", + "left": Object { + "index": "existing_index_with_write_block", + "type": "index_not_found_exception", + }, + } + `); }); it('resolves left wait_for_task_completion_timeout when the task does not finish within the timeout', async () => { @@ -945,11 +986,11 @@ describe('migration actions', () => { targetIndex: 'reindex_target_7', }); await expect(task()).resolves.toMatchInlineSnapshot(` - Object { - "_tag": "Right", - "right": "verify_reindex_succeeded", - } - `); + Object { + "_tag": "Right", + "right": "verify_reindex_succeeded", + } + `); }); it('resolves left if source and target indices have different amount of documents', async () => { expect.assertions(1); @@ -959,13 +1000,13 @@ describe('migration actions', () => { targetIndex: 'existing_index_2', }); await expect(task()).resolves.toMatchInlineSnapshot(` - Object { - "_tag": "Left", - "left": Object { - "type": "verify_reindex_failed", - }, - } - `); + Object { + "_tag": "Left", + "left": Object { + "type": "verify_reindex_failed", + }, + } + `); }); it('rejects if source or target index does not exist', async () => { expect.assertions(2); @@ -1592,11 +1633,11 @@ describe('migration actions', () => { }); await expect(task()).resolves.toMatchInlineSnapshot(` - Object { - "_tag": "Right", - "right": "bulk_index_succeeded", - } - `); + Object { + "_tag": "Right", + "right": "bulk_index_succeeded", + } + `); }); it('resolves right even if there were some version_conflict_engine_exception', async () => { const existingDocs = ( @@ -1637,13 +1678,13 @@ describe('migration actions', () => { refresh: 'wait_for', })() ).resolves.toMatchInlineSnapshot(` - Object { - "_tag": "Left", - "left": Object { - "type": "target_index_had_write_block", - }, - } - `); + Object { + "_tag": "Left", + "left": Object { + "type": "target_index_had_write_block", + }, + } + `); }); it('resolves left request_entity_too_large_exception when the payload is too large', async () => { @@ -1659,13 +1700,13 @@ describe('migration actions', () => { transformedDocs: newDocs, }); await expect(task()).resolves.toMatchInlineSnapshot(` - Object { - "_tag": "Left", - "left": Object { - "type": "request_entity_too_large_exception", - }, - } - `); + Object { + "_tag": "Left", + "left": Object { + "type": "request_entity_too_large_exception", + }, + } + `); }); }); }); diff --git a/src/core/server/saved_objects/migrations/actions/wait_for_index_status_yellow.ts b/src/core/server/saved_objects/migrations/actions/wait_for_index_status_yellow.ts index dbff85ff59c23..fed28252bd2a4 100644 --- a/src/core/server/saved_objects/migrations/actions/wait_for_index_status_yellow.ts +++ b/src/core/server/saved_objects/migrations/actions/wait_for_index_status_yellow.ts @@ -21,6 +21,11 @@ export interface WaitForIndexStatusYellowParams { index: string; timeout?: string; } + +export interface IndexNotYellowTimeout { + type: 'index_not_yellow_timeout'; + message: string; +} /** * A yellow index status means the index's primary shard is allocated and the * index is ready for searching/indexing documents, but ES wasn't able to @@ -37,7 +42,10 @@ export const waitForIndexStatusYellow = client, index, timeout = DEFAULT_TIMEOUT, - }: WaitForIndexStatusYellowParams): TaskEither.TaskEither => + }: WaitForIndexStatusYellowParams): TaskEither.TaskEither< + RetryableEsClientError | IndexNotYellowTimeout, + {} + > => () => { return client.cluster .health( @@ -47,14 +55,14 @@ export const waitForIndexStatusYellow = timeout, }, // Don't reject on status code 408 so that we can handle the timeout - // explicitly and provide more context in the error message + // explicitly with a custom response type and provide more context in the error message { ignore: [408] } ) .then((res) => { if (res.timed_out === true) { return Either.left({ - type: 'retryable_es_client_error' as const, - message: `Timeout waiting for the status of the [${index}] index to become 'yellow'`, + type: 'index_not_yellow_timeout' as const, + message: `[index_not_yellow_timeout] Timeout waiting for the status of the [${index}] index to become 'yellow'`, }); } return Either.right({}); diff --git a/src/core/server/saved_objects/migrations/initial_state.test.ts b/src/core/server/saved_objects/migrations/initial_state.test.ts index 601eb7cf1ce36..2ad3dc38e6d65 100644 --- a/src/core/server/saved_objects/migrations/initial_state.test.ts +++ b/src/core/server/saved_objects/migrations/initial_state.test.ts @@ -8,15 +8,19 @@ import { ByteSizeValue } from '@kbn/config-schema'; import * as Option from 'fp-ts/Option'; +import { DocLinksServiceSetup } from '../../doc_links'; +import { docLinksServiceMock } from '../../mocks'; import { SavedObjectsMigrationConfigType } from '../saved_objects_config'; import { SavedObjectTypeRegistry } from '../saved_objects_type_registry'; import { createInitialState } from './initial_state'; describe('createInitialState', () => { let typeRegistry: SavedObjectTypeRegistry; + let docLinks: DocLinksServiceSetup; beforeEach(() => { typeRegistry = new SavedObjectTypeRegistry(); + docLinks = docLinksServiceMock.createSetupContract(); }); const migrationsConfig = { @@ -36,6 +40,7 @@ describe('createInitialState', () => { indexPrefix: '.kibana_task_manager', migrationsConfig, typeRegistry, + docLinks, }) ).toEqual({ batchSize: 1000, @@ -108,6 +113,14 @@ describe('createInitialState', () => { }, versionAlias: '.kibana_task_manager_8.1.0', versionIndex: '.kibana_task_manager_8.1.0_001', + migrationDocLinks: { + resolveMigrationFailures: + 'https://www.elastic.co/guide/en/kibana/test-branch/resolve-migrations-failures.html', + repeatedTimeoutRequests: + 'https://www.elastic.co/guide/en/kibana/test-branch/resolve-migrations-failures.html#_repeated_time_out_requests_that_eventually_fail', + routingAllocationDisabled: + 'https://www.elastic.co/guide/en/kibana/test-branch/resolve-migrations-failures.html#routing-allocation-disabled', + }, }); }); @@ -135,6 +148,7 @@ describe('createInitialState', () => { indexPrefix: '.kibana_task_manager', migrationsConfig, typeRegistry, + docLinks, }); expect(initialState.knownTypes).toEqual(['foo', 'bar']); @@ -160,6 +174,7 @@ describe('createInitialState', () => { indexPrefix: '.kibana_task_manager', migrationsConfig, typeRegistry, + docLinks, }); expect(initialState.excludeFromUpgradeFilterHooks).toEqual({ foo: fooExcludeOnUpgradeHook }); @@ -178,6 +193,7 @@ describe('createInitialState', () => { indexPrefix: '.kibana_task_manager', migrationsConfig, typeRegistry, + docLinks, }); expect(Option.isSome(initialState.preMigrationScript)).toEqual(true); @@ -199,6 +215,7 @@ describe('createInitialState', () => { indexPrefix: '.kibana_task_manager', migrationsConfig, typeRegistry, + docLinks, }).preMigrationScript ) ).toEqual(true); @@ -216,6 +233,7 @@ describe('createInitialState', () => { indexPrefix: '.kibana_task_manager', migrationsConfig, typeRegistry, + docLinks, }).outdatedDocumentsQuery ).toMatchInlineSnapshot(` Object { diff --git a/src/core/server/saved_objects/migrations/initial_state.ts b/src/core/server/saved_objects/migrations/initial_state.ts index 21b564f8c454f..ae0fe54049505 100644 --- a/src/core/server/saved_objects/migrations/initial_state.ts +++ b/src/core/server/saved_objects/migrations/initial_state.ts @@ -13,6 +13,7 @@ import { SavedObjectsMigrationConfigType } from '../saved_objects_config'; import type { ISavedObjectTypeRegistry } from '../saved_objects_type_registry'; import { InitState } from './state'; import { excludeUnusedTypesQuery } from './core'; +import { DocLinksServiceStart } from '../../doc_links'; /** * Construct the initial state for the model @@ -25,6 +26,7 @@ export const createInitialState = ({ indexPrefix, migrationsConfig, typeRegistry, + docLinks, }: { kibanaVersion: string; targetMappings: IndexMapping; @@ -33,6 +35,7 @@ export const createInitialState = ({ indexPrefix: string; migrationsConfig: SavedObjectsMigrationConfigType; typeRegistry: ISavedObjectTypeRegistry; + docLinks: DocLinksServiceStart; }): InitState => { const outdatedDocumentsQuery = { bool: { @@ -64,6 +67,8 @@ export const createInitialState = ({ .filter((type) => !!type.excludeOnUpgrade) .map((type) => [type.name, type.excludeOnUpgrade!]) ); + // short key to access savedObjects entries directly from docLinks + const migrationDocLinks = docLinks.links.kibanaUpgradeSavedObjects; return { controlState: 'INIT', @@ -87,5 +92,6 @@ export const createInitialState = ({ unusedTypesQuery: excludeUnusedTypesQuery, knownTypes, excludeFromUpgradeFilterHooks: excludeFilterHooks, + migrationDocLinks, }; }; diff --git a/src/core/server/saved_objects/migrations/integration_tests/cluster_routing_allocation_disabled.test.ts b/src/core/server/saved_objects/migrations/integration_tests/cluster_routing_allocation_disabled.test.ts index ea70478d6ce7b..37b278fe9ccf0 100644 --- a/src/core/server/saved_objects/migrations/integration_tests/cluster_routing_allocation_disabled.test.ts +++ b/src/core/server/saved_objects/migrations/integration_tests/cluster_routing_allocation_disabled.test.ts @@ -114,7 +114,7 @@ describe('unsupported_cluster_routing_allocation', () => { await root.setup(); await expect(root.start()).rejects.toThrowError( - /Unable to complete saved object migrations for the \[\.kibana.*\] index: The elasticsearch cluster has cluster routing allocation incorrectly set for migrations to continue\. To proceed, please remove the cluster routing allocation settings with PUT \/_cluster\/settings {"transient": {"cluster\.routing\.allocation\.enable": null}, "persistent": {"cluster\.routing\.allocation\.enable": null}}/ + /Unable to complete saved object migrations for the \[\.kibana\] index: \[unsupported_cluster_routing_allocation\] The elasticsearch cluster has cluster routing allocation incorrectly set for migrations to continue\. To proceed, please remove the cluster routing allocation settings with PUT \/_cluster\/settings {\"transient\": {\"cluster\.routing\.allocation\.enable\": null}, \"persistent\": {\"cluster\.routing\.allocation\.enable\": null}}\. Refer to https:\/\/www.elastic.co\/guide\/en\/kibana\/master\/resolve-migrations-failures.html#routing-allocation-disabled for more information on how to resolve the issue\./ ); await retryAsync( @@ -126,7 +126,7 @@ describe('unsupported_cluster_routing_allocation', () => { .map((str) => JSON5.parse(str)) as LogRecord[]; expect( records.find((rec) => - /^Unable to complete saved object migrations for the \[\.kibana.*\] index: The elasticsearch cluster has cluster routing allocation incorrectly set for migrations to continue\./.test( + /^Unable to complete saved object migrations for the \[\.kibana.*\] index: \[unsupported_cluster_routing_allocation\] The elasticsearch cluster has cluster routing allocation incorrectly set for migrations to continue\./.test( rec.message ) ) @@ -149,7 +149,7 @@ describe('unsupported_cluster_routing_allocation', () => { await root.setup(); await expect(root.start()).rejects.toThrowError( - /Unable to complete saved object migrations for the \[\.kibana.*\] index: The elasticsearch cluster has cluster routing allocation incorrectly set for migrations to continue\. To proceed, please remove the cluster routing allocation settings with PUT \/_cluster\/settings {"transient": {"cluster\.routing\.allocation\.enable": null}, "persistent": {"cluster\.routing\.allocation\.enable": null}}/ + /Unable to complete saved object migrations for the \[\.kibana\] index: \[unsupported_cluster_routing_allocation\] The elasticsearch cluster has cluster routing allocation incorrectly set for migrations to continue\. To proceed, please remove the cluster routing allocation settings with PUT \/_cluster\/settings {\"transient\": {\"cluster\.routing\.allocation\.enable\": null}, \"persistent\": {\"cluster\.routing\.allocation\.enable\": null}}\. Refer to https:\/\/www.elastic.co\/guide\/en\/kibana\/master\/resolve-migrations-failures.html#routing-allocation-disabled for more information on how to resolve the issue\./ ); }); }); diff --git a/src/core/server/saved_objects/migrations/kibana_migrator.test.ts b/src/core/server/saved_objects/migrations/kibana_migrator.test.ts index e5aa51f9d6b0a..77837f066a52f 100644 --- a/src/core/server/saved_objects/migrations/kibana_migrator.test.ts +++ b/src/core/server/saved_objects/migrations/kibana_migrator.test.ts @@ -16,6 +16,7 @@ import { SavedObjectTypeRegistry } from '../saved_objects_type_registry'; import { SavedObjectsType } from '../types'; import { DocumentMigrator } from './core/document_migrator'; import { ByteSizeValue } from '@kbn/config-schema'; +import { docLinksServiceMock } from '../../mocks'; import { lastValueFrom } from 'rxjs'; jest.mock('./core/document_migrator', () => { @@ -287,6 +288,7 @@ const mockOptions = () => { retryAttempts: 20, }, client: elasticsearchClientMock.createElasticsearchClient(), + docLinks: docLinksServiceMock.createSetupContract(), }; return options; }; diff --git a/src/core/server/saved_objects/migrations/kibana_migrator.ts b/src/core/server/saved_objects/migrations/kibana_migrator.ts index 2e2c4e2c63c04..31b9c89f4176f 100644 --- a/src/core/server/saved_objects/migrations/kibana_migrator.ts +++ b/src/core/server/saved_objects/migrations/kibana_migrator.ts @@ -29,6 +29,7 @@ import { ISavedObjectTypeRegistry } from '../saved_objects_type_registry'; import { SavedObjectsType } from '../types'; import { runResilientMigrator } from './run_resilient_migrator'; import { migrateRawDocsSafely } from './core/migrate_raw_docs'; +import { DocLinksServiceStart } from '../../doc_links'; export interface KibanaMigratorOptions { client: ElasticsearchClient; @@ -37,6 +38,7 @@ export interface KibanaMigratorOptions { kibanaIndex: string; kibanaVersion: string; logger: Logger; + docLinks: DocLinksServiceStart; } export type IKibanaMigrator = Pick; @@ -65,6 +67,7 @@ export class KibanaMigrator { private readonly activeMappings: IndexMapping; private readonly soMigrationsConfig: SavedObjectsMigrationConfigType; public readonly kibanaVersion: string; + private readonly docLinks: DocLinksServiceStart; /** * Creates an instance of KibanaMigrator. @@ -76,6 +79,7 @@ export class KibanaMigrator { soMigrationsConfig, kibanaVersion, logger, + docLinks, }: KibanaMigratorOptions) { this.client = client; this.kibanaIndex = kibanaIndex; @@ -93,6 +97,7 @@ export class KibanaMigrator { // Building the active mappings (and associated md5sums) is an expensive // operation so we cache the result this.activeMappings = buildActiveMappings(this.mappingProperties); + this.docLinks = docLinks; } /** @@ -177,6 +182,7 @@ export class KibanaMigrator { indexPrefix: index, migrationsConfig: this.soMigrationsConfig, typeRegistry: this.typeRegistry, + docLinks: this.docLinks, }); }, }; diff --git a/src/core/server/saved_objects/migrations/migrations_state_action_machine.test.ts b/src/core/server/saved_objects/migrations/migrations_state_action_machine.test.ts index 3bc07c0fea0c1..93e6476f8e78c 100644 --- a/src/core/server/saved_objects/migrations/migrations_state_action_machine.test.ts +++ b/src/core/server/saved_objects/migrations/migrations_state_action_machine.test.ts @@ -8,7 +8,7 @@ import { cleanupMock } from './migrations_state_machine_cleanup.mocks'; import { migrationStateActionMachine } from './migrations_state_action_machine'; -import { loggingSystemMock, elasticsearchServiceMock } from '../../mocks'; +import { loggingSystemMock, elasticsearchServiceMock, docLinksServiceMock } from '../../mocks'; import { typeRegistryMock } from '../saved_objects_type_registry.mock'; import * as Either from 'fp-ts/lib/Either'; import * as Option from 'fp-ts/lib/Option'; @@ -33,6 +33,7 @@ describe('migrationsStateActionMachine', () => { const mockLogger = loggingSystemMock.create(); const typeRegistry = typeRegistryMock.create(); + const docLinks = docLinksServiceMock.createSetupContract(); const initialState = createInitialState({ kibanaVersion: '7.11.0', @@ -48,6 +49,7 @@ describe('migrationsStateActionMachine', () => { retryAttempts: 5, }, typeRegistry, + docLinks, }); const next = jest.fn((s: State) => { diff --git a/src/core/server/saved_objects/migrations/model/extract_errors.test.ts b/src/core/server/saved_objects/migrations/model/extract_errors.test.ts index a028c40ca6597..e434a5001a6ae 100644 --- a/src/core/server/saved_objects/migrations/model/extract_errors.test.ts +++ b/src/core/server/saved_objects/migrations/model/extract_errors.test.ts @@ -6,7 +6,11 @@ * Side Public License, v 1. */ -import { extractUnknownDocFailureReason } from './extract_errors'; +import { + extractUnknownDocFailureReason, + fatalReasonClusterRoutingAllocationUnsupported, + fatalReasonDocumentExceedsMaxBatchSizeBytes, +} from './extract_errors'; describe('extractUnknownDocFailureReason', () => { it('generates the correct error message', () => { @@ -37,3 +41,32 @@ describe('extractUnknownDocFailureReason', () => { `); }); }); + +describe('fatalReasonDocumentExceedsMaxBatchSizeBytes', () => { + it('generate the correct error message', () => { + expect( + fatalReasonDocumentExceedsMaxBatchSizeBytes({ + _id: 'abc', + docSizeBytes: 106954752, + maxBatchSizeBytes: 104857600, + }) + ).toMatchInlineSnapshot( + `"The document with _id \\"abc\\" is 106954752 bytes which exceeds the configured maximum batch size of 104857600 bytes. To proceed, please increase the 'migrations.maxBatchSizeBytes' Kibana configuration option and ensure that the Elasticsearch 'http.max_content_length' configuration option is set to an equal or larger value."` + ); + }); +}); + +describe('fatalReasonClusterRoutingAllocationUnsupported', () => { + it('generates the correct error message', () => { + const errorMessages = fatalReasonClusterRoutingAllocationUnsupported({ + errorMessage: '[some-error] message', + docSectionLink: 'linkToDocsSection', + }); + expect(errorMessages.fatalReason).toMatchInlineSnapshot( + `"[some-error] message To proceed, please remove the cluster routing allocation settings with PUT /_cluster/settings {\\"transient\\": {\\"cluster.routing.allocation.enable\\": null}, \\"persistent\\": {\\"cluster.routing.allocation.enable\\": null}}. Refer to linkToDocsSection for more information on how to resolve the issue."` + ); + expect(errorMessages.logsErrorMessage).toMatchInlineSnapshot( + `"[some-error] message Ensure that the persistent and transient Elasticsearch configuration option 'cluster.routing.allocation.enable' is not set or set it to a value of 'all'. Refer to linkToDocsSection for more information on how to resolve the issue."` + ); + }); +}); diff --git a/src/core/server/saved_objects/migrations/model/extract_errors.ts b/src/core/server/saved_objects/migrations/model/extract_errors.ts index 95d10603caa80..f41009ab2127c 100644 --- a/src/core/server/saved_objects/migrations/model/extract_errors.ts +++ b/src/core/server/saved_objects/migrations/model/extract_errors.ts @@ -51,3 +51,32 @@ export function extractUnknownDocFailureReason( `'` ); } + +/** + * Constructs migration failure message string for doc exceeds max batch size in bytes + */ +export const fatalReasonDocumentExceedsMaxBatchSizeBytes = ({ + _id, + docSizeBytes, + maxBatchSizeBytes, +}: { + _id: string; + docSizeBytes: number; + maxBatchSizeBytes: number; +}) => + `The document with _id "${_id}" is ${docSizeBytes} bytes which exceeds the configured maximum batch size of ${maxBatchSizeBytes} bytes. To proceed, please increase the 'migrations.maxBatchSizeBytes' Kibana configuration option and ensure that the Elasticsearch 'http.max_content_length' configuration option is set to an equal or larger value.`; + +/** + * Constructs migration failure message and logs message strings when an unsupported cluster routing allocation is configured. + * The full errorMessage is "[unsupported_cluster_routing_allocation] The elasticsearch cluster has cluster routing allocation incorrectly set for migrations to continue." + */ +export const fatalReasonClusterRoutingAllocationUnsupported = ({ + errorMessage, + docSectionLink, +}: { + errorMessage: string; + docSectionLink: string; +}) => ({ + fatalReason: `${errorMessage} To proceed, please remove the cluster routing allocation settings with PUT /_cluster/settings {"transient": {"cluster.routing.allocation.enable": null}, "persistent": {"cluster.routing.allocation.enable": null}}. Refer to ${docSectionLink} for more information on how to resolve the issue.`, + logsErrorMessage: `${errorMessage} Ensure that the persistent and transient Elasticsearch configuration option 'cluster.routing.allocation.enable' is not set or set it to a value of 'all'. Refer to ${docSectionLink} for more information on how to resolve the issue.`, +}); diff --git a/src/core/server/saved_objects/migrations/model/model.test.ts b/src/core/server/saved_objects/migrations/model/model.test.ts index fc28cca8f4ddc..e44995ac8d30e 100644 --- a/src/core/server/saved_objects/migrations/model/model.test.ts +++ b/src/core/server/saved_objects/migrations/model/model.test.ts @@ -94,6 +94,11 @@ describe('migrations v2 model', () => { }, knownTypes: ['dashboard', 'config'], excludeFromUpgradeFilterHooks: {}, + migrationDocLinks: { + resolveMigrationFailures: 'resolveMigrationFailures', + repeatedTimeoutRequests: 'repeatedTimeoutRequests', + routingAllocationDisabled: 'routingAllocationDisabled', + }, }; describe('exponential retry delays for retryable_es_client_error', () => { @@ -182,7 +187,7 @@ describe('migrations v2 model', () => { expect(newState.controlState).toEqual('FATAL'); expect(newState.reason).toMatchInlineSnapshot( - `"Unable to complete the INIT step after 15 attempts, terminating."` + `"Unable to complete the INIT step after 15 attempts, terminating. The last failure message was: snapshot_in_progress_exception"` ); }); }); @@ -280,12 +285,13 @@ describe('migrations v2 model', () => { test('INIT -> FATAL when cluster routing allocation is not enabled', () => { const res: ResponseType<'INIT'> = Either.left({ type: 'unsupported_cluster_routing_allocation', + message: '[unsupported_cluster_routing_allocation]', }); const newState = model(initState, res) as FatalState; expect(newState.controlState).toEqual('FATAL'); expect(newState.reason).toMatchInlineSnapshot( - `"The elasticsearch cluster has cluster routing allocation incorrectly set for migrations to continue. To proceed, please remove the cluster routing allocation settings with PUT /_cluster/settings {\\"transient\\": {\\"cluster.routing.allocation.enable\\": null}, \\"persistent\\": {\\"cluster.routing.allocation.enable\\": null}}"` + `"[unsupported_cluster_routing_allocation] To proceed, please remove the cluster routing allocation settings with PUT /_cluster/settings {\\"transient\\": {\\"cluster.routing.allocation.enable\\": null}, \\"persistent\\": {\\"cluster.routing.allocation.enable\\": null}}. Refer to routingAllocationDisabled for more information on how to resolve the issue."` ); }); test("INIT -> FATAL when .kibana points to newer version's index", () => { @@ -560,9 +566,29 @@ describe('migrations v2 model', () => { expect(newState.retryCount).toEqual(0); expect(newState.retryDelay).toEqual(0); }); - // The createIndex action called by LEGACY_CREATE_REINDEX_TARGET never - // returns a left, it will always succeed or timeout. Since timeout - // failures are always retried we don't explicitly test this logic + test('LEGACY_CREATE_REINDEX_TARGET -> LEGACY_CREATE_REINDEX_TARGET if action fails with index_not_yellow_timeout', () => { + const res: ResponseType<'LEGACY_CREATE_REINDEX_TARGET'> = Either.left({ + message: '[index_not_yellow_timeout] Timeout waiting for ...', + type: 'index_not_yellow_timeout', + }); + const newState = model(legacyCreateReindexTargetState, res); + expect(newState.controlState).toEqual('LEGACY_CREATE_REINDEX_TARGET'); + expect(newState.retryCount).toEqual(1); + expect(newState.retryDelay).toEqual(2000); + }); + test('LEGACY_CREATE_REINDEX_TARGET -> LEGACY_REINDEX resets retry count and retry delay if action succeeds', () => { + const res: ResponseType<'LEGACY_CREATE_REINDEX_TARGET'> = + Either.right('create_index_succeeded'); + const testState = { + ...legacyCreateReindexTargetState, + retryCount: 1, + retryDelay: 2000, + }; + const newState = model(testState, res); + expect(newState.controlState).toEqual('LEGACY_REINDEX'); + expect(newState.retryCount).toEqual(0); + expect(newState.retryDelay).toEqual(0); + }); }); describe('LEGACY_REINDEX', () => { @@ -707,6 +733,33 @@ describe('migrations v2 model', () => { sourceIndex: Option.some('.kibana_3'), }); }); + + test('WAIT_FOR_YELLOW_SOURCE -> WAIT_FOR_YELLOW_SOURCE if action fails with index_not_yellow_timeout', () => { + const res: ResponseType<'WAIT_FOR_YELLOW_SOURCE'> = Either.left({ + message: '[index_not_yellow_timeout] Timeout waiting for ...', + type: 'index_not_yellow_timeout', + }); + const newState = model(waitForYellowSourceState, res); + expect(newState.controlState).toEqual('WAIT_FOR_YELLOW_SOURCE'); + expect(newState.retryCount).toEqual(1); + expect(newState.retryDelay).toEqual(2000); + }); + + test('WAIT_FOR_YELLOW_SOURCE -> CHECK_UNKNOWN_DOCUMENTS resets retry count and delay if action succeeds', () => { + const res: ResponseType<'WAIT_FOR_YELLOW_SOURCE'> = Either.right({}); + const testState = { + ...waitForYellowSourceState, + retryCount: 1, + retryDelay: 2000, + }; + const newState = model(testState, res); + expect(newState.controlState).toEqual('CHECK_UNKNOWN_DOCUMENTS'); + + expect(newState).toMatchObject({ + controlState: 'CHECK_UNKNOWN_DOCUMENTS', + sourceIndex: Option.some('.kibana_3'), + }); + }); }); describe('CHECK_UNKNOWN_DOCUMENTS', () => { @@ -900,6 +953,28 @@ describe('migrations v2 model', () => { expect(newState.retryCount).toEqual(0); expect(newState.retryDelay).toEqual(0); }); + it('CREATE_REINDEX_TEMP -> CREATE_REINDEX_TEMP if action fails with index_not_yellow_timeout', () => { + const res: ResponseType<'CREATE_REINDEX_TEMP'> = Either.left({ + message: '[index_not_yellow_timeout] Timeout waiting for ...', + type: 'index_not_yellow_timeout', + }); + const newState = model(state, res); + expect(newState.controlState).toEqual('CREATE_REINDEX_TEMP'); + expect(newState.retryCount).toEqual(1); + expect(newState.retryDelay).toEqual(2000); + }); + it('CREATE_REINDEX_TEMP -> REINDEX_SOURCE_TO_TEMP_OPEN_PIT resets retry count if action succeeds', () => { + const res: ResponseType<'CREATE_REINDEX_TEMP'> = Either.right('create_index_succeeded'); + const testState = { + ...state, + retryCount: 1, + retryDelay: 2000, + }; + const newState = model(testState, res); + expect(newState.controlState).toEqual('REINDEX_SOURCE_TO_TEMP_OPEN_PIT'); + expect(newState.retryCount).toEqual(0); + expect(newState.retryDelay).toEqual(0); + }); }); describe('REINDEX_SOURCE_TO_TEMP_OPEN_PIT', () => { @@ -1212,6 +1287,31 @@ describe('migrations v2 model', () => { expect(newState.retryCount).toBe(0); expect(newState.retryDelay).toBe(0); }); + it('CLONE_TEMP_TO_TARGET -> CLONE_TEMP_TO_TARGET if action fails with index_not_yellow_timeout', () => { + const res: ResponseType<'CLONE_TEMP_TO_TARGET'> = Either.left({ + message: '[index_not_yellow_timeout] Timeout waiting for ...', + type: 'index_not_yellow_timeout', + }); + const newState = model(state, res); + expect(newState.controlState).toEqual('CLONE_TEMP_TO_TARGET'); + expect(newState.retryCount).toEqual(1); + expect(newState.retryDelay).toEqual(2000); + }); + it('CREATE_NEW_TARGET -> MARK_VERSION_INDEX_READY resets the retry count and delay', () => { + const res: ResponseType<'CLONE_TEMP_TO_TARGET'> = Either.right({ + acknowledged: true, + shardsAcknowledged: true, + }); + const testState = { + ...state, + retryCount: 1, + retryDelay: 2000, + }; + const newState = model(testState, res); + expect(newState.controlState).toBe('REFRESH_TARGET'); + expect(newState.retryCount).toBe(0); + expect(newState.retryDelay).toBe(0); + }); }); describe('OUTDATED_DOCUMENTS_SEARCH_OPEN_PIT', () => { @@ -1698,6 +1798,29 @@ describe('migrations v2 model', () => { expect(newState.retryCount).toEqual(0); expect(newState.retryDelay).toEqual(0); }); + test('CREATE_NEW_TARGET -> CREATE_NEW_TARGET if action fails with index_not_yellow_timeout', () => { + const res: ResponseType<'CREATE_NEW_TARGET'> = Either.left({ + message: '[index_not_yellow_timeout] Timeout waiting for ...', + type: 'index_not_yellow_timeout', + }); + const newState = model(createNewTargetState, res); + expect(newState.controlState).toEqual('CREATE_NEW_TARGET'); + expect(newState.retryCount).toEqual(1); + expect(newState.retryDelay).toEqual(2000); + }); + test('CREATE_NEW_TARGET -> MARK_VERSION_INDEX_READY resets the retry count and delay', () => { + const res: ResponseType<'CREATE_NEW_TARGET'> = Either.right('create_index_succeeded'); + const testState = { + ...createNewTargetState, + retryCount: 1, + retryDelay: 2000, + }; + + const newState = model(testState, res); + expect(newState.controlState).toEqual('MARK_VERSION_INDEX_READY'); + expect(newState.retryCount).toEqual(0); + expect(newState.retryDelay).toEqual(0); + }); }); describe('MARK_VERSION_INDEX_READY', () => { diff --git a/src/core/server/saved_objects/migrations/model/model.ts b/src/core/server/saved_objects/migrations/model/model.ts index 2e3905fd90fe1..cff23f0eeda65 100644 --- a/src/core/server/saved_objects/migrations/model/model.ts +++ b/src/core/server/saved_objects/migrations/model/model.ts @@ -21,7 +21,12 @@ import { setProgressTotal, } from './progress'; import { delayRetryState, resetRetryState } from './retry_state'; -import { extractTransformFailuresReason, extractUnknownDocFailureReason } from './extract_errors'; +import { + extractTransformFailuresReason, + extractUnknownDocFailureReason, + fatalReasonDocumentExceedsMaxBatchSizeBytes, + fatalReasonClusterRoutingAllocationUnsupported, +} from './extract_errors'; import type { ExcludeRetryableEsError } from './types'; import { getAliases, @@ -33,17 +38,7 @@ import { } from './helpers'; import { createBatches } from './create_batches'; -const FATAL_REASON_REQUEST_ENTITY_TOO_LARGE = `While indexing a batch of saved objects, Elasticsearch returned a 413 Request Entity Too Large exception. Ensure that the Kibana configuration option 'migrations.maxBatchSizeBytes' is set to a value that is lower than or equal to the Elasticsearch 'http.max_content_length' configuration option.`; -const fatalReasonDocumentExceedsMaxBatchSizeBytes = ({ - _id, - docSizeBytes, - maxBatchSizeBytes, -}: { - _id: string; - docSizeBytes: number; - maxBatchSizeBytes: number; -}) => - `The document with _id "${_id}" is ${docSizeBytes} bytes which exceeds the configured maximum batch size of ${maxBatchSizeBytes} bytes. To proceed, please increase the 'migrations.maxBatchSizeBytes' Kibana configuration option and ensure that the Elasticsearch 'http.max_content_length' configuration option is set to an equal or larger value.`; +export const FATAL_REASON_REQUEST_ENTITY_TOO_LARGE = `While indexing a batch of saved objects, Elasticsearch returned a 413 Request Entity Too Large exception. Ensure that the Kibana configuration option 'migrations.maxBatchSizeBytes' is set to a value that is lower than or equal to the Elasticsearch 'http.max_content_length' configuration option.`; export const model = (currentState: State, resW: ResponseType): State => { // The action response `resW` is weakly typed, the type includes all action @@ -73,15 +68,19 @@ export const model = (currentState: State, resW: ResponseType): if (Either.isLeft(res)) { const left = res.left; if (isLeftTypeof(left, 'unsupported_cluster_routing_allocation')) { + const initErrorMessages = fatalReasonClusterRoutingAllocationUnsupported({ + errorMessage: left.message, + docSectionLink: stateP.migrationDocLinks.routingAllocationDisabled, + }); return { ...stateP, controlState: 'FATAL', - reason: `The elasticsearch cluster has cluster routing allocation incorrectly set for migrations to continue. To proceed, please remove the cluster routing allocation settings with PUT /_cluster/settings {"transient": {"cluster.routing.allocation.enable": null}, "persistent": {"cluster.routing.allocation.enable": null}}`, + reason: initErrorMessages.fatalReason, logs: [ ...stateP.logs, { level: 'error', - message: `The elasticsearch cluster has cluster routing allocation incorrectly set for migrations to continue. Ensure that the persistent and transient Elasticsearch configuration option 'cluster.routing.allocation.enable' is not set or set it to a value of 'all'.`, + message: initErrorMessages.logsErrorMessage, }, ], }; @@ -235,7 +234,21 @@ export const model = (currentState: State, resW: ResponseType): } } else if (stateP.controlState === 'LEGACY_CREATE_REINDEX_TARGET') { const res = resW as ExcludeRetryableEsError>; - if (Either.isRight(res)) { + if (Either.isLeft(res)) { + const left = res.left; + if (isLeftTypeof(left, 'index_not_yellow_timeout')) { + // `index_not_yellow_timeout` for the LEGACY_CREATE_REINDEX_TARGET source index: + // A yellow status timeout could theoretically be temporary for a busy cluster + // that takes a long time to allocate the primary and we retry the action to see if + // we get a response. + // If the cluster hit the low watermark for disk usage the LEGACY_CREATE_REINDEX_TARGET action will + // continue to timeout and eventually lead to a failed migration. + const retryErrorMessage = `${left.message} Refer to ${stateP.migrationDocLinks.repeatedTimeoutRequests} for information on how to resolve the issue.`; + return delayRetryState(stateP, retryErrorMessage, stateP.retryAttempts); + } else { + return throwBadResponse(stateP, left); + } + } else if (Either.isRight(res)) { return { ...stateP, controlState: 'LEGACY_REINDEX', @@ -285,7 +298,7 @@ export const model = (currentState: State, resW: ResponseType): // After waiting for the specified timeout, the task has not yet // completed. Retry this step to see if the task has completed after an // exponential delay. We will basically keep polling forever until the - // Elasticeasrch task succeeds or fails. + // Elasticsearch task succeeds or fails. return delayRetryState(stateP, left.message, Number.MAX_SAFE_INTEGER); } else if ( isLeftTypeof(left, 'index_not_found_exception') || @@ -344,6 +357,19 @@ export const model = (currentState: State, resW: ResponseType): ...stateP, controlState: 'CHECK_UNKNOWN_DOCUMENTS', }; + } else if (Either.isLeft(res)) { + const left = res.left; + if (isLeftTypeof(left, 'index_not_yellow_timeout')) { + // A yellow status timeout could theoretically be temporary for a busy cluster + // that takes a long time to allocate the primary and we retry the action to see if + // we get a response. + // In the event of retries running out, we link to the docs to help with diagnosing + // the problem. + const retryErrorMessage = `${left.message} Refer to ${stateP.migrationDocLinks.repeatedTimeoutRequests} for information on how to resolve the issue.`; + return delayRetryState(stateP, retryErrorMessage, stateP.retryAttempts); + } else { + return throwBadResponse(stateP, left); + } } else { return throwBadResponse(stateP, res); } @@ -425,6 +451,20 @@ export const model = (currentState: State, resW: ResponseType): const res = resW as ExcludeRetryableEsError>; if (Either.isRight(res)) { return { ...stateP, controlState: 'REINDEX_SOURCE_TO_TEMP_OPEN_PIT' }; + } else if (Either.isLeft(res)) { + const left = res.left; + if (isLeftTypeof(left, 'index_not_yellow_timeout')) { + // `index_not_yellow_timeout` for the CREATE_REINDEX_TEMP target temp index: + // The index status did not go yellow within the specified timeout period. + // A yellow status timeout could theoretically be temporary for a busy cluster. + // + // If there is a problem CREATE_REINDEX_TEMP action will + // continue to timeout and eventually lead to a failed migration. + const retryErrorMessage = `${left.message} Refer to ${stateP.migrationDocLinks.repeatedTimeoutRequests} for information on how to resolve the issue.`; + return delayRetryState(stateP, retryErrorMessage, stateP.retryAttempts); + } else { + return throwBadResponse(stateP, left); + } } else { // If the createIndex action receives an 'resource_already_exists_exception' // it will wait until the index status turns green so we don't have any @@ -645,6 +685,18 @@ export const model = (currentState: State, resW: ResponseType): ...stateP, controlState: 'REFRESH_TARGET', }; + } else if (isLeftTypeof(left, 'index_not_yellow_timeout')) { + // `index_not_yellow_timeout` for the CLONE_TEMP_TO_TARGET source -> target index: + // The target index status did not go yellow within the specified timeout period. + // The cluster could just be busy and we retry the action. + + // Once we run out of retries, the migration fails. + // Identifying the cause requires inspecting the ouput of the + // `_cluster/allocation/explain?index=${targetIndex}` API. + // Unless the root cause is identified and addressed, the request will + // continue to timeout and eventually lead to a failed migration. + const retryErrorMessage = `${left.message} Refer to ${stateP.migrationDocLinks.repeatedTimeoutRequests} for information on how to resolve the issue.`; + return delayRetryState(stateP, retryErrorMessage, stateP.retryAttempts); } else { throwBadResponse(stateP, left); } @@ -876,7 +928,7 @@ export const model = (currentState: State, resW: ResponseType): if (isLeftTypeof(left, 'wait_for_task_completion_timeout')) { // After waiting for the specified timeout, the task has not yet // completed. Retry this step to see if the task has completed after an - // exponential delay. We will basically keep polling forever until the + // exponential delay. We will basically keep polling forever until the // Elasticsearch task succeeds or fails. return delayRetryState(stateP, res.left.message, Number.MAX_SAFE_INTEGER); } else { @@ -890,6 +942,19 @@ export const model = (currentState: State, resW: ResponseType): ...stateP, controlState: 'MARK_VERSION_INDEX_READY', }; + } else if (Either.isLeft(res)) { + const left = res.left; + if (isLeftTypeof(left, 'index_not_yellow_timeout')) { + // `index_not_yellow_timeout` for the CREATE_NEW_TARGET target index: + // The cluster might just be busy and we retry the action for a set number of times. + // If the cluster hit the low watermark for disk usage the action will continue to timeout. + // Unless the disk space is addressed, the LEGACY_CREATE_REINDEX_TARGET action will + // continue to timeout and eventually lead to a failed migration. + const retryErrorMessage = `${left.message} Refer to ${stateP.migrationDocLinks.repeatedTimeoutRequests} for information on how to resolve the issue.`; + return delayRetryState(stateP, retryErrorMessage, stateP.retryAttempts); + } else { + return throwBadResponse(stateP, left); + } } else { // If the createIndex action receives an 'resource_already_exists_exception' // it will wait until the index status turns green so we don't have any diff --git a/src/core/server/saved_objects/migrations/model/retry_state.test.ts b/src/core/server/saved_objects/migrations/model/retry_state.test.ts index 5a195f8597182..994f3ca2ede4b 100644 --- a/src/core/server/saved_objects/migrations/model/retry_state.test.ts +++ b/src/core/server/saved_objects/migrations/model/retry_state.test.ts @@ -109,7 +109,7 @@ describe('delayRetryState', () => { hello: 'dolly', retryCount: 5, retryDelay: 64, - reason: `Unable to complete the TEST step after 5 attempts, terminating.`, + reason: `Unable to complete the TEST step after 5 attempts, terminating. The last failure message was: some-error`, }); }); }); diff --git a/src/core/server/saved_objects/migrations/model/retry_state.ts b/src/core/server/saved_objects/migrations/model/retry_state.ts index 02057a6af2061..532cc70347916 100644 --- a/src/core/server/saved_objects/migrations/model/retry_state.ts +++ b/src/core/server/saved_objects/migrations/model/retry_state.ts @@ -18,12 +18,11 @@ export const delayRetryState = ( return { ...state, controlState: 'FATAL', - reason: `Unable to complete the ${state.controlState} step after ${maxRetryAttempts} attempts, terminating.`, + reason: `Unable to complete the ${state.controlState} step after ${maxRetryAttempts} attempts, terminating. The last failure message was: ${errorMessage}`, }; } else { const retryCount = state.retryCount + 1; const retryDelay = 1000 * Math.min(Math.pow(2, retryCount), 64); // 2s, 4s, 8s, 16s, 32s, 64s, 64s, 64s ... - return { ...state, retryCount, diff --git a/src/core/server/saved_objects/migrations/run_resilient_migrator.ts b/src/core/server/saved_objects/migrations/run_resilient_migrator.ts index bdc36b2b79ebe..dce9227719389 100644 --- a/src/core/server/saved_objects/migrations/run_resilient_migrator.ts +++ b/src/core/server/saved_objects/migrations/run_resilient_migrator.ts @@ -18,6 +18,7 @@ import { createInitialState } from './initial_state'; import { migrationStateActionMachine } from './migrations_state_action_machine'; import { SavedObjectsMigrationConfigType } from '../saved_objects_config'; import type { ISavedObjectTypeRegistry } from '../saved_objects_type_registry'; +import { DocLinksServiceStart } from '../../doc_links'; /** * Migrates the provided indexPrefix index using a resilient algorithm that is @@ -35,6 +36,7 @@ export async function runResilientMigrator({ indexPrefix, migrationsConfig, typeRegistry, + docLinks, }: { client: ElasticsearchClient; kibanaVersion: string; @@ -46,6 +48,7 @@ export async function runResilientMigrator({ indexPrefix: string; migrationsConfig: SavedObjectsMigrationConfigType; typeRegistry: ISavedObjectTypeRegistry; + docLinks: DocLinksServiceStart; }): Promise { const initialState = createInitialState({ kibanaVersion, @@ -55,6 +58,7 @@ export async function runResilientMigrator({ indexPrefix, migrationsConfig, typeRegistry, + docLinks, }); return migrationStateActionMachine({ initialState, diff --git a/src/core/server/saved_objects/migrations/state.ts b/src/core/server/saved_objects/migrations/state.ts index aacc2826ccb26..dee6839d6b902 100644 --- a/src/core/server/saved_objects/migrations/state.ts +++ b/src/core/server/saved_objects/migrations/state.ts @@ -8,6 +8,7 @@ import * as Option from 'fp-ts/lib/Option'; import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import type { DocLinks } from '@kbn/doc-links'; import { ControlState } from './state_action_machine'; import { AliasAction } from './actions'; import { IndexMapping } from '../mappings'; @@ -122,6 +123,10 @@ export interface BaseState extends ControlState { string, SavedObjectTypeExcludeFromUpgradeFilterHook >; + /** + * DocLinks for savedObjects. to reference online documentation + */ + readonly migrationDocLinks: DocLinks['kibanaUpgradeSavedObjects']; } export interface InitState extends BaseState { diff --git a/src/core/server/saved_objects/routes/bulk_create.ts b/src/core/server/saved_objects/routes/bulk_create.ts index f8438a70d0418..b72cd6715fa10 100644 --- a/src/core/server/saved_objects/routes/bulk_create.ts +++ b/src/core/server/saved_objects/routes/bulk_create.ts @@ -51,7 +51,8 @@ export const registerBulkCreateRoute = (router: IRouter, { coreUsageData }: Rout const usageStatsClient = coreUsageData.getClient(); usageStatsClient.incrementSavedObjectsBulkCreate({ request: req }).catch(() => {}); - const result = await context.core.savedObjects.client.bulkCreate(req.body, { overwrite }); + const { savedObjects } = await context.core; + const result = await savedObjects.client.bulkCreate(req.body, { overwrite }); return res.ok({ body: result }); }) ); diff --git a/src/core/server/saved_objects/routes/bulk_get.ts b/src/core/server/saved_objects/routes/bulk_get.ts index cffa69b06f4e4..87b6a604ac6c4 100644 --- a/src/core/server/saved_objects/routes/bulk_get.ts +++ b/src/core/server/saved_objects/routes/bulk_get.ts @@ -34,7 +34,8 @@ export const registerBulkGetRoute = (router: IRouter, { coreUsageData }: RouteDe const usageStatsClient = coreUsageData.getClient(); usageStatsClient.incrementSavedObjectsBulkGet({ request: req }).catch(() => {}); - const result = await context.core.savedObjects.client.bulkGet(req.body); + const { savedObjects } = await context.core; + const result = await savedObjects.client.bulkGet(req.body); return res.ok({ body: result }); }) ); diff --git a/src/core/server/saved_objects/routes/bulk_resolve.ts b/src/core/server/saved_objects/routes/bulk_resolve.ts index 493f76a2c497c..5754ec180541c 100644 --- a/src/core/server/saved_objects/routes/bulk_resolve.ts +++ b/src/core/server/saved_objects/routes/bulk_resolve.ts @@ -32,7 +32,8 @@ export const registerBulkResolveRoute = (router: IRouter, { coreUsageData }: Rou const usageStatsClient = coreUsageData.getClient(); usageStatsClient.incrementSavedObjectsBulkResolve({ request: req }).catch(() => {}); - const result = await context.core.savedObjects.client.bulkResolve(req.body); + const { savedObjects } = await context.core; + const result = await savedObjects.client.bulkResolve(req.body); return res.ok({ body: result }); }) ); diff --git a/src/core/server/saved_objects/routes/bulk_update.ts b/src/core/server/saved_objects/routes/bulk_update.ts index 277673971dabe..961b8349d1745 100644 --- a/src/core/server/saved_objects/routes/bulk_update.ts +++ b/src/core/server/saved_objects/routes/bulk_update.ts @@ -44,7 +44,8 @@ export const registerBulkUpdateRoute = (router: IRouter, { coreUsageData }: Rout const usageStatsClient = coreUsageData.getClient(); usageStatsClient.incrementSavedObjectsBulkUpdate({ request: req }).catch(() => {}); - const savedObject = await context.core.savedObjects.client.bulkUpdate(req.body); + const { savedObjects } = await context.core; + const savedObject = await savedObjects.client.bulkUpdate(req.body); return res.ok({ body: savedObject }); }) ); diff --git a/src/core/server/saved_objects/routes/create.ts b/src/core/server/saved_objects/routes/create.ts index 3e287e91fec80..eb3938db0a9c7 100644 --- a/src/core/server/saved_objects/routes/create.ts +++ b/src/core/server/saved_objects/routes/create.ts @@ -61,7 +61,8 @@ export const registerCreateRoute = (router: IRouter, { coreUsageData }: RouteDep references, initialNamespaces, }; - const result = await context.core.savedObjects.client.create(type, attributes, options); + const { savedObjects } = await context.core; + const result = await savedObjects.client.create(type, attributes, options); return res.ok({ body: result }); }) ); diff --git a/src/core/server/saved_objects/routes/delete.ts b/src/core/server/saved_objects/routes/delete.ts index e8404ba7fc8cf..5c239a55a6923 100644 --- a/src/core/server/saved_objects/routes/delete.ts +++ b/src/core/server/saved_objects/routes/delete.ts @@ -32,7 +32,7 @@ export const registerDeleteRoute = (router: IRouter, { coreUsageData }: RouteDep catchAndReturnBoomErrors(async (context, req, res) => { const { type, id } = req.params; const { force } = req.query; - const { getClient } = context.core.savedObjects; + const { getClient } = (await context.core).savedObjects; const usageStatsClient = coreUsageData.getClient(); usageStatsClient.incrementSavedObjectsDelete({ request: req }).catch(() => {}); diff --git a/src/core/server/saved_objects/routes/deprecations/delete_unknown_types.ts b/src/core/server/saved_objects/routes/deprecations/delete_unknown_types.ts index 97100980a37b3..a30da9723b916 100644 --- a/src/core/server/saved_objects/routes/deprecations/delete_unknown_types.ts +++ b/src/core/server/saved_objects/routes/deprecations/delete_unknown_types.ts @@ -25,9 +25,10 @@ export const registerDeleteUnknownTypesRoute = ( validate: false, }, catchAndReturnBoomErrors(async (context, req, res) => { + const { elasticsearch, savedObjects } = await context.core; await deleteUnknownTypeObjects({ - esClient: context.core.elasticsearch.client, - typeRegistry: context.core.savedObjects.typeRegistry, + esClient: elasticsearch.client, + typeRegistry: savedObjects.typeRegistry, kibanaIndex, kibanaVersion, }); diff --git a/src/core/server/saved_objects/routes/export.ts b/src/core/server/saved_objects/routes/export.ts index e224f30a1bb02..16547970369c2 100644 --- a/src/core/server/saved_objects/routes/export.ts +++ b/src/core/server/saved_objects/routes/export.ts @@ -165,7 +165,7 @@ export const registerExportRoute = ( }, catchAndReturnBoomErrors(async (context, req, res) => { const cleaned = cleanOptions(req.body); - const { typeRegistry, getExporter, getClient } = context.core.savedObjects; + const { typeRegistry, getExporter, getClient } = (await context.core).savedObjects; const supportedTypes = typeRegistry.getImportableAndExportableTypes().map((t) => t.name); let options: EitherExportOptions; diff --git a/src/core/server/saved_objects/routes/find.ts b/src/core/server/saved_objects/routes/find.ts index 6e009f80bda7d..01ac9ae9025f4 100644 --- a/src/core/server/saved_objects/routes/find.ts +++ b/src/core/server/saved_objects/routes/find.ts @@ -73,8 +73,8 @@ export const registerFindRoute = (router: IRouter, { coreUsageData }: RouteDepen }); } } - - const result = await context.core.savedObjects.client.find({ + const { savedObjects } = await context.core; + const result = await savedObjects.client.find({ perPage: query.per_page, page: query.page, type: Array.isArray(query.type) ? query.type : [query.type], diff --git a/src/core/server/saved_objects/routes/get.ts b/src/core/server/saved_objects/routes/get.ts index ae0656599a1e2..2ea9a13bbce64 100644 --- a/src/core/server/saved_objects/routes/get.ts +++ b/src/core/server/saved_objects/routes/get.ts @@ -32,8 +32,9 @@ export const registerGetRoute = (router: IRouter, { coreUsageData }: RouteDepend const usageStatsClient = coreUsageData.getClient(); usageStatsClient.incrementSavedObjectsGet({ request: req }).catch(() => {}); - const savedObject = await context.core.savedObjects.client.get(type, id); - return res.ok({ body: savedObject }); + const { savedObjects } = await context.core; + const object = await savedObjects.client.get(type, id); + return res.ok({ body: object }); }) ); }; diff --git a/src/core/server/saved_objects/routes/import.ts b/src/core/server/saved_objects/routes/import.ts index d373dd5e63bc6..545d01b454741 100644 --- a/src/core/server/saved_objects/routes/import.ts +++ b/src/core/server/saved_objects/routes/import.ts @@ -63,7 +63,7 @@ export const registerImportRoute = ( }, catchAndReturnBoomErrors(async (context, req, res) => { const { overwrite, createNewCopies } = req.query; - const { getClient, getImporter, typeRegistry } = context.core.savedObjects; + const { getClient, getImporter, typeRegistry } = (await context.core).savedObjects; const usageStatsClient = coreUsageData.getClient(); usageStatsClient diff --git a/src/core/server/saved_objects/routes/legacy_import_export/export.ts b/src/core/server/saved_objects/routes/legacy_import_export/export.ts index fd10e60c4c804..7141d74b71904 100644 --- a/src/core/server/saved_objects/routes/legacy_import_export/export.ts +++ b/src/core/server/saved_objects/routes/legacy_import_export/export.ts @@ -38,7 +38,7 @@ export const registerLegacyExportRoute = ( ); const ids = Array.isArray(req.query.dashboard) ? req.query.dashboard : [req.query.dashboard]; - const { client } = ctx.core.savedObjects; + const { client } = (await ctx.core).savedObjects; const usageStatsClient = coreUsageData.getClient(); usageStatsClient.incrementLegacyDashboardsExport({ request: req }).catch(() => {}); diff --git a/src/core/server/saved_objects/routes/legacy_import_export/import.ts b/src/core/server/saved_objects/routes/legacy_import_export/import.ts index 09027af810149..d98c14f9b620d 100644 --- a/src/core/server/saved_objects/routes/legacy_import_export/import.ts +++ b/src/core/server/saved_objects/routes/legacy_import_export/import.ts @@ -46,7 +46,7 @@ export const registerLegacyImportRoute = ( "The import dashboard API '/api/kibana/dashboards/import' is deprecated. Use the saved objects import objects API '/api/saved_objects/_import' instead." ); - const { client } = ctx.core.savedObjects; + const { client } = (await ctx.core).savedObjects; const objects = req.body.objects as SavedObject[]; const { force, exclude } = req.query; diff --git a/src/core/server/saved_objects/routes/resolve.ts b/src/core/server/saved_objects/routes/resolve.ts index 78e85d17fe1fa..ae09f6526baa3 100644 --- a/src/core/server/saved_objects/routes/resolve.ts +++ b/src/core/server/saved_objects/routes/resolve.ts @@ -27,11 +27,12 @@ export const registerResolveRoute = (router: IRouter, { coreUsageData }: RouteDe }, router.handleLegacyErrors(async (context, req, res) => { const { type, id } = req.params; + const { savedObjects } = await context.core; const usageStatsClient = coreUsageData.getClient(); usageStatsClient.incrementSavedObjectsResolve({ request: req }).catch(() => {}); - const result = await context.core.savedObjects.client.resolve(type, id); + const result = await savedObjects.client.resolve(type, id); return res.ok({ body: result }); }) ); diff --git a/src/core/server/saved_objects/routes/resolve_import_errors.ts b/src/core/server/saved_objects/routes/resolve_import_errors.ts index f1fe2e9cfe431..bf536e906d7da 100644 --- a/src/core/server/saved_objects/routes/resolve_import_errors.ts +++ b/src/core/server/saved_objects/routes/resolve_import_errors.ts @@ -92,7 +92,7 @@ export const registerResolveImportErrorsRoute = ( }); } - const { getClient, getImporter, typeRegistry } = context.core.savedObjects; + const { getClient, getImporter, typeRegistry } = (await context.core).savedObjects; const includedHiddenTypes = chain(req.body.retries) .map('type') diff --git a/src/core/server/saved_objects/routes/update.ts b/src/core/server/saved_objects/routes/update.ts index f21fc183cdade..5383ab76a1e4d 100644 --- a/src/core/server/saved_objects/routes/update.ts +++ b/src/core/server/saved_objects/routes/update.ts @@ -49,7 +49,8 @@ export const registerUpdateRoute = (router: IRouter, { coreUsageData }: RouteDep const usageStatsClient = coreUsageData.getClient(); usageStatsClient.incrementSavedObjectsUpdate({ request: req }).catch(() => {}); - const result = await context.core.savedObjects.client.update(type, id, attributes, options); + const { savedObjects } = await context.core; + const result = await savedObjects.client.update(type, id, attributes, options); return res.ok({ body: result }); }) ); diff --git a/src/core/server/saved_objects/saved_objects_service.test.ts b/src/core/server/saved_objects/saved_objects_service.test.ts index a8bda95af46f9..dea9ea224512a 100644 --- a/src/core/server/saved_objects/saved_objects_service.test.ts +++ b/src/core/server/saved_objects/saved_objects_service.test.ts @@ -36,6 +36,7 @@ import { NodesVersionCompatibility } from '../elasticsearch/version_check/ensure import { SavedObjectsRepository } from './service/lib/repository'; import { registerCoreObjectTypes } from './object_types'; import { getSavedObjectsDeprecationsProvider } from './deprecations'; +import { docLinksServiceMock } from '../doc_links/doc_links_service.mock'; jest.mock('./service/lib/repository'); jest.mock('./object_types'); @@ -79,6 +80,7 @@ describe('SavedObjectsService', () => { return { pluginsInitialized, elasticsearch: elasticsearchServiceMock.createInternalStart(), + docLinks: docLinksServiceMock.createStartContract(), }; }; diff --git a/src/core/server/saved_objects/saved_objects_service.ts b/src/core/server/saved_objects/saved_objects_service.ts index 0729db0e04266..1598d2b1d2764 100644 --- a/src/core/server/saved_objects/saved_objects_service.ts +++ b/src/core/server/saved_objects/saved_objects_service.ts @@ -50,6 +50,7 @@ import { ServiceStatus } from '../status'; import { calculateStatus$ } from './status'; import { registerCoreObjectTypes } from './object_types'; import { getSavedObjectsDeprecationsProvider } from './deprecations'; +import { DocLinksServiceStart } from '../doc_links'; const kibanaIndex = '.kibana'; @@ -284,6 +285,7 @@ interface WrappedClientFactoryWrapper { export interface SavedObjectsStartDeps { elasticsearch: InternalElasticsearchServiceStart; pluginsInitialized?: boolean; + docLinks: DocLinksServiceStart; } export class SavedObjectsService @@ -383,6 +385,7 @@ export class SavedObjectsService public async start({ elasticsearch, pluginsInitialized = true, + docLinks, }: SavedObjectsStartDeps): Promise { if (!this.setupDeps || !this.config) { throw new Error('#setup() needs to be run first'); @@ -394,7 +397,8 @@ export class SavedObjectsService const migrator = this.createMigrator( this.config.migration, - elasticsearch.client.asInternalUser + elasticsearch.client.asInternalUser, + docLinks ); this.migrator$.next(migrator); @@ -509,7 +513,8 @@ export class SavedObjectsService private createMigrator( soMigrationsConfig: SavedObjectsMigrationConfigType, - client: ElasticsearchClient + client: ElasticsearchClient, + docLinks: DocLinksServiceStart ): IKibanaMigrator { return new KibanaMigrator({ typeRegistry: this.typeRegistry, @@ -518,6 +523,7 @@ export class SavedObjectsService soMigrationsConfig, kibanaIndex, client, + docLinks, }); } diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 67aca94de6426..ea83e210cc4e1 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -9,6 +9,7 @@ import { AddConfigDeprecation } from '@kbn/config'; import { AnalyticsClient } from '@kbn/analytics-client'; import apm from 'elastic-apm-node'; +import { AwaitedProperties } from '@kbn/utility-types'; import Boom from '@hapi/boom'; import { ByteSizeValue } from '@kbn/config-schema'; import { CliArgs } from '@kbn/config'; @@ -446,6 +447,30 @@ export interface CorePreboot { preboot: PrebootServicePreboot; } +// @public +export interface CoreRequestHandlerContext { + // (undocumented) + deprecations: { + client: DeprecationsClient; + }; + // (undocumented) + elasticsearch: { + client: IScopedClusterClient; + }; + // (undocumented) + savedObjects: { + client: SavedObjectsClientContract; + typeRegistry: ISavedObjectTypeRegistry; + getClient: (options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract; + getExporter: (client: SavedObjectsClientContract) => ISavedObjectsExporter; + getImporter: (client: SavedObjectsClientContract) => ISavedObjectsImporter; + }; + // (undocumented) + uiSettings: { + client: IUiSettingsClient; + }; +} + // @internal export interface CoreServicesUsageData { // (undocumented) @@ -840,6 +865,11 @@ export interface CustomHttpResponseOptions = RequestHandlerContext & { + [Key in keyof T]: T[Key] extends Promise ? T[Key] : Promise; +}; + // @internal (undocumented) export const DEFAULT_APP_CATEGORIES: Record; @@ -1189,7 +1219,7 @@ export interface HttpServiceSetup { registerOnPreAuth: (handler: OnPreAuthHandler) => void; registerOnPreResponse: (handler: OnPreResponseHandler) => void; registerOnPreRouting: (handler: OnPreRoutingHandler) => void; - registerRouteHandlerContext: (contextName: ContextName, provider: RequestHandlerContextProvider) => RequestHandlerContextContainer; + registerRouteHandlerContext: >(contextName: ContextName, provider: RequestHandlerContextProvider) => RequestHandlerContextContainer; } // @public (undocumented) @@ -1221,7 +1251,7 @@ export interface IContextContainer { } // @public -export type IContextProvider = (context: Omit, ...rest: HandlerParameters) => Promise | Context[ContextName]; +export type IContextProvider = (context: Omit, ...rest: HandlerParameters) => MaybePromise>; // @public export interface ICspConfig { @@ -1840,26 +1870,14 @@ export interface RegisterDeprecationsConfig { export type RequestHandler

= (context: Context, request: KibanaRequest, response: ResponseFactory) => IKibanaResponse | Promise>; // @public -export interface RequestHandlerContext { +export interface RequestHandlerContext extends RequestHandlerContextBase { // (undocumented) - core: { - savedObjects: { - client: SavedObjectsClientContract; - typeRegistry: ISavedObjectTypeRegistry; - getClient: (options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract; - getExporter: (client: SavedObjectsClientContract) => ISavedObjectsExporter; - getImporter: (client: SavedObjectsClientContract) => ISavedObjectsImporter; - }; - elasticsearch: { - client: IScopedClusterClient; - }; - uiSettings: { - client: IUiSettingsClient; - }; - deprecations: { - client: DeprecationsClient; - }; - }; + core: Promise; +} + +// @public (undocumented) +export interface RequestHandlerContextBase { + resolve: >(parts: T[]) => Promise>>; } // @public @@ -2523,7 +2541,7 @@ export class SavedObjectsImporter { typeRegistry: ISavedObjectTypeRegistry; importSizeLimit: number; }); - import({ readStream, createNewCopies, namespace, overwrite, }: SavedObjectsImportOptions): Promise; + import({ readStream, createNewCopies, namespace, overwrite, refresh, }: SavedObjectsImportOptions): Promise; resolveImportErrors({ readStream, createNewCopies, namespace, retries, }: SavedObjectsResolveImportErrorsOptions): Promise; } @@ -2586,6 +2604,7 @@ export interface SavedObjectsImportOptions { namespace?: string; overwrite: boolean; readStream: Readable; + refresh?: boolean | 'wait_for'; } // @public diff --git a/src/core/server/server.ts b/src/core/server/server.ts index dc19f5eeea198..c73e98f4bb6c4 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -42,7 +42,6 @@ import { config as uiSettingsConfig } from './ui_settings'; import { config as statusConfig } from './status'; import { config as i18nConfig } from './i18n'; import { ContextService } from './context'; -import { RequestHandlerContext } from '.'; import { InternalCorePreboot, InternalCoreSetup, @@ -316,6 +315,7 @@ export class Server { const savedObjectsStart = await this.savedObjects.start({ elasticsearch: elasticsearchStart, pluginsInitialized: this.#pluginsInitialized, + docLinks: docLinkStart, }); await this.resolveSavedObjectsStartPromise!(savedObjectsStart); @@ -371,13 +371,9 @@ export class Server { } private registerCoreContext(coreSetup: InternalCoreSetup) { - coreSetup.http.registerRouteHandlerContext( - coreId, - 'core', - (context, req, res): RequestHandlerContext['core'] => { - return new CoreRouteHandlerContext(this.coreStart!, req); - } - ); + coreSetup.http.registerRouteHandlerContext(coreId, 'core', async (context, req, res) => { + return new CoreRouteHandlerContext(this.coreStart!, req); + }); } public setupCoreConfig() { diff --git a/src/core/server/ui_settings/routes/delete.ts b/src/core/server/ui_settings/routes/delete.ts index f8ab4d5d0c2c4..87c6edf386428 100644 --- a/src/core/server/ui_settings/routes/delete.ts +++ b/src/core/server/ui_settings/routes/delete.ts @@ -23,7 +23,7 @@ export function registerDeleteRoute(router: IRouter) { { path: '/api/kibana/settings/{key}', validate }, async (context, request, response) => { try { - const uiSettingsClient = context.core.uiSettings.client; + const uiSettingsClient = (await context.core).uiSettings.client; await uiSettingsClient.remove(request.params.key); diff --git a/src/core/server/ui_settings/routes/get.ts b/src/core/server/ui_settings/routes/get.ts index 051d562c39804..0929330cf0238 100644 --- a/src/core/server/ui_settings/routes/get.ts +++ b/src/core/server/ui_settings/routes/get.ts @@ -14,7 +14,7 @@ export function registerGetRoute(router: IRouter) { { path: '/api/kibana/settings', validate: false }, async (context, request, response) => { try { - const uiSettingsClient = context.core.uiSettings.client; + const uiSettingsClient = (await context.core).uiSettings.client; return response.ok({ body: { settings: await uiSettingsClient.getUserProvided(), diff --git a/src/core/server/ui_settings/routes/set.ts b/src/core/server/ui_settings/routes/set.ts index 7de287f4ebe6a..91518fb6f3476 100644 --- a/src/core/server/ui_settings/routes/set.ts +++ b/src/core/server/ui_settings/routes/set.ts @@ -26,7 +26,7 @@ export function registerSetRoute(router: IRouter) { { path: '/api/kibana/settings/{key}', validate }, async (context, request, response) => { try { - const uiSettingsClient = context.core.uiSettings.client; + const uiSettingsClient = (await context.core).uiSettings.client; const { key } = request.params; const { value } = request.body; diff --git a/src/core/server/ui_settings/routes/set_many.ts b/src/core/server/ui_settings/routes/set_many.ts index c4053dd3e7eed..f4f3f509bf920 100644 --- a/src/core/server/ui_settings/routes/set_many.ts +++ b/src/core/server/ui_settings/routes/set_many.ts @@ -21,7 +21,7 @@ const validate = { export function registerSetManyRoute(router: IRouter) { router.post({ path: '/api/kibana/settings', validate }, async (context, request, response) => { try { - const uiSettingsClient = context.core.uiSettings.client; + const uiSettingsClient = (await context.core).uiSettings.client; const { changes } = request.body; diff --git a/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker b/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker index fbf6d64170ee8..77e8e5d63bbdf 100755 --- a/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker +++ b/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker @@ -40,6 +40,18 @@ kibana_vars=( csp.report_to data.autocomplete.valueSuggestions.terminateAfter data.autocomplete.valueSuggestions.timeout + data.search.sessions.defaultExpiration + data.search.sessions.enabled + data.search.sessions.maxUpdateRetries + data.search.sessions.notTouchedInProgressTimeout + data.search.sessions.notTouchedTimeout + data.search.sessions.pageSize + data.search.sessions.trackingInterval + unifiedSearch.autocomplete.valueSuggestions.terminateAfter + unifiedSearch.autocomplete.valueSuggestions.timeout + unifiedSearch.autocomplete.querySuggestions.enabled + unifiedSearch.autocomplete.valueSuggestions.enabled + unifiedSearch.autocomplete.valueSuggestions.tiers elasticsearch.customHeaders elasticsearch.hosts elasticsearch.logQueries @@ -183,6 +195,7 @@ kibana_vars=( vis_type_vega.enableExternalUrls xpack.actions.allowedHosts xpack.actions.customHostSettings + xpack.actions.email.domain_allowlist xpack.actions.enabledActionTypes xpack.actions.maxResponseContentLength xpack.actions.preconfigured @@ -206,6 +219,7 @@ kibana_vars=( xpack.alerting.rules.minimumScheduleInterval.value xpack.alerting.rules.minimumScheduleInterval.enforce xpack.alerting.rules.run.actions.max + xpack.alerting.rules.run.actions.connectorTypeOverrides xpack.alerts.healthCheck.interval xpack.alerts.invalidateApiKeysTask.interval xpack.alerts.invalidateApiKeysTask.removalDelay diff --git a/src/dev/license_checker/config.ts b/src/dev/license_checker/config.ts index 2a067a54d472e..bd5fd75e30998 100644 --- a/src/dev/license_checker/config.ts +++ b/src/dev/license_checker/config.ts @@ -76,7 +76,7 @@ export const DEV_ONLY_LICENSE_ALLOWED = ['MPL-2.0']; export const LICENSE_OVERRIDES = { 'jsts@1.6.2': ['Eclipse Distribution License - v 1.0'], // cf. https://github.com/bjornharrtell/jsts '@mapbox/jsonlint-lines-primitives@2.0.2': ['MIT'], // license in readme https://github.com/tmcw/jsonlint - '@elastic/ems-client@8.2.0': ['Elastic License 2.0'], - '@elastic/eui@54.0.0': ['SSPL-1.0 OR Elastic License 2.0'], + '@elastic/ems-client@8.3.0': ['Elastic License 2.0'], + '@elastic/eui@55.0.1': ['SSPL-1.0 OR Elastic License 2.0'], 'language-subtag-registry@0.3.21': ['CC-BY-4.0'], // retired ODC‑By license https://github.com/mattcg/language-subtag-registry }; diff --git a/src/dev/prs/README.md b/src/dev/prs/README.md new file mode 100644 index 0000000000000..b24f1ff2f79cb --- /dev/null +++ b/src/dev/prs/README.md @@ -0,0 +1,13 @@ +# Pulling a list of PRs + +This folder contains files used to pull lists of Kibana PRs for release testing. + +`scripts/download_pr_list.js` is the cli wrapper. + +You must have a `GITHUB_TOKEN` either set in your environment or on command line like + +`GITHUB_TOKEN= node scripts/download_pr_list.js` + +Run it with `--help` or without arguments for help. + +`kibana_qa_pr_list.json` is the file currently used by the Kibana QA team and also serves as an example. \ No newline at end of file diff --git a/src/dev/prs/kibana_qa_pr_list.json b/src/dev/prs/kibana_qa_pr_list.json new file mode 100644 index 0000000000000..e8d27ba9f2f0a --- /dev/null +++ b/src/dev/prs/kibana_qa_pr_list.json @@ -0,0 +1,135 @@ +{ + "include": [ +"v8.3.0" +], +"exclude": [ +"v8.2.0", +"v8.1.3", +"v8.1.2", +"v8.1.1", +"v8.1.0", +"v8.0.1", +"v8.0.0", +"v7.17.3", +"v7.17.2", +"v7.17.1", +"v7.17.0", +"v7.16.3", +"v7.16.2", +"v7.16.1", +"v7.16.0", +"v7.15.3", +"v7.15.2", +"v7.15.1", +"v7.15.0", +"v7.14.3", +"v7.14.2", +"v7.14.1", +"v7.14.0", +"v7.13.3", +"v7.13.2", +"v7.13.1", +"v7.13.0", +"v7.12.3", +"v7.12.2", +"v7.12.1", +"v7.12.0", +"v7.11.3", +"v7.11.2", +"v7.11.1", +"v7.11.0", +"v7.10.3", +"v7.10.2", +"v7.10.1", +"v7.10.0", +"v7.9.3", +"v7.9.2", +"v7.9.1", +"v7.9.0", +"v7.8.3", +"v7.8.2", +"v7.8.1", +"v7.8.0", +"v7.7.3", +"v7.7.2", +"v7.7.1", +"v7.7.0", +"v7.6.3", +"v7.6.2", +"v7.6.1", +"v7.6.0", +"v7.5.3", +"v7.5.2", +"v7.5.1", +"v7.5.0", +"v7.4.3", +"v7.4.2", +"v7.4.1", +"v7.4.0", +"v7.3.3", +"v7.3.2", +"v7.3.1", +"v7.3.0", +"v7.2.3", +"v7.2.2", +"v7.2.1", +"v7.2.0", +"v7.1.3", +"v7.1.2", +"v7.1.1", +"v7.1.0", +"v7.0.3", +"v7.0.2", +"v7.0.1", +"v7.0.0", +":ml", +"Feature:Anomaly Detection", +"Feature:Detections", +"Feature:Endpoint", +"Feature:Observability Landing - Milestone 1", +"Feature:Osquery", +"Feature:Transforms", +"Synthetics", +"Team: AWL: Platform", +"Team: Actionable Observability", +"Team: CTI", +"Team: SecuritySolution", +"Team:Asset Management", +"Team:Cloud Security Posture", +"Team:Detection Alerts", +"Team:Detection Rules", +"Team:Detections and Resp", +"Team:Docs", +"Team:Elasticsearch UI", +"Team:Endpoint Data Visibility", +"Team:Endpoint Management", +"Team:Endpoint Response", +"Team:EnterpriseSearch", +"Team:Fleet", +"Team:Infra Monitoring UI", +"Team:Ingest Management", +"Team:Observability", +"Team:Onboarding and Lifecycle Mgt", +"Team:Operations", +"Team:QA", +"Team:ResponseOps", +"Team:SIEM", +"Team:Security Solution Platform", +"Team:Security", +"Team:Threat Hunting", +"Team:Threat Hunting:Explore", +"Team:Threat Hunting:Investigations", +"Team:WorkplaceSearch", +"Team:WorkplaceSearch", +"Team:apm", +"Team:logs-metrics-ui", +"Team:uptime", +"bump", +"docs", +"failed-test", +"Feature:Unit Testing", +"Feature:Functional Testing", +"test_xpack_functional" +] +} + diff --git a/src/dev/storybook/aliases.ts b/src/dev/storybook/aliases.ts index 8075abcdcf79b..4167719d3bb31 100644 --- a/src/dev/storybook/aliases.ts +++ b/src/dev/storybook/aliases.ts @@ -17,7 +17,7 @@ export const storybookAliases = { custom_integrations: 'src/plugins/custom_integrations/storybook', dashboard_enhanced: 'x-pack/plugins/dashboard_enhanced/.storybook', dashboard: 'src/plugins/dashboard/.storybook', - data_enhanced: 'x-pack/plugins/data_enhanced/.storybook', + data: 'src/plugins/data/.storybook', discover: 'src/plugins/discover/.storybook', embeddable: 'src/plugins/embeddable/.storybook', expression_error: 'src/plugins/expression_error/.storybook', diff --git a/src/plugins/chart_expressions/expression_metric/public/components/metric_component.tsx b/src/plugins/chart_expressions/expression_metric/public/components/metric_component.tsx index a7d0eb8cad8c6..50853ea6c6569 100644 --- a/src/plugins/chart_expressions/expression_metric/public/components/metric_component.tsx +++ b/src/plugins/chart_expressions/expression_metric/public/components/metric_component.tsx @@ -81,7 +81,7 @@ class MetricVisComponent extends Component { title = `${bucketValue} - ${title}`; } - const shouldBrush = stops.length > 1 && shouldApplyColor(color ?? ''); + const shouldBrush = shouldApplyColor(color ?? ''); return { label: title, value: formattedValue, diff --git a/src/plugins/chart_expressions/expression_partition_vis/public/components/partition_vis_component.test.tsx b/src/plugins/chart_expressions/expression_partition_vis/public/components/partition_vis_component.test.tsx index 1281fb17bd990..648df546b2992 100644 --- a/src/plugins/chart_expressions/expression_partition_vis/public/components/partition_vis_component.test.tsx +++ b/src/plugins/chart_expressions/expression_partition_vis/public/components/partition_vis_component.test.tsx @@ -12,7 +12,8 @@ import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks'; import type { Datatable } from '@kbn/expressions-plugin/public'; -import { shallow, mount } from 'enzyme'; +import { shallow } from 'enzyme'; +import { mountWithIntl } from '@kbn/test-jest-helpers'; import { findTestSubject } from '@elastic/eui/lib/test'; import { act } from 'react-dom/test-utils'; import PartitionVisComponent, { PartitionVisComponentProps } from './partition_vis_component'; @@ -143,7 +144,7 @@ describe('PartitionVisComponent', function () { }); it('renders the legend toggle component', async () => { - const component = mount(); + const component = mountWithIntl(); await actWithTimeout(async () => { await component.update(); }); @@ -154,7 +155,7 @@ describe('PartitionVisComponent', function () { }); it('hides the legend if the legend toggle is clicked', async () => { - const component = mount(); + const component = mountWithIntl(); await actWithTimeout(async () => { await component.update(); }); @@ -233,7 +234,7 @@ describe('PartitionVisComponent', function () { ], } as unknown as Datatable; const newProps = { ...wrapperProps, visData: newVisData }; - const component = mount(); + const component = mountWithIntl(); expect(findTestSubject(component, 'partitionVisEmptyValues').text()).toEqual( 'No results found' ); @@ -264,7 +265,7 @@ describe('PartitionVisComponent', function () { ], } as unknown as Datatable; const newProps = { ...wrapperProps, visData: newVisData }; - const component = mount(); + const component = mountWithIntl(); expect(findTestSubject(component, 'partitionVisNegativeValues').text()).toEqual( "Pie chart can't render with negative values." ); diff --git a/src/plugins/chart_expressions/expression_xy/common/expression_functions/annotation_layer.ts b/src/plugins/chart_expressions/expression_xy/common/expression_functions/annotation_layer.ts index aac5ec2784ff6..6174b9d40e452 100644 --- a/src/plugins/chart_expressions/expression_xy/common/expression_functions/annotation_layer.ts +++ b/src/plugins/chart_expressions/expression_xy/common/expression_functions/annotation_layer.ts @@ -30,7 +30,7 @@ export function annotationLayerFunction(): ExpressionFunctionDefinition< help: strings.getAnnotationLayerHideHelp(), }, annotations: { - types: ['manual_event_annotation'], + types: ['manual_point_event_annotation', 'manual_range_event_annotation'], help: strings.getAnnotationLayerAnnotationsHelp(), multi: true, }, diff --git a/src/plugins/chart_expressions/expression_xy/common/expression_functions/extended_annotation_layer.ts b/src/plugins/chart_expressions/expression_xy/common/expression_functions/extended_annotation_layer.ts index a87c59925f484..539c11854355c 100644 --- a/src/plugins/chart_expressions/expression_xy/common/expression_functions/extended_annotation_layer.ts +++ b/src/plugins/chart_expressions/expression_xy/common/expression_functions/extended_annotation_layer.ts @@ -30,7 +30,7 @@ export function extendedAnnotationLayerFunction(): ExpressionFunctionDefinition< help: strings.getAnnotationLayerHideHelp(), }, annotations: { - types: ['manual_event_annotation'], + types: ['manual_point_event_annotation', 'manual_range_event_annotation'], help: strings.getAnnotationLayerAnnotationsHelp(), multi: true, }, diff --git a/src/plugins/chart_expressions/expression_xy/common/expression_functions/layered_xy_vis.ts b/src/plugins/chart_expressions/expression_xy/common/expression_functions/layered_xy_vis.ts index 789612ae4dea5..6b926e1ceff05 100644 --- a/src/plugins/chart_expressions/expression_xy/common/expression_functions/layered_xy_vis.ts +++ b/src/plugins/chart_expressions/expression_xy/common/expression_functions/layered_xy_vis.ts @@ -9,17 +9,13 @@ import { i18n } from '@kbn/i18n'; import { LayeredXyVisFn } from '../types'; import { - XY_VIS_RENDERER, EXTENDED_DATA_LAYER, EXTENDED_REFERENCE_LINE_LAYER, LAYERED_XY_VIS, EXTENDED_ANNOTATION_LAYER, } from '../constants'; -import { logDatatables } from '../utils'; import { commonXYArgs } from './common_xy_args'; -import { validateMarkSizeRatioLimits } from './validate'; import { strings } from '../i18n'; -import { appendLayerIds } from '../helpers'; export const layeredXyVisFunction: LayeredXyVisFn = { name: LAYERED_XY_VIS, @@ -36,26 +32,8 @@ export const layeredXyVisFunction: LayeredXyVisFn = { multi: true, }, }, - fn(data, args, handlers) { - const layers = appendLayerIds(args.layers ?? [], 'layers'); - - logDatatables(layers, handlers); - - validateMarkSizeRatioLimits(args.markSizeRatio); - - return { - type: 'render', - as: XY_VIS_RENDERER, - value: { - args: { - ...args, - layers, - ariaLabel: - args.ariaLabel ?? - (handlers.variables?.embeddableTitle as string) ?? - handlers.getExecutionContext?.()?.description, - }, - }, - }; + async fn(data, args, handlers) { + const { layeredXyVisFn } = await import('./layered_xy_vis_fn'); + return await layeredXyVisFn(data, args, handlers); }, }; diff --git a/src/plugins/chart_expressions/expression_xy/common/expression_functions/layered_xy_vis_fn.ts b/src/plugins/chart_expressions/expression_xy/common/expression_functions/layered_xy_vis_fn.ts new file mode 100644 index 0000000000000..29fd21cd43160 --- /dev/null +++ b/src/plugins/chart_expressions/expression_xy/common/expression_functions/layered_xy_vis_fn.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { XY_VIS_RENDERER } from '../constants'; +import { appendLayerIds } from '../helpers'; +import { LayeredXyVisFn } from '../types'; +import { logDatatables } from '../utils'; +import { validateMarkSizeRatioLimits } from './validate'; + +export const layeredXyVisFn: LayeredXyVisFn['fn'] = async (data, args, handlers) => { + const layers = appendLayerIds(args.layers ?? [], 'layers'); + + logDatatables(layers, handlers); + + validateMarkSizeRatioLimits(args.markSizeRatio); + + return { + type: 'render', + as: XY_VIS_RENDERER, + value: { + args: { + ...args, + layers, + ariaLabel: + args.ariaLabel ?? + (handlers.variables?.embeddableTitle as string) ?? + handlers.getExecutionContext?.()?.description, + }, + }, + }; +}; diff --git a/src/plugins/chart_expressions/expression_xy/common/expression_functions/validate.ts b/src/plugins/chart_expressions/expression_xy/common/expression_functions/validate.ts index 2b8fcee6e8a74..bf083c6c2d1a0 100644 --- a/src/plugins/chart_expressions/expression_xy/common/expression_functions/validate.ts +++ b/src/plugins/chart_expressions/expression_xy/common/expression_functions/validate.ts @@ -7,7 +7,14 @@ */ import { i18n } from '@kbn/i18n'; -import { SeriesType } from '../types'; +import { AxisExtentModes, ValueLabelModes } from '../constants'; +import { + SeriesType, + AxisExtentConfigResult, + DataLayerConfigResult, + ValueLabelMode, + CommonXYDataLayerConfig, +} from '../types'; const errors = { markSizeAccessorForNonLineOrAreaChartsError: () => @@ -43,6 +50,90 @@ const errors = { defaultMessage: '`pointsRadius` can be applied only for line or area charts', } ), + extendBoundsAreInvalidError: () => + i18n.translate('expressionXY.reusable.function.xyVis.errors.extendBoundsAreInvalidError', { + defaultMessage: + 'For area and bar modes, and custom extent mode, the lower bound should be less or greater than 0 and the upper bound - be greater or equal than 0', + }), + notUsedFillOpacityError: () => + i18n.translate('expressionXY.reusable.function.xyVis.errors.notUsedFillOpacityError', { + defaultMessage: '`fillOpacity` argument is applicable only for area charts.', + }), + valueLabelsForNotBarsOrHistogramBarsChartsError: () => + i18n.translate( + 'expressionXY.reusable.function.xyVis.errors.valueLabelsForNotBarsOrHistogramBarsChartsError', + { + defaultMessage: + '`valueLabels` argument is applicable only for bar charts, which are not histograms.', + } + ), + dataBoundsForNotLineChartError: () => + i18n.translate('expressionXY.reusable.function.xyVis.errors.dataBoundsForNotLineChartError', { + defaultMessage: 'Only line charts can be fit to the data bounds', + }), +}; + +export const hasBarLayer = (layers: Array) => + layers.filter(({ seriesType }) => seriesType.includes('bar')).length > 0; + +export const hasAreaLayer = (layers: Array) => + layers.filter(({ seriesType }) => seriesType.includes('area')).length > 0; + +export const hasHistogramBarLayer = ( + layers: Array +) => + layers.filter(({ seriesType, isHistogram }) => seriesType.includes('bar') && isHistogram).length > + 0; + +export const isValidExtentWithCustomMode = (extent: AxisExtentConfigResult) => { + const isValidLowerBound = + extent.lowerBound === undefined || (extent.lowerBound !== undefined && extent.lowerBound <= 0); + const isValidUpperBound = + extent.upperBound === undefined || (extent.upperBound !== undefined && extent.upperBound >= 0); + + return isValidLowerBound && isValidUpperBound; +}; + +export const validateExtentForDataBounds = ( + extent: AxisExtentConfigResult, + layers: Array +) => { + const lineSeries = layers.filter(({ seriesType }) => seriesType.includes('line')); + if (!lineSeries.length && extent.mode === AxisExtentModes.DATA_BOUNDS) { + throw new Error(errors.dataBoundsForNotLineChartError()); + } +}; + +export const validateExtent = ( + extent: AxisExtentConfigResult, + hasBarOrArea: boolean, + dataLayers: Array +) => { + if ( + extent.mode === AxisExtentModes.CUSTOM && + hasBarOrArea && + !isValidExtentWithCustomMode(extent) + ) { + throw new Error(errors.extendBoundsAreInvalidError()); + } + + validateExtentForDataBounds(extent, dataLayers); +}; + +export const validateFillOpacity = (fillOpacity: number | undefined, hasArea: boolean) => { + if (fillOpacity !== undefined && !hasArea) { + throw new Error(errors.notUsedFillOpacityError()); + } +}; + +export const validateValueLabels = ( + valueLabels: ValueLabelMode, + hasBar: boolean, + hasNotHistogramBars: boolean +) => { + if ((!hasBar || !hasNotHistogramBars) && valueLabels !== ValueLabelModes.HIDE) { + throw new Error(errors.valueLabelsForNotBarsOrHistogramBarsChartsError()); + } }; const isAreaOrLineChart = (seriesType: SeriesType) => diff --git a/src/plugins/chart_expressions/expression_xy/common/expression_functions/xy_vis_fn.ts b/src/plugins/chart_expressions/expression_xy/common/expression_functions/xy_vis_fn.ts index 8bc66ffd41e03..26d1f20960ad9 100644 --- a/src/plugins/chart_expressions/expression_xy/common/expression_functions/xy_vis_fn.ts +++ b/src/plugins/chart_expressions/expression_xy/common/expression_functions/xy_vis_fn.ts @@ -6,59 +6,20 @@ * Side Public License, v 1. */ -import { i18n } from '@kbn/i18n'; import { Dimension, prepareLogTable } from '@kbn/visualizations-plugin/common/utils'; -import { AxisExtentModes, LayerTypes, ValueLabelModes, XY_VIS_RENDERER } from '../constants'; +import { LayerTypes, XY_VIS_RENDERER } from '../constants'; import { appendLayerIds } from '../helpers'; -import { AxisExtentConfigResult, DataLayerConfigResult, XYLayerConfig, XyVisFn } from '../types'; +import { XYLayerConfig, XyVisFn } from '../types'; import { getLayerDimensions } from '../utils'; -import { validateMarkSizeRatioLimits } from './validate'; - -const errors = { - extendBoundsAreInvalidError: () => - i18n.translate('expressionXY.reusable.function.xyVis.errors.extendBoundsAreInvalidError', { - defaultMessage: - 'For area and bar modes, and custom extent mode, the lower bound should be less or greater than 0 and the upper bound - be greater or equal than 0', - }), - notUsedFillOpacityError: () => - i18n.translate('expressionXY.reusable.function.xyVis.errors.notUsedFillOpacityError', { - defaultMessage: '`fillOpacity` argument is applicable only for area charts.', - }), - valueLabelsForNotBarsOrHistogramBarsChartsError: () => - i18n.translate( - 'expressionXY.reusable.function.xyVis.errors.valueLabelsForNotBarsOrHistogramBarsChartsError', - { - defaultMessage: - '`valueLabels` argument is applicable only for bar charts, which are not histograms.', - } - ), - dataBoundsForNotLineChartError: () => - i18n.translate('expressionXY.reusable.function.xyVis.errors.dataBoundsForNotLineChartError', { - defaultMessage: 'Only line charts can be fit to the data bounds', - }), -}; - -const validateExtent = ( - extent: AxisExtentConfigResult, - hasBarOrArea: boolean, - dataLayers: DataLayerConfigResult[] -) => { - const isValidLowerBound = - extent.lowerBound === undefined || (extent.lowerBound !== undefined && extent.lowerBound <= 0); - const isValidUpperBound = - extent.upperBound === undefined || (extent.upperBound !== undefined && extent.upperBound >= 0); - - const areValidBounds = isValidLowerBound && isValidUpperBound; - - if (hasBarOrArea && extent.mode === AxisExtentModes.CUSTOM && !areValidBounds) { - throw new Error(errors.extendBoundsAreInvalidError()); - } - - const lineSeries = dataLayers.filter(({ seriesType }) => seriesType.includes('line')); - if (!lineSeries.length && extent.mode === AxisExtentModes.DATA_BOUNDS) { - throw new Error(errors.dataBoundsForNotLineChartError()); - } -}; +import { + hasAreaLayer, + hasBarLayer, + hasHistogramBarLayer, + validateExtent, + validateFillOpacity, + validateMarkSizeRatioLimits, + validateValueLabels, +} from './validate'; export const xyVisFn: XyVisFn['fn'] = async (data, args, handlers) => { const { dataLayers = [], referenceLineLayers = [], annotationLayers = [], ...restArgs } = args; @@ -81,24 +42,16 @@ export const xyVisFn: XyVisFn['fn'] = async (data, args, handlers) => { handlers.inspectorAdapters.tables.logDatatable('default', logTable); } - const hasBar = dataLayers.filter(({ seriesType }) => seriesType.includes('bar')).length > 0; - const hasArea = dataLayers.filter(({ seriesType }) => seriesType.includes('area')).length > 0; + const hasBar = hasBarLayer(dataLayers); + const hasArea = hasAreaLayer(dataLayers); validateExtent(args.yLeftExtent, hasBar || hasArea, dataLayers); validateExtent(args.yRightExtent, hasBar || hasArea, dataLayers); + validateFillOpacity(args.fillOpacity, hasArea); - if (!hasArea && args.fillOpacity !== undefined) { - throw new Error(errors.notUsedFillOpacityError()); - } - - const hasNotHistogramBars = - dataLayers.filter(({ seriesType, isHistogram }) => seriesType.includes('bar') && !isHistogram) - .length > 0; - - if ((!hasBar || !hasNotHistogramBars) && args.valueLabels !== ValueLabelModes.HIDE) { - throw new Error(errors.valueLabelsForNotBarsOrHistogramBarsChartsError()); - } + const hasNotHistogramBars = !hasHistogramBarLayer(dataLayers); + validateValueLabels(args.valueLabels, hasBar, hasNotHistogramBars); validateMarkSizeRatioLimits(args.markSizeRatio); return { diff --git a/src/plugins/chart_expressions/expression_xy/common/helpers/layers.ts b/src/plugins/chart_expressions/expression_xy/common/helpers/layers.ts index 344fb3b460cdd..d62ea264acb1a 100644 --- a/src/plugins/chart_expressions/expression_xy/common/helpers/layers.ts +++ b/src/plugins/chart_expressions/expression_xy/common/helpers/layers.ts @@ -5,6 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ + import { WithLayerId } from '../types'; function isWithLayerId(layer: T): layer is T & WithLayerId { diff --git a/src/plugins/chart_expressions/expression_xy/common/index.ts b/src/plugins/chart_expressions/expression_xy/common/index.ts index 78c2bf482002d..4bee4a3e7f2b6 100755 --- a/src/plugins/chart_expressions/expression_xy/common/index.ts +++ b/src/plugins/chart_expressions/expression_xy/common/index.ts @@ -41,7 +41,6 @@ export type { AxesSettingsConfig, CommonXYLayerConfig, AnnotationLayerArgs, - XYLayerConfigResult, ExtendedYConfigResult, GridlinesConfigResult, DataLayerConfigResult, diff --git a/src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts b/src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts index 0e9ad6b9d484a..0c9e3894bdd7c 100644 --- a/src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts +++ b/src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts @@ -107,7 +107,6 @@ export interface DataLayerArgs { yScaleType: YScaleType; xScaleType: XScaleType; isHistogram: boolean; - // palette will always be set on the expression palette: PaletteOutput; yConfig?: YConfigResult[]; } @@ -131,7 +130,6 @@ export interface ExtendedDataLayerArgs { yScaleType: YScaleType; xScaleType: XScaleType; isHistogram: boolean; - // palette will always be set on the expression palette: PaletteOutput; // palette will always be set on the expression yConfig?: YConfigResult[]; @@ -158,11 +156,11 @@ export interface LegendConfig { /** * Horizontal Alignment of the legend when it is set inside chart */ - horizontalAlignment?: HorizontalAlignment; + horizontalAlignment?: typeof HorizontalAlignment.Right | typeof HorizontalAlignment.Left; /** * Vertical Alignment of the legend when it is set inside chart */ - verticalAlignment?: VerticalAlignment; + verticalAlignment?: typeof VerticalAlignment.Top | typeof VerticalAlignment.Bottom; /** * Number of columns when legend is set inside chart */ @@ -305,10 +303,6 @@ export type XYExtendedLayerConfig = | ExtendedReferenceLineLayerConfig | ExtendedAnnotationLayerConfig; -export type XYLayerConfigResult = - | DataLayerConfigResult - | ReferenceLineLayerConfigResult - | AnnotationLayerConfigResult; export type XYExtendedLayerConfigResult = | ExtendedDataLayerConfigResult | ExtendedReferenceLineLayerConfigResult @@ -400,7 +394,7 @@ export type LayeredXyVisFn = ExpressionFunctionDefinition< typeof LAYERED_XY_VIS, Datatable, LayeredXYArgs, - XYRender + Promise >; export type DataLayerFn = ExpressionFunctionDefinition< diff --git a/src/plugins/chart_expressions/expression_xy/common/types/expression_renderers.ts b/src/plugins/chart_expressions/expression_xy/common/types/expression_renderers.ts index 4da90dbb994ba..b03ea975b0143 100644 --- a/src/plugins/chart_expressions/expression_xy/common/types/expression_renderers.ts +++ b/src/plugins/chart_expressions/expression_xy/common/types/expression_renderers.ts @@ -7,7 +7,10 @@ */ import { AnnotationTooltipFormatter } from '@elastic/charts'; -import { AvailableAnnotationIcon, EventAnnotationArgs } from '@kbn/event-annotation-plugin/common'; +import { + AvailableAnnotationIcon, + ManualPointEventAnnotationArgs, +} from '@kbn/event-annotation-plugin/common'; import { XY_VIS_RENDERER } from '../constants'; import { XYProps } from './expression_functions'; @@ -21,7 +24,7 @@ export interface XYRender { value: XYChartProps; } -export interface CollectiveConfig extends Omit { +export interface CollectiveConfig extends Omit { roundedTimestamp: number; axisMode: 'bottom'; icon?: AvailableAnnotationIcon | string; diff --git a/src/plugins/chart_expressions/expression_xy/common/utils/log_datatables.ts b/src/plugins/chart_expressions/expression_xy/common/utils/log_datatables.ts index 16106b6763628..79a3cbd2eef19 100644 --- a/src/plugins/chart_expressions/expression_xy/common/utils/log_datatables.ts +++ b/src/plugins/chart_expressions/expression_xy/common/utils/log_datatables.ts @@ -21,6 +21,9 @@ export const logDatatables = (layers: CommonXYLayerConfig[], handlers: Execution return; } + handlers.inspectorAdapters.tables.reset(); + handlers.inspectorAdapters.tables.allowCsvExport = true; + layers.forEach((layer) => { if (layer.layerType === LayerTypes.ANNOTATIONS) { return; diff --git a/src/plugins/chart_expressions/expression_xy/public/components/__snapshots__/xy_chart.test.tsx.snap b/src/plugins/chart_expressions/expression_xy/public/components/__snapshots__/xy_chart.test.tsx.snap index 4844b1622948d..83bc4fa62ac68 100644 --- a/src/plugins/chart_expressions/expression_xy/public/components/__snapshots__/xy_chart.test.tsx.snap +++ b/src/plugins/chart_expressions/expression_xy/public/components/__snapshots__/xy_chart.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`XYChart component annotations should render basic annotation 1`] = ` +exports[`XYChart component annotations should render basic line annotation 1`] = ` `; -exports[`XYChart component annotations should render grouped annotations preserving the shared styles 1`] = ` +exports[`XYChart component annotations should render basic range annotation 1`] = ` +Array [ + , + , +] +`; + +exports[`XYChart component annotations should render grouped line annotations preserving the shared styles 1`] = ` `; -exports[`XYChart component annotations should render grouped annotations with default styles 1`] = ` +exports[`XYChart component annotations should render grouped line annotations with default styles 1`] = ` `; -exports[`XYChart component annotations should render simplified annotation when hide is true 1`] = ` +exports[`XYChart component annotations should render simplified annotations when hide is true 1`] = ` - } - markerBody={ - - } markerPosition="top" style={ Object { @@ -213,6 +236,50 @@ exports[`XYChart component annotations should render simplified annotation when /> `; +exports[`XYChart component annotations should render simplified annotations when hide is true 2`] = ` +Array [ + , + , +] +`; + exports[`XYChart component it renders area 1`] = ` >; hide?: boolean; minInterval?: number; isBarChart?: boolean; + outsideDimension: number; } const groupVisibleConfigsByInterval = ( @@ -53,9 +62,11 @@ const groupVisibleConfigsByInterval = ( firstTimestamp?: number ) => { return layers - .flatMap(({ annotations }) => annotations.filter((a) => !a.isHidden)) + .flatMap(({ annotations }) => + annotations.filter((a) => !a.isHidden && a.type === 'manual_point_event_annotation') + ) .sort((a, b) => moment(a.time).valueOf() - moment(b.time).valueOf()) - .reduce>((acc, current) => { + .reduce>((acc, current) => { const roundedTimestamp = getRoundedTimestamp( moment(current.time).valueOf(), firstTimestamp, @@ -70,7 +81,7 @@ const groupVisibleConfigsByInterval = ( const createCustomTooltipDetails = ( - config: EventAnnotationArgs[], + config: ManualPointEventAnnotationArgs[], formatter?: FieldFormat ): AnnotationTooltipFormatter | undefined => () => { @@ -93,8 +104,8 @@ const createCustomTooltipDetails = ); }; -function getCommonProperty( - configArr: EventAnnotationArgs[], +function getCommonProperty( + configArr: ManualPointEventAnnotationArgs[], propertyName: K, fallbackValue: T ) { @@ -105,9 +116,9 @@ function getCommonProperty( return fallbackValue; } -const getCommonStyles = (configArr: EventAnnotationArgs[]) => { +const getCommonStyles = (configArr: ManualPointEventAnnotationArgs[]) => { return { - color: getCommonProperty( + color: getCommonProperty( configArr, 'color', defaultAnnotationColor @@ -118,6 +129,20 @@ const getCommonStyles = (configArr: EventAnnotationArgs[]) => { }; }; +export const getRangeAnnotations = (layers: CommonXYAnnotationLayerConfig[]) => { + return layers + .flatMap(({ annotations }) => + annotations.filter( + (a): a is ManualRangeEventAnnotationOutput => + a.type === 'manual_range_event_annotation' && !a.isHidden + ) + ) + .sort((a, b) => moment(a.time).valueOf() - moment(b.time).valueOf()); +}; + +export const OUTSIDE_RECT_ANNOTATION_WIDTH = 8; +export const OUTSIDE_RECT_ANNOTATION_WIDTH_SUGGESTION = 2; + export const getAnnotationsGroupedByInterval = ( layers: CommonXYAnnotationLayerConfig[], minInterval?: number, @@ -145,18 +170,23 @@ export const getAnnotationsGroupedByInterval = ( }); }; +// todo: remove when closed https://github.com/elastic/elastic-charts/issues/1647 +RectAnnotation.displayName = 'RectAnnotation'; + export const Annotations = ({ - groupedAnnotations, + groupedLineAnnotations, + rangeAnnotations, formatter, isHorizontal, paddingMap, hide, minInterval, isBarChart, + outsideDimension, }: AnnotationsProps) => { return ( <> - {groupedAnnotations.map((annotation) => { + {groupedLineAnnotations.map((annotation) => { const markerPositionVertical = Position.Top; const markerPosition = isHorizontal ? mapVerticalToHorizontalPlacement(markerPositionVertical) @@ -227,6 +257,40 @@ export const Annotations = ({ /> ); })} + {rangeAnnotations.map(({ label, time, color, endTime, outside }) => { + const id = snakeCase(label); + + return ( + ( +

+ +

+ {formatter + ? `${formatter.convert(time)} — ${formatter?.convert(endTime)}` + : `${moment(time).toISOString()} — ${moment(endTime).toISOString()}`} +

+
+
{label}
+
+ )} + dataValues={[ + { + coordinates: { + x0: moment(time).valueOf(), + x1: moment(endTime).valueOf(), + }, + details: label, + }, + ]} + style={{ fill: color || defaultAnnotationRangeColor, opacity: 1 }} + outside={Boolean(outside)} + outsideDimension={outsideDimension} + /> + ); + })} ); }; diff --git a/src/plugins/chart_expressions/expression_xy/public/components/data_layers.tsx b/src/plugins/chart_expressions/expression_xy/public/components/data_layers.tsx index 2ea503c404078..1166d41a9e402 100644 --- a/src/plugins/chart_expressions/expression_xy/public/components/data_layers.tsx +++ b/src/plugins/chart_expressions/expression_xy/public/components/data_layers.tsx @@ -13,10 +13,8 @@ import { LineSeries, } from '@elastic/charts'; import React, { FC } from 'react'; -import { i18n } from '@kbn/i18n'; import { PaletteRegistry } from '@kbn/coloring'; import { FormatFactory } from '@kbn/field-formats-plugin/common'; -import { Datatable } from '@kbn/expressions-plugin'; import { CommonXYDataLayerConfig, EndValue, @@ -28,9 +26,9 @@ import { SeriesTypes, ValueLabelModes } from '../../common/constants'; import { getColorAssignments, getFitOptions, - getFormattedTable, GroupsConfiguration, getSeriesProps, + DatatablesWithFormatInfo, } from '../helpers'; interface Props { @@ -42,7 +40,7 @@ interface Props { fittingFunction?: FittingFunction; endValue?: EndValue | undefined; paletteService: PaletteRegistry; - areLayersAlreadyFormatted: Record>; + formattedDatatables: DatatablesWithFormatInfo; syncColors?: boolean; timeZone?: string; emphasizeFitting?: boolean; @@ -65,7 +63,7 @@ export const DataLayers: FC = ({ emphasizeFitting, yAxesConfiguration, shouldShowValueLabels, - areLayersAlreadyFormatted, + formattedDatatables, chartHasMoreThanOneBarSeries, }) => { const colorAssignments = getColorAssignments(layers, formatFactory); @@ -73,7 +71,7 @@ export const DataLayers: FC = ({ <> {layers.flatMap((layer) => layer.accessors.map((accessor, accessorIndex) => { - const { splitAccessor, seriesType, xAccessor, table, columnToLabel, xScaleType } = layer; + const { seriesType, columnToLabel, layerId } = layer; const columnToLabelMap: Record = columnToLabel ? JSON.parse(columnToLabel) : {}; @@ -81,35 +79,10 @@ export const DataLayers: FC = ({ // what if row values are not primitive? That is the case of, for instance, Ranges // remaps them to their serialized version with the formatHint metadata // In order to do it we need to make a copy of the table as the raw one is required for more features (filters, etc...) later on - const formattedTable: Datatable = getFormattedTable( - table, - formatFactory, - xAccessor, - xScaleType - ); + const formattedDatatableInfo = formattedDatatables[layerId]; const isPercentage = seriesType.includes('percentage'); - // For date histogram chart type, we're getting the rows that represent intervals without data. - // To not display them in the legend, they need to be filtered out. - const rows = formattedTable.rows.filter( - (row) => - !(xAccessor && typeof row[xAccessor] === 'undefined') && - !( - splitAccessor && - typeof row[splitAccessor] === 'undefined' && - typeof row[accessor] === 'undefined' - ) - ); - - if (!xAccessor) { - rows.forEach((row) => { - row.unifiedX = i18n.translate('expressionXY.xyChart.emptyXLabel', { - defaultMessage: '(empty)', - }); - }); - } - const yAxis = yAxesConfiguration.find((axisConfiguration) => axisConfiguration.series.find((currentSeries) => currentSeries.accessor === accessor) ); @@ -122,7 +95,7 @@ export const DataLayers: FC = ({ formatFactory, columnToLabelMap, paletteService, - alreadyFormattedColumns: areLayersAlreadyFormatted[layer.layerId] ?? {}, + formattedDatatableInfo, syncColors, yAxis, timeZone, diff --git a/src/plugins/chart_expressions/expression_xy/public/components/legend_action.tsx b/src/plugins/chart_expressions/expression_xy/public/components/legend_action.tsx index e2a4ca8da554b..da1939f223649 100644 --- a/src/plugins/chart_expressions/expression_xy/public/components/legend_action.tsx +++ b/src/plugins/chart_expressions/expression_xy/public/components/legend_action.tsx @@ -12,12 +12,13 @@ import type { FilterEvent } from '../types'; import type { CommonXYDataLayerConfig } from '../../common'; import type { FormatFactory } from '../types'; import { LegendActionPopover } from './legend_action_popover'; +import { DatatablesWithFormatInfo } from '../helpers'; export const getLegendAction = ( dataLayers: CommonXYDataLayerConfig[], onFilter: (data: FilterEvent['data']) => void, formatFactory: FormatFactory, - layersAlreadyFormatted: Record> + formattedDatatables: DatatablesWithFormatInfo ): LegendAction => React.memo(({ series: [xySeries] }) => { const series = xySeries as XYChartSeriesIdentifier; @@ -42,7 +43,7 @@ export const getLegendAction = ( const formatter = formatFactory(splitColumn && splitColumn.meta?.params); const rowIndex = table.rows.findIndex((row) => { - if (layersAlreadyFormatted[layer.layerId]?.[accessor]) { + if (formattedDatatables[layer.layerId]?.formattedColumns[accessor]) { // stringify the value to compare with the chart value return formatter.convert(row[accessor]) === splitLabel; } @@ -67,7 +68,7 @@ export const getLegendAction = ( return ( { onClickValue, onSelectRange, syncColors: false, + syncTooltips: false, useLegacyTimeAxis: false, eventAnnotationService: eventAnnotationServiceMock, }; @@ -2525,31 +2532,36 @@ describe('XYChart component', () => { }); describe('annotations', () => { - const sampleStyledAnnotation: EventAnnotationOutput = { + const customLineStaticAnnotation: EventAnnotationOutput = { time: '2022-03-18T08:25:00.000Z', label: 'Event 1', icon: 'triangle', - type: 'manual_event_annotation', + type: 'manual_point_event_annotation' as const, color: 'red', lineStyle: 'dashed', lineWidth: 3, }; - const sampleAnnotationLayers: CommonXYAnnotationLayerConfig[] = [ - { - layerId: 'annotationLayer', - type: 'annotationLayer', - layerType: LayerTypes.ANNOTATIONS, - annotations: [ - { - time: '2022-03-18T08:25:17.140Z', - label: 'Annotation', - type: 'manual_event_annotation', - }, - ], - }, - ]; - function sampleArgsWithAnnotation(annotationLayers = sampleAnnotationLayers): XYChartProps { + const defaultLineStaticAnnotation = { + time: '2022-03-18T08:25:17.140Z', + label: 'Annotation', + type: 'manual_point_event_annotation' as const, + }; + const defaultRangeStaticAnnotation = { + time: '2022-03-18T08:25:17.140Z', + endTime: '2022-03-31T08:25:17.140Z', + label: 'Event range', + type: 'manual_range_event_annotation' as const, + }; + const createLayerWithAnnotations = ( + annotations: EventAnnotationOutput[] = [defaultLineStaticAnnotation] + ): CommonXYAnnotationLayerConfig => ({ + type: 'annotationLayer', + layerType: LayerTypes.ANNOTATIONS, + layerId: 'annotation', + annotations, + }); + function sampleArgsWithAnnotations(annotationLayers = [createLayerWithAnnotations()]) { const { args } = sampleArgs(); return { args: { @@ -2558,34 +2570,40 @@ describe('XYChart component', () => { }, }; } - test('should render basic annotation', () => { - const { args } = sampleArgsWithAnnotation(); + + test('should render basic line annotation', () => { + const { args } = sampleArgsWithAnnotations(); const component = mount(); expect(component.find('LineAnnotation')).toMatchSnapshot(); }); - test('should render simplified annotation when hide is true', () => { - const { args } = sampleArgsWithAnnotation(); - (args.layers[0] as CommonXYAnnotationLayerConfig).hide = true; + test('should render basic range annotation', () => { + const { args } = sampleArgsWithAnnotations([ + createLayerWithAnnotations([defaultLineStaticAnnotation, defaultRangeStaticAnnotation]), + ]); + const component = mount(); + expect(component.find(RectAnnotation)).toMatchSnapshot(); + }); + test('should render simplified annotations when hide is true', () => { + const { args } = sampleArgsWithAnnotations([ + createLayerWithAnnotations([defaultLineStaticAnnotation, defaultRangeStaticAnnotation]), + ]); + (args.layers[1] as CommonXYAnnotationLayerConfig).hide = true; const component = mount(); expect(component.find('LineAnnotation')).toMatchSnapshot(); + expect(component.find('RectAnnotation')).toMatchSnapshot(); }); - test('should render grouped annotations preserving the shared styles', () => { - const { args } = sampleArgsWithAnnotation([ - { - layerId: 'annotationLayer', - type: 'annotationLayer', - layerType: LayerTypes.ANNOTATIONS, - annotations: [ - sampleStyledAnnotation, - { ...sampleStyledAnnotation, time: '2022-03-18T08:25:00.020Z', label: 'Event 2' }, - { - ...sampleStyledAnnotation, - time: '2022-03-18T08:25:00.001Z', - label: 'Event 3', - }, - ], - }, + test('should render grouped line annotations preserving the shared styles', () => { + const { args } = sampleArgsWithAnnotations([ + createLayerWithAnnotations([ + customLineStaticAnnotation, + { ...customLineStaticAnnotation, time: '2022-03-18T08:25:00.020Z', label: 'Event 2' }, + { + ...customLineStaticAnnotation, + time: '2022-03-18T08:25:00.001Z', + label: 'Event 3', + }, + ]), ]); const component = mount(); const groupedAnnotation = component.find(LineAnnotation); @@ -2605,30 +2623,21 @@ describe('XYChart component', () => { ' Event 1 2022-03-18T08:25:00.000Z Event 3 2022-03-18T08:25:00.001Z Event 2 2022-03-18T08:25:00.020Z' ); }); - test('should render grouped annotations with default styles', () => { - const { args } = sampleArgsWithAnnotation([ - { - layerId: 'annotationLayer', - type: 'annotationLayer', - layerType: LayerTypes.ANNOTATIONS, - annotations: [sampleStyledAnnotation], - }, - { - layerId: 'annotationLayer2', - type: 'annotationLayer', - layerType: LayerTypes.ANNOTATIONS, - annotations: [ - { - ...sampleStyledAnnotation, - icon: 'asterisk', - color: 'blue', - lineStyle: 'dotted', - lineWidth: 10, - time: '2022-03-18T08:25:00.001Z', - label: 'Event 2', - }, - ], - }, + + test('should render grouped line annotations with default styles', () => { + const { args } = sampleArgsWithAnnotations([ + createLayerWithAnnotations([customLineStaticAnnotation]), + createLayerWithAnnotations([ + { + ...customLineStaticAnnotation, + icon: 'triangle' as const, + color: 'blue', + lineStyle: 'dotted', + lineWidth: 10, + time: '2022-03-18T08:25:00.001Z', + label: 'Event 2', + }, + ]), ]); const component = mount(); const groupedAnnotation = component.find(LineAnnotation); @@ -2638,27 +2647,26 @@ describe('XYChart component', () => { expect(groupedAnnotation).toMatchSnapshot(); }); test('should not render hidden annotations', () => { - const { args } = sampleArgsWithAnnotation([ - { - layerId: 'annotationLayer', - type: 'annotationLayer', - layerType: LayerTypes.ANNOTATIONS, - annotations: [ - sampleStyledAnnotation, - { ...sampleStyledAnnotation, time: '2022-03-18T08:30:00.020Z', label: 'Event 2' }, - { - ...sampleStyledAnnotation, - time: '2022-03-18T08:35:00.001Z', - label: 'Event 3', - isHidden: true, - }, - ], - }, + const { args } = sampleArgsWithAnnotations([ + createLayerWithAnnotations([ + customLineStaticAnnotation, + { ...customLineStaticAnnotation, time: '2022-03-18T08:30:00.020Z', label: 'Event 2' }, + { + ...customLineStaticAnnotation, + time: '2022-03-18T08:35:00.001Z', + label: 'Event 3', + isHidden: true, + }, + defaultRangeStaticAnnotation, + { ...defaultRangeStaticAnnotation, label: 'range', isHidden: true }, + ]), ]); const component = mount(); - const annotations = component.find(LineAnnotation); + const lineAnnotations = component.find(LineAnnotation); + const rectAnnotations = component.find(Annotations).find(RectAnnotation); - expect(annotations.length).toEqual(2); + expect(lineAnnotations.length).toEqual(2); + expect(rectAnnotations.length).toEqual(1); }); }); }); diff --git a/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.tsx b/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.tsx index 48bb0c6e498f0..088ae479a5b26 100644 --- a/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.tsx +++ b/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { useRef } from 'react'; +import React, { useMemo, useRef } from 'react'; import { Chart, Settings, @@ -24,6 +24,7 @@ import { DisplayValueStyle, RecursivePartial, AxisStyle, + Placement, } from '@elastic/charts'; import { IconType } from '@elastic/eui'; import { PaletteRegistry } from '@kbn/coloring'; @@ -39,7 +40,7 @@ import { getAnnotationsLayers, getDataLayers, Series, - getAreAlreadyFormattedLayersInfo, + getFormattedTablesByLayers, } from '../helpers'; import { getFilteredLayers, @@ -54,10 +55,15 @@ import { getLegendAction } from './legend_action'; import { ReferenceLineAnnotations, computeChartMargins } from './reference_lines'; import { visualizationDefinitions } from '../definitions'; import { CommonXYLayerConfig } from '../../common/types'; -import { Annotations, getAnnotationsGroupedByInterval } from './annotations'; -import { SeriesTypes, ValueLabelModes } from '../../common/constants'; +import { + Annotations, + getAnnotationsGroupedByInterval, + getRangeAnnotations, + OUTSIDE_RECT_ANNOTATION_WIDTH, + OUTSIDE_RECT_ANNOTATION_WIDTH_SUGGESTION, +} from './annotations'; +import { AxisExtentModes, SeriesTypes, ValueLabelModes } from '../../common/constants'; import { DataLayers } from './data_layers'; - import './xy_chart.scss'; declare global { @@ -82,6 +88,7 @@ export type XYChartRenderProps = XYChartProps & { onSelectRange: (data: BrushEvent['data']) => void; renderMode: RenderMode; syncColors: boolean; + syncTooltips: boolean; eventAnnotationService: EventAnnotationServiceType; }; @@ -124,6 +131,7 @@ export function XYChart({ onSelectRange, interactive = true, syncColors, + syncTooltips, useLegacyTimeAxis, }: XYChartRenderProps) { const { @@ -153,6 +161,12 @@ export function XYChart({ datatables: filteredLayers.map(({ table }) => table), }); + const dataLayers: CommonXYDataLayerConfig[] = filteredLayers.filter(isDataLayer); + const formattedDatatables = useMemo( + () => getFormattedTablesByLayers(dataLayers, formatFactory), + [dataLayers, formatFactory] + ); + if (filteredLayers.length === 0) { const icon: IconType = getIconForSeriesType( getDataLayers(layers)?.[0]?.seriesType || SeriesTypes.BAR @@ -160,17 +174,14 @@ export function XYChart({ return ; } - const dataLayers: CommonXYDataLayerConfig[] = filteredLayers.filter(isDataLayer); - // use formatting hint of first x axis column to format ticks const xAxisColumn = dataLayers[0]?.table.columns.find(({ id }) => id === dataLayers[0].xAccessor); const xAxisFormatter = formatFactory(xAxisColumn && xAxisColumn.meta?.params); - const areLayersAlreadyFormatted = getAreAlreadyFormattedLayersInfo(dataLayers, formatFactory); // This is a safe formatter for the xAccessor that abstracts the knowledge of already formatted layers const safeXAccessorLabelRenderer = (value: unknown): string => - xAxisColumn && areLayersAlreadyFormatted[dataLayers[0]?.layerId]?.[xAxisColumn.id] + xAxisColumn && formattedDatatables[dataLayers[0]?.layerId]?.formattedColumns[xAxisColumn.id] ? String(value) : String(xAxisFormatter.convert(value)); @@ -180,7 +191,7 @@ export function XYChart({ filteredLayers.some((layer) => isDataLayer(layer) && layer.splitAccessor); const shouldRotate = isHorizontalChart(dataLayers); - const yAxesConfiguration = getAxesConfiguration(filteredLayers, shouldRotate, formatFactory); + const yAxesConfiguration = getAxesConfiguration(dataLayers, shouldRotate, formatFactory); const xTitle = args.xTitle || (xAxisColumn && xAxisColumn.name); const axisTitlesVisibilitySettings = args.axisTitlesVisibilitySettings || { @@ -203,8 +214,8 @@ export function XYChart({ filteredBarLayers.some((layer) => layer.accessors.length > 1) || filteredBarLayers.some((layer) => isDataLayer(layer) && layer.splitAccessor); - const isTimeViz = Boolean(filteredLayers.every((l) => isDataLayer(l) && l.xScaleType === 'time')); - const isHistogramViz = filteredLayers.every((l) => isDataLayer(l) && l.isHistogram); + const isTimeViz = Boolean(dataLayers.every((l) => l.xScaleType === 'time')); + const isHistogramViz = dataLayers.every((l) => l.isHistogram); const { baseDomain: rawXDomain, extendedDomain: xDomain } = getXDomain( dataLayers, @@ -239,18 +250,21 @@ export function XYChart({ const xColumnId = firstTable.columns.find((col) => col.id === dataLayers[0]?.xAccessor)?.id; - const groupedAnnotations = getAnnotationsGroupedByInterval( + const groupedLineAnnotations = getAnnotationsGroupedByInterval( annotationsLayers, minInterval, xColumnId ? firstTable.rows[0]?.[xColumnId] : undefined, xAxisFormatter ); + const rangeAnnotations = getRangeAnnotations(annotationsLayers); + const visualConfigs = [ ...referenceLineLayers.flatMap(({ yConfig }) => yConfig), - ...groupedAnnotations, + ...groupedLineAnnotations, ].filter(Boolean); - const linesPaddings = getLinesCausedPaddings(visualConfigs, yAxesMap); + const shouldHideDetails = annotationsLayers.length > 0 ? annotationsLayers[0].hide : false; + const linesPaddings = !shouldHideDetails ? getLinesCausedPaddings(visualConfigs, yAxesMap) : {}; const getYAxesStyle = (groupId: 'left' | 'right') => { const tickVisible = @@ -301,7 +315,9 @@ export function XYChart({ return layer.seriesType.includes('bar') || layer.seriesType.includes('area'); }) ); - const fit = !hasBarOrArea && extent.mode === 'dataBounds'; + + const fit = !hasBarOrArea && extent.mode === AxisExtentModes.DATA_BOUNDS; + let min: number = NaN; let max: number = NaN; if (extent.mode === 'custom') { @@ -354,13 +370,15 @@ export function XYChart({ const xColumn = table.columns.find((col) => col.id === layer.xAccessor); const currentXFormatter = - layer.xAccessor && areLayersAlreadyFormatted[layer.layerId]?.[layer.xAccessor] && xColumn + layer.xAccessor && + formattedDatatables[layer.layerId]?.formattedColumns[layer.xAccessor] && + xColumn ? formatFactory(xColumn.meta.params) : xAxisFormatter; const rowIndex = table.rows.findIndex((row) => { if (layer.xAccessor) { - if (areLayersAlreadyFormatted[layer.layerId]?.[layer.xAccessor]) { + if (formattedDatatables[layer.layerId]?.formattedColumns[layer.xAccessor]) { // stringify the value to compare with the chart value return currentXFormatter.convert(row[layer.xAccessor]) === xyGeometry.x; } @@ -385,7 +403,7 @@ export function XYChart({ points.push({ row: table.rows.findIndex((row) => { if (layer.splitAccessor) { - if (areLayersAlreadyFormatted[layer.layerId]?.[layer.splitAccessor]) { + if (formattedDatatables[layer.layerId]?.formattedColumns[layer.splitAccessor]) { return splitFormatter.convert(row[layer.splitAccessor]) === pointValue; } return row[layer.splitAccessor] === pointValue; @@ -418,13 +436,13 @@ export function XYChart({ onSelectRange(context); }; - const legendInsideParams = { + const legendInsideParams: LegendPositionConfig = { vAlign: legend.verticalAlignment ?? VerticalAlignment.Top, hAlign: legend?.horizontalAlignment ?? HorizontalAlignment.Right, direction: LayoutDirection.Vertical, floating: true, floatingColumns: legend?.floatingColumns ?? 1, - } as LegendPositionConfig; + }; const isHistogramModeEnabled = dataLayers.some( ({ isHistogram, seriesType }) => @@ -474,6 +492,9 @@ export function XYChart({ axis.formatter?.convert(d) || ''} - style={getYAxesStyle(axis.groupId as 'left' | 'right')} + style={getYAxesStyle(axis.groupId)} domain={getYAxisDomain(axis)} ticks={5} /> @@ -592,7 +613,7 @@ export function XYChart({ emphasizeFitting={emphasizeFitting} yAxesConfiguration={yAxesConfiguration} shouldShowValueLabels={shouldShowValueLabels} - areLayersAlreadyFormatted={areLayersAlreadyFormatted} + formattedDatatables={formattedDatatables} chartHasMoreThanOneBarSeries={chartHasMoreThanOneBarSeries} /> )} @@ -612,15 +633,24 @@ export function XYChart({ paddingMap={linesPaddings} /> ) : null} - {groupedAnnotations.length ? ( + {rangeAnnotations.length || groupedLineAnnotations.length ? ( 0} minInterval={minInterval} + hide={annotationsLayers?.[0].hide} + outsideDimension={ + rangeAnnotations.length && shouldHideDetails + ? OUTSIDE_RECT_ANNOTATION_WIDTH_SUGGESTION + : shouldUseNewTimeAxis + ? Number(MULTILAYER_TIME_AXIS_STYLE.tickLine?.padding || 0) + + Number(chartTheme.axes?.tickLabel?.fontSize || 0) + : Number(chartTheme.axes?.tickLine?.size) || OUTSIDE_RECT_ANNOTATION_WIDTH + } /> ) : null} diff --git a/src/plugins/chart_expressions/expression_xy/public/expression_renderers/xy_chart_renderer.tsx b/src/plugins/chart_expressions/expression_xy/public/expression_renderers/xy_chart_renderer.tsx index a35216821c077..c6ad977bbad3a 100644 --- a/src/plugins/chart_expressions/expression_xy/public/expression_renderers/xy_chart_renderer.tsx +++ b/src/plugins/chart_expressions/expression_xy/public/expression_renderers/xy_chart_renderer.tsx @@ -18,7 +18,6 @@ import { ExpressionRenderDefinition } from '@kbn/expressions-plugin'; import { FormatFactory } from '@kbn/field-formats-plugin/common'; import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import type { XYChartProps } from '../../common'; -import { calculateMinInterval } from '../helpers/interval'; import type { BrushEvent, FilterEvent } from '../types'; export type GetStartDepsFn = () => Promise<{ @@ -56,7 +55,10 @@ export const getXyChartRenderer = ({ }; const deps = await getStartDeps(); - const { XYChartReportable } = await import('../components/xy_chart'); + const [{ XYChartReportable }, { calculateMinInterval }] = await Promise.all([ + import('../components/xy_chart'), + import('../helpers/interval'), + ]); ReactDOM.render( @@ -80,6 +82,7 @@ export const getXyChartRenderer = ({ onSelectRange={onSelectRange} renderMode={handlers.getRenderMode()} syncColors={handlers.isSyncColorsEnabled()} + syncTooltips={handlers.isSyncTooltipsEnabled()} /> {' '} diff --git a/src/plugins/chart_expressions/expression_xy/public/helpers/axes_configuration.ts b/src/plugins/chart_expressions/expression_xy/public/helpers/axes_configuration.ts index ea1b7d09709d6..a3120faf9d120 100644 --- a/src/plugins/chart_expressions/expression_xy/public/helpers/axes_configuration.ts +++ b/src/plugins/chart_expressions/expression_xy/public/helpers/axes_configuration.ts @@ -8,12 +8,7 @@ import type { IFieldFormat, SerializedFieldFormat } from '@kbn/field-formats-plugin/common'; import { FormatFactory } from '../types'; -import { - CommonXYDataLayerConfig, - CommonXYReferenceLineLayerConfig, - ExtendedYConfig, - YConfig, -} from '../../common'; +import { CommonXYDataLayerConfig, ExtendedYConfig, YConfig } from '../../common'; import { isDataLayer } from './visualization'; export interface Series { @@ -39,9 +34,7 @@ export function isFormatterCompatible( return formatter1.id === formatter2.id; } -export function groupAxesByType( - layers: Array -) { +export function groupAxesByType(layers: CommonXYDataLayerConfig[]) { const series: { auto: FormattedMetric[]; left: FormattedMetric[]; @@ -111,7 +104,7 @@ export function groupAxesByType( } export function getAxesConfiguration( - layers: Array, + layers: CommonXYDataLayerConfig[], shouldRotate: boolean, formatFactory?: FormatFactory ): GroupsConfiguration { diff --git a/src/plugins/chart_expressions/expression_xy/public/helpers/data_layers.tsx b/src/plugins/chart_expressions/expression_xy/public/helpers/data_layers.tsx index 35197a5175a0d..fe9abe27ee0a4 100644 --- a/src/plugins/chart_expressions/expression_xy/public/helpers/data_layers.tsx +++ b/src/plugins/chart_expressions/expression_xy/public/helpers/data_layers.tsx @@ -21,9 +21,10 @@ import { i18n } from '@kbn/i18n'; import { FieldFormat, FieldFormatParams, + IFieldFormat, SerializedFieldFormat, } from '@kbn/field-formats-plugin/common'; -import { Datatable, DatatableRow } from '@kbn/expressions-plugin'; +import { Datatable } from '@kbn/expressions-plugin'; import { PaletteRegistry, SeriesLayer } from '@kbn/coloring'; import { CommonXYDataLayerConfig, XScaleType } from '../../common'; import { FormatFactory } from '../types'; @@ -41,12 +42,12 @@ type GetSeriesPropsFn = (config: { colorAssignments: ColorAssignments; columnToLabelMap: Record; paletteService: PaletteRegistry; - alreadyFormattedColumns: Record; syncColors?: boolean; yAxis?: GroupsConfiguration[number]; timeZone?: string; emphasizeFitting?: boolean; fillOpacity?: number; + formattedDatatableInfo: DatatableWithFormatInfo; }) => SeriesSpec; type GetSeriesNameFn = ( @@ -80,58 +81,90 @@ type GetLineConfigFn = (config: { pointsRadius?: number; }) => Partial; +export interface DatatableWithFormatInfo { + table: Datatable; + formattedColumns: Record; +} + +export type DatatablesWithFormatInfo = Record; + +export type FormattedDatatables = Record; + const isPrimitive = (value: unknown): boolean => value != null && typeof value !== 'object'; -export const getFormattedTable = ( - table: Datatable, - formatFactory: FormatFactory, +export const getFormattedRow = ( + row: Datatable['rows'][number], + columns: Datatable['columns'], + columnsFormatters: Record, xAccessor: string | undefined, xScaleType: XScaleType -): Datatable => ({ - ...table, - rows: table.rows.map((row: DatatableRow) => { - const newRow = { ...row }; - for (const column of table.columns) { - const record = newRow[column.id]; +): { row: Datatable['rows'][number]; formattedColumns: Record } => + columns.reduce( + (formattedInfo, { id }) => { + const record = formattedInfo.row[id]; if ( record != null && // pre-format values for ordinal x axes because there can only be a single x axis formatter on chart level - (!isPrimitive(record) || (column.id === xAccessor && xScaleType === 'ordinal')) + (!isPrimitive(record) || (id === xAccessor && xScaleType === 'ordinal')) ) { - newRow[column.id] = formatFactory(column.meta.params)!.convert(record); + return { + row: { ...formattedInfo.row, [id]: columnsFormatters[id]!.convert(record) }, + formattedColumns: { ...formattedInfo.formattedColumns, [id]: true }, + }; } - } - return newRow; - }), -}); + return formattedInfo; + }, + { row, formattedColumns: {} } + ); -export const getIsAlreadyFormattedLayerInfo = ( - { table, xAccessor, xScaleType }: CommonXYDataLayerConfig, - formatFactory: FormatFactory -): Record => { - const formattedTable = getFormattedTable(table, formatFactory, xAccessor, xScaleType); - return table.columns.reduce>( - (alreadyFormatted: Record, { id }) => { - if (alreadyFormatted[id]) { - return alreadyFormatted; - } +export const getFormattedTable = ( + table: Datatable, + formatFactory: FormatFactory, + xAccessor: string | undefined, + xScaleType: XScaleType +): { table: Datatable; formattedColumns: Record } => { + const columnsFormatters = table.columns.reduce>( + (formatters, { id, meta }) => ({ ...formatters, [id]: formatFactory(meta.params) }), + {} + ); + + const formattedTableInfo = table.rows.reduce<{ + rows: Datatable['rows']; + formattedColumns: Record; + }>( + ({ rows: formattedRows, formattedColumns }, row) => { + const formattedRowInfo = getFormattedRow( + row, + table.columns, + columnsFormatters, + xAccessor, + xScaleType + ); return { - ...alreadyFormatted, - [id]: table.rows.some((row, i) => row[id] !== formattedTable.rows[i][id]), + rows: [...formattedRows, formattedRowInfo.row], + formattedColumns: { ...formattedColumns, ...formattedRowInfo.formattedColumns }, }; }, - {} + { + rows: [], + formattedColumns: {}, + } ); + + return { + table: { ...table, rows: formattedTableInfo.rows }, + formattedColumns: formattedTableInfo.formattedColumns, + }; }; -export const getAreAlreadyFormattedLayersInfo = ( +export const getFormattedTablesByLayers = ( layers: CommonXYDataLayerConfig[], formatFactory: FormatFactory -): Record> => - layers.reduce>>( - (areAlreadyFormatted, layer) => ({ - ...areAlreadyFormatted, - [layer.layerId]: getIsAlreadyFormattedLayerInfo(layer, formatFactory), +): DatatablesWithFormatInfo => + layers.reduce( + (formattedDatatables, { layerId, table, xAccessor, xScaleType }) => ({ + ...formattedDatatables, + [layerId]: getFormattedTable(table, formatFactory, xAccessor, xScaleType), }), {} ); @@ -227,12 +260,12 @@ export const getSeriesProps: GetSeriesPropsFn = ({ formatFactory, columnToLabelMap, paletteService, - alreadyFormattedColumns, syncColors, yAxis, timeZone, emphasizeFitting, fillOpacity, + formattedDatatableInfo, }): SeriesSpec => { const { table, markSizeAccessor } = layer; const isStacked = layer.seriesType.includes('stacked'); @@ -253,16 +286,11 @@ export const getSeriesProps: GetSeriesPropsFn = ({ // what if row values are not primitive? That is the case of, for instance, Ranges // remaps them to their serialized version with the formatHint metadata // In order to do it we need to make a copy of the table as the raw one is required for more features (filters, etc...) later on - const formattedTable: Datatable = getFormattedTable( - table, - formatFactory, - layer.xAccessor, - layer.xScaleType - ); + const { table: formattedTable, formattedColumns } = formattedDatatableInfo; // For date histogram chart type, we're getting the rows that represent intervals without data. // To not display them in the legend, they need to be filtered out. - const rows = formattedTable.rows.filter( + let rows = formattedTable.rows.filter( (row) => !(layer.xAccessor && typeof row[layer.xAccessor] === 'undefined') && !( @@ -273,11 +301,12 @@ export const getSeriesProps: GetSeriesPropsFn = ({ ); if (!layer.xAccessor) { - rows.forEach((row) => { - row.unifiedX = i18n.translate('expressionXY.xyChart.emptyXLabel', { + rows = rows.map((row) => ({ + ...row, + unifiedX: i18n.translate('expressionXY.xyChart.emptyXLabel', { defaultMessage: '(empty)', - }); - }); + }), + })); } return { @@ -337,7 +366,7 @@ export const getSeriesProps: GetSeriesPropsFn = ({ layer, splitHint, splitFormatter, - alreadyFormattedColumns, + alreadyFormattedColumns: formattedColumns, columnToLabelMap, }); }, diff --git a/src/plugins/console/common/constants/api.ts b/src/plugins/console/common/constants/api.ts index aa0fad1fe4424..3c5aa11519350 100644 --- a/src/plugins/console/common/constants/api.ts +++ b/src/plugins/console/common/constants/api.ts @@ -7,3 +7,4 @@ */ export const API_BASE_PATH = '/api/console'; +export const KIBANA_API_PREFIX = 'kbn:'; diff --git a/src/plugins/console/common/constants/index.ts b/src/plugins/console/common/constants/index.ts index d8768af8fc8d8..756a79883cbdb 100644 --- a/src/plugins/console/common/constants/index.ts +++ b/src/plugins/console/common/constants/index.ts @@ -7,4 +7,4 @@ */ export { MAJOR_VERSION } from './plugin'; -export { API_BASE_PATH } from './api'; +export { API_BASE_PATH, KIBANA_API_PREFIX } from './api'; diff --git a/src/plugins/console/public/application/containers/console_history/history_viewer.tsx b/src/plugins/console/public/application/containers/console_history/history_viewer.tsx index 605f9a254f228..11f4b0a99a993 100644 --- a/src/plugins/console/public/application/containers/console_history/history_viewer.tsx +++ b/src/plugins/console/public/application/containers/console_history/history_viewer.tsx @@ -17,6 +17,7 @@ import * as InputMode from '../../models/legacy_core_editor/mode/input'; const inputMode = new InputMode.Mode(); import * as editor from '../../models/legacy_core_editor'; import { applyCurrentSettings } from '../editor/legacy/console_editor/apply_editor_settings'; +import { formatRequestBodyDoc } from '../../../lib/utils'; interface Props { settings: DevToolsSettings; @@ -41,7 +42,9 @@ export function HistoryViewer({ settings, req }: Props) { if (viewerRef.current) { const { current: viewer } = viewerRef; if (req) { - const s = req.method + ' ' + req.endpoint + '\n' + (req.data || ''); + const indent = true; + const formattedData = req.data ? formatRequestBodyDoc([req.data], indent).data : ''; + const s = req.method + ' ' + req.endpoint + '\n' + formattedData; viewer.update(s, inputMode); viewer.clearSelection(); } else { diff --git a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.test.mock.tsx b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.test.mock.tsx index dfed86a643627..b410e240151d7 100644 --- a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.test.mock.tsx +++ b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.test.mock.tsx @@ -39,8 +39,8 @@ jest.mock('../../../../models/sense_editor', () => { }; }); -jest.mock('../../../../hooks/use_send_current_request_to_es/send_request_to_es', () => ({ - sendRequestToES: jest.fn(), +jest.mock('../../../../hooks/use_send_current_request/send_request', () => ({ + sendRequest: jest.fn(), })); jest.mock('../../../../../lib/autocomplete/get_endpoint_from_position', () => ({ getEndpointFromPosition: jest.fn(), diff --git a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.test.tsx b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.test.tsx index b942a6d830217..ba5f1e78d5f01 100644 --- a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.test.tsx +++ b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.test.tsx @@ -25,7 +25,7 @@ import { } from '../../../../contexts'; // Mocked functions -import { sendRequestToES } from '../../../../hooks/use_send_current_request_to_es/send_request_to_es'; +import { sendRequest } from '../../../../hooks/use_send_current_request/send_request'; import { getEndpointFromPosition } from '../../../../../lib/autocomplete/get_endpoint_from_position'; import type { DevToolsSettings } from '../../../../../services'; import * as consoleMenuActions from '../console_menu_actions'; @@ -58,15 +58,15 @@ describe('Legacy (Ace) Console Editor Component Smoke Test', () => { sandbox.restore(); }); - it('calls send current request to ES', async () => { + it('calls send current request', async () => { (getEndpointFromPosition as jest.Mock).mockReturnValue({ patterns: [] }); - (sendRequestToES as jest.Mock).mockRejectedValue({}); + (sendRequest as jest.Mock).mockRejectedValue({}); const editor = doMount(); act(() => { editor.find('button[data-test-subj~="sendRequestButton"]').simulate('click'); }); await nextTick(); - expect(sendRequestToES).toBeCalledTimes(1); + expect(sendRequest).toBeCalledTimes(1); }); it('opens docs', () => { diff --git a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx index bafe9ee6ca156..d01a40bdd44b3 100644 --- a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx +++ b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx @@ -26,7 +26,7 @@ import { ConsoleMenu } from '../../../../components'; import { useEditorReadContext, useServicesContext } from '../../../../contexts'; import { useSaveCurrentTextObject, - useSendCurrentRequestToES, + useSendCurrentRequest, useSetInputEditor, } from '../../../../hooks'; import * as senseEditor from '../../../../models/sense_editor'; @@ -72,7 +72,7 @@ function EditorUI({ initialTextValue, setEditorInstance }: EditorProps) { const { settings } = useEditorReadContext(); const setInputEditor = useSetInputEditor(); - const sendCurrentRequestToES = useSendCurrentRequestToES(); + const sendCurrentRequest = useSendCurrentRequest(); const saveCurrentTextObject = useSaveCurrentTextObject(); const editorRef = useRef(null); @@ -231,11 +231,11 @@ function EditorUI({ initialTextValue, setEditorInstance }: EditorProps) { if (!isKeyboardShortcutsDisabled) { registerCommands({ senseEditor: editorInstanceRef.current!, - sendCurrentRequestToES, + sendCurrentRequest, openDocumentation, }); } - }, [sendCurrentRequestToES, openDocumentation, settings]); + }, [openDocumentation, settings, sendCurrentRequest]); useEffect(() => { const { current: editor } = editorInstanceRef; @@ -262,7 +262,7 @@ function EditorUI({ initialTextValue, setEditorInstance }: EditorProps) { > void; + sendCurrentRequest: () => void; openDocumentation: () => void; } @@ -24,11 +24,7 @@ const COMMANDS = { GO_TO_LINE: 'gotoline', }; -export function registerCommands({ - senseEditor, - sendCurrentRequestToES, - openDocumentation, -}: Actions) { +export function registerCommands({ senseEditor, sendCurrentRequest, openDocumentation }: Actions) { const throttledAutoIndent = throttle(() => senseEditor.autoIndent(), 500, { leading: true, trailing: true, @@ -39,7 +35,7 @@ export function registerCommands({ keys: { win: 'Ctrl-Enter', mac: 'Command-Enter' }, name: COMMANDS.SEND_TO_ELASTICSEARCH, fn: () => { - sendCurrentRequestToES(); + sendCurrentRequest(); }, }); diff --git a/src/plugins/console/public/application/hooks/index.ts b/src/plugins/console/public/application/hooks/index.ts index 1a9b4e5c472bf..1996330bef66b 100644 --- a/src/plugins/console/public/application/hooks/index.ts +++ b/src/plugins/console/public/application/hooks/index.ts @@ -8,6 +8,6 @@ export { useSetInputEditor } from './use_set_input_editor'; export { useRestoreRequestFromHistory } from './use_restore_request_from_history'; -export { useSendCurrentRequestToES } from './use_send_current_request_to_es'; +export { useSendCurrentRequest } from './use_send_current_request'; export { useSaveCurrentTextObject } from './use_save_current_text_object'; export { useDataInit } from './use_data_init'; diff --git a/src/plugins/console/public/application/hooks/use_restore_request_from_history/restore_request_from_history.ts b/src/plugins/console/public/application/hooks/use_restore_request_from_history/restore_request_from_history.ts index 85c9cf6b9f014..ca8a118e767b6 100644 --- a/src/plugins/console/public/application/hooks/use_restore_request_from_history/restore_request_from_history.ts +++ b/src/plugins/console/public/application/hooks/use_restore_request_from_history/restore_request_from_history.ts @@ -9,6 +9,7 @@ import RowParser from '../../../lib/row_parser'; import { ESRequest } from '../../../types'; import { SenseEditor } from '../../models/sense_editor'; +import { formatRequestBodyDoc } from '../../../lib/utils'; export function restoreRequestFromHistory(editor: SenseEditor, req: ESRequest) { const coreEditor = editor.getCoreEditor(); @@ -32,7 +33,9 @@ export function restoreRequestFromHistory(editor: SenseEditor, req: ESRequest) { let s = prefix + req.method + ' ' + req.endpoint; if (req.data) { - s += '\n' + req.data; + const indent = true; + const formattedData = formatRequestBodyDoc([req.data], indent); + s += '\n' + formattedData.data; } s += suffix; diff --git a/src/plugins/console/public/application/hooks/use_send_current_request/index.ts b/src/plugins/console/public/application/hooks/use_send_current_request/index.ts new file mode 100644 index 0000000000000..33bdbef87f2ef --- /dev/null +++ b/src/plugins/console/public/application/hooks/use_send_current_request/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { useSendCurrentRequest } from './use_send_current_request'; diff --git a/src/plugins/console/public/application/hooks/use_send_current_request/send_request.test.ts b/src/plugins/console/public/application/hooks/use_send_current_request/send_request.test.ts new file mode 100644 index 0000000000000..841633cded51e --- /dev/null +++ b/src/plugins/console/public/application/hooks/use_send_current_request/send_request.test.ts @@ -0,0 +1,143 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { ContextValue } from '../../contexts'; + +jest.mock('./send_request', () => ({ sendRequest: jest.fn(() => Promise.resolve()) })); + +import { sendRequest } from './send_request'; +import { serviceContextMock } from '../../contexts/services_context.mock'; + +const mockedSendRequest = sendRequest as jest.Mock; + +describe('sendRequest', () => { + let mockContextValue: ContextValue; + + beforeEach(() => { + mockContextValue = serviceContextMock.create(); + }); + + afterEach(() => { + jest.resetAllMocks(); + }); + + it('should send request', async () => { + mockedSendRequest.mockResolvedValue([ + { + response: { + statusCode: 200, + value: '{\n "acknowledged": true \n}', + }, + }, + ]); + + const args = { + http: mockContextValue.services.http, + requests: [{ method: 'PUT', url: 'test', data: [] }], + }; + const results = await sendRequest(args); + + const [request] = results; + expect(request.response.statusCode).toEqual(200); + expect(request.response.value).toContain('"acknowledged": true'); + expect(mockedSendRequest).toHaveBeenCalledWith(args); + expect(mockedSendRequest).toHaveBeenCalledTimes(1); + }); + + describe('with multiple requests', () => { + it('should return results with exceptions', async () => { + mockedSendRequest.mockResolvedValue([ + { + response: { + statusCode: 200, + }, + }, + { + response: { + statusCode: 200, + }, + }, + { + response: { + statusCode: 400, + }, + }, + ]); + + const args = { + http: mockContextValue.services.http, + requests: [ + { method: 'GET', url: 'success', data: [] }, + { method: 'GET', url: 'success', data: [] }, + { method: 'GET', url: 'fail', data: [] }, + ], + }; + const results = await sendRequest(args); + + const [firstCall, secondCall, thirdCall] = results; + expect(firstCall.response.statusCode).toEqual(200); + expect(secondCall.response.statusCode).toEqual(200); + expect(thirdCall.response.statusCode).toEqual(400); + expect(mockedSendRequest).toHaveBeenCalledWith(args); + expect(mockedSendRequest).toHaveBeenCalledTimes(1); + }); + }); + + it('should handle errors', async () => { + mockedSendRequest.mockRejectedValue({ + response: { + statusCode: 500, + statusText: 'error', + }, + }); + + try { + await sendRequest({ + http: mockContextValue.services.http, + requests: [{ method: 'GET', url: 'test', data: [] }], + }); + } catch (error) { + expect(error.response.statusCode).toEqual(500); + expect(error.response.statusText).toEqual('error'); + expect(mockedSendRequest).toHaveBeenCalledTimes(1); + } + }); + + describe('successful response value', () => { + describe('with text', () => { + it('should return value with lines separated', async () => { + mockedSendRequest.mockResolvedValue('\ntest_index-1 []\ntest_index-2 []\n'); + const response = await sendRequest({ + http: mockContextValue.services.http, + requests: [{ method: 'GET', url: 'test-1', data: [] }], + }); + + expect(response).toMatchInlineSnapshot(` + " + test_index-1 [] + test_index-2 [] + " + `); + expect(mockedSendRequest).toHaveBeenCalledTimes(1); + }); + }); + + describe('with parsed json', () => { + it('should stringify value', async () => { + mockedSendRequest.mockResolvedValue(JSON.stringify({ test: 'some value' })); + const response = await sendRequest({ + http: mockContextValue.services.http, + requests: [{ method: 'GET', url: 'test-2', data: [] }], + }); + + expect(typeof response).toBe('string'); + expect(mockedSendRequest).toHaveBeenCalledTimes(1); + }); + }); + }); +}); diff --git a/src/plugins/console/public/application/hooks/use_send_current_request/send_request.ts b/src/plugins/console/public/application/hooks/use_send_current_request/send_request.ts new file mode 100644 index 0000000000000..1ac47df30fca5 --- /dev/null +++ b/src/plugins/console/public/application/hooks/use_send_current_request/send_request.ts @@ -0,0 +1,175 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { HttpSetup, IHttpFetchError } from '@kbn/core/public'; +import { XJson } from '@kbn/es-ui-shared-plugin/public'; +import { extractWarningMessages } from '../../../lib/utils'; +// @ts-ignore +import * as es from '../../../lib/es/es'; +import { BaseResponseType } from '../../../types'; + +const { collapseLiteralStrings } = XJson; + +export interface RequestArgs { + http: HttpSetup; + requests: Array<{ url: string; method: string; data: string[] }>; +} + +export interface ResponseObject { + statusCode: number; + statusText: string; + timeMs: number; + contentType: BaseResponseType; + value: V; +} + +export interface RequestResult { + request: { data: string; method: string; path: string }; + response: ResponseObject; +} + +const getContentType = (response: Response | undefined) => + (response?.headers.get('Content-Type') as BaseResponseType) ?? ''; + +let CURRENT_REQ_ID = 0; +export function sendRequest(args: RequestArgs): Promise { + const requests = args.requests.slice(); + return new Promise((resolve, reject) => { + const reqId = ++CURRENT_REQ_ID; + const results: RequestResult[] = []; + if (reqId !== CURRENT_REQ_ID) { + return; + } + + if (requests.length === 0) { + return; + } + + const isMultiRequest = requests.length > 1; + + const sendNextRequest = async () => { + if (reqId !== CURRENT_REQ_ID) { + resolve(results); + return; + } + if (requests.length === 0) { + resolve(results); + return; + } + const req = requests.shift()!; + const path = req.url; + const method = req.method; + let data = collapseLiteralStrings(req.data.join('\n')); + if (data) { + data += '\n'; + } // append a new line for bulk requests. + + const startTime = Date.now(); + + try { + const { response, body } = await es.send({ + http: args.http, + method, + path, + data, + asResponse: true, + }); + + if (reqId !== CURRENT_REQ_ID) { + // Skip if previous request is not resolved yet. This can happen when issuing multiple requests at the same time and with slow networks + return; + } + + if (response) { + const isSuccess = + // Things like DELETE index where the index is not there are OK. + (response.status >= 200 && response.status < 300) || response.status === 404; + + if (isSuccess) { + let value; + // check if object is ArrayBuffer + if (body instanceof ArrayBuffer) { + value = body; + } else { + value = typeof body === 'string' ? body : JSON.stringify(body, null, 2); + } + + const warnings = response.headers.get('warning'); + if (warnings) { + const warningMessages = extractWarningMessages(warnings); + value = warningMessages.join('\n') + '\n' + value; + } + + if (isMultiRequest) { + value = '# ' + req.method + ' ' + req.url + '\n' + value; + } + + results.push({ + response: { + timeMs: Date.now() - startTime, + statusCode: response.status, + statusText: response.statusText, + contentType: getContentType(response), + value, + }, + request: { + data, + method, + path, + }, + }); + + // single request terminate via sendNextRequest as well + await sendNextRequest(); + } + } + } catch (error) { + let value; + const { response, body } = error as IHttpFetchError; + const statusCode = response?.status ?? 500; + const statusText = response?.statusText ?? 'error'; + + if (body) { + value = JSON.stringify(body, null, 2); + } else { + value = 'Request failed to get to the server (status code: ' + statusCode + ')'; + } + + if (isMultiRequest) { + value = '# ' + req.method + ' ' + req.url + '\n' + value; + } + + const result = { + response: { + value, + contentType: getContentType(response), + timeMs: Date.now() - startTime, + statusCode, + statusText, + }, + request: { + data, + method, + path, + }, + }; + + // Reject on unknown errors + if (!response) { + reject(result); + } + + // Add error to the list of results + results.push(result); + await sendNextRequest(); + } + }; + + sendNextRequest(); + }); +} diff --git a/src/plugins/console/public/application/hooks/use_send_current_request_to_es/track.ts b/src/plugins/console/public/application/hooks/use_send_current_request/track.ts similarity index 100% rename from src/plugins/console/public/application/hooks/use_send_current_request_to_es/track.ts rename to src/plugins/console/public/application/hooks/use_send_current_request/track.ts diff --git a/src/plugins/console/public/application/hooks/use_send_current_request/use_send_current_request.test.tsx b/src/plugins/console/public/application/hooks/use_send_current_request/use_send_current_request.test.tsx new file mode 100644 index 0000000000000..d16dc3f832d3a --- /dev/null +++ b/src/plugins/console/public/application/hooks/use_send_current_request/use_send_current_request.test.tsx @@ -0,0 +1,124 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +jest.mock('./send_request', () => ({ sendRequest: jest.fn() })); +jest.mock('../../contexts/editor_context/editor_registry', () => ({ + instance: { getInputEditor: jest.fn() }, +})); +jest.mock('./track', () => ({ track: jest.fn() })); +jest.mock('../../contexts/request_context', () => ({ useRequestActionContext: jest.fn() })); + +import React from 'react'; +import { renderHook, act } from '@testing-library/react-hooks'; + +import { ContextValue, ServicesContextProvider } from '../../contexts'; +import { serviceContextMock } from '../../contexts/services_context.mock'; +import { useRequestActionContext } from '../../contexts/request_context'; +import { instance as editorRegistry } from '../../contexts/editor_context/editor_registry'; + +import { sendRequest } from './send_request'; +import { useSendCurrentRequest } from './use_send_current_request'; + +describe('useSendCurrentRequest', () => { + let mockContextValue: ContextValue; + let dispatch: (...args: unknown[]) => void; + const contexts = ({ children }: { children: JSX.Element }) => ( + {children} + ); + + beforeEach(() => { + mockContextValue = serviceContextMock.create(); + dispatch = jest.fn(); + (useRequestActionContext as jest.Mock).mockReturnValue(dispatch); + }); + + afterEach(() => { + jest.resetAllMocks(); + }); + + it('calls send request', async () => { + // Set up mocks + (mockContextValue.services.settings.toJSON as jest.Mock).mockReturnValue({}); + // This request should succeed + (sendRequest as jest.Mock).mockResolvedValue([]); + (editorRegistry.getInputEditor as jest.Mock).mockImplementation(() => ({ + getRequestsInRange: () => ['test'], + })); + + const { result } = renderHook(() => useSendCurrentRequest(), { wrapper: contexts }); + await act(() => result.current()); + expect(sendRequest).toHaveBeenCalledWith({ + http: mockContextValue.services.http, + requests: ['test'], + }); + + // Second call should be the request success + const [, [requestSucceededCall]] = (dispatch as jest.Mock).mock.calls; + expect(requestSucceededCall).toEqual({ type: 'requestSuccess', payload: { data: [] } }); + }); + + it('handles known errors', async () => { + // Set up mocks + (sendRequest as jest.Mock).mockRejectedValue({ response: 'nada' }); + (editorRegistry.getInputEditor as jest.Mock).mockImplementation(() => ({ + getRequestsInRange: () => ['test'], + })); + + const { result } = renderHook(() => useSendCurrentRequest(), { wrapper: contexts }); + await act(() => result.current()); + // Second call should be the request failure + const [, [requestFailedCall]] = (dispatch as jest.Mock).mock.calls; + + // The request must have concluded + expect(requestFailedCall).toEqual({ type: 'requestFail', payload: { response: 'nada' } }); + }); + + it('handles unknown errors', async () => { + // Set up mocks + (sendRequest as jest.Mock).mockRejectedValue(NaN /* unexpected error value */); + (editorRegistry.getInputEditor as jest.Mock).mockImplementation(() => ({ + getRequestsInRange: () => ['test'], + })); + + const { result } = renderHook(() => useSendCurrentRequest(), { wrapper: contexts }); + await act(() => result.current()); + // Second call should be the request failure + const [, [requestFailedCall]] = (dispatch as jest.Mock).mock.calls; + + // The request must have concluded + expect(requestFailedCall).toEqual({ type: 'requestFail', payload: undefined }); + // It also notified the user + expect(mockContextValue.services.notifications.toasts.addError).toHaveBeenCalledWith(NaN, { + title: 'Unknown Request Error', + }); + }); + + it('notifies the user about save to history errors once only', async () => { + // Set up mocks + (sendRequest as jest.Mock).mockReturnValue( + [{ request: {} }, { request: {} }] /* two responses to save history */ + ); + (mockContextValue.services.settings.toJSON as jest.Mock).mockReturnValue({}); + (mockContextValue.services.history.addToHistory as jest.Mock).mockImplementation(() => { + // Mock throwing + throw new Error('cannot save!'); + }); + (editorRegistry.getInputEditor as jest.Mock).mockImplementation(() => ({ + getRequestsInRange: () => ['test', 'test'], + })); + + const { result } = renderHook(() => useSendCurrentRequest(), { wrapper: contexts }); + await act(() => result.current()); + + expect(dispatch).toHaveBeenCalledTimes(2); + + expect(mockContextValue.services.history.addToHistory).toHaveBeenCalledTimes(2); + // It only called notification once + expect(mockContextValue.services.notifications.toasts.addError).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/plugins/console/public/application/hooks/use_send_current_request/use_send_current_request.ts b/src/plugins/console/public/application/hooks/use_send_current_request/use_send_current_request.ts new file mode 100644 index 0000000000000..ed08304d8d660 --- /dev/null +++ b/src/plugins/console/public/application/hooks/use_send_current_request/use_send_current_request.ts @@ -0,0 +1,133 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { i18n } from '@kbn/i18n'; +import { useCallback } from 'react'; + +import { toMountPoint } from '../../../shared_imports'; +import { isQuotaExceededError } from '../../../services/history'; +// @ts-ignore +import { retrieveAutoCompleteInfo } from '../../../lib/mappings/mappings'; +import { instance as registry } from '../../contexts/editor_context/editor_registry'; +import { useRequestActionContext, useServicesContext } from '../../contexts'; +import { StorageQuotaError } from '../../components/storage_quota_error'; +import { sendRequest } from './send_request'; +import { track } from './track'; + +export const useSendCurrentRequest = () => { + const { + services: { history, settings, notifications, trackUiMetric, http }, + theme$, + } = useServicesContext(); + + const dispatch = useRequestActionContext(); + + return useCallback(async () => { + try { + const editor = registry.getInputEditor(); + const requests = await editor.getRequestsInRange(); + if (!requests.length) { + notifications.toasts.add( + i18n.translate('console.notification.error.noRequestSelectedTitle', { + defaultMessage: + 'No request selected. Select a request by placing the cursor inside it.', + }) + ); + return; + } + + dispatch({ type: 'sendRequest', payload: undefined }); + + // Fire and forget + setTimeout(() => track(requests, editor, trackUiMetric), 0); + + const results = await sendRequest({ http, requests }); + + let saveToHistoryError: undefined | Error; + const { isHistoryDisabled } = settings.toJSON(); + + if (!isHistoryDisabled) { + results.forEach(({ request: { path, method, data } }) => { + try { + history.addToHistory(path, method, data); + } catch (e) { + // Grab only the first error + if (!saveToHistoryError) { + saveToHistoryError = e; + } + } + }); + } + + if (saveToHistoryError) { + const errorTitle = i18n.translate('console.notification.error.couldNotSaveRequestTitle', { + defaultMessage: 'Could not save request to Console history.', + }); + if (isQuotaExceededError(saveToHistoryError)) { + const toast = notifications.toasts.addWarning({ + title: i18n.translate('console.notification.error.historyQuotaReachedMessage', { + defaultMessage: + 'Request history is full. Clear the console history or disable saving new requests.', + }), + text: toMountPoint( + StorageQuotaError({ + onClearHistory: () => { + history.clearHistory(); + notifications.toasts.remove(toast); + }, + onDisableSavingToHistory: () => { + settings.setIsHistoryDisabled(true); + notifications.toasts.remove(toast); + }, + }), + { theme$ } + ), + }); + } else { + // Best effort, but still notify the user. + notifications.toasts.addError(saveToHistoryError, { + title: errorTitle, + }); + } + } + + const { polling } = settings.toJSON(); + if (polling) { + // If the user has submitted a request against ES, something in the fields, indices, aliases, + // or templates may have changed, so we'll need to update this data. Assume that if + // the user disables polling they're trying to optimize performance or otherwise + // preserve resources, so they won't want this request sent either. + retrieveAutoCompleteInfo(http, settings, settings.getAutocomplete()); + } + + dispatch({ + type: 'requestSuccess', + payload: { + data: results, + }, + }); + } catch (e) { + if (e?.response) { + dispatch({ + type: 'requestFail', + payload: e, + }); + } else { + dispatch({ + type: 'requestFail', + payload: undefined, + }); + notifications.toasts.addError(e, { + title: i18n.translate('console.notification.error.unknownErrorTitle', { + defaultMessage: 'Unknown Request Error', + }), + }); + } + } + }, [dispatch, http, settings, notifications.toasts, trackUiMetric, history, theme$]); +}; diff --git a/src/plugins/console/public/application/hooks/use_send_current_request_to_es/index.ts b/src/plugins/console/public/application/hooks/use_send_current_request_to_es/index.ts deleted file mode 100644 index df2431f1f6f43..0000000000000 --- a/src/plugins/console/public/application/hooks/use_send_current_request_to_es/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export { useSendCurrentRequestToES } from './use_send_current_request_to_es'; diff --git a/src/plugins/console/public/application/hooks/use_send_current_request_to_es/send_request_to_es.test.ts b/src/plugins/console/public/application/hooks/use_send_current_request_to_es/send_request_to_es.test.ts deleted file mode 100644 index 8578e271f37b3..0000000000000 --- a/src/plugins/console/public/application/hooks/use_send_current_request_to_es/send_request_to_es.test.ts +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import type { ContextValue } from '../../contexts'; - -jest.mock('./send_request_to_es', () => ({ sendRequestToES: jest.fn(() => Promise.resolve()) })); - -import { sendRequestToES } from './send_request_to_es'; -import { serviceContextMock } from '../../contexts/services_context.mock'; - -const mockedSendRequestToES = sendRequestToES as jest.Mock; - -describe('sendRequestToES', () => { - let mockContextValue: ContextValue; - - beforeEach(() => { - mockContextValue = serviceContextMock.create(); - }); - - afterEach(() => { - jest.resetAllMocks(); - }); - - it('should send request to ES', async () => { - mockedSendRequestToES.mockResolvedValue([ - { - response: { - statusCode: 200, - value: '{\n "acknowledged": true \n}', - }, - }, - ]); - - const args = { - http: mockContextValue.services.http, - requests: [{ method: 'PUT', url: 'test', data: [] }], - }; - const results = await sendRequestToES(args); - - const [request] = results; - expect(request.response.statusCode).toEqual(200); - expect(request.response.value).toContain('"acknowledged": true'); - expect(mockedSendRequestToES).toHaveBeenCalledWith(args); - expect(mockedSendRequestToES).toHaveBeenCalledTimes(1); - }); - - it('should send multiple requests to ES', async () => { - mockedSendRequestToES.mockResolvedValue([ - { - response: { - statusCode: 200, - }, - }, - { - response: { - statusCode: 200, - }, - }, - ]); - - const args = { - http: mockContextValue.services.http, - requests: [ - { method: 'GET', url: 'test-1', data: [] }, - { method: 'GET', url: 'test-2', data: [] }, - ], - }; - const results = await sendRequestToES(args); - - const [firstRequest, secondRequest] = results; - expect(firstRequest.response.statusCode).toEqual(200); - expect(secondRequest.response.statusCode).toEqual(200); - expect(mockedSendRequestToES).toHaveBeenCalledWith(args); - expect(mockedSendRequestToES).toHaveBeenCalledTimes(1); - }); - - it('should handle errors', async () => { - mockedSendRequestToES.mockRejectedValue({ - response: { - statusCode: 500, - statusText: 'error', - }, - }); - - try { - await sendRequestToES({ - http: mockContextValue.services.http, - requests: [{ method: 'GET', url: 'test', data: [] }], - }); - } catch (error) { - expect(error.response.statusCode).toEqual(500); - expect(error.response.statusText).toEqual('error'); - expect(mockedSendRequestToES).toHaveBeenCalledTimes(1); - } - }); - describe('successful response value', () => { - describe('with text', () => { - it('should return value with lines separated', async () => { - mockedSendRequestToES.mockResolvedValue('\ntest_index-1 [] \ntest_index-2 []\n'); - const response = await sendRequestToES({ - http: mockContextValue.services.http, - requests: [{ method: 'GET', url: 'test-1', data: [] }], - }); - - expect(response).toMatchInlineSnapshot(` - " - test_index-1 [] - test_index-2 [] - " - `); - expect(mockedSendRequestToES).toHaveBeenCalledTimes(1); - }); - }); - - describe('with parsed json', () => { - it('should stringify value', async () => { - mockedSendRequestToES.mockResolvedValue(JSON.stringify({ test: 'some value' })); - const response = await sendRequestToES({ - http: mockContextValue.services.http, - requests: [{ method: 'GET', url: 'test-2', data: [] }], - }); - - expect(typeof response).toBe('string'); - expect(mockedSendRequestToES).toHaveBeenCalledTimes(1); - }); - }); - }); -}); diff --git a/src/plugins/console/public/application/hooks/use_send_current_request_to_es/send_request_to_es.ts b/src/plugins/console/public/application/hooks/use_send_current_request_to_es/send_request_to_es.ts deleted file mode 100644 index 451198aaf2d2b..0000000000000 --- a/src/plugins/console/public/application/hooks/use_send_current_request_to_es/send_request_to_es.ts +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import type { HttpSetup, IHttpFetchError } from '@kbn/core/public'; -import { XJson } from '@kbn/es-ui-shared-plugin/public'; -import { extractWarningMessages } from '../../../lib/utils'; -// @ts-ignore -import * as es from '../../../lib/es/es'; -import { BaseResponseType } from '../../../types'; - -const { collapseLiteralStrings } = XJson; - -export interface EsRequestArgs { - http: HttpSetup; - requests: Array<{ url: string; method: string; data: string[] }>; -} - -export interface ESResponseObject { - statusCode: number; - statusText: string; - timeMs: number; - contentType: BaseResponseType; - value: V; -} - -export interface ESRequestResult { - request: { data: string; method: string; path: string }; - response: ESResponseObject; -} - -let CURRENT_REQ_ID = 0; -export function sendRequestToES(args: EsRequestArgs): Promise { - const requests = args.requests.slice(); - return new Promise((resolve, reject) => { - const reqId = ++CURRENT_REQ_ID; - const results: ESRequestResult[] = []; - if (reqId !== CURRENT_REQ_ID) { - return; - } - - if (requests.length === 0) { - return; - } - - const isMultiRequest = requests.length > 1; - - const sendNextRequest = async () => { - if (reqId !== CURRENT_REQ_ID) { - resolve(results); - return; - } - if (requests.length === 0) { - resolve(results); - return; - } - const req = requests.shift()!; - const esPath = req.url; - const esMethod = req.method; - let esData = collapseLiteralStrings(req.data.join('\n')); - if (esData) { - esData += '\n'; - } // append a new line for bulk requests. - - const startTime = Date.now(); - - try { - const { response, body } = await es.send({ - http: args.http, - method: esMethod, - path: esPath, - data: esData, - asResponse: true, - }); - - if (reqId !== CURRENT_REQ_ID) { - // Skip if previous request is not resolved yet. This can happen when issuing multiple requests at the same time and with slow networks - return; - } - - if (response) { - const isSuccess = - // Things like DELETE index where the index is not there are OK. - (response.status >= 200 && response.status < 300) || response.status === 404; - - if (isSuccess) { - let value; - // check if object is ArrayBuffer - if (body instanceof ArrayBuffer) { - value = body; - } else { - value = typeof body === 'string' ? body : JSON.stringify(body, null, 2); - } - - const warnings = response.headers.get('warning'); - if (warnings) { - const warningMessages = extractWarningMessages(warnings); - value = warningMessages.join('\n') + '\n' + value; - } - - if (isMultiRequest) { - value = '# ' + req.method + ' ' + req.url + '\n' + value; - } - - results.push({ - response: { - timeMs: Date.now() - startTime, - statusCode: response.status, - statusText: response.statusText, - contentType: response.headers.get('Content-Type') as BaseResponseType, - value, - }, - request: { - data: esData, - method: esMethod, - path: esPath, - }, - }); - - // single request terminate via sendNextRequest as well - await sendNextRequest(); - } - } - } catch (error) { - let value; - let contentType: string | null = ''; - - const { response, body = {} } = error as IHttpFetchError; - if (response) { - const { status, headers } = response; - if (body) { - value = JSON.stringify(body, null, 2); // ES error should be shown - contentType = headers.get('Content-Type'); - } else { - value = 'Request failed to get to the server (status code: ' + status + ')'; - contentType = headers.get('Content-Type'); - } - - if (isMultiRequest) { - value = '# ' + req.method + ' ' + req.url + '\n' + value; - } - } else { - value = - "\n\nFailed to connect to Console's backend.\nPlease check the Kibana server is up and running"; - } - - reject({ - response: { - value, - contentType, - timeMs: Date.now() - startTime, - statusCode: error?.response?.status ?? 500, - statusText: error?.response?.statusText ?? 'error', - }, - request: { - data: esData, - method: esMethod, - path: esPath, - }, - }); - } - }; - - sendNextRequest(); - }); -} diff --git a/src/plugins/console/public/application/hooks/use_send_current_request_to_es/use_send_current_request_to_es.test.tsx b/src/plugins/console/public/application/hooks/use_send_current_request_to_es/use_send_current_request_to_es.test.tsx deleted file mode 100644 index e0131dc116a34..0000000000000 --- a/src/plugins/console/public/application/hooks/use_send_current_request_to_es/use_send_current_request_to_es.test.tsx +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -jest.mock('./send_request_to_es', () => ({ sendRequestToES: jest.fn() })); -jest.mock('../../contexts/editor_context/editor_registry', () => ({ - instance: { getInputEditor: jest.fn() }, -})); -jest.mock('./track', () => ({ track: jest.fn() })); -jest.mock('../../contexts/request_context', () => ({ useRequestActionContext: jest.fn() })); - -import React from 'react'; -import { renderHook, act } from '@testing-library/react-hooks'; - -import { ContextValue, ServicesContextProvider } from '../../contexts'; -import { serviceContextMock } from '../../contexts/services_context.mock'; -import { useRequestActionContext } from '../../contexts/request_context'; -import { instance as editorRegistry } from '../../contexts/editor_context/editor_registry'; - -import { sendRequestToES } from './send_request_to_es'; -import { useSendCurrentRequestToES } from './use_send_current_request_to_es'; - -describe('useSendCurrentRequestToES', () => { - let mockContextValue: ContextValue; - let dispatch: (...args: unknown[]) => void; - const contexts = ({ children }: { children: JSX.Element }) => ( - {children} - ); - - beforeEach(() => { - mockContextValue = serviceContextMock.create(); - dispatch = jest.fn(); - (useRequestActionContext as jest.Mock).mockReturnValue(dispatch); - }); - - afterEach(() => { - jest.resetAllMocks(); - }); - - it('calls send request to ES', async () => { - // Set up mocks - (mockContextValue.services.settings.toJSON as jest.Mock).mockReturnValue({}); - // This request should succeed - (sendRequestToES as jest.Mock).mockResolvedValue([]); - (editorRegistry.getInputEditor as jest.Mock).mockImplementation(() => ({ - getRequestsInRange: () => ['test'], - })); - - const { result } = renderHook(() => useSendCurrentRequestToES(), { wrapper: contexts }); - await act(() => result.current()); - expect(sendRequestToES).toHaveBeenCalledWith({ - http: mockContextValue.services.http, - requests: ['test'], - }); - - // Second call should be the request success - const [, [requestSucceededCall]] = (dispatch as jest.Mock).mock.calls; - expect(requestSucceededCall).toEqual({ type: 'requestSuccess', payload: { data: [] } }); - }); - - it('handles known errors', async () => { - // Set up mocks - (sendRequestToES as jest.Mock).mockRejectedValue({ response: 'nada' }); - (editorRegistry.getInputEditor as jest.Mock).mockImplementation(() => ({ - getRequestsInRange: () => ['test'], - })); - - const { result } = renderHook(() => useSendCurrentRequestToES(), { wrapper: contexts }); - await act(() => result.current()); - // Second call should be the request failure - const [, [requestFailedCall]] = (dispatch as jest.Mock).mock.calls; - - // The request must have concluded - expect(requestFailedCall).toEqual({ type: 'requestFail', payload: { response: 'nada' } }); - }); - - it('handles unknown errors', async () => { - // Set up mocks - (sendRequestToES as jest.Mock).mockRejectedValue(NaN /* unexpected error value */); - (editorRegistry.getInputEditor as jest.Mock).mockImplementation(() => ({ - getRequestsInRange: () => ['test'], - })); - - const { result } = renderHook(() => useSendCurrentRequestToES(), { wrapper: contexts }); - await act(() => result.current()); - // Second call should be the request failure - const [, [requestFailedCall]] = (dispatch as jest.Mock).mock.calls; - - // The request must have concluded - expect(requestFailedCall).toEqual({ type: 'requestFail', payload: undefined }); - // It also notified the user - expect(mockContextValue.services.notifications.toasts.addError).toHaveBeenCalledWith(NaN, { - title: 'Unknown Request Error', - }); - }); - - it('notifies the user about save to history errors once only', async () => { - // Set up mocks - (sendRequestToES as jest.Mock).mockReturnValue( - [{ request: {} }, { request: {} }] /* two responses to save history */ - ); - (mockContextValue.services.settings.toJSON as jest.Mock).mockReturnValue({}); - (mockContextValue.services.history.addToHistory as jest.Mock).mockImplementation(() => { - // Mock throwing - throw new Error('cannot save!'); - }); - (editorRegistry.getInputEditor as jest.Mock).mockImplementation(() => ({ - getRequestsInRange: () => ['test', 'test'], - })); - - const { result } = renderHook(() => useSendCurrentRequestToES(), { wrapper: contexts }); - await act(() => result.current()); - - expect(dispatch).toHaveBeenCalledTimes(2); - - expect(mockContextValue.services.history.addToHistory).toHaveBeenCalledTimes(2); - // It only called notification once - expect(mockContextValue.services.notifications.toasts.addError).toHaveBeenCalledTimes(1); - }); -}); diff --git a/src/plugins/console/public/application/hooks/use_send_current_request_to_es/use_send_current_request_to_es.ts b/src/plugins/console/public/application/hooks/use_send_current_request_to_es/use_send_current_request_to_es.ts deleted file mode 100644 index e7c436c9806b3..0000000000000 --- a/src/plugins/console/public/application/hooks/use_send_current_request_to_es/use_send_current_request_to_es.ts +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { i18n } from '@kbn/i18n'; -import { useCallback } from 'react'; - -import { toMountPoint } from '../../../shared_imports'; -import { isQuotaExceededError } from '../../../services/history'; -// @ts-ignore -import { retrieveAutoCompleteInfo } from '../../../lib/mappings/mappings'; -import { instance as registry } from '../../contexts/editor_context/editor_registry'; -import { useRequestActionContext, useServicesContext } from '../../contexts'; -import { StorageQuotaError } from '../../components/storage_quota_error'; -import { sendRequestToES } from './send_request_to_es'; -import { track } from './track'; - -export const useSendCurrentRequestToES = () => { - const { - services: { history, settings, notifications, trackUiMetric, http }, - theme$, - } = useServicesContext(); - - const dispatch = useRequestActionContext(); - - return useCallback(async () => { - try { - const editor = registry.getInputEditor(); - const requests = await editor.getRequestsInRange(); - if (!requests.length) { - notifications.toasts.add( - i18n.translate('console.notification.error.noRequestSelectedTitle', { - defaultMessage: - 'No request selected. Select a request by placing the cursor inside it.', - }) - ); - return; - } - - dispatch({ type: 'sendRequest', payload: undefined }); - - // Fire and forget - setTimeout(() => track(requests, editor, trackUiMetric), 0); - - const results = await sendRequestToES({ http, requests }); - - let saveToHistoryError: undefined | Error; - const { isHistoryDisabled } = settings.toJSON(); - - if (!isHistoryDisabled) { - results.forEach(({ request: { path, method, data } }) => { - try { - history.addToHistory(path, method, data); - } catch (e) { - // Grab only the first error - if (!saveToHistoryError) { - saveToHistoryError = e; - } - } - }); - } - - if (saveToHistoryError) { - const errorTitle = i18n.translate('console.notification.error.couldNotSaveRequestTitle', { - defaultMessage: 'Could not save request to Console history.', - }); - if (isQuotaExceededError(saveToHistoryError)) { - const toast = notifications.toasts.addWarning({ - title: i18n.translate('console.notification.error.historyQuotaReachedMessage', { - defaultMessage: - 'Request history is full. Clear the console history or disable saving new requests.', - }), - text: toMountPoint( - StorageQuotaError({ - onClearHistory: () => { - history.clearHistory(); - notifications.toasts.remove(toast); - }, - onDisableSavingToHistory: () => { - settings.setIsHistoryDisabled(true); - notifications.toasts.remove(toast); - }, - }), - { theme$ } - ), - }); - } else { - // Best effort, but still notify the user. - notifications.toasts.addError(saveToHistoryError, { - title: errorTitle, - }); - } - } - - const { polling } = settings.toJSON(); - if (polling) { - // If the user has submitted a request against ES, something in the fields, indices, aliases, - // or templates may have changed, so we'll need to update this data. Assume that if - // the user disables polling they're trying to optimize performance or otherwise - // preserve resources, so they won't want this request sent either. - retrieveAutoCompleteInfo(http, settings, settings.getAutocomplete()); - } - - dispatch({ - type: 'requestSuccess', - payload: { - data: results, - }, - }); - } catch (e) { - if (e?.response) { - dispatch({ - type: 'requestFail', - payload: e, - }); - } else { - dispatch({ - type: 'requestFail', - payload: undefined, - }); - notifications.toasts.addError(e, { - title: i18n.translate('console.notification.error.unknownErrorTitle', { - defaultMessage: 'Unknown Request Error', - }), - }); - } - } - }, [dispatch, http, settings, notifications.toasts, trackUiMetric, history, theme$]); -}; diff --git a/src/plugins/console/public/application/models/sense_editor/sense_editor.test.js b/src/plugins/console/public/application/models/sense_editor/sense_editor.test.js index 0889b98c69388..ff9d245f61275 100644 --- a/src/plugins/console/public/application/models/sense_editor/sense_editor.test.js +++ b/src/plugins/console/public/application/models/sense_editor/sense_editor.test.js @@ -455,11 +455,11 @@ describe('Editor', () => { editorInput1, { start: { lineNumber: 7 }, end: { lineNumber: 14 } }, ` -curl -XGET "http://localhost:9200/_stats?level=shards" +curl -XGET "http://localhost:9200/_stats?level=shards" -H "kbn-xsrf: reporting" #in between comment -curl -XPUT "http://localhost:9200/index_1/type1/1" -H 'Content-Type: application/json' -d' +curl -XPUT "http://localhost:9200/index_1/type1/1" -H "kbn-xsrf: reporting" -H "Content-Type: application/json" -d' { "f": 1 }'`.trim() @@ -470,7 +470,7 @@ curl -XPUT "http://localhost:9200/index_1/type1/1" -H 'Content-Type: application editorInput1, { start: { lineNumber: 29 }, end: { lineNumber: 33 } }, ` -curl -XPOST "http://localhost:9200/_sql?format=txt" -H 'Content-Type: application/json' -d' +curl -XPOST "http://localhost:9200/_sql?format=txt" -H "kbn-xsrf: reporting" -H "Content-Type: application/json" -d' { "query": "SELECT prenom FROM claude_index WHERE prenom = '\\''claude'\\'' ", "fetch_size": 1 diff --git a/src/plugins/console/public/application/models/sense_editor/sense_editor.ts b/src/plugins/console/public/application/models/sense_editor/sense_editor.ts index 5e8ca35f287b7..ac65afce2c18a 100644 --- a/src/plugins/console/public/application/models/sense_editor/sense_editor.ts +++ b/src/plugins/console/public/application/models/sense_editor/sense_editor.ts @@ -14,7 +14,7 @@ import RowParser from '../../../lib/row_parser'; import * as utils from '../../../lib/utils'; // @ts-ignore -import * as es from '../../../lib/es/es'; +import { constructUrl } from '../../../lib/es/es'; import { CoreEditor, Position, Range } from '../../../types'; import { createTokenIterator } from '../../factories'; @@ -467,21 +467,22 @@ export class SenseEditor { return req; } - const esPath = req.url; - const esMethod = req.method; - const esData = req.data; + const path = req.url; + const method = req.method; + const data = req.data; // this is the first url defined in elasticsearch.hosts - const url = es.constructESUrl(elasticsearchBaseUrl, esPath); + const url = constructUrl(elasticsearchBaseUrl, path); - let ret = 'curl -X' + esMethod + ' "' + url + '"'; - if (esData && esData.length) { - ret += " -H 'Content-Type: application/json' -d'\n"; - const dataAsString = collapseLiteralStrings(esData.join('\n')); + // Append 'kbn-xsrf' header to bypass (XSRF/CSRF) protections + let ret = `curl -X${method.toUpperCase()} "${url}" -H "kbn-xsrf: reporting"`; + if (data && data.length) { + ret += ` -H "Content-Type: application/json" -d'\n`; + const dataAsString = collapseLiteralStrings(data.join('\n')); // We escape single quoted strings that that are wrapped in single quoted strings ret += dataAsString.replace(/'/g, "'\\''"); - if (esData.length > 1) { + if (data.length > 1) { ret += '\n'; } // end with a new line ret += "'"; diff --git a/src/plugins/console/public/application/stores/request.ts b/src/plugins/console/public/application/stores/request.ts index 099ab24326d31..8056ab5a7987f 100644 --- a/src/plugins/console/public/application/stores/request.ts +++ b/src/plugins/console/public/application/stores/request.ts @@ -10,18 +10,18 @@ import { Reducer } from 'react'; import { produce } from 'immer'; import { identity } from 'fp-ts/lib/function'; import { BaseResponseType } from '../../types/common'; -import { ESRequestResult } from '../hooks/use_send_current_request_to_es/send_request_to_es'; +import { RequestResult } from '../hooks/use_send_current_request/send_request'; export type Actions = | { type: 'sendRequest'; payload: undefined } - | { type: 'requestSuccess'; payload: { data: ESRequestResult[] } } - | { type: 'requestFail'; payload: ESRequestResult | undefined }; + | { type: 'requestSuccess'; payload: { data: RequestResult[] } } + | { type: 'requestFail'; payload: RequestResult | undefined }; export interface Store { requestInFlight: boolean; lastResult: { - data: ESRequestResult[] | null; - error?: ESRequestResult; + data: RequestResult[] | null; + error?: RequestResult; }; } diff --git a/src/plugins/console/public/lib/autocomplete/autocomplete.ts b/src/plugins/console/public/lib/autocomplete/autocomplete.ts index 1dc41430e3855..3e59c4e6bb023 100644 --- a/src/plugins/console/public/lib/autocomplete/autocomplete.ts +++ b/src/plugins/console/public/lib/autocomplete/autocomplete.ts @@ -11,22 +11,22 @@ import { i18n } from '@kbn/i18n'; // TODO: All of these imports need to be moved to the core editor so that it can inject components from there. import { - getTopLevelUrlCompleteComponents, getEndpointBodyCompleteComponents, getGlobalAutocompleteComponents, + getTopLevelUrlCompleteComponents, getUnmatchedEndpointComponents, // @ts-ignore } from '../kb/kb'; import { createTokenIterator } from '../../application/factories'; -import { Position, Token, Range, CoreEditor } from '../../types'; +import type { CoreEditor, Position, Range, Token } from '../../types'; import type RowParser from '../row_parser'; import * as utils from '../utils'; // @ts-ignore import { populateContext } from './engine'; -import { AutoCompleteContext, ResultTerm } from './types'; +import type { AutoCompleteContext, DataAutoCompleteRulesOneOf, ResultTerm } from './types'; // @ts-ignore import { URL_PATH_END_MARKER } from './components'; @@ -349,14 +349,84 @@ export default function ({ }); } + /** + * Get a different set of templates based on the value configured in the request. + * For example, when creating a snapshot repository of different types (`fs`, `url` etc), + * different properties are inserted in the textarea based on the type. + * E.g. https://github.com/elastic/kibana/blob/main/src/plugins/console/server/lib/spec_definitions/json/overrides/snapshot.create_repository.json + */ + function getConditionalTemplate( + name: string, + autocompleteRules: Record | null | undefined + ) { + const obj = autocompleteRules && autocompleteRules[name]; + + if (obj) { + const currentLineNumber = editor.getCurrentPosition().lineNumber; + + if (hasOneOfIn(obj)) { + // Get the line number of value that should provide different templates based on that + const startLine = getStartLineNumber(currentLineNumber, obj.__one_of); + // Join line values from start to current line + const lines = editor.getLines(startLine, currentLineNumber).join('\n'); + // Get the correct template by comparing the autocomplete rules against the lines + const prop = getProperty(lines, obj.__one_of); + if (prop && prop.__template) { + return prop.__template; + } + } + } + } + + /** + * Check if object has a property of '__one_of' + */ + function hasOneOfIn(value: unknown): value is { __one_of: DataAutoCompleteRulesOneOf[] } { + return typeof value === 'object' && value !== null && '__one_of' in value; + } + + /** + * Get the start line of value that matches the autocomplete rules condition + */ + function getStartLineNumber(currentLine: number, rules: DataAutoCompleteRulesOneOf[]): number { + if (currentLine === 1) { + return currentLine; + } + const value = editor.getLineValue(currentLine); + const prop = getProperty(value, rules); + if (prop) { + return currentLine; + } + return getStartLineNumber(currentLine - 1, rules); + } + + /** + * Get the matching property based on the given condition + */ + function getProperty(condition: string, rules: DataAutoCompleteRulesOneOf[]) { + return rules.find((rule) => { + if (rule.__condition && rule.__condition.lines_regex) { + return new RegExp(rule.__condition.lines_regex, 'm').test(condition); + } + return false; + }); + } + function applyTerm(term: { value?: string; context?: AutoCompleteContext; - template?: { __raw: boolean; value: string }; + template?: { __raw?: boolean; value?: string; [key: string]: unknown }; insertValue?: string; }) { const context = term.context!; + if (context?.endpoint && term.value) { + const { data_autocomplete_rules: autocompleteRules } = context.endpoint; + const template = getConditionalTemplate(term.value, autocompleteRules); + if (template) { + term.template = template; + } + } // make sure we get up to date replacement info. addReplacementInfoToContext(context, editor.getCurrentPosition(), term.insertValue); diff --git a/src/plugins/console/public/lib/autocomplete/types.ts b/src/plugins/console/public/lib/autocomplete/types.ts index 33c543f43be9e..15d32e6426a6c 100644 --- a/src/plugins/console/public/lib/autocomplete/types.ts +++ b/src/plugins/console/public/lib/autocomplete/types.ts @@ -15,6 +15,14 @@ export interface ResultTerm { value?: string; } +export interface DataAutoCompleteRulesOneOf { + __condition?: { + lines_regex: string; + }; + __template: Record; + [key: string]: unknown; +} + export interface AutoCompleteContext { autoCompleteSet?: null | ResultTerm[]; endpoint?: null | { @@ -24,6 +32,7 @@ export interface AutoCompleteContext { bodyAutocompleteRootComponents: unknown; id?: string; documentation?: string; + data_autocomplete_rules?: Record | null; }; urlPath?: null | unknown; urlParamsTokenPath?: Array> | null; diff --git a/src/plugins/console/public/lib/es/es.ts b/src/plugins/console/public/lib/es/es.ts index 2a4059d664e6c..10d0ad95b0496 100644 --- a/src/plugins/console/public/lib/es/es.ts +++ b/src/plugins/console/public/lib/es/es.ts @@ -6,8 +6,9 @@ * Side Public License, v 1. */ -import type { HttpFetchOptions, HttpResponse, HttpSetup } from '@kbn/core/public'; -import { API_BASE_PATH } from '../../../common/constants'; +import type { HttpResponse, HttpSetup } from '@kbn/core/public'; +import { trimStart } from 'lodash'; +import { API_BASE_PATH, KIBANA_API_PREFIX } from '../../../common/constants'; const esVersion: string[] = []; @@ -20,7 +21,7 @@ export function getContentType(body: unknown) { return 'application/json'; } -interface SendProps { +interface SendConfig { http: HttpSetup; method: string; path: string; @@ -30,6 +31,8 @@ interface SendProps { asResponse?: boolean; } +type Method = 'get' | 'post' | 'delete' | 'put' | 'patch' | 'head'; + export async function send({ http, method, @@ -38,18 +41,48 @@ export async function send({ asSystemRequest = false, withProductOrigin = false, asResponse = false, -}: SendProps) { - const options: HttpFetchOptions = { +}: SendConfig) { + const kibanaRequestUrl = getKibanaRequestUrl(path); + + if (kibanaRequestUrl) { + const httpMethod = method.toLowerCase() as Method; + const url = new URL(kibanaRequestUrl); + const { pathname, searchParams } = url; + const query = Object.fromEntries(searchParams.entries()); + const body = ['post', 'put', 'patch'].includes(httpMethod) ? data : null; + + return await http[httpMethod](pathname, { + body, + query, + asResponse, + asSystemRequest, + }); + } + + return await http.post(`${API_BASE_PATH}/proxy`, { query: { path, method, ...(withProductOrigin && { withProductOrigin }) }, body: data, asResponse, asSystemRequest, - }; + }); +} + +function getKibanaRequestUrl(path: string) { + const isKibanaApiRequest = path.startsWith(KIBANA_API_PREFIX); + const kibanaBasePath = window.location.origin; - return await http.post(`${API_BASE_PATH}/proxy`, options); + if (isKibanaApiRequest) { + // window.location.origin is used as a Kibana public base path for sending requests in cURL commands. E.g. "Copy as cURL". + return `${kibanaBasePath}/${trimStart(path.replace(KIBANA_API_PREFIX, ''), '/')}`; + } } -export function constructESUrl(baseUri: string, path: string) { +export function constructUrl(baseUri: string, path: string) { + const kibanaRequestUrl = getKibanaRequestUrl(path); + + if (kibanaRequestUrl) { + return kibanaRequestUrl; + } baseUri = baseUri.replace(/\/+$/, ''); path = path.replace(/^\/+/, ''); return baseUri + '/' + path; diff --git a/src/plugins/console/public/lib/es/index.ts b/src/plugins/console/public/lib/es/index.ts index 61d34ba96ec05..f83893e93713e 100644 --- a/src/plugins/console/public/lib/es/index.ts +++ b/src/plugins/console/public/lib/es/index.ts @@ -6,4 +6,4 @@ * Side Public License, v 1. */ -export { send, constructESUrl, getContentType, getVersion } from './es'; +export { send, constructUrl, getContentType, getVersion } from './es'; diff --git a/src/plugins/controls/common/control_types/options_list/types.ts b/src/plugins/controls/common/control_types/options_list/types.ts index 9c051e4ca6235..0f889bed7bacb 100644 --- a/src/plugins/controls/common/control_types/options_list/types.ts +++ b/src/plugins/controls/common/control_types/options_list/types.ts @@ -8,14 +8,11 @@ import { BoolQuery } from '@kbn/es-query'; import { FieldSpec } from '@kbn/data-views-plugin/common'; -import { ControlInput } from '../../types'; +import { DataControlInput } from '../../types'; export const OPTIONS_LIST_CONTROL = 'optionsListControl'; -export interface OptionsListEmbeddableInput extends ControlInput { - fieldName: string; - dataViewId: string; - +export interface OptionsListEmbeddableInput extends DataControlInput { selectedOptions?: string[]; singleSelect?: boolean; loading?: boolean; diff --git a/src/plugins/controls/common/control_types/range_slider/types.ts b/src/plugins/controls/common/control_types/range_slider/types.ts index e63ec0337a57e..a975fdd27ac31 100644 --- a/src/plugins/controls/common/control_types/range_slider/types.ts +++ b/src/plugins/controls/common/control_types/range_slider/types.ts @@ -6,14 +6,12 @@ * Side Public License, v 1. */ -import { ControlInput } from '../../types'; +import { DataControlInput } from '../../types'; export const RANGE_SLIDER_CONTROL = 'rangeSliderControl'; export type RangeValue = [string, string]; -export interface RangeSliderEmbeddableInput extends ControlInput { - fieldName: string; - dataViewId: string; +export interface RangeSliderEmbeddableInput extends DataControlInput { value: RangeValue; } diff --git a/src/plugins/controls/common/control_types/time_slider/types.ts b/src/plugins/controls/common/control_types/time_slider/types.ts index 73d364da80caa..31272380becde 100644 --- a/src/plugins/controls/common/control_types/time_slider/types.ts +++ b/src/plugins/controls/common/control_types/time_slider/types.ts @@ -6,12 +6,10 @@ * Side Public License, v 1. */ -import { ControlInput } from '../../types'; +import { DataControlInput } from '../../types'; export const TIME_SLIDER_CONTROL = 'timeSlider'; -export interface TimeSliderControlEmbeddableInput extends ControlInput { - fieldName: string; - dataViewId: string; +export interface TimeSliderControlEmbeddableInput extends DataControlInput { value?: [number | null, number | null]; } diff --git a/src/plugins/controls/common/types.ts b/src/plugins/controls/common/types.ts index 3715198d7cfe5..abb24299e8180 100644 --- a/src/plugins/controls/common/types.ts +++ b/src/plugins/controls/common/types.ts @@ -27,3 +27,8 @@ export type ControlInput = EmbeddableInput & { controlStyle?: ControlStyle; ignoreParentSettings?: ParentIgnoreSettings; }; + +export type DataControlInput = ControlInput & { + fieldName: string; + dataViewId: string; +}; diff --git a/src/plugins/controls/kibana.json b/src/plugins/controls/kibana.json index 20afd63505a73..e87af3f517af2 100644 --- a/src/plugins/controls/kibana.json +++ b/src/plugins/controls/kibana.json @@ -17,7 +17,8 @@ "expressions", "embeddable", "dataViews", - "data" + "data", + "unifiedSearch" ], "optionalPlugins": [] } diff --git a/src/plugins/controls/public/__stories__/controls.stories.tsx b/src/plugins/controls/public/__stories__/controls.stories.tsx index 74d0d3e9de6a9..481016af72a36 100644 --- a/src/plugins/controls/public/__stories__/controls.stories.tsx +++ b/src/plugins/controls/public/__stories__/controls.stories.tsx @@ -31,7 +31,7 @@ import { decorators } from './decorators'; import { ControlsPanels } from '../control_group/types'; import { ControlGroupContainer } from '../control_group'; import { pluginServices, registry } from '../services/storybook'; -import { replaceValueSuggestionMethod } from '../services/storybook/data'; +import { replaceValueSuggestionMethod } from '../services/storybook/unified_search'; import { injectStorybookDataView } from '../services/storybook/data_views'; import { populateStorybookControlFactories } from './storybook_control_factories'; import { OptionsListRequest } from '../services/options_list'; diff --git a/src/plugins/controls/public/control_types/range_slider/range_slider.component.tsx b/src/plugins/controls/public/control_types/range_slider/range_slider.component.tsx index f1002290eab3d..259b6bd7f66a1 100644 --- a/src/plugins/controls/public/control_types/range_slider/range_slider.component.tsx +++ b/src/plugins/controls/public/control_types/range_slider/range_slider.component.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC, useCallback, useState } from 'react'; +import React, { FC, useCallback } from 'react'; import { BehaviorSubject } from 'rxjs'; import { DataViewField } from '@kbn/data-views-plugin/public'; @@ -45,16 +45,13 @@ export const RangeSliderComponent: FC = ({ componentStateSubject }) => { componentStateSubject.getValue() ); - const { value = ['', ''], id, title } = useEmbeddableSelector((state) => state); - - const [selectedValue, setSelectedValue] = useState(value || ['', '']); + const { value, id, title } = useEmbeddableSelector((state) => state); const onChangeComplete = useCallback( (range: RangeValue) => { dispatch(selectRange(range)); - setSelectedValue(range); }, - [selectRange, setSelectedValue, dispatch] + [selectRange, dispatch] ); return ( @@ -64,7 +61,7 @@ export const RangeSliderComponent: FC = ({ componentStateSubject }) => { min={min} max={max} title={title} - value={selectedValue} + value={value ?? ['', '']} onChange={onChangeComplete} fieldFormatter={fieldFormatter} /> diff --git a/src/plugins/controls/public/control_types/range_slider/range_slider_embeddable.tsx b/src/plugins/controls/public/control_types/range_slider/range_slider_embeddable.tsx index 2777f45d026bd..1ad34fd361ac6 100644 --- a/src/plugins/controls/public/control_types/range_slider/range_slider_embeddable.tsx +++ b/src/plugins/controls/public/control_types/range_slider/range_slider_embeddable.tsx @@ -311,7 +311,7 @@ export class RangeSliderEmbeddable extends Embeddable { + public reload = () => { this.fetchMinMax(); }; diff --git a/src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx b/src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx index 74bb2d23dbd88..bd8b8a394988b 100644 --- a/src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx +++ b/src/plugins/controls/public/control_types/range_slider/range_slider_embeddable_factory.tsx @@ -37,8 +37,8 @@ export class RangeSliderEmbeddableFactory ) => { if ( embeddable && - (!deepEqual(newInput.fieldName, embeddable.getInput().fieldName) || - !deepEqual(newInput.dataViewId, embeddable.getInput().dataViewId)) + ((newInput.fieldName && !deepEqual(newInput.fieldName, embeddable.getInput().fieldName)) || + (newInput.dataViewId && !deepEqual(newInput.dataViewId, embeddable.getInput().dataViewId))) ) { // if the field name or data view id has changed in this editing session, selected values are invalid, so reset them. newInput.value = ['', '']; diff --git a/src/plugins/controls/public/control_types/range_slider/range_slider_popover.tsx b/src/plugins/controls/public/control_types/range_slider/range_slider_popover.tsx index a51b46d98ff85..1bb7501f7104f 100644 --- a/src/plugins/controls/public/control_types/range_slider/range_slider_popover.tsx +++ b/src/plugins/controls/public/control_types/range_slider/range_slider_popover.tsx @@ -45,6 +45,8 @@ export const RangeSliderPopover: FC = ({ fieldFormatter, }) => { const [isPopoverOpen, setIsPopoverOpen] = useState(false); + const [rangeSliderMin, setRangeSliderMin] = useState(-Infinity); + const [rangeSliderMax, setRangeSliderMax] = useState(Infinity); const rangeRef = useRef(null); let errorMessage = ''; let helpText = ''; @@ -79,17 +81,6 @@ export const RangeSliderPopover: FC = ({ errorMessage = RangeSliderStrings.errors.getUpperLessThanLowerErrorMessage(); } - const rangeSliderMin = Math.min( - roundedMin, - isNaN(lowerBoundValue) ? Infinity : lowerBoundValue, - isNaN(upperBoundValue) ? Infinity : upperBoundValue - ); - const rangeSliderMax = Math.max( - roundedMax, - isNaN(lowerBoundValue) ? -Infinity : lowerBoundValue, - isNaN(upperBoundValue) ? -Infinity : upperBoundValue - ); - const displayedValue = [ hasLowerBoundSelection ? String(lowerBoundValue) : hasAvailableRange ? String(roundedMin) : '', hasUpperBoundSelection ? String(upperBoundValue) : hasAvailableRange ? String(roundedMax) : '', @@ -106,7 +97,27 @@ export const RangeSliderPopover: FC = ({ const button = ( - + - + + + @@ -143,54 +141,52 @@ exports[` can navigate Autoplay Settings 2`] = `
-
- - + -
+ + +
can navigate Autoplay Settings 2`] = `
-
+
-
- - - Cycle Slides -
-
-
+ + + Cycle Slides + +
+
+ +
-
- -
+ Set a custom interval + +
+
-
- -
-
-
- Use shorthand notation, like 30s, 10m, or 1h +
+
+ Use shorthand notation, like 30s, 10m, or 1h +
+
+
-
- -
+ +
- -
+
+
@@ -398,54 +392,52 @@ exports[` can navigate Toolbar Settings, closes when activated 1`] =
-
- - + -
+ + +
@@ -498,54 +490,52 @@ exports[` can navigate Toolbar Settings, closes when activated 2`] =
-
- - + -
+ + +
can navigate Toolbar Settings, closes when activated 2`] =
-
+
-
- - - Hide Toolbar -
-
+ - Hide the toolbar when the mouse is not within the Canvas? -
+ Hide Toolbar + +
+
+ Hide the toolbar when the mouse is not within the Canvas?
@@ -643,4 +631,4 @@ exports[` can navigate Toolbar Settings, closes when activated 2`] =
`; -exports[` can navigate Toolbar Settings, closes when activated 3`] = `"

You are in a dialog. To close this dialog, hit escape.

Settings
Hide Toolbar
Hide the toolbar when the mouse is not within the Canvas?
"`; +exports[` can navigate Toolbar Settings, closes when activated 3`] = `"

You are in a dialog. To close this dialog, hit escape.

Settings
Hide Toolbar
Hide the toolbar when the mouse is not within the Canvas?
"`; diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__stories__/__snapshots__/autoplay_settings.stories.storyshot b/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__stories__/__snapshots__/autoplay_settings.stories.storyshot index e803600fe8d51..df3d090de3132 100644 --- a/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__stories__/__snapshots__/autoplay_settings.stories.storyshot +++ b/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__stories__/__snapshots__/autoplay_settings.stories.storyshot @@ -82,7 +82,7 @@ exports[`Storyshots shareables/Footer/Settings/AutoplaySettings component: off, className="euiFlexItem" >
; +export type SingleCaseMetricsRequest = rt.TypeOf; +export type SingleCaseMetricsResponse = rt.TypeOf; +export type CasesMetricsRequest = rt.TypeOf; +export type CasesMetricsResponse = rt.TypeOf; export type AlertHostsMetrics = rt.TypeOf; export type AlertUsersMetrics = rt.TypeOf; export type StatusInfo = rt.TypeOf; @@ -69,7 +72,43 @@ const AlertUsersMetricsRt = rt.type({ ), }); -export const CaseMetricsResponseRt = rt.partial( +export const SingleCaseMetricsRequestRt = rt.type({ + /** + * The ID of the case. + */ + caseId: rt.string, + /** + * The metrics to retrieve. + */ + features: rt.array(rt.string), +}); + +export const CasesMetricsRequestRt = rt.intersection([ + rt.type({ + /** + * The metrics to retrieve. + */ + features: rt.array(rt.string), + }), + rt.partial({ + /** + * A KQL date. If used all cases created after (gte) the from date will be returned + */ + from: rt.string, + /** + * A KQL date. If used all cases created before (lte) the to date will be returned. + */ + to: rt.string, + /** + * The owner(s) to filter by. The user making the request must have privileges to retrieve cases of that + * ownership or they will be ignored. If no owner is included, then all ownership types will be included in the response + * that the user has access to. + */ + owner: rt.union([rt.array(rt.string), rt.string]), + }), +]); + +export const SingleCaseMetricsResponseRt = rt.partial( rt.type({ alerts: rt.partial( rt.type({ @@ -142,3 +181,9 @@ export const CaseMetricsResponseRt = rt.partial( }), }).props ); + +export const CasesMetricsResponseRt = rt.partial( + rt.type({ + mttr: rt.number, + }).props +); diff --git a/x-pack/plugins/cases/common/constants.ts b/x-pack/plugins/cases/common/constants.ts index 29a8029dda063..cc2cfb5e873ff 100644 --- a/x-pack/plugins/cases/common/constants.ts +++ b/x-pack/plugins/cases/common/constants.ts @@ -69,6 +69,7 @@ export const CASE_USER_ACTIONS_URL = `${CASE_DETAILS_URL}/user_actions` as const export const CASE_ALERTS_URL = `${CASES_URL}/alerts/{alert_id}` as const; export const CASE_DETAILS_ALERTS_URL = `${CASE_DETAILS_URL}/alerts` as const; +export const CASE_METRICS_URL = `${CASES_URL}/metrics` as const; export const CASE_METRICS_DETAILS_URL = `${CASES_URL}/metrics/{case_id}` as const; /** diff --git a/x-pack/plugins/cases/common/ui/types.ts b/x-pack/plugins/cases/common/ui/types.ts index c0c68f5d9964a..4e5671a946506 100644 --- a/x-pack/plugins/cases/common/ui/types.ts +++ b/x-pack/plugins/cases/common/ui/types.ts @@ -7,16 +7,15 @@ import type { SavedObjectsResolveResponse } from '@kbn/core/public'; import { - CaseAttributes, - CaseConnector, CasePatchRequest, CaseStatuses, User, ActionConnector, CaseExternalServiceBasic, CaseUserActionResponse, - CaseMetricsResponse, + SingleCaseMetricsResponse, CommentResponse, + CaseResponse, CommentResponseAlertsType, } from '../api'; import { SnakeToCamelCase } from '../types'; @@ -25,7 +24,7 @@ type DeepRequired = { [K in keyof T]: DeepRequired } & Required; export interface CasesContextFeatures { alerts: { sync?: boolean; enabled?: boolean }; - metrics: CaseMetricsFeature[]; + metrics: SingleCaseMetricsFeature[]; } export type CasesFeaturesAllRequired = DeepRequired; @@ -61,31 +60,7 @@ export type Comment = SnakeToCamelCase; export type AlertComment = SnakeToCamelCase; export type CaseUserActions = SnakeToCamelCase; export type CaseExternalService = SnakeToCamelCase; - -interface BasicCase { - id: string; - owner: string; - closedAt: string | null; - closedBy: ElasticUser | null; - comments: Comment[]; - createdAt: string; - createdBy: ElasticUser; - status: CaseStatuses; - title: string; - totalAlerts: number; - totalComment: number; - updatedAt: string | null; - updatedBy: ElasticUser | null; - version: string; -} - -export interface Case extends BasicCase { - connector: CaseConnector; - description: string; - externalService: CaseExternalService | null; - settings: CaseAttributes['settings']; - tags: string[]; -} +export type Case = Omit, 'comments'> & { comments: Comment[] }; export interface ResolvedCase { case: Case; @@ -122,8 +97,8 @@ export interface AllCases extends CasesStatus { total: number; } -export type CaseMetrics = CaseMetricsResponse; -export type CaseMetricsFeature = +export type SingleCaseMetrics = SingleCaseMetricsResponse; +export type SingleCaseMetricsFeature = | 'alerts.count' | 'alerts.users' | 'alerts.hosts' diff --git a/x-pack/plugins/cases/public/common/navigation/__mocks__/hooks.ts b/x-pack/plugins/cases/public/common/navigation/__mocks__/hooks.ts index 93f202994918d..38f57a9ef45bd 100644 --- a/x-pack/plugins/cases/public/common/navigation/__mocks__/hooks.ts +++ b/x-pack/plugins/cases/public/common/navigation/__mocks__/hooks.ts @@ -26,3 +26,8 @@ export const useConfigureCasesNavigation = jest.fn().mockReturnValue({ getConfigureCasesUrl: jest.fn().mockReturnValue('/app/security/cases/configure'), navigateToConfigureCases: jest.fn(), }); + +export const useUrlParams = jest.fn().mockReturnValue({ + urlParams: {}, + toUrlParams: jest.fn(), +}); diff --git a/x-pack/plugins/cases/public/common/navigation/hooks.ts b/x-pack/plugins/cases/public/common/navigation/hooks.ts index c5488b4060795..1197ef0c5cf11 100644 --- a/x-pack/plugins/cases/public/common/navigation/hooks.ts +++ b/x-pack/plugins/cases/public/common/navigation/hooks.ts @@ -5,9 +5,10 @@ * 2.0. */ -import { useCallback } from 'react'; -import { useParams } from 'react-router-dom'; +import { useCallback, useEffect, useState } from 'react'; +import { useLocation, useParams } from 'react-router-dom'; +import { parse, stringify } from 'query-string'; import { APP_ID } from '../../../common/constants'; import { useNavigation } from '../lib/kibana'; import { useCasesContext } from '../../components/cases_context/use_cases_context'; @@ -16,11 +17,28 @@ import { CASES_CONFIGURE_PATH, CASES_CREATE_PATH, CaseViewPathParams, + CaseViewPathSearchParams, generateCaseViewPath, } from './paths'; export const useCaseViewParams = () => useParams(); +export function useUrlParams() { + const { search } = useLocation(); + const [urlParams, setUrlParams] = useState(() => parse(search)); + const toUrlParams = useCallback( + (params: CaseViewPathSearchParams = urlParams) => stringify(params), + [urlParams] + ); + useEffect(() => { + setUrlParams(parse(search)); + }, [search]); + return { + urlParams, + toUrlParams, + }; +} + type GetCasesUrl = (absolute?: boolean) => string; type NavigateToCases = () => void; type UseCasesNavigation = [GetCasesUrl, NavigateToCases]; diff --git a/x-pack/plugins/cases/public/common/navigation/paths.ts b/x-pack/plugins/cases/public/common/navigation/paths.ts index a8660b5cf63ab..857f832f7aed3 100644 --- a/x-pack/plugins/cases/public/common/navigation/paths.ts +++ b/x-pack/plugins/cases/public/common/navigation/paths.ts @@ -6,17 +6,26 @@ */ import { generatePath } from 'react-router-dom'; +import { CASE_VIEW_PAGE_TABS } from '../../components/case_view/types'; export const DEFAULT_BASE_PATH = '/cases'; -export interface CaseViewPathParams { + +export interface CaseViewPathSearchParams { + tabId?: CASE_VIEW_PAGE_TABS; +} + +export type CaseViewPathParams = { detailName: string; commentId?: string; -} +} & CaseViewPathSearchParams; export const CASES_CREATE_PATH = '/create' as const; export const CASES_CONFIGURE_PATH = '/configure' as const; export const CASE_VIEW_PATH = '/:detailName' as const; export const CASE_VIEW_COMMENT_PATH = `${CASE_VIEW_PATH}/:commentId` as const; +export const CASE_VIEW_ALERT_TABLE_PATH = + `${CASE_VIEW_PATH}/?tabId=${CASE_VIEW_PAGE_TABS.ALERTS}` as const; +export const CASE_VIEW_TAB_PATH = `${CASE_VIEW_PATH}/?tabId=:tabId` as const; const normalizePath = (path: string): string => path.replaceAll('//', '/'); @@ -30,12 +39,19 @@ export const getCaseViewWithCommentPath = (casesBasePath: string) => normalizePath(`${casesBasePath}${CASE_VIEW_COMMENT_PATH}`); export const generateCaseViewPath = (params: CaseViewPathParams): string => { - const { commentId } = params; + const { commentId, tabId } = params; // Cast for generatePath argument type constraint const pathParams = params as unknown as { [paramName: string]: string }; + // paths with commentId have their own specific path. + // Effectively overwrites the tabId if (commentId) { return normalizePath(generatePath(CASE_VIEW_COMMENT_PATH, pathParams)); } + + if (tabId !== undefined) { + return normalizePath(generatePath(CASE_VIEW_TAB_PATH, pathParams)); + } + return normalizePath(generatePath(CASE_VIEW_PATH, pathParams)); }; diff --git a/x-pack/plugins/cases/public/components/all_cases/all_cases_list.test.tsx b/x-pack/plugins/cases/public/components/all_cases/all_cases_list.test.tsx index ef6d789e97a36..87d53aae14e28 100644 --- a/x-pack/plugins/cases/public/components/all_cases/all_cases_list.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/all_cases_list.test.tsx @@ -560,6 +560,7 @@ describe('AllCasesListGeneric', () => { username: 'lknope', }, description: 'Security banana Issue', + duration: null, externalService: { connectorId: '123', connectorName: 'connector name', diff --git a/x-pack/plugins/cases/public/components/case_view/case_view_page.test.tsx b/x-pack/plugins/cases/public/components/case_view/case_view_page.test.tsx index a933e823f8b3a..fd0f7eebe0095 100644 --- a/x-pack/plugins/cases/public/components/case_view/case_view_page.test.tsx +++ b/x-pack/plugins/cases/public/components/case_view/case_view_page.test.tsx @@ -5,29 +5,29 @@ * 2.0. */ -import React from 'react'; +import { act, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { mount } from 'enzyme'; -import { waitFor } from '@testing-library/react'; - +import React from 'react'; +import { ConnectorTypes } from '../../../common/api'; +import { AppMockRenderer, createAppMockRenderer, TestProviders } from '../../common/mock'; import '../../common/mock/match_media'; -import { CaseViewPage } from './case_view_page'; -import { CaseViewPageProps } from './types'; +import { useCaseViewNavigation, useUrlParams } from '../../common/navigation/hooks'; +import { useConnectors } from '../../containers/configure/use_connectors'; import { basicCaseClosed, basicCaseMetrics, caseUserActions, - getAlertUserAction, connectorsMock, + getAlertUserAction, } from '../../containers/mock'; -import { TestProviders } from '../../common/mock'; -import { useUpdateCase } from '../../containers/use_update_case'; +import { useGetCaseMetrics } from '../../containers/use_get_case_metrics'; import { useGetCaseUserActions } from '../../containers/use_get_case_user_actions'; - -import { useConnectors } from '../../containers/configure/use_connectors'; import { usePostPushToService } from '../../containers/use_post_push_to_service'; -import { useGetCaseMetrics } from '../../containers/use_get_case_metrics'; -import { ConnectorTypes } from '../../../common/api'; -import { caseViewProps, caseData } from './index.test'; +import { useUpdateCase } from '../../containers/use_update_case'; +import { CaseViewPage } from './case_view_page'; +import { caseData, caseViewProps } from './index.test'; +import { CaseViewPageProps, CASE_VIEW_PAGE_TABS } from './types'; jest.mock('../../containers/use_update_case'); jest.mock('../../containers/use_get_case_metrics'); @@ -36,9 +36,11 @@ jest.mock('../../containers/use_get_case'); jest.mock('../../containers/configure/use_connectors'); jest.mock('../../containers/use_post_push_to_service'); jest.mock('../user_actions/timestamp'); -jest.mock('../../common/lib/kibana'); jest.mock('../../common/navigation/hooks'); +jest.mock('../../common/hooks'); +const useUrlParamsMock = useUrlParams as jest.Mock; +const useCaseViewNavigationMock = useCaseViewNavigation as jest.Mock; const useUpdateCaseMock = useUpdateCase as jest.Mock; const useGetCaseMetricsMock = useGetCaseMetrics as jest.Mock; const useGetCaseUserActionsMock = useGetCaseUserActions as jest.Mock; @@ -433,7 +435,7 @@ describe('CaseViewPage', () => { }); }); - it('it should call onComponentInitialized on mount', async () => { + it('should call onComponentInitialized on mount', async () => { const onComponentInitialized = jest.fn(); mount( @@ -576,4 +578,108 @@ describe('CaseViewPage', () => { }); }); }); + + describe('Tabs', () => { + let appMockRender: AppMockRenderer; + beforeEach(() => { + appMockRender = createAppMockRenderer(); + }); + + // unskip when alerts tab is activated + it.skip('renders tabs correctly', async () => { + const result = appMockRender.render(); + await act(async () => { + expect(result.getByTestId('case-view-tab-title-alerts')).toBeTruthy(); + expect(result.getByTestId('case-view-tab-title-activity')).toBeTruthy(); + }); + }); + + it('renders the activity tab by default', async () => { + const result = appMockRender.render(); + await act(async () => { + expect(result.getByTestId('case-view-tab-content-activity')).toBeTruthy(); + }); + }); + + it('renders the alerts tab when the query parameter tabId has alerts', async () => { + useUrlParamsMock.mockReturnValue({ + urlParams: { + tabId: CASE_VIEW_PAGE_TABS.ALERTS, + }, + }); + const result = appMockRender.render(); + await act(async () => { + expect(result.getByTestId('case-view-tab-content-alerts')).toBeTruthy(); + }); + }); + + it('renders the activity tab when the query parameter tabId has activity', async () => { + useUrlParamsMock.mockReturnValue({ + urlParams: { + tabId: CASE_VIEW_PAGE_TABS.ACTIVITY, + }, + }); + const result = appMockRender.render(); + await act(async () => { + expect(result.getByTestId('case-view-tab-content-activity')).toBeTruthy(); + }); + }); + + it('renders the activity tab when the query parameter tabId has an unknown value', async () => { + useUrlParamsMock.mockReturnValue({ + urlParams: { + tabId: 'what-is-love', + }, + }); + const result = appMockRender.render(); + await act(async () => { + expect(result.getByTestId('case-view-tab-content-activity')).toBeTruthy(); + expect(result.queryByTestId('case-view-tab-content-alerts')).toBeFalsy(); + }); + }); + + it('navigates to the activity tab when the activity tab is clicked', async () => { + const navigateToCaseViewMock = useCaseViewNavigationMock().navigateToCaseView; + const result = appMockRender.render(); + userEvent.click(result.getByTestId('case-view-tab-title-activity')); + await act(async () => { + expect(navigateToCaseViewMock).toHaveBeenCalledWith({ + detailName: caseData.id, + tabId: CASE_VIEW_PAGE_TABS.ACTIVITY, + }); + }); + }); + + // unskip when alerts tab is activated + it.skip('navigates to the alerts tab when the alerts tab is clicked', async () => { + const navigateToCaseViewMock = useCaseViewNavigationMock().navigateToCaseView; + const result = appMockRender.render(); + userEvent.click(result.getByTestId('case-view-tab-title-alerts')); + await act(async () => { + expect(navigateToCaseViewMock).toHaveBeenCalledWith({ + detailName: caseData.id, + tabId: CASE_VIEW_PAGE_TABS.ALERTS, + }); + }); + }); + + // unskip when alerts tab is activated + it.skip('should display the alerts tab when the feature is enabled', async () => { + appMockRender = createAppMockRenderer({ features: { alerts: { enabled: true } } }); + const result = appMockRender.render(); + await act(async () => { + expect(result.queryByTestId('case-view-tab-title-activity')).toBeTruthy(); + expect(result.queryByTestId('case-view-tab-title-alerts')).toBeTruthy(); + }); + }); + + it('should not display the alerts tab when the feature is disabled', async () => { + appMockRender = createAppMockRenderer({ features: { alerts: { enabled: false } } }); + const result = appMockRender.render(); + await act(async () => { + expect(result.queryByTestId('case-view-tab-title-activity')).toBeTruthy(); + expect(result.queryByTestId('case-view-tab-title-alerts')).toBeFalsy(); + }); + }); + }); }); diff --git a/x-pack/plugins/cases/public/components/case_view/case_view_page.tsx b/x-pack/plugins/cases/public/components/case_view/case_view_page.tsx index 72d976f45f618..b6f22e9c5fb4d 100644 --- a/x-pack/plugins/cases/public/components/case_view/case_view_page.tsx +++ b/x-pack/plugins/cases/public/components/case_view/case_view_page.tsx @@ -5,102 +5,38 @@ * 2.0. */ -import React, { useCallback, useEffect, useMemo, useState, useRef } from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiLoadingContent, EuiSpacer } from '@elastic/eui'; - -import { CaseStatuses, CaseAttributes, CaseConnector } from '../../../common/api'; -import { Case, UpdateKey, UpdateByKey } from '../../../common/ui'; -import { EditableTitle } from '../header_page/editable_title'; -import { TagList } from '../tag_list'; -import { UserActions } from '../user_actions'; -import { UserList } from '../user_list'; -import { useUpdateCase } from '../../containers/use_update_case'; -import { getTypedPayload } from '../../containers/utils'; -import { ContentWrapper, WhitePageWrapper } from '../wrappers'; -import { CaseActionBar } from '../case_action_bar'; +import { + EuiEmptyPrompt, + EuiFlexGroup, + EuiFlexItem, + EuiLoadingLogo, + EuiSpacer, + EuiTab, + EuiTabs, +} from '@elastic/eui'; +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { Case, UpdateKey } from '../../../common/ui'; +import { useCaseViewNavigation, useUrlParams } from '../../common/navigation'; +import { useGetCaseMetrics } from '../../containers/use_get_case_metrics'; import { useGetCaseUserActions } from '../../containers/use_get_case_user_actions'; -import { EditConnector } from '../edit_connector'; -import { useConnectors } from '../../containers/configure/use_connectors'; -import { normalizeActionConnector, getNoneConnector } from '../configure_cases/utils'; -import { StatusActionButton } from '../status/button'; -import * as i18n from './translations'; -import { useTimelineContext } from '../timeline_context/use_timeline_context'; -import { getConnectorById } from '../utils'; import { useCasesContext } from '../cases_context/use_cases_context'; -import { useCaseViewNavigation } from '../../common/navigation'; +import { useCasesFeatures } from '../cases_context/use_cases_features'; +import { CaseActionBar } from '../case_action_bar'; import { HeaderPage } from '../header_page'; +import { EditableTitle } from '../header_page/editable_title'; +import { useTimelineContext } from '../timeline_context/use_timeline_context'; import { useCasesTitleBreadcrumbs } from '../use_breadcrumbs'; -import { useGetCaseMetrics } from '../../containers/use_get_case_metrics'; +import { WhitePageWrapperNoBorder } from '../wrappers'; +import { CaseViewActivity } from './components/case_view_activity'; import { CaseViewMetrics } from './metrics'; -import type { CaseViewPageProps, OnUpdateFields } from './types'; -import { useCasesFeatures } from '../cases_context/use_cases_features'; - -const useOnUpdateField = ({ - caseData, - caseId, - handleUpdateField, -}: { - caseData: Case; - caseId: string; - handleUpdateField: (newCase: Case, updateKey: UpdateKey) => void; -}) => { - const { isLoading, updateKey: loadingKey, updateCaseProperty } = useUpdateCase({ caseId }); +import { ACTIVITY_TAB, ALERTS_TAB } from './translations'; +import { CaseViewPageProps, CASE_VIEW_PAGE_TABS } from './types'; +import { useOnUpdateField } from './use_on_update_field'; - const onUpdateField = useCallback( - ({ key, value, onSuccess, onError }: OnUpdateFields) => { - const callUpdate = (updateKey: UpdateKey, updateValue: UpdateByKey['updateValue']) => - updateCaseProperty({ - updateKey, - updateValue, - updateCase: (newCase) => handleUpdateField(newCase, updateKey), - caseData, - onSuccess, - onError, - }); - - switch (key) { - case 'title': - const titleUpdate = getTypedPayload(value); - if (titleUpdate.length > 0) { - callUpdate('title', titleUpdate); - } - break; - case 'connector': - const connector = getTypedPayload(value); - if (connector != null) { - callUpdate('connector', connector); - } - break; - case 'description': - const descriptionUpdate = getTypedPayload(value); - if (descriptionUpdate.length > 0) { - callUpdate('description', descriptionUpdate); - } - break; - case 'tags': - const tagsUpdate = getTypedPayload(value); - callUpdate('tags', tagsUpdate); - break; - case 'status': - const statusUpdate = getTypedPayload(value); - if (caseData.status !== value) { - callUpdate('status', statusUpdate); - } - break; - case 'settings': - const settingsUpdate = getTypedPayload(value); - if (caseData.settings !== value) { - callUpdate('settings', settingsUpdate); - } - break; - default: - return null; - } - }, - [updateCaseProperty, handleUpdateField, caseData] - ); - return { onUpdateField, isLoading, loadingKey }; -}; +// This hardcoded constant is left here intentionally +// as a way to hide a wip functionality +// that will be merge in the 8.3 release. +const ENABLE_ALERTS_TAB = false; export const CaseViewPage = React.memo( ({ @@ -108,30 +44,37 @@ export const CaseViewPage = React.memo( caseId, fetchCase, onComponentInitialized, - actionsNavigation, + updateCase, + refreshRef, ruleDetailsNavigation, + actionsNavigation, showAlertDetails, - updateCase, useFetchAlertData, - refreshRef, }) => { - const { userCanCrud } = useCasesContext(); + const { userCanCrud, features } = useCasesContext(); const { metricsFeatures } = useCasesFeatures(); - const { getCaseViewUrl } = useCaseViewNavigation(); useCasesTitleBreadcrumbs(caseData.title); + const { navigateToCaseView } = useCaseViewNavigation(); + const { urlParams } = useUrlParams(); + const activeTabId = useMemo(() => { + if (urlParams.tabId && Object.values(CASE_VIEW_PAGE_TABS).includes(urlParams.tabId)) { + return urlParams.tabId; + } + return CASE_VIEW_PAGE_TABS.ACTIVITY; + }, [urlParams.tabId]); + const [initLoadingData, setInitLoadingData] = useState(true); const init = useRef(true); const timelineUi = useTimelineContext()?.ui; + const getCaseUserActions = useGetCaseUserActions(caseId, caseData.connector.id); + const { - caseUserActions, fetchCaseUserActions, caseServices, - hasDataToPush, isLoading: isLoadingUserActions, - participants, - } = useGetCaseUserActions(caseId, caseData.connector.id); + } = getCaseUserActions; const refetchCaseUserActions = useCallback(() => { fetchCaseUserActions(caseId, caseData.connector.id); @@ -149,17 +92,8 @@ export const CaseViewPage = React.memo( refetchCaseUserActions(); }, [fetchCase, refetchCaseUserActions, fetchCaseMetrics]); - const handleUpdateCase = useCallback( - (newCase: Case) => { - updateCase(newCase); - fetchCaseUserActions(caseId, newCase.connector.id); - fetchCaseMetrics(); - }, - [updateCase, fetchCaseUserActions, caseId, fetchCaseMetrics] - ); - const handleUpdateField = useCallback( - (newCase: Case, updateKey: UpdateKey) => { + (newCase: Case, _updateKey: UpdateKey) => { updateCase({ ...newCase, comments: caseData.comments }); fetchCaseUserActions(caseId, newCase.connector.id); fetchCaseMetrics(); @@ -202,13 +136,6 @@ export const CaseViewPage = React.memo( updateCase, ]); - const { loading: isLoadingConnectors, connectors } = useConnectors(); - - const [connectorName, isValidConnector] = useMemo(() => { - const connector = connectors.find((c) => c.id === caseData.connector.id); - return [connector?.name ?? '', !!connector]; - }, [connectors, caseData.connector]); - const currentExternalIncident = useMemo( () => caseServices != null && caseServices[caseData.connector.id] != null @@ -217,28 +144,6 @@ export const CaseViewPage = React.memo( [caseServices, caseData.connector] ); - const onSubmitConnector = useCallback( - (connectorId, connectorFields, onError, onSuccess) => { - const connector = getConnectorById(connectorId, connectors); - const connectorToUpdate = connector - ? normalizeActionConnector(connector) - : getNoneConnector(); - - onUpdateField({ - key: 'connector', - value: { ...connectorToUpdate, fields: connectorFields }, - onSuccess, - onError, - }); - }, - [onUpdateField, connectors] - ); - - const onSubmitTags = useCallback( - (newTags) => onUpdateField({ key: 'tags', value: newTags }), - [onUpdateField] - ); - const onSubmitTitle = useCallback( (newTitle) => onUpdateField({ @@ -248,38 +153,12 @@ export const CaseViewPage = React.memo( [onUpdateField] ); - const changeStatus = useCallback( - (status: CaseStatuses) => - onUpdateField({ - key: 'status', - value: status, - }), - [onUpdateField] - ); - - const emailContent = useMemo( - () => ({ - subject: i18n.EMAIL_SUBJECT(caseData.title), - body: i18n.EMAIL_BODY(getCaseViewUrl({ detailName: caseId })), - }), - [caseData.title, getCaseViewUrl, caseId] - ); - useEffect(() => { if (initLoadingData && !isLoadingUserActions) { setInitLoadingData(false); } }, [initLoadingData, isLoadingUserActions]); - const onShowAlertDetails = useCallback( - (alertId: string, index: string) => { - if (showAlertDetails) { - showAlertDetails(alertId, index); - } - }, - [showAlertDetails] - ); - // useEffect used for component's initialization useEffect(() => { if (init.current) { @@ -290,9 +169,76 @@ export const CaseViewPage = React.memo( } }, [onComponentInitialized]); + const tabs = useMemo( + () => [ + { + id: CASE_VIEW_PAGE_TABS.ACTIVITY, + name: ACTIVITY_TAB, + content: ( + + ), + }, + ...(features.alerts.enabled && ENABLE_ALERTS_TAB + ? [ + { + id: CASE_VIEW_PAGE_TABS.ALERTS, + name: ALERTS_TAB, + content: ( + } + title={

{'Alerts table placeholder'}

} + /> + ), + }, + ] + : []), + ], + [ + actionsNavigation, + caseData, + caseId, + features.alerts.enabled, + fetchCaseMetrics, + getCaseUserActions, + initLoadingData, + ruleDetailsNavigation, + showAlertDetails, + updateCase, + useFetchAlertData, + ] + ); + const selectedTabContent = useMemo(() => { + return tabs.find((obj) => obj.id === activeTabId)?.content; + }, [activeTabId, tabs]); + + const renderTabs = useCallback(() => { + return tabs.map((tab, index) => ( + navigateToCaseView({ detailName: caseId, tabId: tab.id })} + isSelected={tab.id === activeTabId} + > + {tab.name} + + )); + }, [activeTabId, caseId, navigateToCaseView, tabs]); + return ( <> ( /> - - - - - {!initLoadingData && metricsFeatures.length > 0 ? ( + + {!initLoadingData && metricsFeatures.length > 0 ? ( + <> + + - ) : null} - - - - - - {initLoadingData && ( - - )} - {!initLoadingData && ( - - - - ) : null - } - updateCase={updateCase} - useFetchAlertData={useFetchAlertData} - userCanCrud={userCanCrud} - /> - - - )} - - - - - - - - - - + + + + + ) : null} + {renderTabs()} + + + {selectedTabContent} + + {timelineUi?.renderTimelineDetailsPanel ? timelineUi.renderTimelineDetailsPanel() : null} ); diff --git a/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx b/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx new file mode 100644 index 0000000000000..463af7cdac8d8 --- /dev/null +++ b/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx @@ -0,0 +1,136 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + alertComment, + basicCase, + caseUserActions, + connectorsMock, + getAlertUserAction, +} from '../../../containers/mock'; +import React from 'react'; +import { AppMockRenderer, createAppMockRenderer } from '../../../common/mock'; +import { CaseViewActivity } from './case_view_activity'; +import { ConnectorTypes } from '../../../../common/api/connectors'; +import { Case } from '../../../../common'; +import { CaseViewProps } from '../types'; +import { + UseGetCaseUserActions, + useGetCaseUserActions, +} from '../../../containers/use_get_case_user_actions'; +import { useConnectors } from '../../../containers/configure/use_connectors'; +import { usePostPushToService } from '../../../containers/use_post_push_to_service'; +import { useGetActionLicense } from '../../../containers/use_get_action_license'; +import { useGetTags } from '../../../containers/use_get_tags'; + +jest.mock('../../../containers/use_get_case_user_actions'); +jest.mock('../../../containers/configure/use_connectors'); +jest.mock('../../../containers/use_post_push_to_service'); +jest.mock('../../user_actions/timestamp'); +jest.mock('../../../common/navigation/hooks'); +jest.mock('../../../containers/use_get_action_license'); +jest.mock('../../../containers/use_get_tags'); + +(useGetTags as jest.Mock).mockReturnValue({ tags: ['coke', 'pepsi'], fetchTags: jest.fn() }); +(useGetActionLicense as jest.Mock).mockReturnValue({ + actionLicense: null, + isLoading: false, +}); + +const caseData: Case = { + ...basicCase, + comments: [...basicCase.comments, alertComment], + connector: { + id: 'resilient-2', + name: 'Resilient', + type: ConnectorTypes.resilient, + fields: null, + }, +}; + +const caseViewProps: CaseViewProps = { + onComponentInitialized: jest.fn(), + actionsNavigation: { + href: jest.fn(), + onClick: jest.fn(), + }, + ruleDetailsNavigation: { + href: jest.fn(), + onClick: jest.fn(), + }, + showAlertDetails: jest.fn(), + useFetchAlertData: () => [ + false, + { + 'alert-id-1': '1234', + 'alert-id-2': '1234', + }, + ], +}; +const fetchCaseUserActions = jest.fn(); +const pushCaseToExternalService = jest.fn(); + +const defaultUseGetCaseUserActions = { + caseUserActions: [...caseUserActions, getAlertUserAction()], + caseServices: {}, + fetchCaseUserActions, + firstIndexPushToService: -1, + hasDataToPush: false, + isLoading: false, + isError: false, + lastIndexPushToService: -1, + participants: [caseData.createdBy], +}; + +export const caseProps = { + ...caseViewProps, + initLoadingData: false, + caseId: caseData.id, + caseData, + updateCase: jest.fn(), + fetchCaseMetrics: jest.fn(), + getCaseUserActions: { + caseServices: {}, + caseUserActions: [], + hasDataToPush: false, + isError: false, + isLoading: true, + participants: [], + fetchCaseUserActions: jest.fn(), + } as UseGetCaseUserActions, +}; + +const useGetCaseUserActionsMock = useGetCaseUserActions as jest.Mock; +const useConnectorsMock = useConnectors as jest.Mock; +const usePostPushToServiceMock = usePostPushToService as jest.Mock; + +describe('Case View Page activity tab', () => { + beforeAll(() => { + useGetCaseUserActionsMock.mockReturnValue(defaultUseGetCaseUserActions); + useConnectorsMock.mockReturnValue({ connectors: connectorsMock, loading: false }); + usePostPushToServiceMock.mockReturnValue({ isLoading: false, pushCaseToExternalService }); + }); + let appMockRender: AppMockRenderer; + beforeEach(() => { + appMockRender = createAppMockRenderer(); + }); + it('should render the activity content and main components', () => { + const result = appMockRender.render(); + expect(result.getByTestId('case-view-activity')).toBeTruthy(); + expect(result.getByTestId('user-actions')).toBeTruthy(); + expect(result.getByTestId('case-tags')).toBeTruthy(); + expect(result.getByTestId('connector-edit-header')).toBeTruthy(); + expect(result.getByTestId('case-view-status-action-button')).toBeTruthy(); + }); + + it('should show a loading when initLoadingData is true and hide the user actions activity', () => { + const props = { ...caseProps, initLoadingData: true }; + const result = appMockRender.render(); + expect(result.getByTestId('case-view-loading-content')).toBeTruthy(); + expect(result.queryByTestId('case-view-activity')).toBeFalsy(); + }); +}); diff --git a/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.tsx b/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.tsx new file mode 100644 index 0000000000000..b9e4beb5d7e26 --- /dev/null +++ b/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.tsx @@ -0,0 +1,220 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiFlexGroup, EuiFlexItem, EuiLoadingContent } from '@elastic/eui'; +import React, { useCallback, useMemo } from 'react'; +import { useConnectors } from '../../../containers/configure/use_connectors'; +import { useCaseViewNavigation } from '../../../common/navigation'; +import { UpdateKey, UseFetchAlertData } from '../../../../common/ui/types'; +import { Case, CaseStatuses } from '../../../../common'; +import { EditConnector } from '../../edit_connector'; +import { CasesNavigation } from '../../links'; +import { StatusActionButton } from '../../status/button'; +import { TagList } from '../../tag_list'; +import { UserActions } from '../../user_actions'; +import { UserList } from '../../user_list'; +import { useOnUpdateField } from '../use_on_update_field'; +import { useCasesContext } from '../../cases_context/use_cases_context'; +import * as i18n from '../translations'; +import { getNoneConnector, normalizeActionConnector } from '../../configure_cases/utils'; +import { getConnectorById } from '../../utils'; +import { UseGetCaseUserActions } from '../../../containers/use_get_case_user_actions'; + +export const CaseViewActivity = ({ + initLoadingData, + ruleDetailsNavigation, + caseId, + caseData, + actionsNavigation, + showAlertDetails, + updateCase, + fetchCaseMetrics, + useFetchAlertData, + getCaseUserActions, +}: { + initLoadingData: boolean; + ruleDetailsNavigation?: CasesNavigation; + caseId: string; + caseData: Case; + actionsNavigation?: CasesNavigation; + showAlertDetails?: (alertId: string, index: string) => void; + updateCase: (newCase: Case) => void; + fetchCaseMetrics: (silent?: boolean) => Promise; + useFetchAlertData: UseFetchAlertData; + getCaseUserActions: UseGetCaseUserActions; +}) => { + const { userCanCrud } = useCasesContext(); + const { getCaseViewUrl } = useCaseViewNavigation(); + + const { + caseUserActions, + fetchCaseUserActions, + caseServices, + hasDataToPush, + isLoading: isLoadingUserActions, + participants, + } = getCaseUserActions; + + const refetchCaseUserActions = useCallback(() => { + fetchCaseUserActions(caseId, caseData.connector.id); + }, [caseId, fetchCaseUserActions, caseData]); + + const onShowAlertDetails = useCallback( + (alertId: string, index: string) => { + if (showAlertDetails) { + showAlertDetails(alertId, index); + } + }, + [showAlertDetails] + ); + + const handleUpdateField = useCallback( + (newCase: Case, _updateKey: UpdateKey) => { + updateCase({ ...newCase, comments: caseData.comments }); + fetchCaseUserActions(caseId, newCase.connector.id); + fetchCaseMetrics(); + }, + [updateCase, caseData, fetchCaseUserActions, caseId, fetchCaseMetrics] + ); + + const { onUpdateField, isLoading, loadingKey } = useOnUpdateField({ + caseId, + caseData, + handleUpdateField, + }); + + const changeStatus = useCallback( + (status: CaseStatuses) => + onUpdateField({ + key: 'status', + value: status, + }), + [onUpdateField] + ); + + const emailContent = useMemo( + () => ({ + subject: i18n.EMAIL_SUBJECT(caseData.title), + body: i18n.EMAIL_BODY(getCaseViewUrl({ detailName: caseId })), + }), + [caseData.title, getCaseViewUrl, caseId] + ); + + const onSubmitTags = useCallback( + (newTags) => onUpdateField({ key: 'tags', value: newTags }), + [onUpdateField] + ); + const { loading: isLoadingConnectors, connectors } = useConnectors(); + + const [connectorName, isValidConnector] = useMemo(() => { + const connector = connectors.find((c) => c.id === caseData.connector.id); + return [connector?.name ?? '', !!connector]; + }, [connectors, caseData.connector]); + + const handleUpdateCase = useCallback( + (newCase: Case) => { + updateCase(newCase); + fetchCaseUserActions(caseId, newCase.connector.id); + fetchCaseMetrics(); + }, + [updateCase, fetchCaseUserActions, caseId, fetchCaseMetrics] + ); + + const onSubmitConnector = useCallback( + (connectorId, connectorFields, onError, onSuccess) => { + const connector = getConnectorById(connectorId, connectors); + const connectorToUpdate = connector + ? normalizeActionConnector(connector) + : getNoneConnector(); + + onUpdateField({ + key: 'connector', + value: { ...connectorToUpdate, fields: connectorFields }, + onSuccess, + onError, + }); + }, + [onUpdateField, connectors] + ); + + return ( + <> + + {initLoadingData && ( + + )} + {!initLoadingData && ( + + + + ) : null + } + updateCase={updateCase} + useFetchAlertData={useFetchAlertData} + userCanCrud={userCanCrud} + /> + + + )} + + + + + + + + + ); +}; +CaseViewActivity.displayName = 'CaseViewActivity'; diff --git a/x-pack/plugins/cases/public/components/case_view/does_not_exist.tsx b/x-pack/plugins/cases/public/components/case_view/does_not_exist.tsx index 0073d2a491b74..7060265d26e0f 100644 --- a/x-pack/plugins/cases/public/components/case_view/does_not_exist.tsx +++ b/x-pack/plugins/cases/public/components/case_view/does_not_exist.tsx @@ -21,7 +21,7 @@ export const DoesNotExist = React.memo(({ caseId }: Props) => { return ( {i18n.DOES_NOT_EXIST_TITLE}} titleSize="xs" body={

{i18n.DOES_NOT_EXIST_DESCRIPTION(caseId)}

} diff --git a/x-pack/plugins/cases/public/components/case_view/metrics/index.test.tsx b/x-pack/plugins/cases/public/components/case_view/metrics/index.test.tsx index f816d39e8c0e0..cecf49ee5d1a3 100644 --- a/x-pack/plugins/cases/public/components/case_view/metrics/index.test.tsx +++ b/x-pack/plugins/cases/public/components/case_view/metrics/index.test.tsx @@ -13,7 +13,7 @@ import { basicCaseStatusFeatures, } from '../../../containers/mock'; import { CaseViewMetrics } from '.'; -import { CaseMetrics, CaseMetricsFeature } from '../../../../common/ui'; +import { SingleCaseMetrics, SingleCaseMetricsFeature } from '../../../../common/ui'; import { TestProviders } from '../../../common/mock'; const renderCaseMetrics = ({ @@ -21,8 +21,8 @@ const renderCaseMetrics = ({ features = [...basicCaseNumericValueFeatures, ...basicCaseStatusFeatures], isLoading = false, }: { - metrics?: CaseMetrics; - features?: CaseMetricsFeature[]; + metrics?: SingleCaseMetrics; + features?: SingleCaseMetricsFeature[]; isLoading?: boolean; } = {}) => { return render( @@ -33,7 +33,7 @@ const renderCaseMetrics = ({ }; interface FeatureTest { - feature: CaseMetricsFeature; + feature: SingleCaseMetricsFeature; items: Array<{ title: string; value: string | number; diff --git a/x-pack/plugins/cases/public/components/case_view/metrics/status.tsx b/x-pack/plugins/cases/public/components/case_view/metrics/status.tsx index df19d1776d86a..d86c5534e1e40 100644 --- a/x-pack/plugins/cases/public/components/case_view/metrics/status.tsx +++ b/x-pack/plugins/cases/public/components/case_view/metrics/status.tsx @@ -9,7 +9,7 @@ import React, { useMemo } from 'react'; import prettyMilliseconds from 'pretty-ms'; import { EuiFlexGrid, EuiFlexGroup, EuiFlexItem, EuiIconTip, EuiSpacer } from '@elastic/eui'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; -import { CaseMetrics, CaseMetricsFeature } from '../../../../common/ui'; +import { SingleCaseMetrics, SingleCaseMetricsFeature } from '../../../../common/ui'; import { CASE_CREATED, CASE_IN_PROGRESS_DURATION, @@ -90,10 +90,10 @@ export const CaseStatusMetrics: React.FC { - return useMemo(() => { + metrics: SingleCaseMetrics | null, + features: SingleCaseMetricsFeature[] +): SingleCaseMetrics['lifespan'] | undefined => { + return useMemo(() => { const lifespan = metrics?.lifespan ?? { closeDate: '', creationDate: '', diff --git a/x-pack/plugins/cases/public/components/case_view/metrics/totals.tsx b/x-pack/plugins/cases/public/components/case_view/metrics/totals.tsx index 39b3f8613120a..77a0852901b9c 100644 --- a/x-pack/plugins/cases/public/components/case_view/metrics/totals.tsx +++ b/x-pack/plugins/cases/public/components/case_view/metrics/totals.tsx @@ -8,7 +8,7 @@ import React, { useMemo } from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; -import { CaseMetrics, CaseMetricsFeature } from '../../../../common/ui'; +import { SingleCaseMetrics, SingleCaseMetricsFeature } from '../../../../common/ui'; import { ASSOCIATED_HOSTS_METRIC, ASSOCIATED_USERS_METRIC, @@ -50,8 +50,8 @@ interface MetricItem { type MetricItems = MetricItem[]; const useGetTitleValueMetricItems = ( - metrics: CaseMetrics | null, - features: CaseMetricsFeature[] + metrics: SingleCaseMetrics | null, + features: SingleCaseMetricsFeature[] ): MetricItems => { const { alerts, actions, connectors } = metrics ?? {}; const totalConnectors = connectors?.total ?? 0; @@ -61,7 +61,7 @@ const useGetTitleValueMetricItems = ( const totalIsolatedHosts = calculateTotalIsolatedHosts(actions); const metricItems = useMemo(() => { - const items: Array<[CaseMetricsFeature, Omit]> = [ + const items: Array<[SingleCaseMetricsFeature, Omit]> = [ ['alerts.count', { title: TOTAL_ALERTS_METRIC, value: alertsCount }], ['alerts.users', { title: ASSOCIATED_USERS_METRIC, value: totalAlertUsers }], ['alerts.hosts', { title: ASSOCIATED_HOSTS_METRIC, value: totalAlertHosts }], @@ -88,7 +88,7 @@ const useGetTitleValueMetricItems = ( return metricItems; }; -const calculateTotalIsolatedHosts = (actions: CaseMetrics['actions']) => { +const calculateTotalIsolatedHosts = (actions: SingleCaseMetrics['actions']) => { if (!actions?.isolateHost) { return 0; } diff --git a/x-pack/plugins/cases/public/components/case_view/metrics/types.ts b/x-pack/plugins/cases/public/components/case_view/metrics/types.ts index 5a00aed38dd8a..20138a482cb36 100644 --- a/x-pack/plugins/cases/public/components/case_view/metrics/types.ts +++ b/x-pack/plugins/cases/public/components/case_view/metrics/types.ts @@ -5,10 +5,10 @@ * 2.0. */ -import { CaseMetrics, CaseMetricsFeature } from '../../../../common/ui'; +import { SingleCaseMetrics, SingleCaseMetricsFeature } from '../../../../common/ui'; export interface CaseViewMetricsProps { - metrics: CaseMetrics | null; - features: CaseMetricsFeature[]; + metrics: SingleCaseMetrics | null; + features: SingleCaseMetricsFeature[]; isLoading: boolean; } diff --git a/x-pack/plugins/cases/public/components/case_view/translations.ts b/x-pack/plugins/cases/public/components/case_view/translations.ts index 761cecb1121ca..94c19165e515b 100644 --- a/x-pack/plugins/cases/public/components/case_view/translations.ts +++ b/x-pack/plugins/cases/public/components/case_view/translations.ts @@ -155,3 +155,11 @@ export const DOES_NOT_EXIST_DESCRIPTION = (caseId: string) => export const DOES_NOT_EXIST_BUTTON = i18n.translate('xpack.cases.caseView.doesNotExist.button', { defaultMessage: 'Back to Cases', }); + +export const ACTIVITY_TAB = i18n.translate('xpack.cases.caseView.tabs.activity', { + defaultMessage: 'Activity', +}); + +export const ALERTS_TAB = i18n.translate('xpack.cases.caseView.tabs.alerts', { + defaultMessage: 'Alerts', +}); diff --git a/x-pack/plugins/cases/public/components/case_view/types.ts b/x-pack/plugins/cases/public/components/case_view/types.ts index 3d436a7db3186..2b806e5f804cd 100644 --- a/x-pack/plugins/cases/public/components/case_view/types.ts +++ b/x-pack/plugins/cases/public/components/case_view/types.ts @@ -41,3 +41,8 @@ export interface OnUpdateFields { onSuccess?: () => void; onError?: () => void; } + +export enum CASE_VIEW_PAGE_TABS { + ALERTS = 'alerts', + ACTIVITY = 'activity', +} diff --git a/x-pack/plugins/cases/public/components/case_view/use_on_update_field.ts b/x-pack/plugins/cases/public/components/case_view/use_on_update_field.ts new file mode 100644 index 0000000000000..dba7719d24fbf --- /dev/null +++ b/x-pack/plugins/cases/public/components/case_view/use_on_update_field.ts @@ -0,0 +1,82 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useCallback } from 'react'; +import { CaseConnector } from '../../../common/api'; +import { CaseAttributes } from '../../../common/api/cases/case'; +import { CaseStatuses } from '../../../common/api/cases/status'; +import { Case, UpdateByKey, UpdateKey } from '../../containers/types'; +import { useUpdateCase } from '../../containers/use_update_case'; +import { getTypedPayload } from '../../containers/utils'; +import { OnUpdateFields } from './types'; + +export const useOnUpdateField = ({ + caseData, + caseId, + handleUpdateField, +}: { + caseData: Case; + caseId: string; + handleUpdateField: (newCase: Case, updateKey: UpdateKey) => void; +}) => { + const { isLoading, updateKey: loadingKey, updateCaseProperty } = useUpdateCase({ caseId }); + + const onUpdateField = useCallback( + ({ key, value, onSuccess, onError }: OnUpdateFields) => { + const callUpdate = (updateKey: UpdateKey, updateValue: UpdateByKey['updateValue']) => + updateCaseProperty({ + updateKey, + updateValue, + updateCase: (newCase) => handleUpdateField(newCase, updateKey), + caseData, + onSuccess, + onError, + }); + + switch (key) { + case 'title': + const titleUpdate = getTypedPayload(value); + if (titleUpdate.length > 0) { + callUpdate('title', titleUpdate); + } + break; + case 'connector': + const connector = getTypedPayload(value); + if (connector != null) { + callUpdate('connector', connector); + } + break; + case 'description': + const descriptionUpdate = getTypedPayload(value); + if (descriptionUpdate.length > 0) { + callUpdate('description', descriptionUpdate); + } + break; + case 'tags': + const tagsUpdate = getTypedPayload(value); + callUpdate('tags', tagsUpdate); + break; + case 'status': + const statusUpdate = getTypedPayload(value); + if (caseData.status !== value) { + callUpdate('status', statusUpdate); + } + break; + case 'settings': + const settingsUpdate = getTypedPayload(value); + if (caseData.settings !== value) { + callUpdate('settings', settingsUpdate); + } + break; + default: + return null; + } + }, + [updateCaseProperty, handleUpdateField, caseData] + ); + return { onUpdateField, isLoading, loadingKey }; +}; diff --git a/x-pack/plugins/cases/public/components/cases_context/use_cases_features.tsx b/x-pack/plugins/cases/public/components/cases_context/use_cases_features.tsx index 6241e81e419b9..b0316b5ff9665 100644 --- a/x-pack/plugins/cases/public/components/cases_context/use_cases_features.tsx +++ b/x-pack/plugins/cases/public/components/cases_context/use_cases_features.tsx @@ -6,13 +6,13 @@ */ import { useMemo } from 'react'; -import { CaseMetricsFeature } from '../../containers/types'; +import { SingleCaseMetricsFeature } from '../../containers/types'; import { useCasesContext } from './use_cases_context'; export interface UseCasesFeatures { isAlertsEnabled: boolean; isSyncAlertsEnabled: boolean; - metricsFeatures: CaseMetricsFeature[]; + metricsFeatures: SingleCaseMetricsFeature[]; } export const useCasesFeatures = (): UseCasesFeatures => { diff --git a/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_itsm_case_fields.test.tsx b/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_itsm_case_fields.test.tsx index 66ff8c751c461..cfc16f1fb6e8b 100644 --- a/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_itsm_case_fields.test.tsx +++ b/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_itsm_case_fields.test.tsx @@ -146,6 +146,25 @@ describe('ServiceNowITSM Fields', () => { expect(screen.queryByTestId('deprecated-connector-warning-callout')).not.toBeInTheDocument(); }); + it('does not show the deprecated callout when the connector is preconfigured', async () => { + render( + + ); + expect(screen.queryByTestId('deprecated-connector-warning-callout')).not.toBeInTheDocument(); + }); + + it('does not show the deprecated callout when the config of the connector is undefined', async () => { + render( + // @ts-expect-error + + ); + expect(screen.queryByTestId('deprecated-connector-warning-callout')).not.toBeInTheDocument(); + }); + it('should hide subcategory if selecting a category without subcategories', async () => { // Failed Login doesn't have defined subcategories const customFields = { diff --git a/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_sir_case_fields.test.tsx b/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_sir_case_fields.test.tsx index 279cab7e6f879..a2c61ac78be0b 100644 --- a/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_sir_case_fields.test.tsx +++ b/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_sir_case_fields.test.tsx @@ -180,6 +180,25 @@ describe('ServiceNowSIR Fields', () => { expect(screen.queryByTestId('deprecated-connector-warning-callout')).not.toBeInTheDocument(); }); + it('does not show the deprecated callout when the connector is preconfigured', async () => { + render( + + ); + expect(screen.queryByTestId('deprecated-connector-warning-callout')).not.toBeInTheDocument(); + }); + + it('does not show the deprecated callout when the config of the connector is undefined', async () => { + render( + // @ts-expect-error + + ); + expect(screen.queryByTestId('deprecated-connector-warning-callout')).not.toBeInTheDocument(); + }); + test('it should hide subcategory if selecting a category without subcategories', async () => { // Failed Login doesn't have defined subcategories const customFields = { diff --git a/x-pack/plugins/cases/public/components/connectors/servicenow/validator.test.ts b/x-pack/plugins/cases/public/components/connectors/servicenow/validator.test.ts index aa643191ac62e..ab21a6b5c779c 100644 --- a/x-pack/plugins/cases/public/components/connectors/servicenow/validator.test.ts +++ b/x-pack/plugins/cases/public/components/connectors/servicenow/validator.test.ts @@ -22,7 +22,7 @@ describe('ServiceNow validator', () => { expect(connectorValidator(invalidConnector)).toEqual({ message: 'Deprecated connector' }); }); - test('it does not returns an error message if the connector does not uses the table API', () => { + test('it does not return an error message if the connector does not uses the table API', () => { const invalidConnector = { ...connector, config: { @@ -33,5 +33,16 @@ describe('ServiceNow validator', () => { expect(connectorValidator(invalidConnector)).toBeFalsy(); }); + + test('it does not return an error message if the config of the connector is undefined', () => { + const { config, ...invalidConnector } = connector; + + // @ts-expect-error + expect(connectorValidator(invalidConnector)).toBeFalsy(); + }); + + test('it does not return an error message if the config of the connector is preconfigured', () => { + expect(connectorValidator({ ...connector, isPreconfigured: true })).toBeFalsy(); + }); }); }); diff --git a/x-pack/plugins/cases/public/components/connectors/servicenow/validator.ts b/x-pack/plugins/cases/public/components/connectors/servicenow/validator.ts index 7d56163c48350..fed2900715527 100644 --- a/x-pack/plugins/cases/public/components/connectors/servicenow/validator.ts +++ b/x-pack/plugins/cases/public/components/connectors/servicenow/validator.ts @@ -15,10 +15,18 @@ import { CaseActionConnector } from '../../types'; export const connectorValidator = ( connector: CaseActionConnector ): ReturnType => { - const { - config: { usesTableApi }, - } = connector; - if (usesTableApi) { + /** + * It is not possible to know if a preconfigured connector + * is deprecated or not as the config property of a + * preconfigured connector is not returned by the + * actions framework + */ + + if (connector.isPreconfigured || connector.config == null) { + return; + } + + if (connector.config?.usesTableApi) { return { message: 'Deprecated connector', }; diff --git a/x-pack/plugins/cases/public/components/no_privileges/index.tsx b/x-pack/plugins/cases/public/components/no_privileges/index.tsx index 58d2aa36df583..2e5a4ef48839f 100644 --- a/x-pack/plugins/cases/public/components/no_privileges/index.tsx +++ b/x-pack/plugins/cases/public/components/no_privileges/index.tsx @@ -21,7 +21,7 @@ export const NoPrivilegesPage = React.memo(({ pageName }: NoPrivilegesPageProps) return ( {i18n.NO_PRIVILEGES_TITLE}} titleSize="xs" body={

{i18n.NO_PRIVILEGES_MSG(pageName)}

} diff --git a/x-pack/plugins/cases/public/components/utils.test.ts b/x-pack/plugins/cases/public/components/utils.test.ts index 71218492dec95..278bb28b86627 100644 --- a/x-pack/plugins/cases/public/components/utils.test.ts +++ b/x-pack/plugins/cases/public/components/utils.test.ts @@ -83,5 +83,16 @@ describe('Utils', () => { }) ).toBe(true); }); + + it('returns false if the connector preconfigured', () => { + expect(isDeprecatedConnector({ ...connector, isPreconfigured: true })).toBe(false); + }); + + it('returns false if the config is undefined', () => { + expect( + // @ts-expect-error + isDeprecatedConnector({ ...connector, config: undefined }) + ).toBe(false); + }); }); }); diff --git a/x-pack/plugins/cases/public/components/utils.ts b/x-pack/plugins/cases/public/components/utils.ts index 5ff675a31ce61..34ebffb4eacb4 100644 --- a/x-pack/plugins/cases/public/components/utils.ts +++ b/x-pack/plugins/cases/public/components/utils.ts @@ -74,7 +74,13 @@ export const getConnectorIcon = ( // TODO: Remove when the applications are certified export const isDeprecatedConnector = (connector?: CaseActionConnector): boolean => { - if (connector == null) { + /** + * It is not possible to know if a preconfigured connector + * is deprecated or not as the config property of a + * preconfigured connector is not returned by the + * actions framework + */ + if (connector == null || connector.config == null || connector.isPreconfigured) { return false; } diff --git a/x-pack/plugins/cases/public/components/wrappers/index.tsx b/x-pack/plugins/cases/public/components/wrappers/index.tsx index d412ef34451b2..54c575ab95316 100644 --- a/x-pack/plugins/cases/public/components/wrappers/index.tsx +++ b/x-pack/plugins/cases/public/components/wrappers/index.tsx @@ -13,6 +13,10 @@ export const WhitePageWrapper = styled.div` flex: 1 1 auto; `; +export const WhitePageWrapperNoBorder = styled.div` + background-color: ${({ theme }) => theme.eui.euiColorEmptyShade}; + flex: 1 1 auto; +`; export const SectionWrapper = styled.div` box-sizing: content-box; margin: 0 auto; diff --git a/x-pack/plugins/cases/public/containers/__mocks__/api.ts b/x-pack/plugins/cases/public/containers/__mocks__/api.ts index 1f5c1652edfff..3906997349357 100644 --- a/x-pack/plugins/cases/public/containers/__mocks__/api.ts +++ b/x-pack/plugins/cases/public/containers/__mocks__/api.ts @@ -36,7 +36,7 @@ import { CommentRequest, User, CaseStatuses, - CaseMetricsResponse, + SingleCaseMetricsResponse, } from '../../../common/api'; export const getCase = async ( @@ -51,10 +51,10 @@ export const resolveCase = async ( signal: AbortSignal ): Promise => Promise.resolve(basicResolvedCase); -export const getCaseMetrics = async ( +export const getSingleCaseMetrics = async ( caseId: string, signal: AbortSignal -): Promise => Promise.resolve(basicCaseMetrics); +): Promise => Promise.resolve(basicCaseMetrics); export const getCasesStatus = async (signal: AbortSignal): Promise => Promise.resolve(casesStatus); diff --git a/x-pack/plugins/cases/public/containers/api.ts b/x-pack/plugins/cases/public/containers/api.ts index d4593dd1f2813..a33f0e2501ac0 100644 --- a/x-pack/plugins/cases/public/containers/api.ts +++ b/x-pack/plugins/cases/public/containers/api.ts @@ -26,8 +26,8 @@ import { getCasePushUrl, getCaseUserActionUrl, User, - CaseMetricsResponse, getCaseCommentDeleteUrl, + SingleCaseMetricsResponse, } from '../../common/api'; import { CASE_REPORTERS_URL, @@ -45,8 +45,8 @@ import { AllCases, BulkUpdateStatus, Case, - CaseMetrics, - CaseMetricsFeature, + SingleCaseMetrics, + SingleCaseMetricsFeature, CasesStatus, FetchCasesProps, SortFieldCase, @@ -63,7 +63,7 @@ import { decodeCasesStatusResponse, decodeCaseUserActionsResponse, decodeCaseResolveResponse, - decodeCaseMetricsResponse, + decodeSingleCaseMetricsResponse, } from './utils'; export const getCase = async ( @@ -129,12 +129,12 @@ export const getReporters = async (signal: AbortSignal, owner: string[]): Promis return response ?? []; }; -export const getCaseMetrics = async ( +export const getSingleCaseMetrics = async ( caseId: string, - features: CaseMetricsFeature[], + features: SingleCaseMetricsFeature[], signal: AbortSignal -): Promise => { - const response = await KibanaServices.get().http.fetch( +): Promise => { + const response = await KibanaServices.get().http.fetch( getCaseDetailsMetricsUrl(caseId), { method: 'GET', @@ -142,7 +142,9 @@ export const getCaseMetrics = async ( query: { features: JSON.stringify(features) }, } ); - return convertToCamelCase(decodeCaseMetricsResponse(response)); + return convertToCamelCase( + decodeSingleCaseMetricsResponse(response) + ); }; export const getCaseUserActions = async ( diff --git a/x-pack/plugins/cases/public/containers/mock.ts b/x-pack/plugins/cases/public/containers/mock.ts index 69931629a77cb..8c45fd5b083e0 100644 --- a/x-pack/plugins/cases/public/containers/mock.ts +++ b/x-pack/plugins/cases/public/containers/mock.ts @@ -9,8 +9,8 @@ import { ActionLicense, AllCases, Case, CasesStatus, CaseUserActions, Comment } import type { ResolvedCase, - CaseMetrics, - CaseMetricsFeature, + SingleCaseMetrics, + SingleCaseMetricsFeature, AlertComment, } from '../../common/ui/types'; import { @@ -154,6 +154,7 @@ export const basicCase: Case = { fields: null, }, description: 'Security banana Issue', + duration: null, externalService: null, status: CaseStatuses.open, tags, @@ -188,7 +189,7 @@ export const basicResolvedCase: ResolvedCase = { aliasTargetId: `${basicCase.id}_2`, }; -export const basicCaseNumericValueFeatures: CaseMetricsFeature[] = [ +export const basicCaseNumericValueFeatures: SingleCaseMetricsFeature[] = [ 'alerts.count', 'alerts.users', 'alerts.hosts', @@ -196,9 +197,9 @@ export const basicCaseNumericValueFeatures: CaseMetricsFeature[] = [ 'connectors', ]; -export const basicCaseStatusFeatures: CaseMetricsFeature[] = ['lifespan']; +export const basicCaseStatusFeatures: SingleCaseMetricsFeature[] = ['lifespan']; -export const basicCaseMetrics: CaseMetrics = { +export const basicCaseMetrics: SingleCaseMetrics = { alerts: { count: 12, hosts: { @@ -245,6 +246,7 @@ export const mockCase: Case = { type: ConnectorTypes.none, fields: null, }, + duration: null, description: 'Security banana Issue', externalService: null, status: CaseStatuses.open, @@ -383,6 +385,7 @@ export const basicCaseSnake: CaseResponse = { connector: { id: 'none', name: 'My Connector', type: ConnectorTypes.none, fields: null }, created_at: basicCreatedAt, created_by: elasticUserSnake, + duration: null, external_service: null, updated_at: basicUpdatedAt, updated_by: elasticUserSnake, diff --git a/x-pack/plugins/cases/public/containers/use_get_case_metrics.test.tsx b/x-pack/plugins/cases/public/containers/use_get_case_metrics.test.tsx index 73c69ec388977..4c7d446f4f27f 100644 --- a/x-pack/plugins/cases/public/containers/use_get_case_metrics.test.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_case_metrics.test.tsx @@ -6,7 +6,7 @@ */ import { renderHook, act } from '@testing-library/react-hooks'; -import { CaseMetricsFeature } from '../../common/ui'; +import { SingleCaseMetricsFeature } from '../../common/ui'; import { useGetCaseMetrics, UseGetCaseMetrics } from './use_get_case_metrics'; import { basicCase, basicCaseMetrics } from './mock'; import * as api from './api'; @@ -16,7 +16,7 @@ jest.mock('../common/lib/kibana'); describe('useGetCaseMetrics', () => { const abortCtrl = new AbortController(); - const features: CaseMetricsFeature[] = ['alerts.count']; + const features: SingleCaseMetricsFeature[] = ['alerts.count']; beforeEach(() => { jest.clearAllMocks(); @@ -38,8 +38,8 @@ describe('useGetCaseMetrics', () => { }); }); - it('calls getCaseMetrics with correct arguments', async () => { - const spyOnGetCaseMetrics = jest.spyOn(api, 'getCaseMetrics'); + it('calls getSingleCaseMetrics with correct arguments', async () => { + const spyOnGetCaseMetrics = jest.spyOn(api, 'getSingleCaseMetrics'); await act(async () => { const { waitForNextUpdate } = renderHook(() => useGetCaseMetrics(basicCase.id, features) @@ -50,8 +50,8 @@ describe('useGetCaseMetrics', () => { }); }); - it('does not call getCaseMetrics if empty feature parameter passed', async () => { - const spyOnGetCaseMetrics = jest.spyOn(api, 'getCaseMetrics'); + it('does not call getSingleCaseMetrics if empty feature parameter passed', async () => { + const spyOnGetCaseMetrics = jest.spyOn(api, 'getSingleCaseMetrics'); await act(async () => { const { waitForNextUpdate } = renderHook(() => useGetCaseMetrics(basicCase.id, []) @@ -78,7 +78,7 @@ describe('useGetCaseMetrics', () => { }); it('refetch case metrics', async () => { - const spyOnGetCaseMetrics = jest.spyOn(api, 'getCaseMetrics'); + const spyOnGetCaseMetrics = jest.spyOn(api, 'getSingleCaseMetrics'); await act(async () => { const { result, waitForNextUpdate } = renderHook(() => useGetCaseMetrics(basicCase.id, features) @@ -116,8 +116,8 @@ describe('useGetCaseMetrics', () => { }); }); - it('returns an error when getCaseMetrics throws', async () => { - const spyOnGetCaseMetrics = jest.spyOn(api, 'getCaseMetrics'); + it('returns an error when getSingleCaseMetrics throws', async () => { + const spyOnGetCaseMetrics = jest.spyOn(api, 'getSingleCaseMetrics'); spyOnGetCaseMetrics.mockImplementation(() => { throw new Error('Something went wrong'); }); diff --git a/x-pack/plugins/cases/public/containers/use_get_case_metrics.tsx b/x-pack/plugins/cases/public/containers/use_get_case_metrics.tsx index 411b43e050abf..774ecfd2371b6 100644 --- a/x-pack/plugins/cases/public/containers/use_get_case_metrics.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_case_metrics.tsx @@ -7,20 +7,20 @@ import { useEffect, useReducer, useCallback, useRef } from 'react'; -import { CaseMetrics, CaseMetricsFeature } from './types'; +import { SingleCaseMetrics, SingleCaseMetricsFeature } from './types'; import * as i18n from './translations'; import { useToasts } from '../common/lib/kibana'; -import { getCaseMetrics } from './api'; +import { getSingleCaseMetrics } from './api'; interface CaseMeticsState { - metrics: CaseMetrics | null; + metrics: SingleCaseMetrics | null; isLoading: boolean; isError: boolean; } type Action = | { type: 'FETCH_INIT'; payload: { silent: boolean } } - | { type: 'FETCH_SUCCESS'; payload: CaseMetrics } + | { type: 'FETCH_SUCCESS'; payload: SingleCaseMetrics } | { type: 'FETCH_FAILURE' }; const dataFetchReducer = (state: CaseMeticsState, action: Action): CaseMeticsState => { @@ -59,7 +59,7 @@ export interface UseGetCaseMetrics extends CaseMeticsState { export const useGetCaseMetrics = ( caseId: string, - features: CaseMetricsFeature[] + features: SingleCaseMetricsFeature[] ): UseGetCaseMetrics => { const [state, dispatch] = useReducer(dataFetchReducer, { metrics: null, @@ -81,7 +81,7 @@ export const useGetCaseMetrics = ( abortCtrlRef.current = new AbortController(); dispatch({ type: 'FETCH_INIT', payload: { silent } }); - const response: CaseMetrics = await getCaseMetrics( + const response: SingleCaseMetrics = await getSingleCaseMetrics( caseId, features, abortCtrlRef.current.signal diff --git a/x-pack/plugins/cases/public/containers/utils.ts b/x-pack/plugins/cases/public/containers/utils.ts index cd1682c0cd988..deafcda2d24ea 100644 --- a/x-pack/plugins/cases/public/containers/utils.ts +++ b/x-pack/plugins/cases/public/containers/utils.ts @@ -32,8 +32,8 @@ import { CasePatchRequest, CaseResolveResponse, CaseResolveResponseRt, - CaseMetricsResponse, - CaseMetricsResponseRt, + SingleCaseMetricsResponse, + SingleCaseMetricsResponseRt, } from '../../common/api'; import { AllCases, Case, UpdateByKey } from './types'; import * as i18n from './translations'; @@ -96,9 +96,9 @@ export const decodeCaseResolveResponse = (respCase?: CaseResolveResponse) => fold(throwErrors(createToasterPlainError), identity) ); -export const decodeCaseMetricsResponse = (respCase?: CaseMetricsResponse) => +export const decodeSingleCaseMetricsResponse = (respCase?: SingleCaseMetricsResponse) => pipe( - CaseMetricsResponseRt.decode(respCase), + SingleCaseMetricsResponseRt.decode(respCase), fold(throwErrors(createToasterPlainError), identity) ); diff --git a/x-pack/plugins/cases/public/plugin.ts b/x-pack/plugins/cases/public/plugin.ts index 3b124f920e889..559d670eeab68 100644 --- a/x-pack/plugins/cases/public/plugin.ts +++ b/x-pack/plugins/cases/public/plugin.ts @@ -47,7 +47,7 @@ export class CasesUiPlugin id: APP_ID, title: APP_TITLE, description: APP_DESC, - icon: 'watchesApp', + icon: 'casesApp', path: APP_PATH, showOnHomePage: false, category: 'admin', diff --git a/x-pack/plugins/cases/server/authorization/__snapshots__/audit_logger.test.ts.snap b/x-pack/plugins/cases/server/authorization/__snapshots__/audit_logger.test.ts.snap index 0ec6dffee02ea..bbeb9ce05445b 100644 --- a/x-pack/plugins/cases/server/authorization/__snapshots__/audit_logger.test.ts.snap +++ b/x-pack/plugins/cases/server/authorization/__snapshots__/audit_logger.test.ts.snap @@ -1344,6 +1344,90 @@ Object { } `; +exports[`audit_logger log function event structure creates the correct audit event for operation: "getCasesMetrics" with an error and entity 1`] = ` +Object { + "error": Object { + "code": "Error", + "message": "an error", + }, + "event": Object { + "action": "cases_get_metrics", + "category": Array [ + "database", + ], + "outcome": "failure", + "type": Array [ + "access", + ], + }, + "kibana": Object { + "saved_object": Object { + "id": "1", + "type": "cases", + }, + }, + "message": "Failed attempt to access cases [id=1] as owner \\"awesome\\"", +} +`; + +exports[`audit_logger log function event structure creates the correct audit event for operation: "getCasesMetrics" with an error but no entity 1`] = ` +Object { + "error": Object { + "code": "Error", + "message": "an error", + }, + "event": Object { + "action": "cases_get_metrics", + "category": Array [ + "database", + ], + "outcome": "failure", + "type": Array [ + "access", + ], + }, + "message": "Failed attempt to access a cases as any owners", +} +`; + +exports[`audit_logger log function event structure creates the correct audit event for operation: "getCasesMetrics" without an error but with an entity 1`] = ` +Object { + "event": Object { + "action": "cases_get_metrics", + "category": Array [ + "database", + ], + "outcome": "success", + "type": Array [ + "access", + ], + }, + "kibana": Object { + "saved_object": Object { + "id": "5", + "type": "cases", + }, + }, + "message": "User has accessed cases [id=5] as owner \\"super\\"", +} +`; + +exports[`audit_logger log function event structure creates the correct audit event for operation: "getCasesMetrics" without an error or entity 1`] = ` +Object { + "event": Object { + "action": "cases_get_metrics", + "category": Array [ + "database", + ], + "outcome": "success", + "type": Array [ + "access", + ], + }, + "message": "User has accessed a cases as any owners", +} +`; + exports[`audit_logger log function event structure creates the correct audit event for operation: "getComment" with an error and entity 1`] = ` Object { "error": Object { diff --git a/x-pack/plugins/cases/server/authorization/index.ts b/x-pack/plugins/cases/server/authorization/index.ts index cd3ceebf02f92..122eb90f44dc1 100644 --- a/x-pack/plugins/cases/server/authorization/index.ts +++ b/x-pack/plugins/cases/server/authorization/index.ts @@ -126,6 +126,14 @@ const CaseOperations = { docType: 'case', savedObjectType: CASE_SAVED_OBJECT, }, + [ReadOperations.GetCasesMetrics]: { + ecsType: EVENT_TYPES.access, + name: ACCESS_CASE_OPERATION, + action: 'cases_get_metrics', + verbs: accessVerbs, + docType: 'cases', + savedObjectType: CASE_SAVED_OBJECT, + }, [WriteOperations.CreateCase]: { ecsType: EVENT_TYPES.creation, name: WriteOperations.CreateCase as const, diff --git a/x-pack/plugins/cases/server/authorization/types.ts b/x-pack/plugins/cases/server/authorization/types.ts index 8c672ffb9d245..81c3d0746aa33 100644 --- a/x-pack/plugins/cases/server/authorization/types.ts +++ b/x-pack/plugins/cases/server/authorization/types.ts @@ -43,6 +43,7 @@ export enum ReadOperations { GetAlertsAttachedToCase = 'getAlertsAttachedToCase', GetAttachmentMetrics = 'getAttachmentMetrics', GetCaseMetrics = 'getCaseMetrics', + GetCasesMetrics = 'getCasesMetrics', GetUserActionMetrics = 'getUserActionMetrics', } diff --git a/x-pack/plugins/cases/server/client/cases/update.ts b/x-pack/plugins/cases/server/client/cases/update.ts index ae53cb03c28a7..6569dcd3f52b2 100644 --- a/x-pack/plugins/cases/server/client/cases/update.ts +++ b/x-pack/plugins/cases/server/client/cases/update.ts @@ -50,6 +50,7 @@ import { import { UpdateAlertRequest } from '../alerts/types'; import { CasesClientArgs } from '..'; import { Operations, OwnerEntity } from '../../authorization'; +import { getClosedInfoForUpdate, getDurationForUpdate } from './utils'; /** * Throws an error if any of the requests attempt to update the owner of a case. @@ -311,37 +312,29 @@ export const update = async ( throwIfUpdateOwner(updateCases); throwIfTitleIsInvalid(updateCases); - // eslint-disable-next-line @typescript-eslint/naming-convention - const { username, full_name, email } = user; const updatedDt = new Date().toISOString(); const updatedCases = await caseService.patchCases({ cases: updateCases.map(({ updateReq, originalCase }) => { // intentionally removing owner from the case so that we don't accidentally allow it to be updated const { id: caseId, version, owner, ...updateCaseAttributes } = updateReq; - let closedInfo = {}; - if (updateCaseAttributes.status && updateCaseAttributes.status === CaseStatuses.closed) { - closedInfo = { - closed_at: updatedDt, - closed_by: { email, full_name, username }, - }; - } else if ( - updateCaseAttributes.status && - (updateCaseAttributes.status === CaseStatuses.open || - updateCaseAttributes.status === CaseStatuses['in-progress']) - ) { - closedInfo = { - closed_at: null, - closed_by: null, - }; - } + return { caseId, originalCase, updatedAttributes: { ...updateCaseAttributes, - ...closedInfo, + ...getClosedInfoForUpdate({ + user, + closedDate: updatedDt, + status: updateCaseAttributes.status, + }), + ...getDurationForUpdate({ + status: updateCaseAttributes.status, + closedAt: updatedDt, + createdAt: originalCase.attributes.created_at, + }), updated_at: updatedDt, - updated_by: { email, full_name, username }, + updated_by: user, }, version, }; diff --git a/x-pack/plugins/cases/server/client/cases/utils.test.ts b/x-pack/plugins/cases/server/client/cases/utils.test.ts index 3dca8014957da..4832ffe5b2eaf 100644 --- a/x-pack/plugins/cases/server/client/cases/utils.test.ts +++ b/x-pack/plugins/cases/server/client/cases/utils.test.ts @@ -24,13 +24,15 @@ import { import { createIncident, + getClosedInfoForUpdate, + getDurationForUpdate, getLatestPushInfo, prepareFieldsForTransformation, transformComments, transformers, transformFields, } from './utils'; -import { Actions } from '../../../common/api'; +import { Actions, CaseStatuses } from '../../../common/api'; import { flattenCaseSavedObject } from '../../common/utils'; import { SECURITY_SOLUTION_OWNER } from '../../../common/constants'; import { casesConnectors } from '../../connectors'; @@ -836,5 +838,119 @@ describe('utils', () => { }); }); }); + + describe('getClosedInfoForUpdate', () => { + const date = '2021-02-03T17:41:26.108Z'; + const user = { full_name: 'Elastic', username: 'elastic', email: 'elastic@elastic.co' }; + + it('returns the correct closed info when the case closes', async () => { + expect( + getClosedInfoForUpdate({ status: CaseStatuses.closed, closedDate: date, user }) + ).toEqual({ + closed_at: date, + closed_by: user, + }); + }); + + it.each([[CaseStatuses.open], [CaseStatuses['in-progress']]])( + 'returns the correct closed info when the case %s', + async (status) => { + expect(getClosedInfoForUpdate({ status, closedDate: date, user })).toEqual({ + closed_at: null, + closed_by: null, + }); + } + ); + + it('returns undefined if the status is not provided', async () => { + expect(getClosedInfoForUpdate({ closedDate: date, user })).toBe(undefined); + }); + }); + + describe('getDurationForUpdate', () => { + const createdAt = '2021-11-23T19:00:00Z'; + const closedAt = '2021-11-23T19:02:00Z'; + + it('returns the correct duration when the case closes', () => { + expect(getDurationForUpdate({ status: CaseStatuses.closed, closedAt, createdAt })).toEqual({ + duration: 120, + }); + }); + + it.each([[CaseStatuses.open], [CaseStatuses['in-progress']]])( + 'returns the correct duration when the case %s', + (status) => { + expect(getDurationForUpdate({ status, closedAt, createdAt })).toEqual({ + duration: null, + }); + } + ); + + it('returns undefined if the status is not provided', async () => { + expect(getDurationForUpdate({ closedAt, createdAt })).toBe(undefined); + }); + + it.each([['invalid'], [null]])( + 'returns undefined if the createdAt date is %s', + (createdAtInvalid) => { + expect( + getDurationForUpdate({ + status: CaseStatuses.closed, + closedAt, + // @ts-expect-error + createdAt: createdAtInvalid, + }) + ).toBe(undefined); + } + ); + + it.each([['invalid'], [null]])( + 'returns undefined if the closedAt date is %s', + (closedAtInvalid) => { + expect( + getDurationForUpdate({ + status: CaseStatuses.closed, + // @ts-expect-error + closedAt: closedAtInvalid, + createdAt, + }) + ).toBe(undefined); + } + ); + + it('returns undefined if created_at > closed_at', async () => { + expect( + getDurationForUpdate({ + status: CaseStatuses.closed, + closedAt: '2021-11-23T19:00:00Z', + createdAt: '2021-11-23T19:05:00Z', + }) + ).toBe(undefined); + }); + + it('rounds the seconds correctly', () => { + expect( + getDurationForUpdate({ + status: CaseStatuses.closed, + createdAt: '2022-04-11T15:56:00.087Z', + closedAt: '2022-04-11T15:58:56.187Z', + }) + ).toEqual({ + duration: 176, + }); + }); + + it('rounds the zero correctly', () => { + expect( + getDurationForUpdate({ + status: CaseStatuses.closed, + createdAt: '2022-04-11T15:56:00.087Z', + closedAt: '2022-04-11T15:56:00.187Z', + }) + ).toEqual({ + duration: 0, + }); + }); + }); }); }); diff --git a/x-pack/plugins/cases/server/client/cases/utils.ts b/x-pack/plugins/cases/server/client/cases/utils.ts index 42a9a54466906..01c1a9ab897b5 100644 --- a/x-pack/plugins/cases/server/client/cases/utils.ts +++ b/x-pack/plugins/cases/server/client/cases/utils.ts @@ -23,6 +23,9 @@ import { CommentRequestAlertType, CommentRequestActionsType, ActionTypes, + CaseStatuses, + User, + CaseAttributes, } from '../../../common/api'; import { CasesClientGetAlertsResponse } from '../alerts/types'; import { @@ -405,3 +408,62 @@ export const getCommentContextFromAttributes = ( }; } }; + +export const getClosedInfoForUpdate = ({ + user, + status, + closedDate, +}: { + closedDate: string; + user: User; + status?: CaseStatuses; +}): Pick | undefined => { + if (status && status === CaseStatuses.closed) { + return { + closed_at: closedDate, + closed_by: user, + }; + } + + if (status && (status === CaseStatuses.open || status === CaseStatuses['in-progress'])) { + return { + closed_at: null, + closed_by: null, + }; + } +}; + +export const getDurationForUpdate = ({ + status, + closedAt, + createdAt, +}: { + closedAt: string; + createdAt: CaseAttributes['created_at']; + status?: CaseStatuses; +}): Pick | undefined => { + if (status && status === CaseStatuses.closed) { + try { + if (createdAt != null && closedAt != null) { + const createdAtMillis = new Date(createdAt).getTime(); + const closedAtMillis = new Date(closedAt).getTime(); + + if ( + !isNaN(createdAtMillis) && + !isNaN(closedAtMillis) && + closedAtMillis >= createdAtMillis + ) { + return { duration: Math.floor((closedAtMillis - createdAtMillis) / 1000) }; + } + } + } catch (err) { + // Silence date errors + } + } + + if (status && (status === CaseStatuses.open || status === CaseStatuses['in-progress'])) { + return { + duration: null, + }; + } +}; diff --git a/x-pack/plugins/cases/server/client/configure/client.test.ts b/x-pack/plugins/cases/server/client/configure/client.test.ts index fa3f2b3f987f1..2889f00b6d28b 100644 --- a/x-pack/plugins/cases/server/client/configure/client.test.ts +++ b/x-pack/plugins/cases/server/client/configure/client.test.ts @@ -5,11 +5,10 @@ * 2.0. */ -import { CasesClientArgs } from '../types'; import { loggingSystemMock } from '@kbn/core/server/mocks'; -import { getConnectors } from './client'; import { actionsClientMock } from '@kbn/actions-plugin/server/mocks'; -import { ActionType } from '@kbn/actions-plugin/common/types'; +import { CasesClientArgs } from '../types'; +import { getConnectors } from './client'; describe('client', () => { describe('getConnectors', () => { @@ -18,72 +17,170 @@ describe('client', () => { const args = { actionsClient, logger } as unknown as CasesClientArgs; - const jiraType: ActionType = { - id: '.jira', - name: '1', - enabled: true, - enabledInConfig: true, - enabledInLicense: true, - minimumLicenseRequired: 'basic', - }; + const actionTypes = [ + { + id: '.jira', + name: '1', + enabled: true, + enabledInConfig: true, + enabledInLicense: true, + minimumLicenseRequired: 'basic' as const, + }, + { + id: '.servicenow', + name: '2', + enabled: true, + enabledInConfig: true, + enabledInLicense: true, + minimumLicenseRequired: 'basic' as const, + }, + { + id: '.unsupported', + name: '3', + enabled: true, + enabledInConfig: true, + enabledInLicense: true, + minimumLicenseRequired: 'basic' as const, + }, + { + id: '.swimlane', + name: 'swimlane', + enabled: true, + enabledInConfig: true, + enabledInLicense: false, + minimumLicenseRequired: 'basic' as const, + }, + ]; + + const connectors = [ + { + id: '1', + actionTypeId: '.jira', + name: '1', + config: {}, + isPreconfigured: false, + isDeprecated: false, + referencedByCount: 1, + }, + { + id: '2', + actionTypeId: '.servicenow', + name: '2', + config: {}, + isPreconfigured: false, + isDeprecated: false, + referencedByCount: 1, + }, + { + id: '3', + actionTypeId: '.unsupported', + name: '3', + config: {}, + isPreconfigured: false, + isDeprecated: false, + referencedByCount: 1, + }, + ]; beforeEach(() => { jest.clearAllMocks(); }); - it('removes connectors without a config field defined', async () => { - actionsClient.listTypes.mockImplementation(async () => [jiraType]); + it('remove unsupported connectors', async () => { + actionsClient.listTypes.mockImplementation(async () => actionTypes); + actionsClient.getAll.mockImplementation(async () => connectors); - actionsClient.getAll.mockImplementation(async () => [ + expect(await getConnectors(args)).toEqual([ { id: '1', actionTypeId: '.jira', name: '1', + config: {}, isPreconfigured: false, + isDeprecated: false, + referencedByCount: 1, + }, + { + id: '2', + actionTypeId: '.servicenow', + name: '2', + config: {}, + isPreconfigured: false, + isDeprecated: false, referencedByCount: 1, }, ]); - - expect(await getConnectors(args)).toEqual([]); }); - it('removes connectors that are pre configured', async () => { - actionsClient.listTypes.mockImplementation(async () => [jiraType]); - + it('returns preconfigured connectors', async () => { + actionsClient.listTypes.mockImplementation(async () => actionTypes); actionsClient.getAll.mockImplementation(async () => [ + ...connectors, + { + id: '4', + actionTypeId: '.servicenow', + name: 'sn-preconfigured', + config: {}, + isPreconfigured: true, + isDeprecated: false, + referencedByCount: 1, + }, + ]); + + expect(await getConnectors(args)).toEqual([ { id: '1', actionTypeId: '.jira', name: '1', config: {}, + isPreconfigured: false, + isDeprecated: false, + referencedByCount: 1, + }, + { + id: '2', + actionTypeId: '.servicenow', + name: '2', + config: {}, + isPreconfigured: false, + isDeprecated: false, + referencedByCount: 1, + }, + { + id: '4', + actionTypeId: '.servicenow', + name: 'sn-preconfigured', + config: {}, isPreconfigured: true, + isDeprecated: false, referencedByCount: 1, }, ]); - - expect(await getConnectors(args)).toEqual([]); }); - it('includes connectors that have a config and are not pre configured', async () => { - actionsClient.listTypes.mockImplementation(async () => [ - jiraType, + it('filter out connectors that are unsupported by the current license', async () => { + actionsClient.listTypes.mockImplementation(async () => actionTypes); + actionsClient.getAll.mockImplementation(async () => [ + ...connectors, { - id: '.servicenow', - name: '2', - enabled: true, - enabledInConfig: true, - enabledInLicense: true, - minimumLicenseRequired: 'basic', + id: '4', + actionTypeId: '.swimlane', + name: 'swimlane', + config: {}, + isPreconfigured: false, + isDeprecated: false, + referencedByCount: 1, }, ]); - const connectors = [ + expect(await getConnectors(args)).toEqual([ { id: '1', actionTypeId: '.jira', name: '1', config: {}, isPreconfigured: false, + isDeprecated: false, referencedByCount: 1, }, { @@ -92,13 +189,10 @@ describe('client', () => { name: '2', config: {}, isPreconfigured: false, + isDeprecated: false, referencedByCount: 1, }, - ]; - - actionsClient.getAll.mockImplementation(async () => connectors); - - expect(await getConnectors(args)).toEqual(connectors); + ]); }); }); }); diff --git a/x-pack/plugins/cases/server/client/configure/client.ts b/x-pack/plugins/cases/server/client/configure/client.ts index c4b07019627e4..9bb6b83316264 100644 --- a/x-pack/plugins/cases/server/client/configure/client.ts +++ b/x-pack/plugins/cases/server/client/configure/client.ts @@ -223,9 +223,7 @@ function isConnectorSupported( ): boolean { return ( SUPPORTED_CONNECTORS.includes(action.actionTypeId) && - actionTypes[action.actionTypeId]?.enabledInLicense && - action.config != null && - !action.isPreconfigured + actionTypes[action.actionTypeId]?.enabledInLicense ); } diff --git a/x-pack/plugins/cases/server/client/metrics/actions/actions.ts b/x-pack/plugins/cases/server/client/metrics/actions/actions.ts index c700c3998e503..4eecc37339c2d 100644 --- a/x-pack/plugins/cases/server/client/metrics/actions/actions.ts +++ b/x-pack/plugins/cases/server/client/metrics/actions/actions.ts @@ -6,30 +6,32 @@ */ import { merge } from 'lodash'; -import { CaseMetricsResponse } from '../../../../common/api'; +import { SingleCaseMetricsResponse } from '../../../../common/api'; import { Operations } from '../../../authorization'; import { createCaseError } from '../../../common/error'; -import { AggregationHandler } from '../aggregation_handler'; -import { AggregationBuilder, BaseHandlerCommonOptions } from '../types'; +import { SingleCaseAggregationHandler } from '../single_case_aggregation_handler'; +import { AggregationBuilder, SingleCaseBaseHandlerCommonOptions } from '../types'; import { IsolateHostActions } from './aggregations/isolate_host'; -export class Actions extends AggregationHandler { - constructor(options: BaseHandlerCommonOptions) { +export class Actions extends SingleCaseAggregationHandler { + constructor(options: SingleCaseBaseHandlerCommonOptions) { super( options, - new Map([['actions.isolateHost', new IsolateHostActions()]]) + new Map>([ + ['actions.isolateHost', new IsolateHostActions()], + ]) ); } - public async compute(): Promise { + public async compute(): Promise { const { unsecuredSavedObjectsClient, authorization, attachmentService, logger } = this.options.clientArgs; - const { caseId, casesClient } = this.options; + const { casesClient } = this.options; try { // This will perform an authorization check to ensure the user has access to the parent case const theCase = await casesClient.cases.get({ - id: caseId, + id: this.caseId, includeComments: false, }); @@ -48,13 +50,13 @@ export class Actions extends AggregationHandler { aggregations, }); - return this.aggregationBuilders.reduce( + return this.aggregationBuilders.reduce( (acc, aggregator) => merge(acc, aggregator.formatResponse(response)), {} ); } catch (error) { throw createCaseError({ - message: `Failed to compute actions attached case id: ${caseId}: ${error}`, + message: `Failed to compute actions attached case id: ${this.caseId}: ${error}`, error, logger, }); diff --git a/x-pack/plugins/cases/server/client/metrics/actions/aggregations/isolate_host.ts b/x-pack/plugins/cases/server/client/metrics/actions/aggregations/isolate_host.ts index f0cf670a105db..479de16bc262f 100644 --- a/x-pack/plugins/cases/server/client/metrics/actions/aggregations/isolate_host.ts +++ b/x-pack/plugins/cases/server/client/metrics/actions/aggregations/isolate_host.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { IsolateHostActionType } from '../../../../../common/api'; +import { IsolateHostActionType, SingleCaseMetricsResponse } from '../../../../../common/api'; import { CASE_COMMENT_SAVED_OBJECT } from '../../../../../common/constants'; import { AggregationBuilder, AggregationResponse } from '../../types'; @@ -16,7 +16,7 @@ interface ActionsAggregation { } type ActionsAggregationResponse = ActionsAggregation | undefined; -export class IsolateHostActions implements AggregationBuilder { +export class IsolateHostActions implements AggregationBuilder { // uniqueValuesLimit should not be lower than the number of actions.type values (currently 2) or some information could be lost constructor(private readonly uniqueValuesLimit: number = 10) {} diff --git a/x-pack/plugins/cases/server/client/metrics/aggregation_handler.ts b/x-pack/plugins/cases/server/client/metrics/aggregation_handler.ts index 382faa354db59..e70c7add20f5e 100644 --- a/x-pack/plugins/cases/server/client/metrics/aggregation_handler.ts +++ b/x-pack/plugins/cases/server/client/metrics/aggregation_handler.ts @@ -5,15 +5,16 @@ * 2.0. */ +import { merge } from 'lodash'; import { BaseHandler } from './base_handler'; -import { AggregationBuilder, BaseHandlerCommonOptions } from './types'; +import { AggregationBuilder, AggregationResponse, BaseHandlerCommonOptions } from './types'; -export abstract class AggregationHandler extends BaseHandler { - protected aggregationBuilders: AggregationBuilder[] = []; +export abstract class AggregationHandler extends BaseHandler { + protected aggregationBuilders: Array> = []; constructor( options: BaseHandlerCommonOptions, - private readonly aggregations: Map + protected readonly aggregations: Map> ) { super(options); } @@ -28,4 +29,11 @@ export abstract class AggregationHandler extends BaseHandler { this.aggregationBuilders.push(aggregation); } } + + public formatResponse(aggregationsResponse?: AggregationResponse): F { + return this.aggregationBuilders.reduce( + (acc, feature) => merge(acc, feature.formatResponse(aggregationsResponse)), + {} as F + ); + } } diff --git a/x-pack/plugins/cases/server/client/metrics/alerts/aggregations/hosts.ts b/x-pack/plugins/cases/server/client/metrics/alerts/aggregations/hosts.ts index dc2a1162bd9de..a9052e2e2a9ce 100644 --- a/x-pack/plugins/cases/server/client/metrics/alerts/aggregations/hosts.ts +++ b/x-pack/plugins/cases/server/client/metrics/alerts/aggregations/hosts.ts @@ -8,6 +8,7 @@ import { get } from 'lodash'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { SingleCaseMetricsResponse } from '../../../../../common/api'; import { AggregationBuilder, AggregationResponse } from '../../types'; type HostsAggregate = HostsAggregateResponse | undefined; @@ -30,7 +31,7 @@ interface FieldAggregateBucket { const hostName = 'host.name'; const hostId = 'host.id'; -export class AlertHosts implements AggregationBuilder { +export class AlertHosts implements AggregationBuilder { constructor(private readonly uniqueValuesLimit: number = 10) {} build() { diff --git a/x-pack/plugins/cases/server/client/metrics/alerts/aggregations/users.ts b/x-pack/plugins/cases/server/client/metrics/alerts/aggregations/users.ts index 46db6c665327a..8d068e354693b 100644 --- a/x-pack/plugins/cases/server/client/metrics/alerts/aggregations/users.ts +++ b/x-pack/plugins/cases/server/client/metrics/alerts/aggregations/users.ts @@ -5,9 +5,10 @@ * 2.0. */ +import { SingleCaseMetricsResponse } from '../../../../../common/api'; import { AggregationBuilder, AggregationResponse } from '../../types'; -export class AlertUsers implements AggregationBuilder { +export class AlertUsers implements AggregationBuilder { constructor(private readonly uniqueValuesLimit: number = 10) {} build() { diff --git a/x-pack/plugins/cases/server/client/metrics/alerts/count.test.ts b/x-pack/plugins/cases/server/client/metrics/alerts/count.test.ts new file mode 100644 index 0000000000000..58776f7bdb77e --- /dev/null +++ b/x-pack/plugins/cases/server/client/metrics/alerts/count.test.ts @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { CaseResponse } from '../../../../common/api'; +import { createCasesClientMock } from '../../mocks'; +import { CasesClientArgs } from '../../types'; +import { loggingSystemMock } from '@kbn/core/server/mocks'; +import { createAttachmentServiceMock } from '../../../services/mocks'; + +import { AlertsCount } from './count'; + +const clientMock = createCasesClientMock(); +const attachmentService = createAttachmentServiceMock(); + +const logger = loggingSystemMock.createLogger(); +const getAuthorizationFilter = jest.fn().mockResolvedValue({}); + +const clientArgs = { + logger, + attachmentService, + authorization: { getAuthorizationFilter }, +} as unknown as CasesClientArgs; + +const constructorOptions = { caseId: 'test-id', casesClient: clientMock, clientArgs }; + +describe('AlertsCount', () => { + beforeAll(() => { + getAuthorizationFilter.mockResolvedValue({}); + clientMock.cases.get.mockResolvedValue({ id: 'test-id' } as unknown as CaseResponse); + }); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('returns empty values when attachment services returns undefined', async () => { + attachmentService.countAlertsAttachedToCase.mockResolvedValue(undefined); + const handler = new AlertsCount(constructorOptions); + expect(await handler.compute()).toEqual({ alerts: { count: 0 } }); + }); + + it('returns values when the attachment service returns a value', async () => { + attachmentService.countAlertsAttachedToCase.mockResolvedValue(5); + const handler = new AlertsCount(constructorOptions); + + expect(await handler.compute()).toEqual({ alerts: { count: 5 } }); + }); +}); diff --git a/x-pack/plugins/cases/server/client/metrics/alerts/count.ts b/x-pack/plugins/cases/server/client/metrics/alerts/count.ts index 10fb1b97b4511..2afbd41863a11 100644 --- a/x-pack/plugins/cases/server/client/metrics/alerts/count.ts +++ b/x-pack/plugins/cases/server/client/metrics/alerts/count.ts @@ -5,27 +5,27 @@ * 2.0. */ -import { CaseMetricsResponse } from '../../../../common/api'; +import { SingleCaseMetricsResponse } from '../../../../common/api'; import { Operations } from '../../../authorization'; import { createCaseError } from '../../../common/error'; -import { BaseHandler } from '../base_handler'; -import { BaseHandlerCommonOptions } from '../types'; +import { SingleCaseBaseHandler } from '../single_case_base_handler'; +import { SingleCaseBaseHandlerCommonOptions } from '../types'; -export class AlertsCount extends BaseHandler { - constructor(options: BaseHandlerCommonOptions) { +export class AlertsCount extends SingleCaseBaseHandler { + constructor(options: SingleCaseBaseHandlerCommonOptions) { super(options, ['alerts.count']); } - public async compute(): Promise { + public async compute(): Promise { const { unsecuredSavedObjectsClient, authorization, attachmentService, logger } = this.options.clientArgs; - const { caseId, casesClient } = this.options; + const { casesClient } = this.options; try { // This will perform an authorization check to ensure the user has access to the parent case const theCase = await casesClient.cases.get({ - id: caseId, + id: this.caseId, includeComments: false, }); @@ -46,7 +46,7 @@ export class AlertsCount extends BaseHandler { }; } catch (error) { throw createCaseError({ - message: `Failed to count alerts attached case id: ${caseId}: ${error}`, + message: `Failed to count alerts attached case id: ${this.caseId}: ${error}`, error, logger, }); diff --git a/x-pack/plugins/cases/server/client/metrics/alerts/details.test.ts b/x-pack/plugins/cases/server/client/metrics/alerts/details.test.ts index 6f8a7b284d1eb..a8f5cda3501c4 100644 --- a/x-pack/plugins/cases/server/client/metrics/alerts/details.test.ts +++ b/x-pack/plugins/cases/server/client/metrics/alerts/details.test.ts @@ -11,13 +11,13 @@ import { loggingSystemMock } from '@kbn/core/server/mocks'; import { AlertDetails } from './details'; import { mockAlertsService } from '../test_utils/alerts'; -import { BaseHandlerCommonOptions } from '../types'; +import { SingleCaseBaseHandlerCommonOptions } from '../types'; describe('AlertDetails', () => { let client: CasesClientMock; let mockServices: ReturnType['mockServices']; let clientArgs: ReturnType['clientArgs']; - let constructorOptions: BaseHandlerCommonOptions; + let constructorOptions: SingleCaseBaseHandlerCommonOptions; beforeEach(() => { client = createMockClient(); diff --git a/x-pack/plugins/cases/server/client/metrics/alerts/details.ts b/x-pack/plugins/cases/server/client/metrics/alerts/details.ts index eec21d23c4639..87cb0fc3be2ac 100644 --- a/x-pack/plugins/cases/server/client/metrics/alerts/details.ts +++ b/x-pack/plugins/cases/server/client/metrics/alerts/details.ts @@ -5,33 +5,31 @@ * 2.0. */ -import { merge } from 'lodash'; - -import { CaseMetricsResponse } from '../../../../common/api'; +import { SingleCaseMetricsResponse } from '../../../../common/api'; import { createCaseError } from '../../../common/error'; -import { AggregationHandler } from '../aggregation_handler'; -import { AggregationBuilder, AggregationResponse, BaseHandlerCommonOptions } from '../types'; +import { SingleCaseAggregationHandler } from '../single_case_aggregation_handler'; +import { AggregationBuilder, SingleCaseBaseHandlerCommonOptions } from '../types'; import { AlertHosts, AlertUsers } from './aggregations'; -export class AlertDetails extends AggregationHandler { - constructor(options: BaseHandlerCommonOptions) { +export class AlertDetails extends SingleCaseAggregationHandler { + constructor(options: SingleCaseBaseHandlerCommonOptions) { super( options, - new Map([ + new Map>([ ['alerts.hosts', new AlertHosts()], ['alerts.users', new AlertUsers()], ]) ); } - public async compute(): Promise { + public async compute(): Promise { const { alertsService, logger } = this.options.clientArgs; - const { caseId, casesClient } = this.options; + const { casesClient } = this.options; try { const alerts = await casesClient.attachments.getAllAlertsAttachToCase({ - caseId, + caseId: this.caseId, }); if (alerts.length <= 0 || this.aggregationBuilders.length <= 0) { @@ -43,20 +41,13 @@ export class AlertDetails extends AggregationHandler { alerts, }); - return this.formatResponse(aggregationsResponse); + return this.formatResponse(aggregationsResponse); } catch (error) { throw createCaseError({ - message: `Failed to retrieve alerts details attached case id: ${caseId}: ${error}`, + message: `Failed to retrieve alerts details attached case id: ${this.caseId}: ${error}`, error, logger, }); } } - - private formatResponse(aggregationsResponse?: AggregationResponse): CaseMetricsResponse { - return this.aggregationBuilders.reduce( - (acc, feature) => merge(acc, feature.formatResponse(aggregationsResponse)), - {} - ); - } } diff --git a/x-pack/plugins/cases/server/client/metrics/all_cases/aggregations/avg_duration.test.ts b/x-pack/plugins/cases/server/client/metrics/all_cases/aggregations/avg_duration.test.ts new file mode 100644 index 0000000000000..1e63332fd419b --- /dev/null +++ b/x-pack/plugins/cases/server/client/metrics/all_cases/aggregations/avg_duration.test.ts @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { AverageDuration } from './avg_duration'; + +describe('AverageDuration', () => { + it('returns the correct aggregation', async () => { + const agg = new AverageDuration(); + + expect(agg.build()).toEqual({ + mttr: { + avg: { + field: 'cases.attributes.duration', + }, + }, + }); + }); + + it('formats the response correctly', async () => { + const agg = new AverageDuration(); + const res = agg.formatResponse({ mttr: { value: 5 } }); + expect(res).toEqual({ mttr: 5 }); + }); + + it('formats the response correctly if the res is undefined', async () => { + const agg = new AverageDuration(); + // @ts-expect-error + const res = agg.formatResponse(); + expect(res).toEqual({ mttr: 0 }); + }); + + it('formats the response correctly if the mttr is not defined', async () => { + const agg = new AverageDuration(); + const res = agg.formatResponse({}); + expect(res).toEqual({ mttr: 0 }); + }); + + it('formats the response correctly if the value is not defined', async () => { + const agg = new AverageDuration(); + const res = agg.formatResponse({ mttr: {} }); + expect(res).toEqual({ mttr: 0 }); + }); + + it('gets the name correctly', async () => { + const agg = new AverageDuration(); + expect(agg.getName()).toBe('mttr'); + }); +}); diff --git a/x-pack/plugins/cases/server/client/metrics/all_cases/aggregations/avg_duration.ts b/x-pack/plugins/cases/server/client/metrics/all_cases/aggregations/avg_duration.ts new file mode 100644 index 0000000000000..afa0638a2cf0a --- /dev/null +++ b/x-pack/plugins/cases/server/client/metrics/all_cases/aggregations/avg_duration.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { CASE_SAVED_OBJECT } from '../../../../../common/constants'; +import { CasesMetricsResponse } from '../../../../../common/api'; +import { AggregationBuilder, AggregationResponse } from '../../types'; + +export class AverageDuration implements AggregationBuilder { + build() { + return { + mttr: { + avg: { + field: `${CASE_SAVED_OBJECT}.attributes.duration`, + }, + }, + }; + } + + formatResponse(aggregations: AggregationResponse) { + const aggs = aggregations as MTTRAggregate; + + const mttr = aggs?.mttr?.value ?? 0; + + return { mttr }; + } + + getName() { + return 'mttr'; + } +} + +type MTTRAggregate = MTTRAggregateResponse | undefined; + +interface MTTRAggregateResponse { + mttr?: { + value: number; + }; +} diff --git a/x-pack/plugins/cases/server/client/metrics/all_cases/mttr.test.ts b/x-pack/plugins/cases/server/client/metrics/all_cases/mttr.test.ts new file mode 100644 index 0000000000000..e133082e69756 --- /dev/null +++ b/x-pack/plugins/cases/server/client/metrics/all_cases/mttr.test.ts @@ -0,0 +1,160 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { CaseResponse } from '../../../../common/api'; +import { createCasesClientMock } from '../../mocks'; +import { CasesClientArgs } from '../../types'; +import { loggingSystemMock } from '@kbn/core/server/mocks'; +import { createCaseServiceMock } from '../../../services/mocks'; + +import { MTTR } from './mttr'; + +const clientMock = createCasesClientMock(); +const caseService = createCaseServiceMock(); + +const logger = loggingSystemMock.createLogger(); +const getAuthorizationFilter = jest.fn().mockResolvedValue({}); + +const clientArgs = { + logger, + caseService, + authorization: { getAuthorizationFilter }, +} as unknown as CasesClientArgs; + +const constructorOptions = { casesClient: clientMock, clientArgs }; + +describe('MTTR', () => { + beforeAll(() => { + getAuthorizationFilter.mockResolvedValue({}); + clientMock.cases.get.mockResolvedValue({ id: '' } as unknown as CaseResponse); + }); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('returns empty values when no features set up', async () => { + caseService.executeAggregations.mockResolvedValue(undefined); + const handler = new MTTR(constructorOptions); + expect(await handler.compute()).toEqual({}); + }); + + it('returns zero values when aggregation returns undefined', async () => { + caseService.executeAggregations.mockResolvedValue(undefined); + const handler = new MTTR(constructorOptions); + handler.setupFeature('mttr'); + + expect(await handler.compute()).toEqual({ mttr: 0 }); + }); + + it('returns zero values when aggregation returns empty object', async () => { + caseService.executeAggregations.mockResolvedValue({}); + const handler = new MTTR(constructorOptions); + handler.setupFeature('mttr'); + + expect(await handler.compute()).toEqual({ mttr: 0 }); + }); + + it('returns zero values when aggregation returns empty mttr object', async () => { + caseService.executeAggregations.mockResolvedValue({ mttr: {} }); + const handler = new MTTR(constructorOptions); + handler.setupFeature('mttr'); + + expect(await handler.compute()).toEqual({ mttr: 0 }); + }); + + it('returns values when there is a mttr value', async () => { + caseService.executeAggregations.mockResolvedValue({ mttr: { value: 5 } }); + const handler = new MTTR(constructorOptions); + handler.setupFeature('mttr'); + + expect(await handler.compute()).toEqual({ mttr: 5 }); + }); + + it('passes the query options correctly', async () => { + caseService.executeAggregations.mockResolvedValue({ mttr: { value: 5 } }); + const handler = new MTTR({ + ...constructorOptions, + from: '2022-04-28T15:18:00.000Z', + to: '2022-04-28T15:22:00.000Z', + owner: 'cases', + }); + + handler.setupFeature('mttr'); + await handler.compute(); + + expect(caseService.executeAggregations.mock.calls[0][0]).toMatchInlineSnapshot(` + Object { + "aggregationBuilders": Array [ + AverageDuration {}, + ], + "options": Object { + "filter": Object { + "arguments": Array [ + Object { + "arguments": Array [ + Object { + "arguments": Array [ + Object { + "type": "literal", + "value": "cases.attributes.created_at", + }, + "gte", + Object { + "type": "literal", + "value": "2022-04-28T15:18:00.000Z", + }, + ], + "function": "range", + "type": "function", + }, + Object { + "arguments": Array [ + Object { + "type": "literal", + "value": "cases.attributes.created_at", + }, + "lte", + Object { + "type": "literal", + "value": "2022-04-28T15:22:00.000Z", + }, + ], + "function": "range", + "type": "function", + }, + ], + "function": "and", + "type": "function", + }, + Object { + "arguments": Array [ + Object { + "type": "literal", + "value": "cases.attributes.owner", + }, + Object { + "type": "literal", + "value": "cases", + }, + Object { + "type": "literal", + "value": false, + }, + ], + "function": "is", + "type": "function", + }, + ], + "function": "and", + "type": "function", + }, + }, + } + `); + }); +}); diff --git a/x-pack/plugins/cases/server/client/metrics/all_cases/mttr.ts b/x-pack/plugins/cases/server/client/metrics/all_cases/mttr.ts new file mode 100644 index 0000000000000..69cacb7e2318e --- /dev/null +++ b/x-pack/plugins/cases/server/client/metrics/all_cases/mttr.ts @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { CasesMetricsResponse } from '../../../../common/api'; +import { Operations } from '../../../authorization'; +import { createCaseError } from '../../../common/error'; +import { constructQueryOptions } from '../../utils'; +import { AllCasesAggregationHandler } from '../all_cases_aggregation_handler'; +import { AggregationBuilder, AllCasesBaseHandlerCommonOptions } from '../types'; +import { AverageDuration } from './aggregations/avg_duration'; + +export class MTTR extends AllCasesAggregationHandler { + constructor(options: AllCasesBaseHandlerCommonOptions) { + super( + options, + new Map>([['mttr', new AverageDuration()]]) + ); + } + + public async compute(): Promise { + const { authorization, caseService, logger } = this.options.clientArgs; + + try { + const { filter: authorizationFilter } = await authorization.getAuthorizationFilter( + Operations.getCasesMetrics + ); + + const caseQueryOptions = constructQueryOptions({ + from: this.from, + to: this.to, + owner: this.owner, + authorizationFilter, + }); + + const aggregationsResponse = await caseService.executeAggregations({ + aggregationBuilders: this.aggregationBuilders, + options: { filter: caseQueryOptions.filter }, + }); + + return this.formatResponse(aggregationsResponse); + } catch (error) { + throw createCaseError({ + message: `Failed to calculate average mttr: ${error}`, + error, + logger, + }); + } + } +} diff --git a/x-pack/plugins/cases/server/client/metrics/all_cases_aggregation_handler.ts b/x-pack/plugins/cases/server/client/metrics/all_cases_aggregation_handler.ts new file mode 100644 index 0000000000000..3a5a259c28296 --- /dev/null +++ b/x-pack/plugins/cases/server/client/metrics/all_cases_aggregation_handler.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { CasesMetricsResponse } from '../../../common/api'; +import { AggregationHandler } from './aggregation_handler'; +import { AggregationBuilder, AllCasesBaseHandlerCommonOptions } from './types'; + +export abstract class AllCasesAggregationHandler extends AggregationHandler { + protected readonly from?: string; + protected readonly to?: string; + protected readonly owner?: string | string[]; + + constructor( + options: AllCasesBaseHandlerCommonOptions, + aggregations: Map> + ) { + const { owner, from, to, ...restOptions } = options; + super(restOptions, aggregations); + + this.from = from; + this.to = to; + this.owner = owner; + } +} diff --git a/x-pack/plugins/cases/server/client/metrics/all_cases_base_handler.ts b/x-pack/plugins/cases/server/client/metrics/all_cases_base_handler.ts new file mode 100644 index 0000000000000..de9f1f089c8c8 --- /dev/null +++ b/x-pack/plugins/cases/server/client/metrics/all_cases_base_handler.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { CasesMetricsResponse } from '../../../common/api'; +import { BaseHandler } from './base_handler'; +import { AllCasesBaseHandlerCommonOptions } from './types'; + +export abstract class AllCasesBaseHandler extends BaseHandler { + protected readonly owner?: string | string[]; + + constructor(options: AllCasesBaseHandlerCommonOptions, features?: string[]) { + const { owner, ...restOptions } = options; + super(restOptions, features); + + this.owner = owner; + } +} diff --git a/x-pack/plugins/cases/server/client/metrics/base_handler.ts b/x-pack/plugins/cases/server/client/metrics/base_handler.ts index bf76be05f58b3..6525de35bc00c 100644 --- a/x-pack/plugins/cases/server/client/metrics/base_handler.ts +++ b/x-pack/plugins/cases/server/client/metrics/base_handler.ts @@ -5,10 +5,9 @@ * 2.0. */ -import { CaseMetricsResponse } from '../../../common/api'; import { BaseHandlerCommonOptions, MetricsHandler } from './types'; -export abstract class BaseHandler implements MetricsHandler { +export abstract class BaseHandler implements MetricsHandler { constructor( protected readonly options: BaseHandlerCommonOptions, private readonly features?: string[] @@ -18,5 +17,5 @@ export abstract class BaseHandler implements MetricsHandler { return new Set(this.features); } - abstract compute(): Promise; + abstract compute(): Promise; } diff --git a/x-pack/plugins/cases/server/client/metrics/client.ts b/x-pack/plugins/cases/server/client/metrics/client.ts index 8fbb30486bc41..e2e0dfb5c9415 100644 --- a/x-pack/plugins/cases/server/client/metrics/client.ts +++ b/x-pack/plugins/cases/server/client/metrics/client.ts @@ -5,19 +5,27 @@ * 2.0. */ -import { CaseMetricsResponse, CasesStatusRequest, CasesStatusResponse } from '../../../common/api'; +import { + SingleCaseMetricsResponse, + CasesMetricsRequest, + CasesStatusRequest, + CasesStatusResponse, + SingleCaseMetricsRequest, + CasesMetricsResponse, +} from '../../../common/api'; import { CasesClient } from '../client'; import { CasesClientArgs } from '../types'; -import { getStatusTotalsByType } from './get_cases_metrics'; - -import { getCaseMetrics, CaseMetricsParams } from './get_case_metrics'; +import { getStatusTotalsByType } from './get_status_totals'; +import { getCaseMetrics } from './get_case_metrics'; +import { getCasesMetrics } from './get_cases_metrics'; /** * API for interacting with the metrics. */ export interface MetricsSubClient { - getCaseMetrics(params: CaseMetricsParams): Promise; + getCaseMetrics(params: SingleCaseMetricsRequest): Promise; + getCasesMetrics(params: CasesMetricsRequest): Promise; /** * Retrieves the total number of open, closed, and in-progress cases. */ @@ -34,7 +42,10 @@ export const createMetricsSubClient = ( casesClient: CasesClient ): MetricsSubClient => { const casesSubClient: MetricsSubClient = { - getCaseMetrics: (params: CaseMetricsParams) => getCaseMetrics(params, casesClient, clientArgs), + getCaseMetrics: (params: SingleCaseMetricsRequest) => + getCaseMetrics(params, casesClient, clientArgs), + getCasesMetrics: (params: CasesMetricsRequest) => + getCasesMetrics(params, casesClient, clientArgs), getStatusTotalsByType: (params: CasesStatusRequest) => getStatusTotalsByType(params, clientArgs), }; diff --git a/x-pack/plugins/cases/server/client/metrics/connectors.ts b/x-pack/plugins/cases/server/client/metrics/connectors.ts index 3dd29b8b6dda7..1701cef3b8cf9 100644 --- a/x-pack/plugins/cases/server/client/metrics/connectors.ts +++ b/x-pack/plugins/cases/server/client/metrics/connectors.ts @@ -5,30 +5,28 @@ * 2.0. */ -import { CaseMetricsResponse } from '../../../common/api'; +import { SingleCaseMetricsResponse } from '../../../common/api'; import { Operations } from '../../authorization'; import { createCaseError } from '../../common/error'; -import { BaseHandler } from './base_handler'; -import { BaseHandlerCommonOptions } from './types'; +import { SingleCaseBaseHandler } from './single_case_base_handler'; +import { SingleCaseBaseHandlerCommonOptions } from './types'; -export class Connectors extends BaseHandler { - constructor(options: BaseHandlerCommonOptions) { +export class Connectors extends SingleCaseBaseHandler { + constructor(options: SingleCaseBaseHandlerCommonOptions) { super(options, ['connectors']); } - public async compute(): Promise { + public async compute(): Promise { const { unsecuredSavedObjectsClient, authorization, userActionService, logger } = this.options.clientArgs; - const { caseId } = this.options; - const { filter: authorizationFilter } = await authorization.getAuthorizationFilter( Operations.getUserActionMetrics ); const uniqueConnectors = await userActionService.getUniqueConnectors({ unsecuredSavedObjectsClient, - caseId, + caseId: this.caseId, filter: authorizationFilter, }); @@ -38,7 +36,7 @@ export class Connectors extends BaseHandler { }; } catch (error) { throw createCaseError({ - message: `Failed to retrieve total connectors metrics for case id: ${caseId}: ${error}`, + message: `Failed to retrieve total connectors metrics for case id: ${this.caseId}: ${error}`, error, logger, }); diff --git a/x-pack/plugins/cases/server/client/metrics/get_case_metrics.test.ts b/x-pack/plugins/cases/server/client/metrics/get_case_metrics.test.ts index 03b03eafa7d97..51353d9558c1b 100644 --- a/x-pack/plugins/cases/server/client/metrics/get_case_metrics.test.ts +++ b/x-pack/plugins/cases/server/client/metrics/get_case_metrics.test.ts @@ -5,22 +5,23 @@ * 2.0. */ +import { loggingSystemMock, savedObjectsClientMock } from '@kbn/core/server/mocks'; +import { SavedObject } from '@kbn/core/server'; + import { getCaseMetrics } from './get_case_metrics'; import { CaseAttributes, CaseResponse, CaseStatuses } from '../../../common/api'; import { CasesClientMock, createCasesClientMock } from '../mocks'; import { CasesClientArgs } from '../types'; import { createAuthorizationMock } from '../../authorization/mock'; -import { loggingSystemMock, savedObjectsClientMock } from '@kbn/core/server/mocks'; import { createAttachmentServiceMock, createCaseServiceMock, createUserActionServiceMock, } from '../../services/mocks'; -import { SavedObject } from '@kbn/core/server'; import { mockAlertsService } from './test_utils/alerts'; import { createStatusChangeSavedObject } from './test_utils/lifespan'; -describe('getMetrics', () => { +describe('getCaseMetrics', () => { const inProgressStatusChangeTimestamp = new Date('2021-11-23T20:00:43Z'); const currentTime = new Date('2021-11-23T20:01:43Z'); diff --git a/x-pack/plugins/cases/server/client/metrics/get_case_metrics.ts b/x-pack/plugins/cases/server/client/metrics/get_case_metrics.ts index d2ce8c03edeb7..e3132b4a590f7 100644 --- a/x-pack/plugins/cases/server/client/metrics/get_case_metrics.ts +++ b/x-pack/plugins/cases/server/client/metrics/get_case_metrics.ts @@ -5,36 +5,23 @@ * 2.0. */ import { merge } from 'lodash'; -import Boom from '@hapi/boom'; -import { CaseMetricsResponseRt, CaseMetricsResponse } from '../../../common/api'; +import { + SingleCaseMetricsRequest, + SingleCaseMetricsResponse, + SingleCaseMetricsResponseRt, +} from '../../../common/api'; import { Operations } from '../../authorization'; import { createCaseError } from '../../common/error'; import { CasesClient } from '../client'; import { CasesClientArgs } from '../types'; -import { AlertsCount } from './alerts/count'; -import { AlertDetails } from './alerts/details'; -import { Actions } from './actions'; -import { Connectors } from './connectors'; -import { Lifespan } from './lifespan'; -import { MetricsHandler } from './types'; - -export interface CaseMetricsParams { - /** - * The ID of the case. - */ - caseId: string; - /** - * The metrics to retrieve. - */ - features: string[]; -} +import { buildHandlers } from './utils'; export const getCaseMetrics = async ( - params: CaseMetricsParams, + params: SingleCaseMetricsRequest, casesClient: CasesClient, clientArgs: CasesClientArgs -): Promise => { +): Promise => { const { logger } = clientArgs; try { @@ -49,9 +36,9 @@ export const getCaseMetrics = async ( const mergedResults = computedMetrics.reduce((acc, metric) => { return merge(acc, metric); - }, {}); + }, {}) as SingleCaseMetricsResponse; - return CaseMetricsResponseRt.encode(mergedResults); + return SingleCaseMetricsResponseRt.encode(mergedResults); } catch (error) { throw createCaseError({ logger, @@ -61,50 +48,10 @@ export const getCaseMetrics = async ( } }; -const buildHandlers = ( - params: CaseMetricsParams, - casesClient: CasesClient, +const checkAuthorization = async ( + params: SingleCaseMetricsRequest, clientArgs: CasesClientArgs -): Set => { - const handlers: MetricsHandler[] = [AlertsCount, AlertDetails, Actions, Connectors, Lifespan].map( - (ClassName) => new ClassName({ caseId: params.caseId, casesClient, clientArgs }) - ); - - const uniqueFeatures = new Set(params.features); - const handlerFeatures = new Set(); - const handlersToExecute = new Set(); - for (const handler of handlers) { - for (const handlerFeature of handler.getFeatures()) { - if (uniqueFeatures.has(handlerFeature)) { - handler.setupFeature?.(handlerFeature); - handlersToExecute.add(handler); - } - - handlerFeatures.add(handlerFeature); - } - } - - checkAndThrowIfInvalidFeatures(params, handlerFeatures); - - return handlersToExecute; -}; - -const checkAndThrowIfInvalidFeatures = ( - params: CaseMetricsParams, - handlerFeatures: Set ) => { - const invalidFeatures = params.features.filter((feature) => !handlerFeatures.has(feature)); - if (invalidFeatures.length > 0) { - const invalidFeaturesAsString = invalidFeatures.join(', '); - const validFeaturesAsString = [...handlerFeatures.keys()].sort().join(', '); - - throw Boom.badRequest( - `invalid features: [${invalidFeaturesAsString}], please only provide valid features: [${validFeaturesAsString}]` - ); - } -}; - -const checkAuthorization = async (params: CaseMetricsParams, clientArgs: CasesClientArgs) => { const { caseService, authorization } = clientArgs; const caseInfo = await caseService.getCase({ diff --git a/x-pack/plugins/cases/server/client/metrics/get_cases_metrics.test.ts b/x-pack/plugins/cases/server/client/metrics/get_cases_metrics.test.ts new file mode 100644 index 0000000000000..3e94f58a2ba05 --- /dev/null +++ b/x-pack/plugins/cases/server/client/metrics/get_cases_metrics.test.ts @@ -0,0 +1,120 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { CasesClientMock } from '../mocks'; +import { getCasesMetrics } from './get_cases_metrics'; +import { createMockClientArgs, createMockClient } from './test_utils/client'; + +describe('getCasesMetrics', () => { + let client: CasesClientMock; + let mockServices: ReturnType['mockServices']; + let clientArgs: ReturnType['clientArgs']; + + beforeEach(() => { + client = createMockClient(); + ({ mockServices, clientArgs } = createMockClientArgs()); + + jest.clearAllMocks(); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + describe('MTTR', () => { + beforeEach(() => { + mockServices.caseService.executeAggregations.mockResolvedValue({ mttr: { value: 5 } }); + }); + + it('returns the mttr metric', async () => { + const metrics = await getCasesMetrics({ features: ['mttr'] }, client, clientArgs); + expect(metrics).toEqual({ mttr: 5 }); + }); + + it('calls the executeAggregations correctly', async () => { + await getCasesMetrics( + { + features: ['mttr'], + from: '2022-04-28T15:18:00.000Z', + to: '2022-04-28T15:22:00.000Z', + owner: 'cases', + }, + client, + clientArgs + ); + expect(mockServices.caseService.executeAggregations.mock.calls[0][0]).toMatchInlineSnapshot(` + Object { + "aggregationBuilders": Array [ + AverageDuration {}, + ], + "options": Object { + "filter": Object { + "arguments": Array [ + Object { + "arguments": Array [ + Object { + "arguments": Array [ + Object { + "type": "literal", + "value": "cases.attributes.created_at", + }, + "gte", + Object { + "type": "literal", + "value": "2022-04-28T15:18:00.000Z", + }, + ], + "function": "range", + "type": "function", + }, + Object { + "arguments": Array [ + Object { + "type": "literal", + "value": "cases.attributes.created_at", + }, + "lte", + Object { + "type": "literal", + "value": "2022-04-28T15:22:00.000Z", + }, + ], + "function": "range", + "type": "function", + }, + ], + "function": "and", + "type": "function", + }, + Object { + "arguments": Array [ + Object { + "type": "literal", + "value": "cases.attributes.owner", + }, + Object { + "type": "literal", + "value": "cases", + }, + Object { + "type": "literal", + "value": false, + }, + ], + "function": "is", + "type": "function", + }, + ], + "function": "and", + "type": "function", + }, + }, + } + `); + }); + }); +}); diff --git a/x-pack/plugins/cases/server/client/metrics/get_cases_metrics.ts b/x-pack/plugins/cases/server/client/metrics/get_cases_metrics.ts index e02f882820fa7..c7cb0673db42e 100644 --- a/x-pack/plugins/cases/server/client/metrics/get_cases_metrics.ts +++ b/x-pack/plugins/cases/server/client/metrics/get_cases_metrics.ts @@ -5,57 +5,55 @@ * 2.0. */ +import { merge } from 'lodash'; import Boom from '@hapi/boom'; import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; import { identity } from 'fp-ts/lib/function'; import { - CasesStatusRequest, - CasesStatusResponse, - excess, - CasesStatusRequestRt, + CasesMetricsRequest, + CasesMetricsRequestRt, + CasesMetricsResponse, + CasesMetricsResponseRt, throwErrors, - CasesStatusResponseRt, } from '../../../common/api'; -import { CasesClientArgs } from '../types'; -import { Operations } from '../../authorization'; -import { constructQueryOptions } from '../utils'; import { createCaseError } from '../../common/error'; +import { CasesClient } from '../client'; +import { CasesClientArgs } from '../types'; +import { buildHandlers } from './utils'; -export async function getStatusTotalsByType( - params: CasesStatusRequest, +export const getCasesMetrics = async ( + params: CasesMetricsRequest, + casesClient: CasesClient, clientArgs: CasesClientArgs -): Promise { - const { caseService, logger, authorization } = clientArgs; +): Promise => { + const { logger } = clientArgs; + + const queryParams = pipe( + CasesMetricsRequestRt.decode(params), + fold(throwErrors(Boom.badRequest), identity) + ); try { - const queryParams = pipe( - excess(CasesStatusRequestRt).decode(params), - fold(throwErrors(Boom.badRequest), identity) - ); + const handlers = buildHandlers(queryParams, casesClient, clientArgs); - const { filter: authorizationFilter } = await authorization.getAuthorizationFilter( - Operations.getCaseStatuses + const computedMetrics = await Promise.all( + Array.from(handlers).map(async (handler) => { + return handler.compute(); + }) ); - const options = constructQueryOptions({ - owner: queryParams.owner, - from: queryParams.from, - to: queryParams.to, - authorizationFilter, - }); + const mergedResults = computedMetrics.reduce((acc, metric) => { + return merge(acc, metric); + }, {}) as CasesMetricsResponse; - const statusStats = await caseService.getCaseStatusStats({ - searchOptions: options, - }); - - return CasesStatusResponseRt.encode({ - count_open_cases: statusStats.open, - count_in_progress_cases: statusStats['in-progress'], - count_closed_cases: statusStats.closed, - }); + return CasesMetricsResponseRt.encode(mergedResults); } catch (error) { - throw createCaseError({ message: `Failed to get status stats: ${error}`, error, logger }); + throw createCaseError({ + logger, + message: `Failed to retrieve metrics within client for cases: ${error}`, + error, + }); } -} +}; diff --git a/x-pack/plugins/cases/server/client/metrics/get_status_totals.test.ts b/x-pack/plugins/cases/server/client/metrics/get_status_totals.test.ts new file mode 100644 index 0000000000000..775a6904783bf --- /dev/null +++ b/x-pack/plugins/cases/server/client/metrics/get_status_totals.test.ts @@ -0,0 +1,122 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { getStatusTotalsByType } from './get_status_totals'; +import { createMockClientArgs } from './test_utils/client'; + +describe('getStatusTotalsByType', () => { + let mockServices: ReturnType['mockServices']; + let clientArgs: ReturnType['clientArgs']; + + beforeEach(() => { + ({ mockServices, clientArgs } = createMockClientArgs()); + + jest.clearAllMocks(); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + describe('MTTR', () => { + beforeEach(() => { + mockServices.caseService.getCaseStatusStats.mockResolvedValue({ + open: 1, + 'in-progress': 2, + closed: 1, + }); + }); + + it('returns the status correctly', async () => { + const metrics = await getStatusTotalsByType({}, clientArgs); + expect(metrics).toEqual({ + count_closed_cases: 1, + count_in_progress_cases: 2, + count_open_cases: 1, + }); + }); + + it('calls the executeAggregations correctly', async () => { + await getStatusTotalsByType( + { + from: '2022-04-28T15:18:00.000Z', + to: '2022-04-28T15:22:00.000Z', + owner: 'cases', + }, + clientArgs + ); + + expect(mockServices.caseService.getCaseStatusStats.mock.calls[0][0]).toMatchInlineSnapshot(` + Object { + "searchOptions": Object { + "filter": Object { + "arguments": Array [ + Object { + "arguments": Array [ + Object { + "arguments": Array [ + Object { + "type": "literal", + "value": "cases.attributes.created_at", + }, + "gte", + Object { + "type": "literal", + "value": "2022-04-28T15:18:00.000Z", + }, + ], + "function": "range", + "type": "function", + }, + Object { + "arguments": Array [ + Object { + "type": "literal", + "value": "cases.attributes.created_at", + }, + "lte", + Object { + "type": "literal", + "value": "2022-04-28T15:22:00.000Z", + }, + ], + "function": "range", + "type": "function", + }, + ], + "function": "and", + "type": "function", + }, + Object { + "arguments": Array [ + Object { + "type": "literal", + "value": "cases.attributes.owner", + }, + Object { + "type": "literal", + "value": "cases", + }, + Object { + "type": "literal", + "value": false, + }, + ], + "function": "is", + "type": "function", + }, + ], + "function": "and", + "type": "function", + }, + "sortField": "created_at", + }, + } + `); + }); + }); +}); diff --git a/x-pack/plugins/cases/server/client/metrics/get_status_totals.ts b/x-pack/plugins/cases/server/client/metrics/get_status_totals.ts new file mode 100644 index 0000000000000..e02f882820fa7 --- /dev/null +++ b/x-pack/plugins/cases/server/client/metrics/get_status_totals.ts @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import Boom from '@hapi/boom'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { fold } from 'fp-ts/lib/Either'; +import { identity } from 'fp-ts/lib/function'; + +import { + CasesStatusRequest, + CasesStatusResponse, + excess, + CasesStatusRequestRt, + throwErrors, + CasesStatusResponseRt, +} from '../../../common/api'; +import { CasesClientArgs } from '../types'; +import { Operations } from '../../authorization'; +import { constructQueryOptions } from '../utils'; +import { createCaseError } from '../../common/error'; + +export async function getStatusTotalsByType( + params: CasesStatusRequest, + clientArgs: CasesClientArgs +): Promise { + const { caseService, logger, authorization } = clientArgs; + + try { + const queryParams = pipe( + excess(CasesStatusRequestRt).decode(params), + fold(throwErrors(Boom.badRequest), identity) + ); + + const { filter: authorizationFilter } = await authorization.getAuthorizationFilter( + Operations.getCaseStatuses + ); + + const options = constructQueryOptions({ + owner: queryParams.owner, + from: queryParams.from, + to: queryParams.to, + authorizationFilter, + }); + + const statusStats = await caseService.getCaseStatusStats({ + searchOptions: options, + }); + + return CasesStatusResponseRt.encode({ + count_open_cases: statusStats.open, + count_in_progress_cases: statusStats['in-progress'], + count_closed_cases: statusStats.closed, + }); + } catch (error) { + throw createCaseError({ message: `Failed to get status stats: ${error}`, error, logger }); + } +} diff --git a/x-pack/plugins/cases/server/client/metrics/lifespan.ts b/x-pack/plugins/cases/server/client/metrics/lifespan.ts index 6198886036471..d5acf266dd9a0 100644 --- a/x-pack/plugins/cases/server/client/metrics/lifespan.ts +++ b/x-pack/plugins/cases/server/client/metrics/lifespan.ts @@ -7,9 +7,9 @@ import { SavedObject } from '@kbn/core/server'; import { - CaseMetricsResponse, CaseStatuses, CaseUserActionResponse, + SingleCaseMetricsResponse, StatusInfo, StatusUserAction, StatusUserActionRt, @@ -17,22 +17,22 @@ import { } from '../../../common/api'; import { Operations } from '../../authorization'; import { createCaseError } from '../../common/error'; -import { BaseHandler } from './base_handler'; -import { BaseHandlerCommonOptions } from './types'; +import { SingleCaseBaseHandler } from './single_case_base_handler'; +import { SingleCaseBaseHandlerCommonOptions } from './types'; -export class Lifespan extends BaseHandler { - constructor(options: BaseHandlerCommonOptions) { +export class Lifespan extends SingleCaseBaseHandler { + constructor(options: SingleCaseBaseHandlerCommonOptions) { super(options, ['lifespan']); } - public async compute(): Promise { + public async compute(): Promise { const { unsecuredSavedObjectsClient, authorization, userActionService, logger } = this.options.clientArgs; - const { caseId, casesClient } = this.options; + const { casesClient } = this.options; try { - const caseInfo = await casesClient.cases.get({ id: caseId }); + const caseInfo = await casesClient.cases.get({ id: this.caseId }); const caseOpenTimestamp = new Date(caseInfo.created_at); if (!isDateValid(caseOpenTimestamp)) { @@ -47,7 +47,7 @@ export class Lifespan extends BaseHandler { const statusUserActions = await userActionService.findStatusChanges({ unsecuredSavedObjectsClient, - caseId, + caseId: this.caseId, filter: authorizationFilter, }); @@ -62,7 +62,7 @@ export class Lifespan extends BaseHandler { }; } catch (error) { throw createCaseError({ - message: `Failed to retrieve lifespan metrics for case id: ${caseId}: ${error}`, + message: `Failed to retrieve lifespan metrics for case id: ${this.caseId}: ${error}`, error, logger, }); diff --git a/x-pack/plugins/cases/server/client/metrics/single_case_aggregation_handler.ts b/x-pack/plugins/cases/server/client/metrics/single_case_aggregation_handler.ts new file mode 100644 index 0000000000000..509a2f0125ec6 --- /dev/null +++ b/x-pack/plugins/cases/server/client/metrics/single_case_aggregation_handler.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { SingleCaseMetricsResponse } from '../../../common/api'; +import { AggregationHandler } from './aggregation_handler'; +import { AggregationBuilder, SingleCaseBaseHandlerCommonOptions } from './types'; + +export abstract class SingleCaseAggregationHandler extends AggregationHandler { + protected readonly caseId: string; + + constructor( + options: SingleCaseBaseHandlerCommonOptions, + aggregations: Map> + ) { + const { caseId, ...restOptions } = options; + super(restOptions, aggregations); + + this.caseId = caseId; + } +} diff --git a/x-pack/plugins/cases/server/client/metrics/single_case_base_handler.ts b/x-pack/plugins/cases/server/client/metrics/single_case_base_handler.ts new file mode 100644 index 0000000000000..d11af800186b0 --- /dev/null +++ b/x-pack/plugins/cases/server/client/metrics/single_case_base_handler.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { SingleCaseMetricsResponse } from '../../../common/api'; +import { BaseHandler } from './base_handler'; +import { SingleCaseBaseHandlerCommonOptions } from './types'; + +export abstract class SingleCaseBaseHandler extends BaseHandler { + protected readonly caseId: string; + + constructor(options: SingleCaseBaseHandlerCommonOptions, features?: string[]) { + const { caseId, ...restOptions } = options; + super(restOptions, features); + + this.caseId = caseId; + } +} diff --git a/x-pack/plugins/cases/server/client/metrics/test_utils/alerts.ts b/x-pack/plugins/cases/server/client/metrics/test_utils/alerts.ts index 6412f7eb27959..73d22fb575f27 100644 --- a/x-pack/plugins/cases/server/client/metrics/test_utils/alerts.ts +++ b/x-pack/plugins/cases/server/client/metrics/test_utils/alerts.ts @@ -12,7 +12,11 @@ import { AlertHosts, AlertUsers } from '../alerts/aggregations'; export function mockAlertsService() { const alertsService = createAlertServiceMock(); alertsService.executeAggregations.mockImplementation( - async ({ aggregationBuilders }: { aggregationBuilders: AggregationBuilder[] }) => { + async ({ + aggregationBuilders, + }: { + aggregationBuilders: Array>; + }) => { let result = {}; for (const builder of aggregationBuilders) { switch (builder.constructor) { diff --git a/x-pack/plugins/cases/server/client/metrics/test_utils/client.ts b/x-pack/plugins/cases/server/client/metrics/test_utils/client.ts new file mode 100644 index 0000000000000..b132503d41458 --- /dev/null +++ b/x-pack/plugins/cases/server/client/metrics/test_utils/client.ts @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { savedObjectsClientMock, loggingSystemMock } from '@kbn/core/server/mocks'; +import { createAuthorizationMock } from '../../../authorization/mock'; +import { createCaseServiceMock } from '../../../services/mocks'; +import { createCasesClientMock } from '../../mocks'; +import { CasesClientArgs } from '../../types'; + +export function createMockClient() { + const client = createCasesClientMock(); + + return client; +} + +export function createMockClientArgs() { + const authorization = createAuthorizationMock(); + authorization.getAuthorizationFilter.mockImplementation(async () => { + return { filter: undefined, ensureSavedObjectsAreAuthorized: () => {} }; + }); + + const soClient = savedObjectsClientMock.create(); + + const caseService = createCaseServiceMock(); + const logger = loggingSystemMock.createLogger(); + + const clientArgs = { + authorization, + unsecuredSavedObjectsClient: soClient, + caseService, + logger, + }; + + return { mockServices: clientArgs, clientArgs: clientArgs as unknown as CasesClientArgs }; +} diff --git a/x-pack/plugins/cases/server/client/metrics/types.ts b/x-pack/plugins/cases/server/client/metrics/types.ts index 6773ab59b0b02..35bdbc0933fbc 100644 --- a/x-pack/plugins/cases/server/client/metrics/types.ts +++ b/x-pack/plugins/cases/server/client/metrics/types.ts @@ -6,26 +6,34 @@ */ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { CaseMetricsResponse } from '../../../common/api'; import { CasesClient } from '../client'; import { CasesClientArgs } from '../types'; -export interface MetricsHandler { +export interface MetricsHandler { getFeatures(): Set; - compute(): Promise; + compute(): Promise; setupFeature?(feature: string): void; } -export interface AggregationBuilder { +export interface AggregationBuilder { build(): Record; - formatResponse(aggregations: AggregationResponse): CaseMetricsResponse; + formatResponse(aggregations: AggregationResponse): R; getName(): string; } export type AggregationResponse = Record | undefined; export interface BaseHandlerCommonOptions { - caseId: string; casesClient: CasesClient; clientArgs: CasesClientArgs; } + +export interface SingleCaseBaseHandlerCommonOptions extends BaseHandlerCommonOptions { + caseId: string; +} + +export interface AllCasesBaseHandlerCommonOptions extends BaseHandlerCommonOptions { + from?: string; + to?: string; + owner?: string | string[]; +} diff --git a/x-pack/plugins/cases/server/client/metrics/utils.test.ts b/x-pack/plugins/cases/server/client/metrics/utils.test.ts new file mode 100644 index 0000000000000..d376ed56dc232 --- /dev/null +++ b/x-pack/plugins/cases/server/client/metrics/utils.test.ts @@ -0,0 +1,129 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createMockClient, createMockClientArgs } from './test_utils/client'; +import { buildHandlers } from './utils'; + +describe('utils', () => { + describe('buildHandlers', () => { + const casesClient = createMockClient(); + const clientArgs = createMockClientArgs(); + const SINGLE_CASE_FEATURES = [ + 'alerts.count', + 'alerts.users', + 'alerts.hosts', + 'actions.isolateHost', + 'connectors', + 'lifespan', + ]; + + const CASES_FEATURES = ['mttr']; + + it('returns the correct single case handlers', async () => { + const handlers = buildHandlers( + { + caseId: 'test-case-id', + features: SINGLE_CASE_FEATURES, + }, + casesClient, + clientArgs.clientArgs + ); + + handlers.forEach((handler) => { + // @ts-expect-error + expect(handler.caseId).toBe('test-case-id'); + expect( + Array.from(handler.getFeatures().values()).every((feature) => + SINGLE_CASE_FEATURES.includes(feature) + ) + ).toBe(true); + }); + }); + + it('returns the correct cases handlers', async () => { + const handlers = buildHandlers( + { + features: CASES_FEATURES, + from: '2022-04-28T15:18:00.000Z', + to: '2022-04-28T15:22:00.000Z', + owner: 'cases', + }, + casesClient, + clientArgs.clientArgs + ); + + handlers.forEach((handler) => { + // @ts-expect-error + expect(handler.from).toBe('2022-04-28T15:18:00.000Z'); + // @ts-expect-error + expect(handler.to).toBe('2022-04-28T15:22:00.000Z'); + // @ts-expect-error + expect(handler.owner).toBe('cases'); + + expect( + Array.from(handler.getFeatures().values()).every((feature) => + CASES_FEATURES.includes(feature) + ) + ).toBe(true); + }); + }); + + it.each([ + [ + { caseId: 'test-case-id' }, + 'invalid features: [not-exists], please only provide valid features: [actions.isolateHost, alerts.count, alerts.hosts, alerts.users, connectors, lifespan]', + ], + [ + { caseId: null }, + 'invalid features: [not-exists], please only provide valid features: [mttr]', + ], + ])('throws if the feature is not supported: %s', async (opts, msg) => { + expect(() => + buildHandlers( + { + ...opts, + features: ['not-exists'], + }, + casesClient, + clientArgs.clientArgs + ) + ).toThrow(msg); + }); + + it('filters the handlers correctly', async () => { + const handlers = buildHandlers( + { + caseId: 'test-case-id', + features: ['alerts.count'], + }, + casesClient, + clientArgs.clientArgs + ); + + const handler = Array.from(handlers)[0]; + // @ts-expect-error + expect(handler.caseId).toBe('test-case-id'); + expect(Array.from(handler.getFeatures().values())).toEqual(['alerts.count']); + }); + + it('set up the feature correctly', async () => { + const handlers = buildHandlers( + { + caseId: 'test-case-id', + features: ['alerts.hosts'], + }, + casesClient, + clientArgs.clientArgs + ); + + const handler = Array.from(handlers)[0]; + // @ts-expect-error + const aggregationBuilder = handler.aggregationBuilders[0]; + expect(aggregationBuilder.getName()).toBe('hosts'); + }); + }); +}); diff --git a/x-pack/plugins/cases/server/client/metrics/utils.ts b/x-pack/plugins/cases/server/client/metrics/utils.ts new file mode 100644 index 0000000000000..9d6634d888d71 --- /dev/null +++ b/x-pack/plugins/cases/server/client/metrics/utils.ts @@ -0,0 +1,81 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import Boom from '@hapi/boom'; +import { CasesMetricsRequest, SingleCaseMetricsRequest } from '../../../common/api'; +import { CasesClient } from '../client'; +import { CasesClientArgs } from '../types'; +import { AlertsCount } from './alerts/count'; +import { AlertDetails } from './alerts/details'; +import { Actions } from './actions'; +import { Connectors } from './connectors'; +import { Lifespan } from './lifespan'; +import { MetricsHandler } from './types'; +import { MTTR } from './all_cases/mttr'; + +const isSingleCaseMetrics = ( + params: SingleCaseMetricsRequest | CasesMetricsRequest +): params is SingleCaseMetricsRequest => (params as SingleCaseMetricsRequest).caseId != null; + +export const buildHandlers = ( + params: SingleCaseMetricsRequest | CasesMetricsRequest, + casesClient: CasesClient, + clientArgs: CasesClientArgs +): Set> => { + let handlers: Array> = []; + + if (isSingleCaseMetrics(params)) { + handlers = [AlertsCount, AlertDetails, Actions, Connectors, Lifespan].map( + (ClassName) => new ClassName({ caseId: params.caseId, casesClient, clientArgs }) + ); + } else { + handlers = [MTTR].map( + (ClassName) => + new ClassName({ + owner: params.owner, + from: params.from, + to: params.to, + casesClient, + clientArgs, + }) + ); + } + + const uniqueFeatures = new Set(params.features); + const handlerFeatures = new Set(); + const handlersToExecute = new Set>(); + + for (const handler of handlers) { + for (const handlerFeature of handler.getFeatures()) { + if (uniqueFeatures.has(handlerFeature)) { + handler.setupFeature?.(handlerFeature); + handlersToExecute.add(handler); + } + + handlerFeatures.add(handlerFeature); + } + } + + checkAndThrowIfInvalidFeatures(params, handlerFeatures); + + return handlersToExecute; +}; + +const checkAndThrowIfInvalidFeatures = ( + params: SingleCaseMetricsRequest | CasesMetricsRequest, + handlerFeatures: Set +) => { + const invalidFeatures = params.features.filter((feature) => !handlerFeatures.has(feature)); + if (invalidFeatures.length > 0) { + const invalidFeaturesAsString = invalidFeatures.join(', '); + const validFeaturesAsString = [...handlerFeatures.keys()].sort().join(', '); + + throw Boom.badRequest( + `invalid features: [${invalidFeaturesAsString}], please only provide valid features: [${validFeaturesAsString}]` + ); + } +}; diff --git a/x-pack/plugins/cases/server/client/mocks.ts b/x-pack/plugins/cases/server/client/mocks.ts index 6ad4663f1e5ea..a5842cf9137ba 100644 --- a/x-pack/plugins/cases/server/client/mocks.ts +++ b/x-pack/plugins/cases/server/client/mocks.ts @@ -37,6 +37,7 @@ type MetricsSubClientMock = jest.Mocked; const createMetricsSubClientMock = (): MetricsSubClientMock => { return { getCaseMetrics: jest.fn(), + getCasesMetrics: jest.fn(), getStatusTotalsByType: jest.fn(), }; }; diff --git a/x-pack/plugins/cases/server/client/utils.test.ts b/x-pack/plugins/cases/server/client/utils.test.ts index 0210ce9eaf3d4..24e1135020a88 100644 --- a/x-pack/plugins/cases/server/client/utils.test.ts +++ b/x-pack/plugins/cases/server/client/utils.test.ts @@ -87,6 +87,7 @@ describe('utils', () => { "username": "elastic", }, "description": "A description", + "duration": null, "external_service": null, "owner": "securitySolution", "settings": Object { @@ -117,18 +118,6 @@ describe('utils', () => { expect(node).toBeFalsy(); }); - it('returns undefined if the from is malformed', () => { - expect(() => buildRangeFilter({ from: '<' })).toThrowError( - 'Invalid "from" and/or "to" query parameters' - ); - }); - - it('returns undefined if the to is malformed', () => { - expect(() => buildRangeFilter({ to: '<' })).toThrowError( - 'Invalid "from" and/or "to" query parameters' - ); - }); - it('creates a range filter with only the from correctly', () => { const node = buildRangeFilter({ from: 'now-1M' }); expect(toElasticsearchQuery(node!)).toMatchInlineSnapshot(` @@ -216,6 +205,7 @@ describe('utils', () => { field: 'test', savedObjectType: 'test-type', }); + expect(toElasticsearchQuery(node!)).toMatchInlineSnapshot(` Object { "bool": Object { @@ -253,5 +243,51 @@ describe('utils', () => { } `); }); + + it('escapes the query correctly', () => { + const node = buildRangeFilter({ + from: '2022-04-27T12:55:47.576Z', + to: '2022-04-27T12:56:47.576Z', + field: '= ${from}` : undefined; - const toKQL = to != null ? `${savedObjectType}.attributes.${field} <= ${to}` : undefined; + const fromKQL = + from != null + ? `${escapeKuery(savedObjectType)}.attributes.${escapeKuery(field)} >= ${escapeKuery(from)}` + : undefined; + const toKQL = + to != null + ? `${escapeKuery(savedObjectType)}.attributes.${escapeKuery(field)} <= ${escapeKuery(to)}` + : undefined; const rangeKQLQuery = `${fromKQL != null ? fromKQL : ''} ${ fromKQL != null && toKQL != null ? 'and' : '' diff --git a/x-pack/plugins/cases/server/common/utils.test.ts b/x-pack/plugins/cases/server/common/utils.test.ts index 47af4b11a0a96..974c36bd0d8a6 100644 --- a/x-pack/plugins/cases/server/common/utils.test.ts +++ b/x-pack/plugins/cases/server/common/utils.test.ts @@ -103,6 +103,7 @@ describe('common utils', () => { "username": "elastic", }, "description": "This is a brand new case of a bad meanie defacing data", + "duration": null, "external_service": null, "id": "mock-id-1", "owner": "securitySolution", @@ -141,6 +142,7 @@ describe('common utils', () => { "username": "elastic", }, "description": "Oh no, a bad meanie destroying data!", + "duration": null, "external_service": null, "id": "mock-id-2", "owner": "securitySolution", @@ -183,6 +185,7 @@ describe('common utils', () => { "username": "elastic", }, "description": "Oh no, a bad meanie going LOLBins all over the place!", + "duration": null, "external_service": null, "id": "mock-id-3", "owner": "securitySolution", @@ -229,6 +232,7 @@ describe('common utils', () => { "username": "elastic", }, "description": "Oh no, a bad meanie going LOLBins all over the place!", + "duration": null, "external_service": null, "id": "mock-id-4", "owner": "securitySolution", @@ -292,6 +296,7 @@ describe('common utils', () => { "username": "elastic", }, "description": "Oh no, a bad meanie going LOLBins all over the place!", + "duration": null, "external_service": null, "id": "mock-id-3", "owner": "securitySolution", @@ -346,6 +351,7 @@ describe('common utils', () => { "username": "elastic", }, "description": "Oh no, a bad meanie going LOLBins all over the place!", + "duration": null, "external_service": null, "id": "mock-id-3", "owner": "securitySolution", @@ -423,6 +429,7 @@ describe('common utils', () => { "username": "elastic", }, "description": "Oh no, a bad meanie going LOLBins all over the place!", + "duration": null, "external_service": null, "id": "mock-id-3", "owner": "securitySolution", @@ -475,6 +482,7 @@ describe('common utils', () => { "username": "elastic", }, "description": "This is a brand new case of a bad meanie defacing data", + "duration": null, "external_service": null, "id": "mock-id-1", "owner": "securitySolution", diff --git a/x-pack/plugins/cases/server/common/utils.ts b/x-pack/plugins/cases/server/common/utils.ts index 9385e83c948c9..11e77c5eb4579 100644 --- a/x-pack/plugins/cases/server/common/utils.ts +++ b/x-pack/plugins/cases/server/common/utils.ts @@ -55,6 +55,7 @@ export const transformNewCase = ({ newCase: CasePostRequest; }): CaseAttributes => ({ ...newCase, + duration: null, closed_at: null, closed_by: null, created_at: new Date().toISOString(), diff --git a/x-pack/plugins/cases/server/plugin.ts b/x-pack/plugins/cases/server/plugin.ts index 52d413cb1ef83..4ec2415bae54d 100644 --- a/x-pack/plugins/cases/server/plugin.ts +++ b/x-pack/plugins/cases/server/plugin.ts @@ -6,12 +6,12 @@ */ import { - CoreSetup, - CoreStart, IContextProvider, KibanaRequest, Logger, PluginInitializerContext, + CoreSetup, + CoreStart, } from '@kbn/core/server'; import { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server'; @@ -198,10 +198,11 @@ export class CasePlugin { return { getCasesClient: async () => { const [{ savedObjects }] = await core.getStartServices(); + const coreContext = await context.core; return this.clientFactory.create({ request, - scopedClusterClient: context.core.elasticsearch.client.asCurrentUser, + scopedClusterClient: coreContext.elasticsearch.client.asCurrentUser, savedObjectsService: savedObjects, }); }, diff --git a/x-pack/plugins/cases/server/routes/api/__fixtures__/mock_saved_objects.ts b/x-pack/plugins/cases/server/routes/api/__fixtures__/mock_saved_objects.ts index cf5de90f4f61f..cc45ef0e2d069 100644 --- a/x-pack/plugins/cases/server/routes/api/__fixtures__/mock_saved_objects.ts +++ b/x-pack/plugins/cases/server/routes/api/__fixtures__/mock_saved_objects.ts @@ -34,6 +34,7 @@ export const mockCases: Array> = [ email: 'testemail@elastic.co', username: 'elastic', }, + duration: null, description: 'This is a brand new case of a bad meanie defacing data', external_service: null, title: 'Super Bad Security Issue', @@ -72,6 +73,7 @@ export const mockCases: Array> = [ email: 'testemail@elastic.co', username: 'elastic', }, + duration: null, description: 'Oh no, a bad meanie destroying data!', external_service: null, title: 'Damaging Data Destruction Detected', @@ -110,6 +112,7 @@ export const mockCases: Array> = [ email: 'testemail@elastic.co', username: 'elastic', }, + duration: null, description: 'Oh no, a bad meanie going LOLBins all over the place!', external_service: null, title: 'Another bad one', @@ -152,6 +155,7 @@ export const mockCases: Array> = [ email: 'testemail@elastic.co', username: 'elastic', }, + duration: null, description: 'Oh no, a bad meanie going LOLBins all over the place!', external_service: null, status: CaseStatuses.closed, diff --git a/x-pack/plugins/cases/server/routes/api/cases/alerts/get_cases.ts b/x-pack/plugins/cases/server/routes/api/cases/alerts/get_cases.ts index 00a368e834a0a..8a9c02cf574d7 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/alerts/get_cases.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/alerts/get_cases.ts @@ -24,7 +24,8 @@ export const getCasesByAlertIdRoute = createCasesRoute({ try { const alertID = request.params.alert_id; - const casesClient = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const casesClient = await caseContext.getCasesClient(); const options = request.query as CasesByAlertIDRequest; return response.ok({ diff --git a/x-pack/plugins/cases/server/routes/api/cases/delete_cases.ts b/x-pack/plugins/cases/server/routes/api/cases/delete_cases.ts index a63d07037de01..5a397841f976d 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/delete_cases.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/delete_cases.ts @@ -21,7 +21,8 @@ export const deleteCaseRoute = createCasesRoute({ }, handler: async ({ context, request, response }) => { try { - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); await client.cases.delete(request.query.ids); return response.noContent(); diff --git a/x-pack/plugins/cases/server/routes/api/cases/find_cases.ts b/x-pack/plugins/cases/server/routes/api/cases/find_cases.ts index 711c6909df46c..2a42bb3fa3353 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/find_cases.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/find_cases.ts @@ -15,7 +15,8 @@ export const findCaseRoute = createCasesRoute({ path: `${CASES_URL}/_find`, handler: async ({ context, request, response }) => { try { - const casesClient = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const casesClient = await caseContext.getCasesClient(); const options = request.query as CasesFindRequest; return response.ok({ diff --git a/x-pack/plugins/cases/server/routes/api/cases/get_case.ts b/x-pack/plugins/cases/server/routes/api/cases/get_case.ts index f0e53e82f1494..736b9b973ce7d 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/get_case.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/get_case.ts @@ -41,7 +41,8 @@ export const getCaseRoute = createCasesRoute({ ); } - const casesClient = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const casesClient = await caseContext.getCasesClient(); const id = request.params.case_id; return response.ok({ @@ -70,7 +71,8 @@ export const resolveCaseRoute = createCasesRoute({ params, handler: async ({ context, request, response }) => { try { - const casesClient = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const casesClient = await caseContext.getCasesClient(); const id = request.params.case_id; return response.ok({ diff --git a/x-pack/plugins/cases/server/routes/api/cases/patch_cases.ts b/x-pack/plugins/cases/server/routes/api/cases/patch_cases.ts index c148a45220a74..bb9649aaa092c 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/patch_cases.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/patch_cases.ts @@ -15,7 +15,8 @@ export const patchCaseRoute = createCasesRoute({ path: CASES_URL, handler: async ({ context, request, response }) => { try { - const casesClient = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const casesClient = await caseContext.getCasesClient(); const cases = request.body as CasesPatchRequest; return response.ok({ diff --git a/x-pack/plugins/cases/server/routes/api/cases/post_case.ts b/x-pack/plugins/cases/server/routes/api/cases/post_case.ts index 226d0308a3152..8c4d43274f21a 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/post_case.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/post_case.ts @@ -15,7 +15,8 @@ export const postCaseRoute = createCasesRoute({ path: CASES_URL, handler: async ({ context, request, response }) => { try { - const casesClient = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const casesClient = await caseContext.getCasesClient(); const theCase = request.body as CasePostRequest; return response.ok({ diff --git a/x-pack/plugins/cases/server/routes/api/cases/push_case.ts b/x-pack/plugins/cases/server/routes/api/cases/push_case.ts index 175838a9d313c..9ee30ed34f2a5 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/push_case.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/push_case.ts @@ -21,7 +21,8 @@ export const pushCaseRoute: CaseRoute = createCasesRoute({ path: CASE_PUSH_URL, handler: async ({ context, request, response }) => { try { - const casesClient = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const casesClient = await caseContext.getCasesClient(); const params = pipe( CasePushRequestParamsRt.decode(request.params), diff --git a/x-pack/plugins/cases/server/routes/api/cases/reporters/get_reporters.ts b/x-pack/plugins/cases/server/routes/api/cases/reporters/get_reporters.ts index ee413d73565ee..56465fd7be1c4 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/reporters/get_reporters.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/reporters/get_reporters.ts @@ -15,7 +15,8 @@ export const getReportersRoute = createCasesRoute({ path: CASE_REPORTERS_URL, handler: async ({ context, request, response }) => { try { - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); const options = request.query as AllReportersFindRequest; return response.ok({ body: await client.cases.getReporters({ ...options }) }); diff --git a/x-pack/plugins/cases/server/routes/api/cases/tags/get_tags.ts b/x-pack/plugins/cases/server/routes/api/cases/tags/get_tags.ts index 7dfa948aa623c..8c2071750f5e6 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/tags/get_tags.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/tags/get_tags.ts @@ -15,7 +15,8 @@ export const getTagsRoute = createCasesRoute({ path: CASE_TAGS_URL, handler: async ({ context, request, response }) => { try { - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); const options = request.query as AllTagsFindRequest; return response.ok({ body: await client.cases.getTags({ ...options }) }); diff --git a/x-pack/plugins/cases/server/routes/api/comments/delete_all_comments.ts b/x-pack/plugins/cases/server/routes/api/comments/delete_all_comments.ts index 0a1ebd3b66a74..317ebaec20a13 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/delete_all_comments.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/delete_all_comments.ts @@ -20,7 +20,8 @@ export const deleteAllCommentsRoute = createCasesRoute({ }, handler: async ({ context, request, response }) => { try { - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); await client.attachments.deleteAll({ caseID: request.params.case_id, diff --git a/x-pack/plugins/cases/server/routes/api/comments/delete_comment.ts b/x-pack/plugins/cases/server/routes/api/comments/delete_comment.ts index 220fbffc76cc0..775fabb846408 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/delete_comment.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/delete_comment.ts @@ -22,7 +22,8 @@ export const deleteCommentRoute = createCasesRoute({ }, handler: async ({ context, request, response }) => { try { - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); await client.attachments.delete({ attachmentID: request.params.comment_id, caseID: request.params.case_id, diff --git a/x-pack/plugins/cases/server/routes/api/comments/find_comments.ts b/x-pack/plugins/cases/server/routes/api/comments/find_comments.ts index 14c6090d62ea1..23a7ecb601534 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/find_comments.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/find_comments.ts @@ -32,7 +32,8 @@ export const findCommentsRoute = createCasesRoute({ fold(throwErrors(Boom.badRequest), identity) ); - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); return response.ok({ body: await client.attachments.find({ caseID: request.params.case_id, diff --git a/x-pack/plugins/cases/server/routes/api/comments/get_alerts.ts b/x-pack/plugins/cases/server/routes/api/comments/get_alerts.ts index 4fa793059ed63..a0b0da466e7ce 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/get_alerts.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/get_alerts.ts @@ -23,7 +23,8 @@ export const getAllAlertsAttachedToCaseRoute = createCasesRoute({ try { const caseId = request.params.case_id; - const casesClient = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const casesClient = await caseContext.getCasesClient(); return response.ok({ body: await casesClient.attachments.getAllAlertsAttachToCase({ caseId }), diff --git a/x-pack/plugins/cases/server/routes/api/comments/get_all_comment.ts b/x-pack/plugins/cases/server/routes/api/comments/get_all_comment.ts index 44f8f59550fb3..72b8f7e6ac98b 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/get_all_comment.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/get_all_comment.ts @@ -23,9 +23,10 @@ export const getAllCommentsRoute = createCasesRoute({ }), }, options: { deprecated: true }, - handler: async ({ context, request, response, logger, kibanaVersion }) => { + handler: async ({ context, request, response }) => { try { - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); return response.ok({ body: await client.attachments.getAll({ diff --git a/x-pack/plugins/cases/server/routes/api/comments/get_comment.ts b/x-pack/plugins/cases/server/routes/api/comments/get_comment.ts index 91adf832f1ea6..2a863f3ee4df4 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/get_comment.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/get_comment.ts @@ -22,7 +22,8 @@ export const getCommentRoute = createCasesRoute({ }, handler: async ({ context, request, response }) => { try { - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); return response.ok({ body: await client.attachments.get({ diff --git a/x-pack/plugins/cases/server/routes/api/comments/patch_comment.ts b/x-pack/plugins/cases/server/routes/api/comments/patch_comment.ts index ebc17daa25611..4bb6493475a9c 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/patch_comment.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/patch_comment.ts @@ -31,7 +31,8 @@ export const patchCommentRoute = createCasesRoute({ fold(throwErrors(Boom.badRequest), identity) ); - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); return response.ok({ body: await client.attachments.update({ diff --git a/x-pack/plugins/cases/server/routes/api/comments/post_comment.ts b/x-pack/plugins/cases/server/routes/api/comments/post_comment.ts index 1ececb3653741..f501f3a425801 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/post_comment.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/post_comment.ts @@ -21,7 +21,8 @@ export const postCommentRoute = createCasesRoute({ }, handler: async ({ context, request, response }) => { try { - const casesClient = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const casesClient = await caseContext.getCasesClient(); const caseId = request.params.case_id; const comment = request.body as CommentRequest; diff --git a/x-pack/plugins/cases/server/routes/api/configure/get_configure.ts b/x-pack/plugins/cases/server/routes/api/configure/get_configure.ts index 8dabf7862fc88..72ca1f6a38324 100644 --- a/x-pack/plugins/cases/server/routes/api/configure/get_configure.ts +++ b/x-pack/plugins/cases/server/routes/api/configure/get_configure.ts @@ -15,7 +15,8 @@ export const getCaseConfigureRoute = createCasesRoute({ path: CASE_CONFIGURE_URL, handler: async ({ context, request, response }) => { try { - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); const options = request.query as GetConfigureFindRequest; return response.ok({ diff --git a/x-pack/plugins/cases/server/routes/api/configure/get_connectors.ts b/x-pack/plugins/cases/server/routes/api/configure/get_connectors.ts index da99cd19065d6..4c28b896bd855 100644 --- a/x-pack/plugins/cases/server/routes/api/configure/get_connectors.ts +++ b/x-pack/plugins/cases/server/routes/api/configure/get_connectors.ts @@ -17,7 +17,8 @@ export const getConnectorsRoute = createCasesRoute({ path: `${CASE_CONFIGURE_CONNECTORS_URL}/_find`, handler: async ({ context, response }) => { try { - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); return response.ok({ body: await client.configure.getConnectors() }); } catch (error) { diff --git a/x-pack/plugins/cases/server/routes/api/configure/patch_configure.ts b/x-pack/plugins/cases/server/routes/api/configure/patch_configure.ts index 40b0d5123f429..b6754dc6da8f6 100644 --- a/x-pack/plugins/cases/server/routes/api/configure/patch_configure.ts +++ b/x-pack/plugins/cases/server/routes/api/configure/patch_configure.ts @@ -30,7 +30,8 @@ export const patchCaseConfigureRoute = createCasesRoute({ fold(throwErrors(Boom.badRequest), identity) ); - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); const configuration = request.body as CasesConfigurePatch; return response.ok({ diff --git a/x-pack/plugins/cases/server/routes/api/configure/post_configure.ts b/x-pack/plugins/cases/server/routes/api/configure/post_configure.ts index bb64175fb52ad..102d618fdc052 100644 --- a/x-pack/plugins/cases/server/routes/api/configure/post_configure.ts +++ b/x-pack/plugins/cases/server/routes/api/configure/post_configure.ts @@ -25,7 +25,8 @@ export const postCaseConfigureRoute = createCasesRoute({ fold(throwErrors(Boom.badRequest), identity) ); - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); return response.ok({ body: await client.configure.create(query), diff --git a/x-pack/plugins/cases/server/routes/api/get_external_routes.ts b/x-pack/plugins/cases/server/routes/api/get_external_routes.ts index 7908e4eb84359..7b7a18cc7c83c 100644 --- a/x-pack/plugins/cases/server/routes/api/get_external_routes.ts +++ b/x-pack/plugins/cases/server/routes/api/get_external_routes.ts @@ -30,6 +30,7 @@ import { patchCaseConfigureRoute } from './configure/patch_configure'; import { postCaseConfigureRoute } from './configure/post_configure'; import { getAllAlertsAttachedToCaseRoute } from './comments/get_alerts'; import { getCaseMetricRoute } from './metrics/get_case_metrics'; +import { getCasesMetricRoute } from './metrics/get_cases_metrics'; export const getExternalRoutes = () => [ @@ -58,4 +59,5 @@ export const getExternalRoutes = () => postCaseConfigureRoute, getAllAlertsAttachedToCaseRoute, getCaseMetricRoute, + getCasesMetricRoute, ] as CaseRoute[]; diff --git a/x-pack/plugins/cases/server/routes/api/internal/bulk_create_attachments.ts b/x-pack/plugins/cases/server/routes/api/internal/bulk_create_attachments.ts index 1940cd442eb27..cd2facd2391e3 100644 --- a/x-pack/plugins/cases/server/routes/api/internal/bulk_create_attachments.ts +++ b/x-pack/plugins/cases/server/routes/api/internal/bulk_create_attachments.ts @@ -23,7 +23,8 @@ export const bulkCreateAttachmentsRoute = createCasesRoute({ }, handler: async ({ context, request, response }) => { try { - const casesClient = await context.cases.getCasesClient(); + const casesContext = await context.cases; + const casesClient = await casesContext.getCasesClient(); const caseId = request.params.case_id; const attachments = request.body as BulkCreateCommentRequest; diff --git a/x-pack/plugins/cases/server/routes/api/metrics/get_case_metrics.ts b/x-pack/plugins/cases/server/routes/api/metrics/get_case_metrics.ts index b86b84410abe6..13bfa2093f623 100644 --- a/x-pack/plugins/cases/server/routes/api/metrics/get_case_metrics.ts +++ b/x-pack/plugins/cases/server/routes/api/metrics/get_case_metrics.ts @@ -24,7 +24,8 @@ export const getCaseMetricRoute = createCasesRoute({ }, handler: async ({ context, request, response }) => { try { - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); return response.ok({ body: await client.metrics.getCaseMetrics({ caseId: request.params.case_id, diff --git a/x-pack/plugins/cases/server/routes/api/metrics/get_cases_metrics.ts b/x-pack/plugins/cases/server/routes/api/metrics/get_cases_metrics.ts new file mode 100644 index 0000000000000..3eb9ec26a9297 --- /dev/null +++ b/x-pack/plugins/cases/server/routes/api/metrics/get_cases_metrics.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; + +import { CASE_METRICS_URL } from '../../../../common/constants'; +import { createCaseError } from '../../../common/error'; +import { createCasesRoute } from '../create_cases_route'; + +export const getCasesMetricRoute = createCasesRoute({ + method: 'get', + path: CASE_METRICS_URL, + params: { + query: schema.object({ + features: schema.arrayOf(schema.string({ minLength: 1 })), + owner: schema.maybe(schema.oneOf([schema.arrayOf(schema.string()), schema.string()])), + from: schema.maybe(schema.string()), + to: schema.maybe(schema.string()), + }), + }, + handler: async ({ context, request, response }) => { + try { + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); + return response.ok({ + body: await client.metrics.getCasesMetrics({ + ...request.query, + }), + }); + } catch (error) { + throw createCaseError({ + message: `Failed to get cases metrics in route: ${error}`, + error, + }); + } + }, +}); diff --git a/x-pack/plugins/cases/server/routes/api/stats/get_status.ts b/x-pack/plugins/cases/server/routes/api/stats/get_status.ts index c245f435835f6..d35d366534c14 100644 --- a/x-pack/plugins/cases/server/routes/api/stats/get_status.ts +++ b/x-pack/plugins/cases/server/routes/api/stats/get_status.ts @@ -19,9 +19,10 @@ export const getStatusRoute: CaseRoute = createCasesRoute({ method: 'get', path: CASE_STATUS_URL, options: { deprecated: true }, - handler: async ({ context, request, response, logger, kibanaVersion }) => { + handler: async ({ context, request, response }) => { try { - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); return response.ok({ body: await client.metrics.getStatusTotalsByType(request.query as CasesStatusRequest), }); diff --git a/x-pack/plugins/cases/server/routes/api/user_actions/get_all_user_actions.ts b/x-pack/plugins/cases/server/routes/api/user_actions/get_all_user_actions.ts index ae686969974ea..257db8ab70f00 100644 --- a/x-pack/plugins/cases/server/routes/api/user_actions/get_all_user_actions.ts +++ b/x-pack/plugins/cases/server/routes/api/user_actions/get_all_user_actions.ts @@ -23,9 +23,10 @@ export const getUserActionsRoute = createCasesRoute({ }), }, options: { deprecated: true }, - handler: async ({ context, request, response, logger, kibanaVersion }) => { + handler: async ({ context, request, response }) => { try { - const casesClient = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const casesClient = await caseContext.getCasesClient(); const caseId = request.params.case_id; return response.ok({ diff --git a/x-pack/plugins/cases/server/saved_object_types/cases.ts b/x-pack/plugins/cases/server/saved_object_types/cases.ts index 441bd818189ae..ea68fc24f60ca 100644 --- a/x-pack/plugins/cases/server/saved_object_types/cases.ts +++ b/x-pack/plugins/cases/server/saved_object_types/cases.ts @@ -59,6 +59,9 @@ export const createCaseSavedObjectType = ( }, }, }, + duration: { + type: 'unsigned_long', + }, description: { type: 'text', }, @@ -155,7 +158,7 @@ export const createCaseSavedObjectType = ( management: { importableAndExportable: true, defaultSearchField: 'title', - icon: 'folderExclamation', + icon: 'casesApp', getTitle: (savedObject: SavedObject) => savedObject.attributes.title, onExport: async ( context: SavedObjectsExportTransformContext, diff --git a/x-pack/plugins/cases/server/saved_object_types/migrations/cases.test.ts b/x-pack/plugins/cases/server/saved_object_types/migrations/cases.test.ts index bdc6b6ca18e64..70e0e91caa57f 100644 --- a/x-pack/plugins/cases/server/saved_object_types/migrations/cases.test.ts +++ b/x-pack/plugins/cases/server/saved_object_types/migrations/cases.test.ts @@ -15,7 +15,7 @@ import { import { CASE_SAVED_OBJECT } from '../../../common/constants'; import { getNoneCaseConnector } from '../../common/utils'; import { createExternalService, ESCaseConnectorWithId } from '../../services/test_utils'; -import { caseConnectorIdMigration, removeCaseType } from './cases'; +import { addDuration, caseConnectorIdMigration, removeCaseType } from './cases'; // eslint-disable-next-line @typescript-eslint/naming-convention const create_7_14_0_case = ({ @@ -371,4 +371,129 @@ describe('case migrations', () => { }); }); }); + + describe('addDuration', () => { + it('adds the duration correctly', () => { + const doc = { + id: '123', + attributes: { + created_at: '2021-11-23T19:00:00Z', + closed_at: '2021-11-23T19:02:00Z', + }, + type: 'abc', + references: [], + } as unknown as SavedObjectSanitizedDoc; + + expect(addDuration(doc)).toEqual({ + ...doc, + attributes: { + ...doc.attributes, + duration: 120, + }, + }); + }); + + it.each([['invalid'], [null]])( + 'returns null if the createdAt date is %s', + (createdAtInvalid) => { + const doc = { + id: '123', + attributes: { + created_at: createdAtInvalid, + closed_at: '2021-11-23T19:02:00Z', + }, + type: 'abc', + references: [], + } as unknown as SavedObjectSanitizedDoc; + + expect(addDuration(doc)).toEqual({ + ...doc, + attributes: { + ...doc.attributes, + duration: null, + }, + }); + } + ); + + it.each([['invalid'], [null]])('returns null if the closedAt date is %s', (closedAtInvalid) => { + const doc = { + id: '123', + attributes: { + created_at: '2021-11-23T19:02:00Z', + closed_at: closedAtInvalid, + }, + type: 'abc', + references: [], + } as unknown as SavedObjectSanitizedDoc; + + expect(addDuration(doc)).toEqual({ + ...doc, + attributes: { + ...doc.attributes, + duration: null, + }, + }); + }); + + it('returns null if created_at > closed_at', () => { + const doc = { + id: '123', + attributes: { + created_at: '2021-11-23T19:05:00Z', + closed_at: '2021-11-23T19:00:00Z', + }, + type: 'abc', + references: [], + } as unknown as SavedObjectSanitizedDoc; + + expect(addDuration(doc)).toEqual({ + ...doc, + attributes: { + ...doc.attributes, + duration: null, + }, + }); + }); + + it('rounds the seconds correctly', () => { + const doc = { + id: '123', + attributes: { + created_at: '2022-04-11T15:56:00.087Z', + closed_at: '2022-04-11T15:58:56.187Z', + }, + type: 'abc', + references: [], + } as unknown as SavedObjectSanitizedDoc; + + expect(addDuration(doc)).toEqual({ + ...doc, + attributes: { + ...doc.attributes, + duration: 176, + }, + }); + }); + + it('rounds to zero correctly', () => { + const doc = { + id: '123', + attributes: { + created_at: '2022-04-11T15:56:00.087Z', + closed_at: '2022-04-11T15:56:00.187Z', + }, + type: 'abc', + references: [], + } as unknown as SavedObjectSanitizedDoc; + + expect(addDuration(doc)).toEqual({ + ...doc, + attributes: { + ...doc.attributes, + duration: 0, + }, + }); + }); + }); }); diff --git a/x-pack/plugins/cases/server/saved_object_types/migrations/cases.ts b/x-pack/plugins/cases/server/saved_object_types/migrations/cases.ts index eaa93a585015f..91a462c5c8053 100644 --- a/x-pack/plugins/cases/server/saved_object_types/migrations/cases.ts +++ b/x-pack/plugins/cases/server/saved_object_types/migrations/cases.ts @@ -11,7 +11,7 @@ import { cloneDeep, unset } from 'lodash'; import { SavedObjectUnsanitizedDoc, SavedObjectSanitizedDoc } from '@kbn/core/server'; import { addOwnerToSO, SanitizedCaseOwner } from '.'; import { ESConnectorFields } from '../../services'; -import { ConnectorTypes } from '../../../common/api'; +import { CaseAttributes, ConnectorTypes } from '../../../common/api'; import { CONNECTOR_ID_REFERENCE_NAME, PUSH_CONNECTOR_ID_REFERENCE_NAME, @@ -86,6 +86,34 @@ export const removeCaseType = ( return { ...docCopy, references: doc.references ?? [] }; }; +export const addDuration = ( + doc: SavedObjectUnsanitizedDoc> +): SavedObjectSanitizedDoc => { + let duration = null; + + try { + const createdAt = doc.attributes.created_at; + const closedAt = doc.attributes.closed_at; + + if (createdAt != null && closedAt != null) { + const createdAtMillis = new Date(createdAt).getTime(); + const closedAtMillis = new Date(closedAt).getTime(); + + if (!isNaN(createdAtMillis) && !isNaN(closedAtMillis) && closedAtMillis >= createdAtMillis) { + duration = Math.floor((closedAtMillis - createdAtMillis) / 1000); + } + } + } catch (err) { + // Silence date errors + } + + /** + * Duration is the time from the creation of the case to the close of the case in seconds + * If an error occurs or the case has not been closed then the duration is set to null + */ + return { ...doc, attributes: { ...doc.attributes, duration }, references: doc.references ?? [] }; +}; + export const caseMigrations = { '7.10.0': ( doc: SavedObjectUnsanitizedDoc @@ -147,4 +175,5 @@ export const caseMigrations = { }, '7.15.0': caseConnectorIdMigration, '8.1.0': removeCaseType, + '8.3.0': addDuration, }; diff --git a/x-pack/plugins/cases/server/services/alerts/index.ts b/x-pack/plugins/cases/server/services/alerts/index.ts index 69c44b30fec28..b219c50964d39 100644 --- a/x-pack/plugins/cases/server/services/alerts/index.ts +++ b/x-pack/plugins/cases/server/services/alerts/index.ts @@ -30,7 +30,7 @@ export class AlertService { aggregationBuilders, alerts, }: { - aggregationBuilders: AggregationBuilder[]; + aggregationBuilders: Array>; alerts: AlertIdIndex[]; }): Promise { try { diff --git a/x-pack/plugins/cases/server/services/cases/index.test.ts b/x-pack/plugins/cases/server/services/cases/index.test.ts index 7e576b83404db..84c580c8800e3 100644 --- a/x-pack/plugins/cases/server/services/cases/index.test.ts +++ b/x-pack/plugins/cases/server/services/cases/index.test.ts @@ -20,6 +20,7 @@ import { SavedObject, SavedObjectReference, SavedObjectsCreateOptions, + SavedObjectsFindResponse, SavedObjectsFindResult, SavedObjectsUpdateOptions, SavedObjectsUpdateResponse, @@ -160,6 +161,7 @@ describe('CasesService', () => { "username": "elastic", }, "description": "This is a brand new case of a bad meanie defacing data", + "duration": null, "owner": "securitySolution", "settings": Object { "syncAlerts": true, @@ -500,6 +502,7 @@ describe('CasesService', () => { "username": "elastic", }, "description": "This is a brand new case of a bad meanie defacing data", + "duration": null, "external_service": Object { "connector_name": ".jira", "external_id": "100", @@ -1132,4 +1135,71 @@ describe('CasesService', () => { }); }); }); + + describe('executeAggregations', () => { + const aggregationBuilders = [ + { + build: () => ({ + myAggregation: { avg: { field: 'avg-field' } }, + }), + getName: () => 'avg-test-builder', + formatResponse: () => {}, + }, + { + build: () => ({ + myAggregation: { min: { field: 'min-field' } }, + }), + getName: () => 'min-test-builder', + formatResponse: () => {}, + }, + ]; + + it('returns an aggregation correctly', async () => { + unsecuredSavedObjectsClient.find.mockResolvedValue({ + saved_objects: [], + total: 0, + page: 1, + per_page: 1, + aggregations: { myAggregation: { value: 0 } }, + } as SavedObjectsFindResponse); + + const res = await service.executeAggregations({ aggregationBuilders }); + expect(res).toEqual({ myAggregation: { value: 0 } }); + }); + + it('calls find correctly', async () => { + unsecuredSavedObjectsClient.find.mockResolvedValue({ + saved_objects: [], + total: 0, + page: 1, + per_page: 1, + aggregations: { myAggregation: { value: 0 } }, + } as SavedObjectsFindResponse); + + await service.executeAggregations({ aggregationBuilders, options: { perPage: 20 } }); + expect(unsecuredSavedObjectsClient.find.mock.calls[0][0]).toMatchInlineSnapshot(` + Object { + "aggs": Object { + "myAggregation": Object { + "min": Object { + "field": "min-field", + }, + }, + }, + "perPage": 20, + "sortField": "created_at", + "type": "cases", + } + `); + }); + + it('throws an error correctly', async () => { + expect.assertions(1); + unsecuredSavedObjectsClient.find.mockRejectedValue(new Error('Aggregation error')); + + await expect(service.executeAggregations({ aggregationBuilders })).rejects.toThrow( + 'Failed to execute aggregations [avg-test-builder,min-test-builder]: Error: Aggregation error' + ); + }); + }); }); diff --git a/x-pack/plugins/cases/server/services/cases/index.ts b/x-pack/plugins/cases/server/services/cases/index.ts index 26557d4ea7748..f75e52e63dca9 100644 --- a/x-pack/plugins/cases/server/services/cases/index.ts +++ b/x-pack/plugins/cases/server/services/cases/index.ts @@ -16,6 +16,7 @@ import { SavedObjectsBulkUpdateResponse, SavedObjectsUpdateResponse, SavedObjectsResolveResponse, + SavedObjectsFindOptions, } from '@kbn/core/server'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; @@ -52,6 +53,8 @@ import { } from './transform'; import { ESCaseAttributes } from './types'; import { AttachmentService } from '../attachments'; +import { AggregationBuilder, AggregationResponse } from '../../client/metrics/types'; +import { createCaseError } from '../../common/error'; interface GetCaseIdsByAlertIdArgs { alertId: string; @@ -626,4 +629,38 @@ export class CasesService { throw error; } } + + public async executeAggregations({ + aggregationBuilders, + options, + }: { + aggregationBuilders: Array>; + options?: Omit; + }): Promise { + try { + const builtAggs = aggregationBuilders.reduce((acc, agg) => { + return { ...acc, ...agg.build() }; + }, {}); + + const res = await this.unsecuredSavedObjectsClient.find< + ESCaseAttributes, + AggregationResponse + >({ + sortField: defaultSortField, + ...options, + aggs: builtAggs, + type: CASE_SAVED_OBJECT, + }); + + return res.aggregations; + } catch (error) { + const aggregationNames = aggregationBuilders.map((agg) => agg.getName()); + + throw createCaseError({ + message: `Failed to execute aggregations [${aggregationNames.join(',')}]: ${error}`, + error, + logger: this.log, + }); + } + } } diff --git a/x-pack/plugins/cases/server/services/mocks.ts b/x-pack/plugins/cases/server/services/mocks.ts index a9f3d427bba65..acd19506277c1 100644 --- a/x-pack/plugins/cases/server/services/mocks.ts +++ b/x-pack/plugins/cases/server/services/mocks.ts @@ -39,6 +39,7 @@ export const createCaseServiceMock = (): CaseServiceMock => { patchCases: jest.fn(), findCasesGroupedByID: jest.fn(), getCaseStatusStats: jest.fn(), + executeAggregations: jest.fn(), }; // the cast here is required because jest.Mocked tries to include private members and would throw an error diff --git a/x-pack/plugins/cases/server/services/test_utils.ts b/x-pack/plugins/cases/server/services/test_utils.ts index 16c6445af774f..617dedd368ab3 100644 --- a/x-pack/plugins/cases/server/services/test_utils.ts +++ b/x-pack/plugins/cases/server/services/test_utils.ts @@ -105,6 +105,7 @@ export const basicCaseFields = { email: 'testemail@elastic.co', username: 'elastic', }, + duration: null, description: 'This is a brand new case of a bad meanie defacing data', title: 'Super Bad Security Issue', status: CaseStatuses.open, diff --git a/x-pack/plugins/cases/server/types.ts b/x-pack/plugins/cases/server/types.ts index 962dc9c85231d..2154aec6f5324 100644 --- a/x-pack/plugins/cases/server/types.ts +++ b/x-pack/plugins/cases/server/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { IRouter, RequestHandlerContext } from '@kbn/core/server'; +import type { IRouter, CustomRequestHandlerContext } from '@kbn/core/server'; import { ActionTypeConfig, ActionTypeSecrets, @@ -22,9 +22,9 @@ export interface CaseRequestContext { /** * @internal */ -export interface CasesRequestHandlerContext extends RequestHandlerContext { +export type CasesRequestHandlerContext = CustomRequestHandlerContext<{ cases: CaseRequestContext; -} +}>; /** * @internal diff --git a/x-pack/plugins/cloud/server/env.ts b/x-pack/plugins/cloud/server/env.ts new file mode 100644 index 0000000000000..435e62bf47698 --- /dev/null +++ b/x-pack/plugins/cloud/server/env.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +// Best effort to get instance size from process.env +export function readInstanceSizeMb(): undefined | number { + const capacityString = process.env.CLOUD_KIBANA_CAPACITY; + if (capacityString) { + const instanceSizeMb = parseInt(capacityString, 10); + return isNaN(instanceSizeMb) ? undefined : instanceSizeMb; + } +} diff --git a/x-pack/plugins/cloud/server/plugin.ts b/x-pack/plugins/cloud/server/plugin.ts index fbf3c925cff87..284d37804be21 100644 --- a/x-pack/plugins/cloud/server/plugin.ts +++ b/x-pack/plugins/cloud/server/plugin.ts @@ -14,6 +14,7 @@ import { getIsCloudEnabled } from '../common/is_cloud_enabled'; import { parseDeploymentIdFromDeploymentUrl } from './utils'; import { registerFullstoryRoute } from './routes/fullstory'; import { registerChatRoute } from './routes/chat'; +import { readInstanceSizeMb } from './env'; interface PluginsSetup { usageCollection?: UsageCollectionSetup; @@ -24,6 +25,7 @@ export interface CloudSetup { cloudId?: string; deploymentId?: string; isCloudEnabled: boolean; + instanceSizeMb?: number; apm: { url?: string; secretToken?: string; @@ -41,7 +43,7 @@ export class CloudPlugin implements Plugin { this.isDev = this.context.env.mode.dev; } - public setup(core: CoreSetup, { usageCollection, security }: PluginsSetup) { + public setup(core: CoreSetup, { usageCollection, security }: PluginsSetup): CloudSetup { this.logger.debug('Setting up Cloud plugin'); const isCloudEnabled = getIsCloudEnabled(this.config.id); registerCloudUsageCollector(usageCollection, { isCloudEnabled }); @@ -64,6 +66,7 @@ export class CloudPlugin implements Plugin { return { cloudId: this.config.id, + instanceSizeMb: readInstanceSizeMb(), deploymentId: parseDeploymentIdFromDeploymentUrl(this.config.deployment_url), isCloudEnabled, apm: { diff --git a/x-pack/plugins/cloud_security_posture/common/constants.ts b/x-pack/plugins/cloud_security_posture/common/constants.ts index 363adc568ba9b..1d35d6439bead 100644 --- a/x-pack/plugins/cloud_security_posture/common/constants.ts +++ b/x-pack/plugins/cloud_security_posture/common/constants.ts @@ -11,19 +11,16 @@ export const BENCHMARKS_ROUTE_PATH = '/internal/cloud_security_posture/benchmark export const UPDATE_RULES_CONFIG_ROUTE_PATH = '/internal/cloud_security_posture/update_rules_config'; -export const CSP_FINDINGS_INDEX_NAME = 'findings'; -export const CIS_KUBERNETES_PACKAGE_NAME = 'cis_kubernetes_benchmark'; -export const FINDINGS_DATA_STREAM_NAME = - // Currently 'cis_kubernetes_benchmark.findings', To be refactored to 'cloud_security_posture.findings' - CIS_KUBERNETES_PACKAGE_NAME + '.' + CSP_FINDINGS_INDEX_NAME; +export const CLOUD_SECURITY_POSTURE_PACKAGE_NAME = 'cloud_security_posture'; + +export const CSP_LATEST_FINDINGS_DATA_VIEW = 'logs-cloud_security_posture.findings_latest-*'; +export const FINDINGS_INDEX_PATTERN = 'logs-cloud_security_posture.findings-default*'; + export const LATEST_FINDINGS_INDEX_NAME = 'cloud_security_posture.findings_latest'; -export const BENCHMARK_SCORE_INDEX_NAME = 'cloud_security_posture.scores'; +export const LATEST_FINDINGS_INDEX_DEFAULT_NS = 'logs-' + LATEST_FINDINGS_INDEX_NAME + '-default'; -export const AGENT_LOGS_INDEX_PATTERN = '.logs-cis_kubernetes_benchmark.metadata*'; -export const CSP_KUBEBEAT_INDEX_PATTERN = 'logs-cis_kubernetes_benchmark.findings-*'; -export const FINDINGS_INDEX_PATTERN = 'logs-' + FINDINGS_DATA_STREAM_NAME + '-default*'; -export const LATEST_FINDINGS_INDEX_PATTERN = 'logs-' + LATEST_FINDINGS_INDEX_NAME + '-default'; -export const BENCHMARK_SCORE_INDEX_PATTERN = 'logs-' + BENCHMARK_SCORE_INDEX_NAME + '-default'; +export const BENCHMARK_SCORE_INDEX_NAME = 'cloud_security_posture.scores'; +export const BENCHMARK_SCORE_INDEX_DEFAULT_NS = 'logs-' + BENCHMARK_SCORE_INDEX_NAME + '-default'; export const RULE_PASSED = `passed`; export const RULE_FAILED = `failed`; @@ -31,7 +28,7 @@ export const RULE_FAILED = `failed`; // A mapping of in-development features to their status. These features should be hidden from users but can be easily // activated via a simple code change in a single location. export const INTERNAL_FEATURE_FLAGS = { - showBenchmarks: false, + showBenchmarks: true, showManageRulesMock: false, showRisksMock: false, showFindingsGroupBy: false, diff --git a/x-pack/plugins/cloud_security_posture/common/schemas/csp_rule.ts b/x-pack/plugins/cloud_security_posture/common/schemas/csp_rule.ts index a2c7f06e0a676..a6aaa26e7a1a0 100644 --- a/x-pack/plugins/cloud_security_posture/common/schemas/csp_rule.ts +++ b/x-pack/plugins/cloud_security_posture/common/schemas/csp_rule.ts @@ -8,7 +8,7 @@ import { schema as rt, TypeOf } from '@kbn/config-schema'; export const cspRuleAssetSavedObjectType = 'csp_rule'; -// TODO: needs to be shared with kubebeat +// TODO: needs to be shared with cloudbeat export const cspRuleSchema = rt.object({ id: rt.string(), name: rt.string(), diff --git a/x-pack/plugins/cloud_security_posture/common/types.ts b/x-pack/plugins/cloud_security_posture/common/types.ts index 0aee5ce2f350d..4bc388d39ebe4 100644 --- a/x-pack/plugins/cloud_security_posture/common/types.ts +++ b/x-pack/plugins/cloud_security_posture/common/types.ts @@ -21,7 +21,7 @@ export interface Stats extends FindingsEvaluation { postureScore: Score; } -export interface ResourceType extends FindingsEvaluation { +export interface GroupedFindingsEvaluation extends FindingsEvaluation { name: string; } @@ -36,13 +36,13 @@ export interface Cluster { lastUpdate: number; // unix epoch time }; stats: Stats; - resourcesTypes: ResourceType[]; + groupedFindingsEvaluation: GroupedFindingsEvaluation[]; trend: PostureTrend[]; } export interface ComplianceDashboardData { stats: Stats; - resourcesTypes: ResourceType[]; + groupedFindingsEvaluation: GroupedFindingsEvaluation[]; clusters: Cluster[]; trend: PostureTrend[]; } diff --git a/x-pack/plugins/cloud_security_posture/public/common/api/use_cis_kubernetes_integration.tsx b/x-pack/plugins/cloud_security_posture/public/common/api/use_cis_kubernetes_integration.tsx index 0a9f2c2134a6e..5660080cb0a43 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/api/use_cis_kubernetes_integration.tsx +++ b/x-pack/plugins/cloud_security_posture/public/common/api/use_cis_kubernetes_integration.tsx @@ -11,7 +11,7 @@ import { type GetInfoResponse, type DefaultPackagesInstallationError, } from '@kbn/fleet-plugin/common'; -import { CIS_KUBERNETES_PACKAGE_NAME } from '../../../common/constants'; +import { CLOUD_SECURITY_POSTURE_PACKAGE_NAME } from '../../../common/constants'; import { useKibana } from '../hooks/use_kibana'; /** @@ -21,7 +21,7 @@ export const useCisKubernetesIntegration = () => { const { http } = useKibana().services; return useQuery(['integrations'], () => - http.get(epmRouteService.getInfoPath(CIS_KUBERNETES_PACKAGE_NAME), { + http.get(epmRouteService.getInfoPath(CLOUD_SECURITY_POSTURE_PACKAGE_NAME), { query: { experimental: true }, }) ); diff --git a/x-pack/plugins/cloud_security_posture/public/common/api/use_kubebeat_data_view.ts b/x-pack/plugins/cloud_security_posture/public/common/api/use_kubebeat_data_view.ts deleted file mode 100644 index 20d22b93cb9d2..0000000000000 --- a/x-pack/plugins/cloud_security_posture/public/common/api/use_kubebeat_data_view.ts +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { useQuery } from 'react-query'; -import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { CSP_KUBEBEAT_INDEX_PATTERN } from '../../../common/constants'; -import { CspClientPluginStartDeps } from '../../types'; - -/** - * TODO: use perfected kibana data views - */ -export const useKubebeatDataView = () => { - const { - data: { dataViews }, - } = useKibana().services; - - // TODO: check if index exists - // if not, no point in creating a data view - // const check = () => http?.get(`/kubebeat`); - - // TODO: use `dataViews.get(ID)` - const findDataView = async () => (await dataViews.find(CSP_KUBEBEAT_INDEX_PATTERN))?.[0]; - - return useQuery(['kubebeat_dataview'], findDataView); -}; diff --git a/x-pack/plugins/cloud_security_posture/public/common/api/use_latest_findings_data_view.ts b/x-pack/plugins/cloud_security_posture/public/common/api/use_latest_findings_data_view.ts new file mode 100644 index 0000000000000..21708c3be1f5e --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/common/api/use_latest_findings_data_view.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useQuery } from 'react-query'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { CSP_LATEST_FINDINGS_DATA_VIEW } from '../../../common/constants'; +import { CspClientPluginStartDeps } from '../../types'; + +/** + * TODO: use perfected kibana data views + */ +export const useLatestFindingsDataView = () => { + const { + data: { dataViews }, + } = useKibana().services; + + // TODO: use `dataViews.get(ID)` + const findDataView = async () => (await dataViews.find(CSP_LATEST_FINDINGS_DATA_VIEW))?.[0]; + + return useQuery(['latest_findings_dataview'], findDataView); +}; diff --git a/x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.ts b/x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.ts index b5ce12095f99a..e4afcd3306576 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.ts +++ b/x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.ts @@ -7,7 +7,7 @@ import { useHistory } from 'react-router-dom'; import { Query } from '@kbn/es-query'; -import { allNavigationItems } from '../navigation/constants'; +import { findingsNavigation } from '../navigation/constants'; import { encodeQuery } from '../navigation/query_utils'; import { FindingsBaseURLQuery } from '../../pages/findings/types'; @@ -18,7 +18,7 @@ const getFindingsQuery = (queryValue: Query['query']): Pick((a, [key, value]) => { - a.push(`${key} : "${value}"`); + a.push(`${key}: "${value}"`); return a; }, []) .join(' and '); @@ -37,7 +37,7 @@ export const useNavigateFindings = () => { return (query?: Query['query']) => { history.push({ - pathname: allNavigationItems.findings.path, + pathname: findingsNavigation.findings_default.path, ...(query && { search: encodeQuery(getFindingsQuery(query)) }), }); }; diff --git a/x-pack/plugins/cloud_security_posture/public/common/hooks/use_url_query.ts b/x-pack/plugins/cloud_security_posture/public/common/hooks/use_url_query.ts index 69055de1a78af..2eea943f757cf 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/hooks/use_url_query.ts +++ b/x-pack/plugins/cloud_security_posture/public/common/hooks/use_url_query.ts @@ -6,6 +6,7 @@ */ import { useEffect, useCallback, useMemo } from 'react'; import { useHistory, useLocation } from 'react-router-dom'; +import type { RisonObject } from 'rison-node'; import { decodeQuery, encodeQuery } from '../navigation/query_utils'; /** @@ -14,7 +15,7 @@ import { decodeQuery, encodeQuery } from '../navigation/query_utils'; * @note shallow-merges default, current and next query */ export const useUrlQuery = (getDefaultQuery: () => T) => { - const { push } = useHistory(); + const { push, replace } = useHistory(); const { search, key } = useLocation(); const urlQuery = useMemo( @@ -35,8 +36,8 @@ export const useUrlQuery = (getDefaultQuery: () => T) => { // TODO: condition should be if decoding failed if (search) return; - setUrlQuery(getDefaultQuery()); - }, [getDefaultQuery, search, setUrlQuery]); + replace({ search: encodeQuery(getDefaultQuery() as RisonObject) }); + }, [getDefaultQuery, search, replace]); return { key, diff --git a/x-pack/plugins/cloud_security_posture/public/common/navigation/constants.ts b/x-pack/plugins/cloud_security_posture/public/common/navigation/constants.ts index 1132b7a348b5d..b9089b4b5a58d 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/navigation/constants.ts +++ b/x-pack/plugins/cloud_security_posture/public/common/navigation/constants.ts @@ -24,3 +24,9 @@ export const allNavigationItems: Record = { disabled: !INTERNAL_FEATURE_FLAGS.showBenchmarks, }, }; + +export const findingsNavigation = { + findings_default: { name: TEXT.FINDINGS, path: '/findings/default' }, + findings_by_resource: { name: TEXT.FINDINGS, path: '/findings/resource' }, + resource_findings: { name: TEXT.FINDINGS, path: '/findings/resource/:resourceId' }, +}; diff --git a/x-pack/plugins/cloud_security_posture/public/components/csp_evaluation_badge.tsx b/x-pack/plugins/cloud_security_posture/public/components/csp_evaluation_badge.tsx index af1cf6c5c43c1..ab193ab6dc8be 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/csp_evaluation_badge.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/csp_evaluation_badge.tsx @@ -22,9 +22,9 @@ const getColor = (type: Props['type']): EuiBadgeProps['color'] => { export const CspEvaluationBadge = ({ type }: Props) => ( {type === 'failed' ? ( - + ) : ( - + )} ); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks.test.tsx index 990140f3cf949..48e9d3f67e8e5 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks.test.tsx @@ -8,9 +8,6 @@ import React from 'react'; import { render, screen, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import type { UseQueryResult } from 'react-query/types/react/types'; -import { createStubDataView } from '@kbn/data-views-plugin/public/data_views/data_view.stub'; -import { CSP_KUBEBEAT_INDEX_PATTERN } from '../../../common/constants'; -import { useKubebeatDataView } from '../../common/api/use_kubebeat_data_view'; import { createCspBenchmarkIntegrationFixture } from '../../test/fixtures/csp_benchmark_integration'; import { createReactQueryResponse } from '../../test/fixtures/react_query'; import { TestProvider } from '../../test/test_provider'; @@ -24,7 +21,6 @@ import { useCspBenchmarkIntegrations } from './use_csp_benchmark_integrations'; import { useCisKubernetesIntegration } from '../../common/api/use_cis_kubernetes_integration'; jest.mock('./use_csp_benchmark_integrations'); -jest.mock('../../common/api/use_kubebeat_data_view'); jest.mock('../../common/api/use_cis_kubernetes_integration'); describe('', () => { @@ -35,17 +31,6 @@ describe('', () => { (useCisKubernetesIntegration as jest.Mock).mockImplementation(() => ({ data: { item: { status: 'installed' } }, })); - // Required for the page template to render the benchmarks page - (useKubebeatDataView as jest.Mock).mockImplementation(() => - createReactQueryResponse({ - status: 'success', - data: createStubDataView({ - spec: { - id: CSP_KUBEBEAT_INDEX_PATTERN, - }, - }), - }) - ); }); const renderBenchmarks = ( diff --git a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_charts/risks_table.tsx b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_charts/risks_table.tsx index 086fea34a2c50..b6b309cadbb02 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_charts/risks_table.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_charts/risks_table.tsx @@ -14,7 +14,7 @@ import { EuiLink, EuiText, } from '@elastic/eui'; -import { ComplianceDashboardData, ResourceType } from '../../../../common/types'; +import { ComplianceDashboardData, GroupedFindingsEvaluation } from '../../../../common/types'; import { CompactFormattedNumber } from '../../../components/compact_formatted_number'; import * as TEXT from '../translations'; import { INTERNAL_FEATURE_FLAGS } from '../../../../common/constants'; @@ -59,17 +59,17 @@ const mockData = [ ]; export interface RisksTableProps { - data: ComplianceDashboardData['resourcesTypes']; + data: ComplianceDashboardData['groupedFindingsEvaluation']; maxItems: number; - onCellClick: (resourceTypeName: string) => void; + onCellClick: (name: string) => void; onViewAllClick: () => void; } export const getTopRisks = ( - resourcesTypes: ComplianceDashboardData['resourcesTypes'], + groupedFindingsEvaluation: ComplianceDashboardData['groupedFindingsEvaluation'], maxItems: number ) => { - const filtered = resourcesTypes.filter((x) => x.totalFailed > 0); + const filtered = groupedFindingsEvaluation.filter((x) => x.totalFailed > 0); const sorted = filtered.slice().sort((first, second) => second.totalFailed - first.totalFailed); return sorted.slice(0, maxItems); @@ -85,15 +85,18 @@ export const RisksTable = ({ () => [ { field: 'name', - name: TEXT.RESOURCE_TYPE, - render: (resourceTypeName: ResourceType['name']) => ( - onCellClick(resourceTypeName)}>{resourceTypeName} + name: TEXT.CIS_SECTION, + render: (name: GroupedFindingsEvaluation['name']) => ( + onCellClick(name)}>{name} ), }, { field: 'totalFailed', name: TEXT.FINDINGS, - render: (totalFailed: ResourceType['totalFailed'], resource: ResourceType) => ( + render: ( + totalFailed: GroupedFindingsEvaluation['totalFailed'], + resource: GroupedFindingsEvaluation + ) => ( <> @@ -114,7 +117,7 @@ export const RisksTable = ({ return ( - + rowHeader="name" items={INTERNAL_FEATURE_FLAGS.showRisksMock ? getTopRisks(mockData, maxItems) : items} columns={columns} diff --git a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/dashboard_sections/benchmarks_section.tsx b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/dashboard_sections/benchmarks_section.tsx index a3b32ef3fe2c6..daa154f62aad7 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/dashboard_sections/benchmarks_section.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/dashboard_sections/benchmarks_section.tsx @@ -42,19 +42,19 @@ export const BenchmarksSection = ({ const [layerValue] = element; const evaluation = layerValue[0].groupByRollup as Evaluation; - navToFindings({ cluster_id: clusterId, 'result.evaluation': evaluation }); + navToFindings({ 'cluster_id.keyword': clusterId, 'result.evaluation.keyword': evaluation }); }; - const handleCellClick = (clusterId: string, resourceTypeName: string) => { + const handleCellClick = (clusterId: string, ruleSection: string) => { navToFindings({ - cluster_id: clusterId, - 'resource.type': resourceTypeName, - 'result.evaluation': RULE_FAILED, + 'cluster_id.keyword': clusterId, + 'rule.section.keyword': ruleSection, + 'result.evaluation.keyword': RULE_FAILED, }); }; const handleViewAllClick = (clusterId: string) => { - navToFindings({ cluster_id: clusterId, 'result.evaluation': RULE_FAILED }); + navToFindings({ 'cluster_id.keyword': clusterId, 'result.evaluation.keyword': RULE_FAILED }); }; return ( @@ -110,7 +110,7 @@ export const BenchmarksSection = ({ handleCellClick(cluster.meta.clusterId, resourceTypeName) diff --git a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/dashboard_sections/summary_section.tsx b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/dashboard_sections/summary_section.tsx index c123459d9e963..b7782e5778bd3 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/dashboard_sections/summary_section.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/dashboard_sections/summary_section.tsx @@ -32,15 +32,18 @@ export const SummarySection = ({ complianceData }: { complianceData: ComplianceD const [layerValue] = element; const evaluation = layerValue[0].groupByRollup as Evaluation; - navToFindings({ 'result.evaluation': evaluation }); + navToFindings({ 'result.evaluation.keyword': evaluation }); }; - const handleCellClick = (resourceTypeName: string) => { - navToFindings({ 'resource.type': resourceTypeName, 'result.evaluation': RULE_FAILED }); + const handleCellClick = (ruleSection: string) => { + navToFindings({ + 'rule.section.keyword': ruleSection, + 'result.evaluation.keyword': RULE_FAILED, + }); }; const handleViewAllClick = () => { - navToFindings({ 'result.evaluation': RULE_FAILED }); + navToFindings({ 'result.evaluation.keyword': RULE_FAILED }); }; return ( @@ -58,7 +61,7 @@ export const SummarySection = ({ complianceData }: { complianceData: ComplianceD { @@ -40,8 +40,8 @@ const Wrapper = ({ ); -describe('', () => { - it("renders the success state component when 'kubebeat' DataView exists and request status is 'success'", async () => { +describe.skip('', () => { + it("renders the success state component when 'latest findings' DataView exists and request status is 'success'", async () => { const data = dataPluginMock.createStartContract(); const unifiedSearch = unifiedSearchPluginMock.createStartContract(); const source = await data.search.searchSource.create(); @@ -51,11 +51,11 @@ describe('', () => { })); (source.fetch$ as jest.Mock).mockReturnValue(of({ rawResponse: { hits: { hits: [] } } })); - (useKubebeatDataView as jest.Mock).mockReturnValue({ + (useLatestFindingsDataView as jest.Mock).mockReturnValue({ status: 'success', data: createStubDataView({ spec: { - id: CSP_KUBEBEAT_INDEX_PATTERN, + id: CSP_LATEST_FINDINGS_DATA_VIEW, }, }), } as UseQueryResult); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings.tsx index 4eae5610da15a..4fa5c33903477 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings.tsx @@ -5,19 +5,47 @@ * 2.0. */ import React from 'react'; -import { useKubebeatDataView } from '../../common/api/use_kubebeat_data_view'; -import { allNavigationItems } from '../../common/navigation/constants'; -import { useCspBreadcrumbs } from '../../common/navigation/use_csp_breadcrumbs'; -import { FindingsContainer } from './findings_container'; +import { Redirect, Switch, Route, useLocation } from 'react-router-dom'; +import { useLatestFindingsDataView } from '../../common/api/use_latest_findings_data_view'; +import { allNavigationItems, findingsNavigation } from '../../common/navigation/constants'; import { CspPageTemplate } from '../../components/csp_page_template'; +import { FindingsByResourceContainer } from './latest_findings_by_resource/findings_by_resource_container'; +import { LatestFindingsContainer } from './latest_findings/latest_findings_container'; export const Findings = () => { - const dataViewQuery = useKubebeatDataView(); - useCspBreadcrumbs([allNavigationItems.findings]); + const location = useLocation(); + const dataViewQuery = useLatestFindingsDataView(); + + if (!dataViewQuery.data) return ; return ( - {dataViewQuery.data && } + + ( + + )} + /> + } + /> + } + /> + } + /> + ); }; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_container.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_container.test.tsx deleted file mode 100644 index ea2cd9ce7c0cf..0000000000000 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_container.test.tsx +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import React from 'react'; -import { render } from '@testing-library/react'; -import { FindingsContainer, getDefaultQuery } from './findings_container'; -import { createStubDataView } from '@kbn/data-views-plugin/common/mocks'; -import { CSP_KUBEBEAT_INDEX_PATTERN } from '../../../common/constants'; -import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; -import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; -import { TestProvider } from '../../test/test_provider'; -import { getFindingsQuery } from './use_findings'; -import { encodeQuery } from '../../common/navigation/query_utils'; -import { useLocation } from 'react-router-dom'; -import { RisonObject } from 'rison-node'; -import { buildEsQuery } from '@kbn/es-query'; -import { getFindingsCountAggQuery } from './use_findings_count'; - -jest.mock('../../common/api/use_kubebeat_data_view'); -jest.mock('../../common/api/use_cis_kubernetes_integration'); - -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), - useHistory: () => ({ push: jest.fn() }), - useLocation: jest.fn(), -})); - -beforeEach(() => { - jest.restoreAllMocks(); -}); - -describe('', () => { - it('data#search.search fn called with URL query', () => { - const query = getDefaultQuery(); - const dataMock = dataPluginMock.createStartContract(); - const dataView = createStubDataView({ - spec: { - id: CSP_KUBEBEAT_INDEX_PATTERN, - }, - }); - - (useLocation as jest.Mock).mockReturnValue({ - search: encodeQuery(query as unknown as RisonObject), - }); - - render( - - - - ); - - const baseQuery = { - index: dataView.title, - query: buildEsQuery(dataView, query.query, query.filters), - }; - - expect(dataMock.search.search).toHaveBeenNthCalledWith(1, { - params: getFindingsCountAggQuery(baseQuery), - }); - - expect(dataMock.search.search).toHaveBeenNthCalledWith(2, { - params: getFindingsQuery({ - ...baseQuery, - sort: query.sort, - size: query.size, - from: query.from, - }), - }); - }); -}); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_container.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_container.tsx deleted file mode 100644 index 213592d50e069..0000000000000 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_container.tsx +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import React, { useMemo } from 'react'; -import { EuiComboBoxOptionOption, EuiSpacer, EuiTitle, useEuiTheme } from '@elastic/eui'; -import { css } from '@emotion/react'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { i18n } from '@kbn/i18n'; -import type { DataView } from '@kbn/data-plugin/common'; -import { SortDirection } from '@kbn/data-plugin/common'; -import { buildEsQuery } from '@kbn/es-query'; -import { FindingsTable } from './findings_table'; -import { FindingsSearchBar } from './findings_search_bar'; -import * as TEST_SUBJECTS from './test_subjects'; -import { useUrlQuery } from '../../common/hooks/use_url_query'; -import { useFindings } from './use_findings'; -import type { FindingsGroupByNoneQuery } from './use_findings'; -import type { FindingsBaseURLQuery } from './types'; -import { useFindingsByResource } from './use_findings_by_resource'; -import { FindingsGroupBySelector } from './findings_group_by_selector'; -import { INTERNAL_FEATURE_FLAGS } from '../../../common/constants'; -import { useFindingsCounter } from './use_findings_count'; -import { FindingsDistributionBar } from './findings_distribution_bar'; -import { FindingsByResourceTable } from './findings_by_resource_table'; - -// TODO: define this as a schema with default values -export const getDefaultQuery = (): FindingsBaseURLQuery & FindingsGroupByNoneQuery => ({ - query: { language: 'kuery', query: '' }, - filters: [], - sort: [{ ['@timestamp']: SortDirection.desc }], - from: 0, - size: 10, - groupBy: 'none', -}); - -const getGroupByOptions = (): Array> => [ - { - value: 'none', - label: i18n.translate('xpack.csp.findings.groupBySelector.groupByNoneLabel', { - defaultMessage: 'None', - }), - }, - { - value: 'resource', - label: i18n.translate('xpack.csp.findings.groupBySelector.groupByResourceIdLabel', { - defaultMessage: 'Resource', - }), - }, -]; - -export const FindingsContainer = ({ dataView }: { dataView: DataView }) => { - const { euiTheme } = useEuiTheme(); - const groupByOptions = useMemo(getGroupByOptions, []); - const { urlQuery, setUrlQuery } = useUrlQuery(getDefaultQuery); - - const baseEsQuery = useMemo( - () => ({ - index: dataView.title, - // TODO: this will throw for malformed query - // page will display an error boundary with the JS error - // will be accounted for before releasing the feature - query: buildEsQuery(dataView, urlQuery.query, urlQuery.filters), - }), - [dataView, urlQuery] - ); - - const findingsGroupByResource = useFindingsByResource({ - ...baseEsQuery, - enabled: urlQuery.groupBy === 'resource', - }); - - const findingsCount = useFindingsCounter({ - ...baseEsQuery, - enabled: urlQuery.groupBy === 'none', - }); - - const findingsGroupByNone = useFindings({ - ...baseEsQuery, - enabled: urlQuery.groupBy === 'none', - size: urlQuery.size, - from: urlQuery.from, - sort: urlQuery.sort, - }); - - return ( -
- -
- - - {INTERNAL_FEATURE_FLAGS.showFindingsGroupBy && ( - setUrlQuery({ groupBy: type[0]?.value })} - options={groupByOptions} - /> - )} - - {urlQuery.groupBy === 'none' && ( - <> - - - - - )} - {urlQuery.groupBy === 'resource' && ( - <> - - - )} -
-
- ); -}; - -const PageTitle = () => ( - -

- -

-
-); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout.tsx deleted file mode 100644 index 65493bd493342..0000000000000 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout.tsx +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import React, { useState } from 'react'; -import { - EuiCodeBlock, - EuiFlexItem, - EuiSpacer, - EuiDescriptionList, - EuiTextColor, - EuiFlyout, - EuiFlyoutHeader, - EuiTitle, - EuiFlyoutBody, - EuiBadge, - EuiTabs, - EuiTab, - EuiFlexGrid, - EuiCard, - EuiFlexGroup, - EuiIcon, - type PropsOf, -} from '@elastic/eui'; -import { assertNever } from '@kbn/std'; -import type { CspFinding } from './types'; -import { CspEvaluationBadge } from '../../components/csp_evaluation_badge'; -import * as TEXT from './translations'; -import cisLogoIcon from '../../assets/icons/cis_logo.svg'; -import k8sLogoIcon from '../../assets/icons/k8s_logo.svg'; - -const tabs = ['remediation', 'resource', 'general'] as const; - -const CodeBlock: React.FC> = (props) => ( - -); - -type FindingsTab = typeof tabs[number]; - -type EuiListItemsProps = NonNullable['listItems']>[number]; - -interface Card { - title: string; - listItems: Array<[EuiListItemsProps['title'], EuiListItemsProps['description']]>; -} - -interface FindingFlyoutProps { - onClose(): void; - findings: CspFinding; -} - -export const FindingsRuleFlyout = ({ onClose, findings }: FindingFlyoutProps) => { - const [tab, setTab] = useState('remediation'); - return ( - - - - - - - - - - {findings.rule.name} - - - - - - - {tabs.map((v) => ( - setTab(v)} - style={{ textTransform: 'capitalize' }} - > - {v} - - ))} - - - - - - - ); -}; - -const Cards = ({ data }: { data: Card[] }) => ( - - {data.map((card) => ( - - - ({ title: v[0], description: v[1] }))} - style={{ flexFlow: 'column' }} - descriptionProps={{ - style: { width: '100%' }, - }} - /> - - - ))} - -); - -const FindingsTab = ({ tab, findings }: { findings: CspFinding; tab: FindingsTab }) => { - switch (tab) { - case 'remediation': - return ; - case 'resource': - return ; - case 'general': - return ; - default: - assertNever(tab); - } -}; - -const getResourceCards = ({ resource, host }: CspFinding): Card[] => [ - { - title: TEXT.RESOURCE, - listItems: [ - [TEXT.FILENAME, {resource.filename}], - [TEXT.MODE, resource.mode], - [TEXT.PATH, {resource.path}], - [TEXT.TYPE, resource.type], - [TEXT.UID, resource.uid], - ], - }, - { - title: TEXT.HOST, - listItems: [ - [TEXT.ARCHITECTURE, host.architecture], - [TEXT.CONTAINERIZED, host.containerized ? 'true' : 'false'], - [TEXT.HOSTNAME, host.hostname], - [TEXT.ID, {host.id}], - [TEXT.IP, {host.ip.join(', ')}], - [TEXT.MAC, {host.mac.join(', ')}], - [TEXT.NAME, host.name], - ], - }, - { - title: TEXT.OS, - listItems: [ - [TEXT.CODENAME, host.os.codename], - [TEXT.FAMILY, host.os.family], - [TEXT.KERNEL, host.os.kernel], - [TEXT.NAME, host.os.name], - [TEXT.PLATFORM, host.os.platform], - [TEXT.TYPE, host.os.type], - [TEXT.VERSION, host.os.version], - ], - }, -]; - -const getGeneralCards = ({ rule }: CspFinding): Card[] => [ - { - title: TEXT.RULE, - listItems: [ - [TEXT.SEVERITY, ''], - [TEXT.INDEX, ''], - [TEXT.RULE_EVALUATED_AT, ''], - [ - TEXT.FRAMEWORK_SOURCES, - - - - - - - - , - ], - [TEXT.SECTION, ''], - [TEXT.PROFILE_APPLICABILITY, ''], - [TEXT.AUDIT, ''], - [TEXT.BENCHMARK, rule.benchmark.name], - [TEXT.NAME, rule.name], - [TEXT.DESCRIPTION, rule.description], - [ - TEXT.TAGS, - rule.tags.map((t) => ( - - {t} - - )), - ], - ], - }, -]; - -const getRemediationCards = ({ result, ...rest }: CspFinding): Card[] => [ - { - title: TEXT.RESULT, - listItems: [ - [TEXT.EXPECTED, ''], - [TEXT.EVIDENCE, {JSON.stringify(result.evidence, null, 2)}], - [TEXT.TIMESTAMP, {rest['@timestamp']}], - ], - }, - { - title: TEXT.REMEDIATION, - listItems: [ - ['', {rest.rule.remediation}], - [TEXT.IMPACT, rest.rule.impact], - [TEXT.DEFAULT_VALUE, ''], - [TEXT.RATIONALE, ''], - ], - }, -]; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/__snapshots__/resource_tab.test.ts.snap b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/__snapshots__/resource_tab.test.ts.snap new file mode 100644 index 0000000000000..ffa5d91e2d677 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/__snapshots__/resource_tab.test.ts.snap @@ -0,0 +1,100 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`prepareDescriptionList create description lists accordingly 1`] = ` +Array [ + Object { + "description": + string + , + "title": + + a + + , + }, + Object { + "description": + 123 + , + "title": + + b + + , + }, + Object { + "description": "undefined", + "title": + + c + + , + }, + Object { + "description": + null + , + "title": + + d + + , + }, + Object { + "description": + true + , + "title": + + e + + , + }, + Object { + "description": + false + , + "title": + + f + + , + }, + Object { + "description": + [ + { + "a": "another string", + "b": 123 + } +] + , + "title": + + g + + , + }, +] +`; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/findings_flyout.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/findings_flyout.tsx new file mode 100644 index 0000000000000..be05e2b8418d6 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/findings_flyout.tsx @@ -0,0 +1,185 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { useState } from 'react'; +import { + EuiCodeBlock, + EuiFlexItem, + EuiSpacer, + EuiDescriptionList, + EuiTextColor, + EuiFlyout, + EuiFlyoutHeader, + EuiTitle, + EuiFlyoutBody, + EuiTabs, + EuiTab, + EuiFlexGrid, + EuiCard, + EuiFlexGroup, + EuiIcon, + type PropsOf, + EuiMarkdownFormat, +} from '@elastic/eui'; +import { assertNever } from '@kbn/std'; +import moment from 'moment'; +import type { CspFinding } from '../types'; +import { CspEvaluationBadge } from '../../../components/csp_evaluation_badge'; +import * as TEXT from '../translations'; +import cisLogoIcon from '../../../assets/icons/cis_logo.svg'; +import k8sLogoIcon from '../../../assets/icons/k8s_logo.svg'; +import { ResourceTab } from './resource_tab'; +import { JsonTab } from './json_tab'; + +const tabs = [ + { title: TEXT.REMEDIATION, id: 'remediation' }, + { title: TEXT.RESOURCE, id: 'resource' }, + { title: TEXT.GENERAL, id: 'general' }, + { title: TEXT.JSON, id: 'json' }, +] as const; + +const CodeBlock: React.FC> = (props) => ( + +); + +const Markdown: React.FC> = (props) => ( + +); + +type FindingsTab = typeof tabs[number]; + +type EuiListItemsProps = NonNullable['listItems']>[number]; + +interface Card { + title: string; + listItems: Array<[EuiListItemsProps['title'], EuiListItemsProps['description']]>; +} + +interface FindingFlyoutProps { + onClose(): void; + findings: CspFinding; +} + +const Cards = ({ data }: { data: Card[] }) => ( + + {data.map((card) => ( + + + ({ title: v[0], description: v[1] }))} + style={{ flexFlow: 'column' }} + descriptionProps={{ + style: { width: '100%' }, + }} + /> + + + ))} + +); + +const FindingsTab = ({ tab, findings }: { findings: CspFinding; tab: FindingsTab }) => { + switch (tab.id) { + case 'remediation': + return ; + case 'resource': + return ; + case 'general': + return ; + case 'json': + return ; + default: + assertNever(tab); + } +}; + +export const FindingsRuleFlyout = ({ onClose, findings }: FindingFlyoutProps) => { + const [tab, setTab] = useState(tabs[0]); + + return ( + + + + + + + + + + {findings.rule.name} + + + + + + + {tabs.map((v) => ( + setTab(v)}> + {v.title} + + ))} + + + + + + + ); +}; + +const getGeneralCards = ({ rule, ...rest }: CspFinding): Card[] => [ + { + title: TEXT.RULE, + listItems: [ + [TEXT.RULE_EVALUATED_AT, moment(rest['@timestamp']).format('MMMM D, YYYY @ HH:mm:ss.SSS')], + [ + TEXT.FRAMEWORK_SOURCES, + + + + + + + + , + ], + [TEXT.CIS_SECTION, rule.section], + [TEXT.PROFILE_APPLICABILITY, {rule.profile_applicability}], + [TEXT.BENCHMARK, rule.benchmark.name], + [TEXT.NAME, rule.name], + [TEXT.DESCRIPTION, {rule.description}], + [TEXT.AUDIT, {rule.audit}], + [TEXT.REFERENCES, {rule.references}], + ], + }, +]; + +const getRemediationCards = ({ result, rule, ...rest }: CspFinding): Card[] => [ + { + title: TEXT.RESULT_DETAILS, + listItems: [ + result.expected + ? [TEXT.EXPECTED, {JSON.stringify(result.expected, null, 2)}] + : ['', ''], + [TEXT.EVIDENCE, {JSON.stringify(result.evidence, null, 2)}], + [ + TEXT.RULE_EVALUATED_AT, + {moment(rest['@timestamp']).format('MMMM D, YYYY @ HH:mm:ss.SSS')}, + ], + ], + }, + { + title: TEXT.REMEDIATION, + listItems: [ + ['', {rule.remediation}], + [TEXT.IMPACT, {rule.impact}], + [TEXT.DEFAULT_VALUE, {rule.default_value}], + [TEXT.RATIONALE, {rule.rationale}], + ], + }, +]; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/json_tab.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/json_tab.tsx new file mode 100644 index 0000000000000..ed5845abf19bb --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/json_tab.tsx @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { CodeEditor } from '@kbn/kibana-react-plugin/public'; +import { XJsonLang } from '@kbn/monaco'; +import { CspFinding } from '../types'; + +const offsetHeight = 120; + +export const JsonTab = ({ data }: { data: CspFinding }) => ( +
+ +
+); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/resource_tab.test.ts b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/resource_tab.test.ts new file mode 100644 index 0000000000000..94886e8fb254d --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/resource_tab.test.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { prepareDescriptionList } from './resource_tab'; + +const mockData = { + a: 'string', + b: 123, + c: undefined, + d: null, + e: true, + f: false, + g: [{ a: 'another string', b: 123 }], +}; + +describe('prepareDescriptionList', () => { + it('create description lists accordingly', () => { + const descriptionList = prepareDescriptionList(mockData); + expect(descriptionList).toMatchSnapshot(); + }); +}); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/resource_tab.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/resource_tab.tsx new file mode 100644 index 0000000000000..7919b836a3a73 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/resource_tab.tsx @@ -0,0 +1,102 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + EuiAccordion, + EuiCode, + EuiCodeBlock, + EuiDescriptionList, + EuiPanel, + EuiSpacer, + EuiText, + useEuiTheme, +} from '@elastic/eui'; +import React, { useMemo } from 'react'; +import { getFlattenedObject } from '@kbn/std'; +import { CspFinding } from '../types'; +import * as TEXT from '../translations'; + +const getDescriptionDisplay = (value: unknown) => { + if (value === undefined) return 'undefined'; + if (typeof value === 'boolean' || value === null) { + return {JSON.stringify(value)}; + } + + if (typeof value === 'object') { + return ( + + {JSON.stringify(value, null, 2)} + + ); + } + + return {value as string}; +}; + +export const prepareDescriptionList = (data: Record) => + Object.entries(getFlattenedObject(data)) + .sort((a, b) => a[0].localeCompare(b[0])) + .map(([key, value]) => ({ + title: ( + + {key} + + ), + description: getDescriptionDisplay(value), + })); + +export const ResourceTab = ({ data }: { data: CspFinding }) => { + const { euiTheme } = useEuiTheme(); + + const accordions = useMemo( + () => [ + { + title: TEXT.RESOURCE, + id: 'resourceAccordion', + listItems: prepareDescriptionList(data.resource), + }, + { + title: TEXT.HOST, + id: 'hostAccordion', + listItems: prepareDescriptionList(data.host), + }, + ], + [data.host, data.resource] + ); + + return ( + <> + {accordions.map((accordion) => ( + + + + {accordion.title} +
+ } + arrowDisplay="right" + initialIsOpen + > + + + + + + ))} + + ); +}; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_group_by_selector.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_group_by_selector.tsx deleted file mode 100644 index 84adf919a5fe1..0000000000000 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_group_by_selector.tsx +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import React from 'react'; -import { EuiComboBox, EuiFormLabel, type EuiComboBoxOptionOption } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n-react'; -import type { FindingsGroupByKind } from './types'; - -interface Props { - type: FindingsGroupByKind; - options: Array>; - onChange(selectedOptions: Array>): void; -} - -export const FindingsGroupBySelector = ({ type, options, onChange }: Props) => ( - } - singleSelection={{ asPlainText: true }} - options={options} - selectedOptions={options.filter((o) => o.value === type)} - onChange={onChange} - /> -); - -const GroupByLabel = () => ( - - - -); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_table.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_table.test.tsx deleted file mode 100644 index 28d14b42ae099..0000000000000 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_table.test.tsx +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import React from 'react'; -import { render, screen } from '@testing-library/react'; -import * as TEST_SUBJECTS from './test_subjects'; -import { FindingsTable } from './findings_table'; -import type { PropsOf } from '@elastic/eui'; -import Chance from 'chance'; -import type { CspFinding } from './types'; - -const chance = new Chance(); - -const getFakeFindings = (name: string): CspFinding & { id: string } => ({ - id: chance.word(), - result: { - evaluation: chance.weighted(['passed', 'failed'], [0.5, 0.5]), - evidence: { - filemode: chance.word(), - }, - }, - rule: { - name, - description: chance.paragraph(), - impact: chance.word(), - remediation: chance.word(), - benchmark: { - name: 'CIS Kubernetes', - version: '1.6.0', - }, - tags: [], - }, - agent: { - id: chance.string(), - name: chance.string(), - type: chance.string(), - version: chance.string(), - }, - resource: { - filename: chance.string(), - type: chance.string(), - path: chance.string(), - uid: chance.string(), - mode: chance.string(), - }, - cycle_id: chance.string(), - host: {} as any, - ecs: {} as any, - '@timestamp': new Date().toISOString(), -}); - -type TableProps = PropsOf; - -describe('', () => { - it('renders the zero state when status success and data has a length of zero ', async () => { - const props: TableProps = { - loading: false, - data: { page: [], total: 0 }, - error: null, - sort: [], - from: 1, - size: 10, - setQuery: jest.fn, - }; - - render(); - - expect(screen.getByTestId(TEST_SUBJECTS.FINDINGS_TABLE_ZERO_STATE)).toBeInTheDocument(); - }); - - it('renders the table with provided items', () => { - const names = chance.unique(chance.sentence, 10); - const data = names.map(getFakeFindings); - - const props: TableProps = { - loading: false, - data: { page: data, total: 10 }, - error: null, - sort: [], - from: 0, - size: 10, - setQuery: jest.fn, - }; - - render(); - - data.forEach((item) => { - expect(screen.getByText(item.rule.name)).toBeInTheDocument(); - }); - }); -}); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_table.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_table.tsx deleted file mode 100644 index 189cf42994382..0000000000000 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_table.tsx +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import React, { useCallback, useMemo, useState } from 'react'; -import { - type Criteria, - EuiToolTip, - EuiLink, - EuiTableFieldDataColumnType, - EuiEmptyPrompt, - EuiBasicTable, - PropsOf, - EuiBasicTableProps, -} from '@elastic/eui'; -import moment from 'moment'; -import { SortDirection } from '@kbn/data-plugin/common'; -import { extractErrorMessage } from '../../../common/utils/helpers'; -import * as TEST_SUBJECTS from './test_subjects'; -import * as TEXT from './translations'; -import type { CspFinding } from './types'; -import { CspEvaluationBadge } from '../../components/csp_evaluation_badge'; -import type { FindingsGroupByNoneQuery, CspFindingsResult } from './use_findings'; -import { FindingsRuleFlyout } from './findings_flyout'; - -interface BaseFindingsTableProps extends FindingsGroupByNoneQuery { - setQuery(query: Partial): void; -} - -type FindingsTableProps = CspFindingsResult & BaseFindingsTableProps; - -const FindingsTableComponent = ({ - setQuery, - from, - size, - sort = [], - error, - data, - loading, -}: FindingsTableProps) => { - const [selectedFinding, setSelectedFinding] = useState(); - - const pagination = useMemo( - () => - getEuiPaginationFromEsSearchSource({ - from, - size, - total: data?.total, - }), - [from, size, data] - ); - - const sorting = useMemo(() => getEuiSortFromEsSearchSource(sort), [sort]); - - const getCellProps = useCallback( - (item: CspFinding, column: EuiTableFieldDataColumnType) => ({ - onClick: column.field === 'rule.name' ? () => setSelectedFinding(item) : undefined, - }), - [] - ); - - const onTableChange = useCallback( - (params: Criteria) => { - setQuery(getEsSearchQueryFromEuiTableParams(params)); - }, - [setQuery] - ); - - // Show "zero state" - if (!loading && !data?.page.length) - // TODO: use our own logo - return ( - {TEXT.NO_FINDINGS}} - data-test-subj={TEST_SUBJECTS.FINDINGS_TABLE_ZERO_STATE} - /> - ); - - return ( - <> - - {selectedFinding && ( - setSelectedFinding(undefined)} - /> - )} - - ); -}; - -const getEuiPaginationFromEsSearchSource = ({ - from: pageIndex, - size: pageSize, - total, -}: Pick & { - total: number | undefined; -}): EuiBasicTableProps['pagination'] => ({ - pageSize, - pageIndex: Math.ceil(pageIndex / pageSize), - totalItemCount: total || 0, - pageSizeOptions: [10, 25, 100], - showPerPageOptions: true, -}); - -const getEuiSortFromEsSearchSource = ( - sort: FindingsGroupByNoneQuery['sort'] -): EuiBasicTableProps['sorting'] => { - if (!sort.length) return; - - const entry = Object.entries(sort[0])?.[0]; - if (!entry) return; - - const [field, direction] = entry; - return { sort: { field: field as keyof CspFinding, direction: direction as SortDirection } }; -}; - -const getEsSearchQueryFromEuiTableParams = ({ - page, - sort, -}: Criteria): Partial => ({ - ...(!!page && { from: page.index * page.size, size: page.size }), - sort: sort ? [{ [sort.field]: SortDirection[sort.direction] }] : undefined, -}); - -const timestampRenderer = (timestamp: string) => ( - - {moment.duration(moment().diff(timestamp)).humanize()} - -); - -const resourceFilenameRenderer = (filename: string) => ( - - {filename} - -); - -const ruleNameRenderer = (name: string) => ( - - {name} - -); - -const resultEvaluationRenderer = (type: PropsOf['type']) => ( - -); - -const columns: Array> = [ - { - field: 'resource.filename', - name: TEXT.RESOURCE, - truncateText: true, - width: '15%', - sortable: true, - render: resourceFilenameRenderer, - }, - { - field: 'rule.name', - name: TEXT.RULE_NAME, - truncateText: true, - render: ruleNameRenderer, - sortable: true, - }, - { - field: 'result.evaluation', - name: TEXT.EVALUATION, - width: '100px', - render: resultEvaluationRenderer, - sortable: true, - }, - { - field: '@timestamp', - width: '100px', - name: TEXT.TIMESTAMP, - truncateText: true, - render: timestampRenderer, - sortable: true, - }, -]; - -export const FindingsTable = React.memo(FindingsTableComponent); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_container.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_container.test.tsx new file mode 100644 index 0000000000000..ae980c1e492bb --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_container.test.tsx @@ -0,0 +1,78 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import { render } from '@testing-library/react'; +import { LatestFindingsContainer, getDefaultQuery } from './latest_findings_container'; +import { createStubDataView } from '@kbn/data-views-plugin/common/mocks'; +import { CSP_LATEST_FINDINGS_DATA_VIEW } from '../../../../common/constants'; +import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; +import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; +import { TestProvider } from '../../../test/test_provider'; +import { getFindingsQuery } from './use_latest_findings'; +import { encodeQuery } from '../../../common/navigation/query_utils'; +import { useLocation } from 'react-router-dom'; +import { RisonObject } from 'rison-node'; +import { buildEsQuery } from '@kbn/es-query'; +import { getFindingsCountAggQuery } from '../use_findings_count'; + +jest.mock('../../../common/api/use_latest_findings_data_view'); +jest.mock('../../../common/api/use_cis_kubernetes_integration'); + +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useHistory: () => ({ push: jest.fn() }), + useLocation: jest.fn(), +})); + +beforeEach(() => { + jest.restoreAllMocks(); +}); + +describe('', () => { + it('data#search.search fn called with URL query', () => { + const query = getDefaultQuery(); + const dataMock = dataPluginMock.createStartContract(); + const dataView = createStubDataView({ + spec: { + id: CSP_LATEST_FINDINGS_DATA_VIEW, + }, + }); + + (useLocation as jest.Mock).mockReturnValue({ + search: encodeQuery(query as unknown as RisonObject), + }); + + render( + + + + ); + + const baseQuery = { + index: dataView.title, + query: buildEsQuery(dataView, query.query, query.filters), + }; + + expect(dataMock.search.search).toHaveBeenNthCalledWith(1, { + params: getFindingsCountAggQuery(baseQuery), + }); + + expect(dataMock.search.search).toHaveBeenNthCalledWith(2, { + params: getFindingsQuery({ + ...baseQuery, + sort: query.sort, + size: query.size, + from: query.from, + }), + }); + }); +}); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_container.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_container.tsx new file mode 100644 index 0000000000000..78a1fd758b6ee --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_container.tsx @@ -0,0 +1,87 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { useMemo } from 'react'; +import { EuiSpacer } from '@elastic/eui'; +import type { DataView } from '@kbn/data-plugin/common'; +import { SortDirection } from '@kbn/data-plugin/common'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { FindingsTable } from './latest_findings_table'; +import { FindingsSearchBar } from '../layout/findings_search_bar'; +import * as TEST_SUBJECTS from '../test_subjects'; +import { useUrlQuery } from '../../../common/hooks/use_url_query'; +import { useLatestFindings } from './use_latest_findings'; +import type { FindingsGroupByNoneQuery } from './use_latest_findings'; +import type { FindingsBaseURLQuery } from '../types'; +import { useFindingsCounter } from '../use_findings_count'; +import { FindingsDistributionBar } from '../layout/findings_distribution_bar'; +import { getBaseQuery } from '../utils'; +import { PageWrapper, PageTitle, PageTitleText } from '../layout/findings_layout'; +import { FindingsGroupBySelector } from '../layout/findings_group_by_selector'; +import { useCspBreadcrumbs } from '../../../common/navigation/use_csp_breadcrumbs'; +import { findingsNavigation } from '../../../common/navigation/constants'; + +export const getDefaultQuery = (): FindingsBaseURLQuery & FindingsGroupByNoneQuery => ({ + query: { language: 'kuery', query: '' }, + filters: [], + sort: [{ ['@timestamp']: SortDirection.desc }], + from: 0, + size: 10, +}); + +export const LatestFindingsContainer = ({ dataView }: { dataView: DataView }) => { + useCspBreadcrumbs([findingsNavigation.findings_default]); + const { urlQuery, setUrlQuery } = useUrlQuery(getDefaultQuery); + const baseEsQuery = useMemo( + () => getBaseQuery({ dataView, filters: urlQuery.filters, query: urlQuery.query }), + [dataView, urlQuery.filters, urlQuery.query] + ); + + const findingsCount = useFindingsCounter(baseEsQuery); + const findingsGroupByNone = useLatestFindings({ + ...baseEsQuery, + size: urlQuery.size, + from: urlQuery.from, + sort: urlQuery.sort, + }); + + return ( +
+ + + + + } + /> + + + + + + +
+ ); +}; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_table.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_table.test.tsx new file mode 100644 index 0000000000000..d01af2fa96e94 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_table.test.tsx @@ -0,0 +1,112 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import * as TEST_SUBJECTS from '../test_subjects'; +import { FindingsTable } from './latest_findings_table'; +import type { PropsOf } from '@elastic/eui'; +import Chance from 'chance'; +import type { CspFinding } from '../types'; +import { TestProvider } from '../../../test/test_provider'; + +const chance = new Chance(); + +const getFakeFindings = (name: string): CspFinding & { id: string } => ({ + id: chance.word(), + result: { + expected: { + source: {}, + }, + evaluation: chance.weighted(['passed', 'failed'], [0.5, 0.5]), + evidence: { + filemode: chance.word(), + }, + }, + rule: { + name, + description: chance.paragraph(), + impact: chance.word(), + remediation: chance.word(), + benchmark: { + name: 'CIS Kubernetes', + version: '1.6.0', + }, + section: chance.sentence(), + audit: chance.paragraph(), + references: chance.paragraph(), + profile_applicability: chance.sentence(), + rationale: chance.paragraph(), + default_value: chance.sentence(), + tags: [], + }, + agent: { + id: chance.string(), + name: chance.string(), + type: chance.string(), + version: chance.string(), + }, + resource: { + filename: chance.string(), + type: chance.string(), + path: chance.string(), + uid: chance.string(), + mode: chance.string(), + }, + cycle_id: chance.string(), + host: {} as any, + ecs: {} as any, + '@timestamp': new Date().toISOString(), +}); + +type TableProps = PropsOf; + +describe('', () => { + it('renders the zero state when status success and data has a length of zero ', async () => { + const props: TableProps = { + loading: false, + data: { page: [], total: 0 }, + error: null, + sort: [], + from: 1, + size: 10, + setQuery: jest.fn, + }; + + render( + + + + ); + + expect(screen.getByTestId(TEST_SUBJECTS.FINDINGS_TABLE_ZERO_STATE)).toBeInTheDocument(); + }); + + it('renders the table with provided items', () => { + const names = chance.unique(chance.sentence, 10); + const data = names.map(getFakeFindings); + + const props: TableProps = { + loading: false, + data: { page: data, total: 10 }, + error: null, + sort: [], + from: 0, + size: 10, + setQuery: jest.fn, + }; + + render( + + + + ); + + data.forEach((item) => { + expect(screen.getByText(item.rule.name)).toBeInTheDocument(); + }); + }); +}); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_table.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_table.tsx new file mode 100644 index 0000000000000..6a2bd1c129b50 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_table.tsx @@ -0,0 +1,137 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { useCallback, useMemo, useState } from 'react'; +import { + type Criteria, + EuiEmptyPrompt, + EuiBasicTable, + EuiBasicTableProps, + EuiBasicTableColumn, +} from '@elastic/eui'; +import { SortDirection } from '@kbn/data-plugin/common'; +import { EuiTableActionsColumnType } from '@elastic/eui/src/components/basic_table/table_types'; +import { extractErrorMessage } from '../../../../common/utils/helpers'; +import * as TEST_SUBJECTS from '../test_subjects'; +import * as TEXT from '../translations'; +import type { CspFinding } from '../types'; +import type { FindingsGroupByNoneQuery, CspFindingsResult } from './use_latest_findings'; +import { FindingsRuleFlyout } from '../findings_flyout/findings_flyout'; +import { getExpandColumn, getFindingsColumns } from '../layout/findings_layout'; + +interface BaseFindingsTableProps extends FindingsGroupByNoneQuery { + setQuery(query: Partial): void; +} + +type FindingsTableProps = CspFindingsResult & BaseFindingsTableProps; + +const FindingsTableComponent = ({ + setQuery, + from, + size, + sort = [], + error, + data, + loading, +}: FindingsTableProps) => { + const [selectedFinding, setSelectedFinding] = useState(); + + const columns: [ + EuiTableActionsColumnType, + ...Array> + ] = useMemo( + () => [getExpandColumn({ onClick: setSelectedFinding }), ...getFindingsColumns()], + [] + ); + + const pagination = useMemo( + () => + getEuiPaginationFromEsSearchSource({ + from, + size, + total: data?.total, + }), + [from, size, data] + ); + + const sorting = useMemo(() => getEuiSortFromEsSearchSource(sort), [sort]); + + const onTableChange = useCallback( + (params: Criteria) => { + setQuery(getEsSearchQueryFromEuiTableParams(params)); + }, + [setQuery] + ); + + // Show "zero state" + if (!loading && !data?.page.length) + // TODO: use our own logo + return ( + {TEXT.NO_FINDINGS}} + data-test-subj={TEST_SUBJECTS.FINDINGS_TABLE_ZERO_STATE} + /> + ); + + return ( + <> + + {selectedFinding && ( + setSelectedFinding(undefined)} + /> + )} + + ); +}; + +const getEuiPaginationFromEsSearchSource = ({ + from: pageIndex, + size: pageSize, + total, +}: Pick & { + total: number | undefined; +}): EuiBasicTableProps['pagination'] => ({ + pageSize, + pageIndex: Math.ceil(pageIndex / pageSize), + totalItemCount: total || 0, + pageSizeOptions: [10, 25, 100], + showPerPageOptions: true, +}); + +const getEuiSortFromEsSearchSource = ( + sort: FindingsGroupByNoneQuery['sort'] +): EuiBasicTableProps['sorting'] => { + if (!sort.length) return; + + const entry = Object.entries(sort[0])?.[0]; + if (!entry) return; + + const [field, direction] = entry; + return { sort: { field: field as keyof CspFinding, direction: direction as SortDirection } }; +}; + +const getEsSearchQueryFromEuiTableParams = ({ + page, + sort, +}: Criteria): Partial => ({ + ...(!!page && { from: page.index * page.size, size: page.size }), + sort: sort ? [{ [sort.field]: SortDirection[sort.direction] }] : undefined, +}); + +export const FindingsTable = React.memo(FindingsTableComponent); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/use_latest_findings.ts b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/use_latest_findings.ts new file mode 100644 index 0000000000000..608f400953c86 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/use_latest_findings.ts @@ -0,0 +1,95 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { useQuery } from 'react-query'; +import { number } from 'io-ts'; +import { lastValueFrom } from 'rxjs'; +import type { EsQuerySortValue, IEsSearchResponse } from '@kbn/data-plugin/common'; +import type { CoreStart } from '@kbn/core/public'; +import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { extractErrorMessage } from '../../../../common/utils/helpers'; +import * as TEXT from '../translations'; +import type { CspFinding, FindingsQueryResult } from '../types'; +import { useKibana } from '../../../common/hooks/use_kibana'; +import type { FindingsBaseEsQuery } from '../types'; + +interface UseFindingsOptions extends FindingsBaseEsQuery, FindingsGroupByNoneQuery {} + +export interface FindingsGroupByNoneQuery { + from: NonNullable; + size: NonNullable; + sort: EsQuerySortValue[]; +} + +interface CspFindingsData { + page: CspFinding[]; + total: number; +} + +export type CspFindingsResult = FindingsQueryResult; + +const FIELDS_WITHOUT_KEYWORD_MAPPING = new Set(['@timestamp']); + +// NOTE: .keyword comes from the mapping we defined for the Findings index +const getSortKey = (key: string): string => + FIELDS_WITHOUT_KEYWORD_MAPPING.has(key) ? key : `${key}.keyword`; + +/** + * @description utility to transform a column header key to its field mapping for sorting + * @example Adds '.keyword' to every property we sort on except values of `FIELDS_WITHOUT_KEYWORD_MAPPING` + * @todo find alternative + * @note we choose the keyword 'keyword' in the field mapping + */ +const mapEsQuerySortKey = (sort: readonly EsQuerySortValue[]): EsQuerySortValue[] => + sort.slice().reduce((acc, cur) => { + const entry = Object.entries(cur)[0]; + if (!entry) return acc; + + const [k, v] = entry; + acc.push({ [getSortKey(k)]: v }); + + return acc; + }, []); + +export const showErrorToast = ( + toasts: CoreStart['notifications']['toasts'], + error: unknown +): void => { + if (error instanceof Error) toasts.addError(error, { title: TEXT.SEARCH_FAILED }); + else toasts.addDanger(extractErrorMessage(error, TEXT.SEARCH_FAILED)); +}; + +export const getFindingsQuery = ({ index, query, size, from, sort }: UseFindingsOptions) => ({ + index, + query, + size, + from, + sort: mapEsQuerySortKey(sort), +}); + +export const useLatestFindings = ({ index, query, sort, from, size }: UseFindingsOptions) => { + const { + data, + notifications: { toasts }, + } = useKibana().services; + + return useQuery( + ['csp_findings', { index, query, sort, from, size }], + () => + lastValueFrom>( + data.search.search({ + params: getFindingsQuery({ index, query, sort, from, size }), + }) + ), + { + select: ({ rawResponse: { hits } }) => ({ + page: hits.hits.map((hit) => hit._source!), + total: number.is(hits.total) ? hits.total : 0, + }), + onError: (err) => showErrorToast(toasts, err), + } + ); +}; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/findings_by_resource_container.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/findings_by_resource_container.tsx new file mode 100644 index 0000000000000..3dfbd477d4236 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/findings_by_resource_container.tsx @@ -0,0 +1,79 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import type { DataView } from '@kbn/data-plugin/common'; +import { Route, Switch } from 'react-router-dom'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { FindingsSearchBar } from '../layout/findings_search_bar'; +import * as TEST_SUBJECTS from '../test_subjects'; +import { useUrlQuery } from '../../../common/hooks/use_url_query'; +import type { FindingsBaseURLQuery } from '../types'; +import { useFindingsByResource } from './use_findings_by_resource'; +import { FindingsByResourceTable } from './findings_by_resource_table'; +import { getBaseQuery } from '../utils'; +import { PageTitle, PageTitleText, PageWrapper } from '../layout/findings_layout'; +import { FindingsGroupBySelector } from '../layout/findings_group_by_selector'; +import { findingsNavigation } from '../../../common/navigation/constants'; +import { useCspBreadcrumbs } from '../../../common/navigation/use_csp_breadcrumbs'; +import { ResourceFindings } from './resource_findings/resource_findings_container'; + +const getDefaultQuery = (): FindingsBaseURLQuery => ({ + query: { language: 'kuery', query: '' }, + filters: [], +}); + +export const FindingsByResourceContainer = ({ dataView }: { dataView: DataView }) => ( + + } + /> + } + /> + +); + +const LatestFindingsByResource = ({ dataView }: { dataView: DataView }) => { + useCspBreadcrumbs([findingsNavigation.findings_by_resource]); + const { urlQuery, setUrlQuery } = useUrlQuery(getDefaultQuery); + const findingsGroupByResource = useFindingsByResource( + getBaseQuery({ dataView, filters: urlQuery.filters, query: urlQuery.query }) + ); + + return ( +
+ + + + + } + /> + + + + +
+ ); +}; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_by_resource_table.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/findings_by_resource_table.test.tsx similarity index 85% rename from x-pack/plugins/cloud_security_posture/public/pages/findings/findings_by_resource_table.test.tsx rename to x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/findings_by_resource_table.test.tsx index 3018de31aeb58..f51be5f7a43e1 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_by_resource_table.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/findings_by_resource_table.test.tsx @@ -6,12 +6,13 @@ */ import React from 'react'; import { render, screen, within } from '@testing-library/react'; -import * as TEST_SUBJECTS from './test_subjects'; +import * as TEST_SUBJECTS from '../test_subjects'; import { FindingsByResourceTable, formatNumber, getResourceId } from './findings_by_resource_table'; -import * as TEXT from './translations'; +import * as TEXT from '../translations'; import type { PropsOf } from '@elastic/eui'; import Chance from 'chance'; import numeral from '@elastic/numeral'; +import { TestProvider } from '../../../test/test_provider'; const chance = new Chance(); @@ -35,7 +36,11 @@ describe('', () => { error: null, }; - render(); + render( + + + + ); expect(screen.getByText(TEXT.NO_FINDINGS)).toBeInTheDocument(); }); @@ -49,7 +54,11 @@ describe('', () => { error: null, }; - render(); + render( + + + + ); data.forEach((item, i) => { const row = screen.getByTestId( diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_by_resource_table.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/findings_by_resource_table.tsx similarity index 87% rename from x-pack/plugins/cloud_security_posture/public/pages/findings/findings_by_resource_table.tsx rename to x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/findings_by_resource_table.tsx index d2acee177686a..ef7b3da67fbb4 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_by_resource_table.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/findings_by_resource_table.tsx @@ -12,14 +12,15 @@ import { EuiTextColor, EuiFlexGroup, EuiFlexItem, - EuiLink, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import numeral from '@elastic/numeral'; -import { extractErrorMessage } from '../../../common/utils/helpers'; -import * as TEST_SUBJECTS from './test_subjects'; -import * as TEXT from './translations'; +import { Link, generatePath } from 'react-router-dom'; +import { extractErrorMessage } from '../../../../common/utils/helpers'; +import * as TEST_SUBJECTS from '../test_subjects'; +import * as TEXT from '../translations'; import type { CspFindingsByResourceResult } from './use_findings_by_resource'; +import { findingsNavigation } from '../../../common/navigation/constants'; export const formatNumber = (value: number) => value < 1000 ? value : numeral(value).format('0.0a'); @@ -62,7 +63,11 @@ const columns: Array> = [ defaultMessage="Resource ID" /> ), - render: (resourceId: CspFindingsByResource['resource_id']) => {resourceId}, + render: (resourceId: CspFindingsByResource['resource_id']) => ( + + {resourceId} + + ), }, { field: 'cis_section', diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/resource_findings/resource_findings_container.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/resource_findings/resource_findings_container.tsx new file mode 100644 index 0000000000000..a48926b3653aa --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/resource_findings/resource_findings_container.tsx @@ -0,0 +1,87 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import { EuiSpacer, EuiButtonEmpty } from '@elastic/eui'; +import type { DataView } from '@kbn/data-plugin/common'; +import { Link, useParams } from 'react-router-dom'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { useEuiTheme } from '@elastic/eui'; +import { generatePath } from 'react-router-dom'; +import * as TEST_SUBJECTS from '../../test_subjects'; +import { PageWrapper, PageTitle, PageTitleText } from '../../layout/findings_layout'; +import { useCspBreadcrumbs } from '../../../../common/navigation/use_csp_breadcrumbs'; +import { findingsNavigation } from '../../../../common/navigation/constants'; +import { useResourceFindings } from './use_resource_findings'; +import { useUrlQuery } from '../../../../common/hooks/use_url_query'; +import type { FindingsBaseURLQuery } from '../../types'; +import { getBaseQuery } from '../../utils'; +import { ResourceFindingsTable } from './resource_findings_table'; +import { FindingsSearchBar } from '../../layout/findings_search_bar'; + +const getDefaultQuery = (): FindingsBaseURLQuery => ({ + query: { language: 'kuery', query: '' }, + filters: [], +}); + +const BackToResourcesButton = () => { + return ( + + + + + + ); +}; + +export const ResourceFindings = ({ dataView }: { dataView: DataView }) => { + useCspBreadcrumbs([findingsNavigation.findings_default]); + const { euiTheme } = useEuiTheme(); + const params = useParams<{ resourceId: string }>(); + const { urlQuery, setUrlQuery } = useUrlQuery(getDefaultQuery); + + const resourceFindings = useResourceFindings({ + ...getBaseQuery({ dataView, filters: urlQuery.filters, query: urlQuery.query }), + resourceId: params.resourceId, + }); + + return ( +
+ + + + + + +
+ } + /> + + + + +
+ ); +}; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/resource_findings/resource_findings_table.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/resource_findings/resource_findings_table.tsx new file mode 100644 index 0000000000000..ec04d05109cdd --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/resource_findings/resource_findings_table.tsx @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import { EuiEmptyPrompt, EuiBasicTable } from '@elastic/eui'; +import { extractErrorMessage } from '../../../../../common/utils/helpers'; +import * as TEXT from '../../translations'; +import type { ResourceFindingsResult } from './use_resource_findings'; +import { getFindingsColumns } from '../../layout/findings_layout'; + +type FindingsGroupByResourceProps = ResourceFindingsResult; + +const columns = getFindingsColumns(); + +const ResourceFindingsTableComponent = ({ error, data, loading }: FindingsGroupByResourceProps) => { + if (!loading && !data?.page.length) + return {TEXT.NO_FINDINGS}} />; + + return ( + + ); +}; + +export const ResourceFindingsTable = React.memo(ResourceFindingsTableComponent); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/resource_findings/use_resource_findings.ts b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/resource_findings/use_resource_findings.ts new file mode 100644 index 0000000000000..7123b80ef0228 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/resource_findings/use_resource_findings.ts @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { useQuery } from 'react-query'; +import { lastValueFrom } from 'rxjs'; +import { IEsSearchResponse } from '@kbn/data-plugin/common'; +import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { useKibana } from '../../../../common/hooks/use_kibana'; +import { showErrorToast } from '../../latest_findings/use_latest_findings'; +import type { CspFinding, FindingsBaseEsQuery, FindingsQueryResult } from '../../types'; + +interface UseResourceFindingsOptions extends FindingsBaseEsQuery { + resourceId: string; +} + +export type ResourceFindingsResult = FindingsQueryResult< + ReturnType['data'] | undefined, + unknown +>; + +export const getResourceFindingsQuery = ({ + index, + query, + resourceId, +}: UseResourceFindingsOptions): estypes.SearchRequest => ({ + index, + body: { + query: { + ...query, + bool: { + ...query?.bool, + filter: [...(query?.bool?.filter || []), { term: { 'resource_id.keyword': resourceId } }], + }, + }, + }, +}); + +export const useResourceFindings = ({ index, query, resourceId }: UseResourceFindingsOptions) => { + const { + data, + notifications: { toasts }, + } = useKibana().services; + + return useQuery( + ['csp_resource_findings', { index, query, resourceId }], + () => + lastValueFrom>( + data.search.search({ + params: getResourceFindingsQuery({ index, query, resourceId }), + }) + ), + { + select: ({ rawResponse: { hits } }) => ({ + page: hits.hits.map((hit) => hit._source!), + total: hits.total as number, + }), + onError: (err) => showErrorToast(toasts, err), + } + ); +}; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/use_findings_by_resource.ts b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/use_findings_by_resource.ts similarity index 81% rename from x-pack/plugins/cloud_security_posture/public/pages/findings/use_findings_by_resource.ts rename to x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/use_findings_by_resource.ts index b5596d55a6664..6fec85531b196 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/use_findings_by_resource.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/use_findings_by_resource.ts @@ -8,11 +8,9 @@ import { useQuery } from 'react-query'; import { lastValueFrom } from 'rxjs'; import { IKibanaSearchRequest, IKibanaSearchResponse } from '@kbn/data-plugin/common'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { useKibana } from '../../common/hooks/use_kibana'; -import { showErrorToast } from './use_findings'; -import type { FindingsBaseEsQuery, FindingsQueryResult, FindingsQueryStatus } from './types'; - -interface UseFindingsByResourceOptions extends FindingsBaseEsQuery, FindingsQueryStatus {} +import { useKibana } from '../../../common/hooks/use_kibana'; +import { showErrorToast } from '../latest_findings/use_latest_findings'; +import type { FindingsBaseEsQuery, FindingsQueryResult } from '../types'; type FindingsAggRequest = IKibanaSearchRequest; type FindingsAggResponse = IKibanaSearchResponse< @@ -43,7 +41,7 @@ interface FindingsAggBucket { export const getFindingsByResourceAggQuery = ({ index, query, -}: Omit): estypes.SearchRequest => ({ +}: FindingsBaseEsQuery): estypes.SearchRequest => ({ index, size: 0, body: { @@ -55,7 +53,7 @@ export const getFindingsByResourceAggQuery = ({ sources: [ { resource_id: { terms: { field: 'resource_id.keyword' } } }, { cluster_id: { terms: { field: 'cluster_id.keyword' } } }, - { cis_section: { terms: { field: 'rule.section' } } }, + { cis_section: { terms: { field: 'rule.section.keyword' } } }, ], }, aggs: { @@ -68,7 +66,7 @@ export const getFindingsByResourceAggQuery = ({ }, }); -export const useFindingsByResource = ({ enabled, index, query }: UseFindingsByResourceOptions) => { +export const useFindingsByResource = ({ index, query }: FindingsBaseEsQuery) => { const { data, notifications: { toasts }, @@ -83,7 +81,6 @@ export const useFindingsByResource = ({ enabled, index, query }: UseFindingsByRe }) ), { - enabled, select: ({ rawResponse }) => ({ page: rawResponse.aggregations?.groupBy.buckets.map(createFindingsByResource) || [], }), diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_distribution_bar.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/layout/findings_distribution_bar.tsx similarity index 100% rename from x-pack/plugins/cloud_security_posture/public/pages/findings/findings_distribution_bar.tsx rename to x-pack/plugins/cloud_security_posture/public/pages/findings/layout/findings_distribution_bar.tsx diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/layout/findings_group_by_selector.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/layout/findings_group_by_selector.tsx new file mode 100644 index 0000000000000..efbda89eb3e4d --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/layout/findings_group_by_selector.tsx @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { useMemo } from 'react'; +import { EuiComboBox, EuiFormLabel, EuiSpacer, type EuiComboBoxOptionOption } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { useHistory } from 'react-router-dom'; +import { i18n } from '@kbn/i18n'; +import { INTERNAL_FEATURE_FLAGS } from '../../../../common/constants'; +import type { FindingsGroupByKind } from '../types'; +import { findingsNavigation } from '../../../common/navigation/constants'; + +const getGroupByOptions = (): Array> => [ + { + value: 'default', + label: i18n.translate('xpack.csp.findings.groupBySelector.groupByNoneLabel', { + defaultMessage: 'None', + }), + }, + { + value: 'resource', + label: i18n.translate('xpack.csp.findings.groupBySelector.groupByResourceIdLabel', { + defaultMessage: 'Resource', + }), + }, +]; + +interface Props { + type: FindingsGroupByKind; +} + +const getFindingsGroupPath = (opts: Array>) => { + const [firstOption] = opts; + + switch (firstOption?.value) { + case 'resource': + return findingsNavigation.findings_by_resource.path; + case 'default': + default: + return findingsNavigation.findings_default.path; + } +}; + +export const FindingsGroupBySelector = ({ type }: Props) => { + const groupByOptions = useMemo(getGroupByOptions, []); + const history = useHistory(); + + if (!INTERNAL_FEATURE_FLAGS.showFindingsGroupBy) return null; + + const onChange = (options: Array>) => + history.push({ pathname: getFindingsGroupPath(options) }); + + return ( +
+ } + singleSelection={{ asPlainText: true }} + options={groupByOptions} + selectedOptions={groupByOptions.filter((o) => o.value === type)} + onChange={onChange} + /> + +
+ ); +}; + +const GroupByLabel = () => ( + + + +); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/layout/findings_layout.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/layout/findings_layout.tsx new file mode 100644 index 0000000000000..ee1a00abc4901 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/layout/findings_layout.tsx @@ -0,0 +1,114 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import { + EuiBasicTableColumn, + EuiSpacer, + EuiTableActionsColumnType, + EuiTitle, + EuiToolTip, + PropsOf, + useEuiTheme, +} from '@elastic/eui'; +import { css } from '@emotion/react'; +import moment from 'moment'; +import { CspEvaluationBadge } from '../../../components/csp_evaluation_badge'; +import * as TEXT from '../translations'; +import { CspFinding } from '../types'; + +export const PageWrapper: React.FC = ({ children }) => { + const { euiTheme } = useEuiTheme(); + return ( +
+ {children} +
+ ); +}; + +export const PageTitle: React.FC = ({ children }) => ( + +
+ {children} + +
+
+); + +export const PageTitleText = ({ title }: { title: React.ReactNode }) =>

{title}

; + +export const getExpandColumn = ({ + onClick, +}: { + onClick(item: T): void; +}): EuiTableActionsColumnType => ({ + width: '40px', + actions: [ + { + name: 'Expand', + description: 'Expand', + type: 'icon', + icon: 'expand', + onClick, + }, + ], +}); + +export const getFindingsColumns = (): Array> => [ + { + field: 'resource_id', + name: TEXT.RESOURCE_ID, + truncateText: true, + width: '15%', + sortable: true, + render: (filename: string) => ( + + {filename} + + ), + }, + { + field: 'result.evaluation', + name: TEXT.RESULT, + width: '100px', + sortable: true, + render: (type: PropsOf['type']) => ( + + ), + }, + { + field: 'rule.name', + name: TEXT.RULE, + sortable: true, + }, + { + field: 'cluster_id', + name: TEXT.CLUSTER_ID, + truncateText: true, + sortable: true, + }, + { + field: 'rule.section', + name: TEXT.CIS_SECTION, + sortable: true, + truncateText: true, + }, + { + field: '@timestamp', + name: TEXT.LAST_CHECKED, + truncateText: true, + sortable: true, + render: (timestamp: number) => ( + + {moment(timestamp).fromNow()} + + ), + }, +]; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_search_bar.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/layout/findings_search_bar.tsx similarity index 83% rename from x-pack/plugins/cloud_security_posture/public/pages/findings/findings_search_bar.tsx rename to x-pack/plugins/cloud_security_posture/public/pages/findings/layout/findings_search_bar.tsx index 89673dabbf91f..ba8309ea57261 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_search_bar.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/layout/findings_search_bar.tsx @@ -9,18 +9,17 @@ import { css } from '@emotion/react'; import { EuiThemeComputed, useEuiTheme } from '@elastic/eui'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import type { DataView } from '@kbn/data-plugin/common'; -import * as TEST_SUBJECTS from './test_subjects'; -import type { CspFindingsResult } from './use_findings'; -import type { FindingsBaseURLQuery } from './types'; -import type { CspClientPluginStartDeps } from '../../types'; -import { PLUGIN_NAME } from '../../../common'; -import { FINDINGS_SEARCH_PLACEHOLDER } from './translations'; +import * as TEST_SUBJECTS from '../test_subjects'; +import type { FindingsBaseURLQuery } from '../types'; +import type { CspClientPluginStartDeps } from '../../../types'; +import { PLUGIN_NAME } from '../../../../common'; +import { FINDINGS_SEARCH_PLACEHOLDER } from '../translations'; type SearchBarQueryProps = Pick; interface FindingsSearchBarProps extends SearchBarQueryProps { setQuery(v: Partial): void; - loading: CspFindingsResult['loading']; + loading: boolean; } export const FindingsSearchBar = ({ diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/translations.ts b/x-pack/plugins/cloud_security_posture/public/pages/findings/translations.ts index 5ffa474e7a63d..53d4b8a86e5c0 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/translations.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/translations.ts @@ -42,6 +42,49 @@ export const RESOURCE = i18n.translate('xpack.csp.findings.resourceLabel', { defaultMessage: 'Resource', }); +export const GENERAL = i18n.translate('xpack.csp.findings.findingsFlyout.generalTabLabel', { + defaultMessage: 'General', +}); + +export const JSON = i18n.translate('xpack.csp.findings.findingsFlyout.jsonTabLabel', { + defaultMessage: 'JSON', +}); + +export const RESOURCE_ID = i18n.translate( + 'xpack.csp.findings.findingsTable.findingsTableColumn.resourceIdColumnLabel', + { + defaultMessage: 'Resource ID', + } +); + +export const RESULT = i18n.translate( + 'xpack.csp.findings.findingsTable.findingsTableColumn.resultColumnLabel', + { + defaultMessage: 'Result', + } +); + +export const CLUSTER_ID = i18n.translate( + 'xpack.csp.findings.findingsTable.findingsTableColumn.clusterIdColumnLabel', + { + defaultMessage: 'Cluster ID', + } +); + +export const CIS_SECTION = i18n.translate( + 'xpack.csp.findings.findingsTable.findingsTableColumn.ruleSectionColumnLabel', + { + defaultMessage: 'CIS Section', + } +); + +export const LAST_CHECKED = i18n.translate( + 'xpack.csp.findings.findingsTable.findingsTableColumn.lastCheckedColumnLabel', + { + defaultMessage: 'Last Checked', + } +); + export const FILENAME = i18n.translate('xpack.csp.findings.filenameLabel', { defaultMessage: 'Filename', }); @@ -106,7 +149,14 @@ export const AUDIT = i18n.translate('xpack.csp.findings.auditLabel', { defaultMessage: 'Audit', }); -export const RESULT = i18n.translate('xpack.csp.findings.resultLabel', { +export const REFERENCES = i18n.translate( + 'xpack.csp.findings.findingsFlyout.generalTab.referencesLabel', + { + defaultMessage: 'References', + } +); + +export const RESULT_DETAILS = i18n.translate('xpack.csp.findings.resultLabel', { defaultMessage: 'Result Details', }); @@ -144,7 +194,7 @@ export const ID = i18n.translate('xpack.csp.findings.idLabel', { }); export const HOST = i18n.translate('xpack.csp.findings.hostLabel', { - defaultMessage: 'HOST', + defaultMessage: 'Host', }); export const ARCHITECTURE = i18n.translate('xpack.csp.findings.architectureLabel', { diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/types.ts b/x-pack/plugins/cloud_security_posture/public/pages/findings/types.ts index 79d8f3507c896..9fed484a88128 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/types.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/types.ts @@ -7,10 +7,9 @@ import type { BoolQuery, Filter, Query } from '@kbn/es-query'; import { UseQueryResult } from 'react-query'; -export type FindingsGroupByKind = 'none' | 'resource'; +export type FindingsGroupByKind = 'default' | 'resource'; export interface FindingsBaseURLQuery { - groupBy: FindingsGroupByKind; query: Query; filters: Filter[]; } @@ -22,10 +21,6 @@ export interface FindingsBaseEsQuery { }; } -export interface FindingsQueryStatus { - enabled: boolean; -} - export interface FindingsQueryResult { loading: UseQueryResult['isLoading']; error: TError; @@ -48,8 +43,14 @@ export interface CspFinding { interface CspRule { benchmark: { name: string; version: string }; + section: string; + audit: string; + references: string; + profile_applicability: string; description: string; impact: string; + default_value: string; + rationale: string; name: string; remediation: string; tags: string[]; @@ -57,9 +58,8 @@ interface CspRule { interface CspFindingResult { evaluation: 'passed' | 'failed'; - evidence: { - filemode: string; - }; + expected?: Record; + evidence: Record; } interface CspFindingResource { @@ -69,6 +69,7 @@ interface CspFindingResource { mode: string; path: string; type: string; + [other_keys: string]: unknown; } interface CspFindingHost { @@ -88,6 +89,7 @@ interface CspFindingHost { family: string; name: string; }; + [other_keys: string]: unknown; } interface CspFindingAgent { diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/use_findings.ts b/x-pack/plugins/cloud_security_posture/public/pages/findings/use_findings.ts deleted file mode 100644 index 1f7e8dae483bf..0000000000000 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/use_findings.ts +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { useQuery } from 'react-query'; -import { number } from 'io-ts'; -import { lastValueFrom } from 'rxjs'; -import type { EsQuerySortValue, IEsSearchResponse } from '@kbn/data-plugin/common'; -import type { CoreStart } from '@kbn/core/public'; -import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { extractErrorMessage } from '../../../common/utils/helpers'; -import * as TEXT from './translations'; -import type { CspFinding, FindingsQueryResult } from './types'; -import { useKibana } from '../../common/hooks/use_kibana'; -import type { FindingsBaseEsQuery, FindingsQueryStatus } from './types'; - -interface UseFindingsOptions - extends FindingsBaseEsQuery, - FindingsGroupByNoneQuery, - FindingsQueryStatus {} - -export interface FindingsGroupByNoneQuery { - from: NonNullable; - size: NonNullable; - sort: EsQuerySortValue[]; -} - -interface CspFindingsData { - page: CspFinding[]; - total: number; -} - -export type CspFindingsResult = FindingsQueryResult; - -const FIELDS_WITHOUT_KEYWORD_MAPPING = new Set(['@timestamp']); - -// NOTE: .keyword comes from the mapping we defined for the Findings index -const getSortKey = (key: string): string => - FIELDS_WITHOUT_KEYWORD_MAPPING.has(key) ? key : `${key}.keyword`; - -/** - * @description utility to transform a column header key to its field mapping for sorting - * @example Adds '.keyword' to every property we sort on except values of `FIELDS_WITHOUT_KEYWORD_MAPPING` - * @todo find alternative - * @note we choose the keyword 'keyword' in the field mapping - */ -const mapEsQuerySortKey = (sort: readonly EsQuerySortValue[]): EsQuerySortValue[] => - sort.slice().reduce((acc, cur) => { - const entry = Object.entries(cur)[0]; - if (!entry) return acc; - - const [k, v] = entry; - acc.push({ [getSortKey(k)]: v }); - - return acc; - }, []); - -export const showErrorToast = ( - toasts: CoreStart['notifications']['toasts'], - error: unknown -): void => { - if (error instanceof Error) toasts.addError(error, { title: TEXT.SEARCH_FAILED }); - else toasts.addDanger(extractErrorMessage(error, TEXT.SEARCH_FAILED)); -}; - -export const getFindingsQuery = ({ - index, - query, - size, - from, - sort, -}: Omit) => ({ - index, - query, - size, - from, - sort: mapEsQuerySortKey(sort), -}); - -export const useFindings = ({ enabled, index, query, sort, from, size }: UseFindingsOptions) => { - const { - data, - notifications: { toasts }, - } = useKibana().services; - - return useQuery( - ['csp_findings', { index, query, sort, from, size }], - () => - lastValueFrom>( - data.search.search({ - params: getFindingsQuery({ index, query, sort, from, size }), - }) - ), - { - enabled, - select: ({ rawResponse: { hits } }) => ({ - page: hits.hits.map((hit) => hit._source!), - total: number.is(hits.total) ? hits.total : 0, - }), - onError: (err) => showErrorToast(toasts, err), - } - ); -}; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/use_findings_count.ts b/x-pack/plugins/cloud_security_posture/public/pages/findings/use_findings_count.ts index 6ed56ea1d4397..f48e630b489d4 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/use_findings_count.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/use_findings_count.ts @@ -9,10 +9,8 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { lastValueFrom } from 'rxjs'; import type { IKibanaSearchRequest, IKibanaSearchResponse } from '@kbn/data-plugin/public'; import { useKibana } from '../../common/hooks/use_kibana'; -import { showErrorToast } from './use_findings'; -import type { FindingsBaseEsQuery, FindingsQueryStatus } from './types'; - -interface UseFindingsCountOptions extends FindingsBaseEsQuery, FindingsQueryStatus {} +import { showErrorToast } from './latest_findings/use_latest_findings'; +import type { FindingsBaseEsQuery } from './types'; type FindingsAggRequest = IKibanaSearchRequest; type FindingsAggResponse = IKibanaSearchResponse>; @@ -35,7 +33,7 @@ export const getFindingsCountAggQuery = ({ index, query }: FindingsBaseEsQuery) }, }); -export const useFindingsCounter = ({ enabled, index, query }: UseFindingsCountOptions) => { +export const useFindingsCounter = ({ index, query }: FindingsBaseEsQuery) => { const { data, notifications: { toasts }, @@ -50,7 +48,6 @@ export const useFindingsCounter = ({ enabled, index, query }: UseFindingsCountOp }) ), { - enabled, onError: (err) => showErrorToast(toasts, err), select: (response) => Object.fromEntries( diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/utils.ts b/x-pack/plugins/cloud_security_posture/public/pages/findings/utils.ts new file mode 100644 index 0000000000000..d3281a1a0dbc8 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/utils.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { buildEsQuery } from '@kbn/es-query'; +import type { DataView } from '@kbn/data-plugin/common'; +import type { FindingsBaseEsQuery, FindingsBaseURLQuery } from './types'; + +export const getBaseQuery = ({ + dataView, + query, + filters, +}: FindingsBaseURLQuery & { dataView: DataView }): FindingsBaseEsQuery => ({ + index: dataView.title, + // TODO: this will throw for malformed query + // page will display an error boundary with the JS error + // will be accounted for before releasing the feature + query: buildEsQuery(dataView, query, filters), +}); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx index 7782be9c4917e..0787bc37c45e7 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx @@ -13,6 +13,7 @@ import { useFindCspRules, useBulkUpdateCspRules, type RuleSavedObject } from './ import * as TEST_SUBJECTS from './test_subjects'; import { Chance } from 'chance'; import { TestProvider } from '../../test/test_provider'; +import { useParams } from 'react-router-dom'; const chance = new Chance(); @@ -21,6 +22,11 @@ jest.mock('./use_csp_rules', () => ({ useBulkUpdateCspRules: jest.fn(), })); +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useParams: jest.fn(), +})); + const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false }, @@ -32,21 +38,54 @@ const getWrapper = ({ children }) => {children}; -const getRuleMock = ({ id = chance.guid(), enabled }: { id?: string; enabled: boolean }) => +const getRuleMock = ({ + packagePolicyId = chance.guid(), + policyId = chance.guid(), + savedObjectId = chance.guid(), + id = chance.guid(), + enabled, +}: { + packagePolicyId?: string; + policyId?: string; + savedObjectId?: string; + id?: string; + enabled: boolean; +}) => ({ - id, + id: savedObjectId, updatedAt: chance.date().toISOString(), attributes: { id, name: chance.sentence(), + package_policy_id: packagePolicyId, + policy_id: policyId, enabled, }, } as RuleSavedObject); +const getSavedObjectRuleEnable = ( + rule: RuleSavedObject, + enabled: RuleSavedObject['attributes']['enabled'] +) => ({ + ...rule, + attributes: { + ...rule.attributes, + enabled, + }, +}); + +const params = { + policyId: chance.guid(), + packagePolicyId: chance.guid(), +}; + describe('', () => { beforeEach(() => { queryClient.clear(); jest.clearAllMocks(); + + (useParams as jest.Mock).mockReturnValue(params); + (useBulkUpdateCspRules as jest.Mock).mockReturnValue({ status: 'idle', mutate: jest.fn(), @@ -102,6 +141,13 @@ describe('', () => { const switchId1 = TEST_SUBJECTS.getCspRulesTableItemSwitchTestId(rule1.id); const switchId2 = TEST_SUBJECTS.getCspRulesTableItemSwitchTestId(rule2.id); + expect(screen.getByTestId(switchId1).getAttribute('aria-checked')).toEqual( + rule1.attributes.enabled.toString() + ); + expect(screen.getByTestId(switchId2).getAttribute('aria-checked')).toEqual( + rule2.attributes.enabled.toString() + ); + fireEvent.click(screen.getByTestId(switchId1)); fireEvent.click(screen.getByTestId(switchId2)); @@ -154,6 +200,7 @@ describe('', () => { it('updates rules with local changes done by non-bulk toggles', () => { const Wrapper = getWrapper(); + const rule1 = getRuleMock({ enabled: false }); const rule2 = getRuleMock({ enabled: true }); const rule3 = getRuleMock({ enabled: true }); @@ -184,10 +231,13 @@ describe('', () => { fireEvent.click(screen.getByTestId(TEST_SUBJECTS.CSP_RULES_SAVE_BUTTON)); expect(mutate).toHaveBeenCalledTimes(1); - expect(mutate).toHaveBeenCalledWith([ - { ...rule1.attributes, enabled: !rule1.attributes.enabled }, - { ...rule2.attributes, enabled: !rule2.attributes.enabled }, - ]); + expect(mutate).toHaveBeenCalledWith({ + packagePolicyId: params.packagePolicyId, + savedObjectRules: [ + getSavedObjectRuleEnable(rule1, !rule1.attributes.enabled), + getSavedObjectRuleEnable(rule2, !rule2.attributes.enabled), + ], + }); }); it('updates rules with local changes done by bulk toggles', () => { @@ -217,9 +267,10 @@ describe('', () => { fireEvent.click(screen.getByTestId(TEST_SUBJECTS.CSP_RULES_SAVE_BUTTON)); expect(mutate).toHaveBeenCalledTimes(1); - expect(mutate).toHaveBeenCalledWith([ - { ...rule1.attributes, enabled: !rule1.attributes.enabled }, - ]); + expect(mutate).toHaveBeenCalledWith({ + packagePolicyId: params.packagePolicyId, + savedObjectRules: [getSavedObjectRuleEnable(rule1, !rule1.attributes.enabled)], + }); }); it('only changes selected rules in bulk operations', () => { @@ -254,11 +305,14 @@ describe('', () => { fireEvent.click(screen.getByTestId(TEST_SUBJECTS.CSP_RULES_SAVE_BUTTON)); expect(mutate).toHaveBeenCalledTimes(1); - expect(mutate).toHaveBeenCalledWith([ - { ...rule1.attributes, enabled: !rule1.attributes.enabled }, - { ...rule4.attributes, enabled: !rule4.attributes.enabled }, - { ...rule5.attributes, enabled: !rule5.attributes.enabled }, - ]); + expect(mutate).toHaveBeenCalledWith({ + packagePolicyId: params.packagePolicyId, + savedObjectRules: [ + getSavedObjectRuleEnable(rule1, !rule1.attributes.enabled), + getSavedObjectRuleEnable(rule4, !rule4.attributes.enabled), + getSavedObjectRuleEnable(rule5, !rule5.attributes.enabled), + ], + }); }); it('updates rules with changes of both bulk/non-bulk toggles', () => { @@ -295,11 +349,14 @@ describe('', () => { fireEvent.click(screen.getByTestId(TEST_SUBJECTS.CSP_RULES_SAVE_BUTTON)); expect(mutate).toHaveBeenCalledTimes(1); - expect(mutate).toHaveBeenCalledWith([ - { ...rule1.attributes, enabled: !rule1.attributes.enabled }, - { ...rule4.attributes, enabled: !rule4.attributes.enabled }, - { ...rule5.attributes, enabled: !rule5.attributes.enabled }, - ]); + expect(mutate).toHaveBeenCalledWith({ + packagePolicyId: params.packagePolicyId, + savedObjectRules: [ + getSavedObjectRuleEnable(rule1, !rule1.attributes.enabled), + getSavedObjectRuleEnable(rule4, !rule4.attributes.enabled), + getSavedObjectRuleEnable(rule5, !rule5.attributes.enabled), + ], + }); }); it('selects and updates all rules', async () => { @@ -329,12 +386,12 @@ describe('', () => { fireEvent.click(screen.getByTestId(TEST_SUBJECTS.CSP_RULES_SAVE_BUTTON)); expect(mutate).toHaveBeenCalledTimes(1); - expect(mutate).toHaveBeenCalledWith( - rules.map((rule) => ({ - ...rule.attributes, - enabled: !enabled, - })) - ); + expect(mutate).toHaveBeenCalledWith({ + packagePolicyId: params.packagePolicyId, + savedObjectRules: rules.map((rule) => + getSavedObjectRuleEnable(rule, !rule.attributes.enabled) + ), + }); }); it('updates the rules from within the flyout', () => { @@ -370,6 +427,9 @@ describe('', () => { const { mutate } = useBulkUpdateCspRules(); expect(mutate).toHaveBeenCalledTimes(1); - expect(mutate).toHaveBeenCalledWith([{ ...rule.attributes, enabled: !enabled }]); + expect(mutate).toHaveBeenCalledWith({ + packagePolicyId: params.packagePolicyId, + savedObjectRules: [getSavedObjectRuleEnable(rule, !rule.attributes.enabled)], + }); }); }); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.tsx index cf77fba3c513f..e7bc2d5c1b344 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.tsx @@ -16,6 +16,7 @@ import { import { useParams } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n-react'; import { pagePathGetters } from '@kbn/fleet-plugin/public'; +import { cspRuleAssetSavedObjectType } from '../../../common/schemas/csp_rule'; import { extractErrorMessage, isNonNullable } from '../../../common/utils/helpers'; import { RulesTable } from './rules_table'; import { RulesBottomBar } from './rules_bottom_bar'; @@ -81,7 +82,7 @@ const getRulesPageData = ( error: error ? extractErrorMessage(error) : undefined, all_rules: rules, rules_map: new Map(rules.map((rule) => [rule.id, rule])), - rules_page: page.map((rule) => changedRules.get(rule.attributes.id) || rule), + rules_page: page.map((rule) => changedRules.get(rule.id) || rule), total: data?.total || 0, lastModified: getLastModified(rules) || null, }; @@ -107,9 +108,15 @@ export const RulesContainer = () => { const [selectedRuleId, setSelectedRuleId] = useState(null); const [isAllSelected, setIsAllSelected] = useState(false); const [visibleSelectedRulesIds, setVisibleSelectedRulesIds] = useState([]); - const [rulesQuery, setRulesQuery] = useState({ page: 0, perPage: 5, search: '' }); + const [rulesQuery, setRulesQuery] = useState({ + filter: `${cspRuleAssetSavedObjectType}.attributes.policy_id: "${params.policyId}" and ${cspRuleAssetSavedObjectType}.attributes.package_policy_id: "${params.packagePolicyId}"`, + search: '', + page: 0, + perPage: 5, + }); const { data, status, error, refetch } = useFindCspRules({ + filter: rulesQuery.filter, search: getSimpleQueryString(rulesQuery.search), page: 1, perPage: MAX_ITEMS_PER_PAGE, @@ -152,7 +159,11 @@ export const RulesContainer = () => { const toggleRule = (rule: RuleSavedObject) => toggleRules([rule], !rule.attributes.enabled); - const bulkUpdateRules = () => bulkUpdate([...changedRules].map(([, rule]) => rule.attributes)); + const bulkUpdateRules = () => + bulkUpdate({ + savedObjectRules: [...changedRules].map(([, savedObjectRule]) => savedObjectRule), + packagePolicyId: params.packagePolicyId, + }); const discardChanges = useCallback(() => setChangedRules(new Map()), []); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_flyout.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_flyout.tsx index 54657660c7aa4..f21ca53b76649 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_flyout.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_flyout.tsx @@ -146,7 +146,7 @@ const RuleOverviewTab = ({ rule, toggleRule }: { rule: RuleSavedObject; toggleRu label={TEXT.ACTIVATED} checked={rule.attributes.enabled} onChange={toggleRule} - data-test-subj={TEST_SUBJECTS.getCspRulesTableItemSwitchTestId(rule.attributes.id)} + data-test-subj={TEST_SUBJECTS.getCspRulesTableItemSwitchTestId(rule.id)} /> diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_table.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_table.tsx index c577daebb58a6..704b87697094c 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_table.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_table.tsx @@ -148,7 +148,7 @@ const getColumns = ({ label={enabled ? TEXT.DISABLE : TEXT.ENABLE} checked={enabled} onChange={() => toggleRule(rule)} - data-test-subj={TEST_SUBJECTS.getCspRulesTableItemSwitchTestId(rule.attributes.id)} + data-test-subj={TEST_SUBJECTS.getCspRulesTableItemSwitchTestId(rule.id)} /> ), diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts b/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts index 87f06fe70df76..2ce088cd5c29b 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts @@ -7,6 +7,7 @@ import { useQuery, useMutation, useQueryClient } from 'react-query'; import { FunctionKeys } from 'utility-types'; import type { SavedObjectsFindOptions, SimpleSavedObject } from '@kbn/core/public'; +import { UPDATE_RULES_CONFIG_ROUTE_PATH } from '../../../common/constants'; import { cspRuleAssetSavedObjectType, type CspRuleSchema } from '../../../common/schemas/csp_rule'; import { useKibana } from '../../common/hooks/use_kibana'; import { UPDATE_FAILED } from './translations'; @@ -16,11 +17,14 @@ export type RuleSavedObject = Omit< FunctionKeys >; -export type RulesQuery = Required>; +export type RulesQuery = Required< + Pick +>; export type RulesQueryResult = ReturnType; -export const useFindCspRules = ({ search, page, perPage }: RulesQuery) => { +export const useFindCspRules = ({ search, page, perPage, filter }: RulesQuery) => { const { savedObjects } = useKibana().services; + return useQuery( [cspRuleAssetSavedObjectType, { search, page, perPage }], () => @@ -32,24 +36,37 @@ export const useFindCspRules = ({ search, page, perPage }: RulesQuery) => { // NOTE: 'name.raw' is a field mapping we defined on 'name' sortField: 'name.raw', perPage, + filter, }), { refetchOnWindowFocus: false } ); }; export const useBulkUpdateCspRules = () => { - const { savedObjects, notifications } = useKibana().services; + const { savedObjects, notifications, http } = useKibana().services; const queryClient = useQueryClient(); return useMutation( - (rules: CspRuleSchema[]) => - savedObjects.client.bulkUpdate( - rules.map((rule) => ({ + async ({ + savedObjectRules, + packagePolicyId, + }: { + savedObjectRules: RuleSavedObject[]; + packagePolicyId: CspRuleSchema['package_policy_id']; + }) => { + await savedObjects.client.bulkUpdate( + savedObjectRules.map((savedObjectRule) => ({ type: cspRuleAssetSavedObjectType, - id: rule.id, - attributes: rule, + id: savedObjectRule.id, + attributes: savedObjectRule.attributes, })) - ), + ); + await http.post(UPDATE_RULES_CONFIG_ROUTE_PATH, { + body: JSON.stringify({ + package_policy_id: packagePolicyId, + }), + }); + }, { onError: (err) => { if (err instanceof Error) notifications.toasts.addError(err, { title: UPDATE_FAILED }); diff --git a/x-pack/plugins/cloud_security_posture/server/create_indices/create_transforms_indices.ts b/x-pack/plugins/cloud_security_posture/server/create_indices/create_transforms_indices.ts index c30bf09a60e0f..4ee09119c15e4 100644 --- a/x-pack/plugins/cloud_security_posture/server/create_indices/create_transforms_indices.ts +++ b/x-pack/plugins/cloud_security_posture/server/create_indices/create_transforms_indices.ts @@ -10,9 +10,9 @@ import type { ElasticsearchClient, Logger } from '@kbn/core/server'; import { benchmarkScoreMapping } from './benchmark_score_mapping'; import { latestFindingsMapping } from './latest_findings_mapping'; import { - LATEST_FINDINGS_INDEX_PATTERN, + LATEST_FINDINGS_INDEX_DEFAULT_NS, LATEST_FINDINGS_INDEX_NAME, - BENCHMARK_SCORE_INDEX_PATTERN, + BENCHMARK_SCORE_INDEX_DEFAULT_NS, BENCHMARK_SCORE_INDEX_NAME, } from '../../common/constants'; @@ -25,14 +25,14 @@ export const initializeCspTransformsIndices = async ( createIndexIfNotExists( esClient, LATEST_FINDINGS_INDEX_NAME, - LATEST_FINDINGS_INDEX_PATTERN, + LATEST_FINDINGS_INDEX_DEFAULT_NS, latestFindingsMapping, logger ), createIndexIfNotExists( esClient, BENCHMARK_SCORE_INDEX_NAME, - BENCHMARK_SCORE_INDEX_PATTERN, + BENCHMARK_SCORE_INDEX_DEFAULT_NS, benchmarkScoreMapping, logger ), @@ -41,7 +41,7 @@ export const initializeCspTransformsIndices = async ( export const createIndexIfNotExists = async ( esClient: ElasticsearchClient, - indexName: string, + indexTemplateName: string, indexPattern: string, mappings: MappingTypeMapping, logger: Logger @@ -53,7 +53,7 @@ export const createIndexIfNotExists = async ( if (!isLatestIndexExists) { await esClient.indices.putIndexTemplate({ - name: indexName, + name: indexTemplateName, index_patterns: indexPattern, template: { mappings }, priority: 500, @@ -65,7 +65,7 @@ export const createIndexIfNotExists = async ( } } catch (err) { const error = transformError(err); - logger.error(`Failed to create ${LATEST_FINDINGS_INDEX_PATTERN}`); + logger.error(`Failed to create the index template: ${indexTemplateName}`); logger.error(error.message); } }; diff --git a/x-pack/plugins/cloud_security_posture/server/create_indices/latest_findings_mapping.ts b/x-pack/plugins/cloud_security_posture/server/create_indices/latest_findings_mapping.ts index 4392cc5a47d30..80c35083e09a4 100644 --- a/x-pack/plugins/cloud_security_posture/server/create_indices/latest_findings_mapping.ts +++ b/x-pack/plugins/cloud_security_posture/server/create_indices/latest_findings_mapping.ts @@ -103,6 +103,24 @@ export const latestFindingsMapping: MappingTypeMapping = { }, }, }, + section: { + type: 'text', + fields: { + keyword: { + ignore_above: 1024, + type: 'keyword', + }, + }, + }, + }, + }, + cluster_id: { + type: 'text', + fields: { + keyword: { + ignore_above: 1024, + type: 'keyword', + }, }, }, }, diff --git a/x-pack/plugins/cloud_security_posture/server/create_transforms/benchmark_score_transform.ts b/x-pack/plugins/cloud_security_posture/server/create_transforms/benchmark_score_transform.ts index 8837fea0fa183..19528d42f09af 100644 --- a/x-pack/plugins/cloud_security_posture/server/create_transforms/benchmark_score_transform.ts +++ b/x-pack/plugins/cloud_security_posture/server/create_transforms/benchmark_score_transform.ts @@ -7,18 +7,18 @@ import type { TransformPutTransformRequest } from '@elastic/elasticsearch/lib/api/types'; import { - LATEST_FINDINGS_INDEX_PATTERN, - BENCHMARK_SCORE_INDEX_PATTERN, + LATEST_FINDINGS_INDEX_DEFAULT_NS, + BENCHMARK_SCORE_INDEX_DEFAULT_NS, } from '../../common/constants'; export const benchmarkScoreTransform: TransformPutTransformRequest = { transform_id: 'cloud_security_posture.score-default-0.0.1', description: 'Calculate latest findings score', source: { - index: LATEST_FINDINGS_INDEX_PATTERN, + index: LATEST_FINDINGS_INDEX_DEFAULT_NS, }, dest: { - index: BENCHMARK_SCORE_INDEX_PATTERN, + index: BENCHMARK_SCORE_INDEX_DEFAULT_NS, }, frequency: '30m', sync: { diff --git a/x-pack/plugins/cloud_security_posture/server/create_transforms/create_transforms.ts b/x-pack/plugins/cloud_security_posture/server/create_transforms/create_transforms.ts index 3347d5f36b5d8..02217aea35210 100644 --- a/x-pack/plugins/cloud_security_posture/server/create_transforms/create_transforms.ts +++ b/x-pack/plugins/cloud_security_posture/server/create_transforms/create_transforms.ts @@ -11,8 +11,11 @@ import { latestFindingsTransform } from './latest_findings_transform'; import { benchmarkScoreTransform } from './benchmark_score_transform'; // TODO: Move transforms to integration package -export const initializeCspTransforms = async (esClient: ElasticsearchClient, logger: Logger) => { - return Promise.all([ +export const initializeCspTransforms = async ( + esClient: ElasticsearchClient, + logger: Logger +): Promise => { + await Promise.all([ initializeTransform(esClient, latestFindingsTransform, logger), initializeTransform(esClient, benchmarkScoreTransform, logger), ]); diff --git a/x-pack/plugins/cloud_security_posture/server/create_transforms/latest_findings_transform.ts b/x-pack/plugins/cloud_security_posture/server/create_transforms/latest_findings_transform.ts index fc042149f3193..fb8027a7675d2 100644 --- a/x-pack/plugins/cloud_security_posture/server/create_transforms/latest_findings_transform.ts +++ b/x-pack/plugins/cloud_security_posture/server/create_transforms/latest_findings_transform.ts @@ -5,7 +5,7 @@ * 2.0. */ import type { TransformPutTransformRequest } from '@elastic/elasticsearch/lib/api/types'; -import { FINDINGS_INDEX_PATTERN, LATEST_FINDINGS_INDEX_PATTERN } from '../../common/constants'; +import { FINDINGS_INDEX_PATTERN, LATEST_FINDINGS_INDEX_DEFAULT_NS } from '../../common/constants'; export const latestFindingsTransform: TransformPutTransformRequest = { transform_id: 'cloud_security_posture.findings_latest-default-0.0.1', @@ -14,7 +14,7 @@ export const latestFindingsTransform: TransformPutTransformRequest = { index: FINDINGS_INDEX_PATTERN, }, dest: { - index: LATEST_FINDINGS_INDEX_PATTERN, + index: LATEST_FINDINGS_INDEX_DEFAULT_NS, }, frequency: '5m', sync: { diff --git a/x-pack/plugins/cloud_security_posture/server/fleet_integration/fleet_integration.test.ts b/x-pack/plugins/cloud_security_posture/server/fleet_integration/fleet_integration.test.ts index 8872c359fc770..69e13ab8c5065 100644 --- a/x-pack/plugins/cloud_security_posture/server/fleet_integration/fleet_integration.test.ts +++ b/x-pack/plugins/cloud_security_posture/server/fleet_integration/fleet_integration.test.ts @@ -8,7 +8,7 @@ import { loggingSystemMock, savedObjectsClientMock } from '@kbn/core/server/mocks'; import { SavedObjectsClientContract, SavedObjectsFindResponse } from '@kbn/core/server'; import { createPackagePolicyMock } from '@kbn/fleet-plugin/common/mocks'; -import { CIS_KUBERNETES_PACKAGE_NAME } from '../../common/constants'; +import { CLOUD_SECURITY_POSTURE_PACKAGE_NAME } from '../../common/constants'; import { onPackagePolicyPostCreateCallback } from './fleet_integration'; describe('create CSP rules with post package create callback', () => { @@ -40,7 +40,7 @@ describe('create CSP rules with post package create callback', () => { }); it('should create stateful rules based on rule template', async () => { const mockPackagePolicy = createPackagePolicyMock(); - mockPackagePolicy.package!.name = CIS_KUBERNETES_PACKAGE_NAME; + mockPackagePolicy.package!.name = CLOUD_SECURITY_POSTURE_PACKAGE_NAME; mockSoClient.find.mockResolvedValueOnce({ saved_objects: [ { diff --git a/x-pack/plugins/cloud_security_posture/server/fleet_integration/fleet_integration.ts b/x-pack/plugins/cloud_security_posture/server/fleet_integration/fleet_integration.ts index 521252f1558e4..da45a53256bde 100644 --- a/x-pack/plugins/cloud_security_posture/server/fleet_integration/fleet_integration.ts +++ b/x-pack/plugins/cloud_security_posture/server/fleet_integration/fleet_integration.ts @@ -17,7 +17,7 @@ import { cloudSecurityPostureRuleTemplateSavedObjectType, CloudSecurityPostureRuleTemplateSchema, } from '../../common/schemas/csp_rule_template'; -import { CIS_KUBERNETES_PACKAGE_NAME } from '../../common/constants'; +import { CLOUD_SECURITY_POSTURE_PACKAGE_NAME } from '../../common/constants'; import { CspRuleSchema, cspRuleAssetSavedObjectType } from '../../common/schemas/csp_rule'; type ArrayElement = ArrayType extends ReadonlyArray< @@ -29,7 +29,7 @@ type ArrayElement = ArrayType extends Read const isCspPackagePolicy = ( packagePolicy: T ): boolean => { - return packagePolicy.package?.name === CIS_KUBERNETES_PACKAGE_NAME; + return packagePolicy.package?.name === CLOUD_SECURITY_POSTURE_PACKAGE_NAME; }; /** @@ -79,7 +79,7 @@ export const onPackagePolicyDeleteCallback = async ( const { saved_objects: cspRules }: SavedObjectsFindResponse = await soClient.find({ type: cspRuleAssetSavedObjectType, - filter: `csp_rule.attributes.package_policy_id: ${deletedPackagePolicy.id} AND csp_rule.attributes.policy_id: ${deletedPackagePolicy.policy_id}`, + filter: `${cspRuleAssetSavedObjectType}.attributes.package_policy_id: ${deletedPackagePolicy.id} AND ${cspRuleAssetSavedObjectType}.attributes.policy_id: ${deletedPackagePolicy.policy_id}`, }); await Promise.all( cspRules.map((rule) => soClient.delete(cspRuleAssetSavedObjectType, rule.id)) diff --git a/x-pack/plugins/cloud_security_posture/server/plugin.test.ts b/x-pack/plugins/cloud_security_posture/server/plugin.test.ts new file mode 100644 index 0000000000000..43dc550a677a9 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/server/plugin.test.ts @@ -0,0 +1,202 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { coreMock, httpServerMock, savedObjectsClientMock } from '@kbn/core/server/mocks'; +import { + createPackagePolicyServiceMock, + createArtifactsClientMock, + createMockPackageService, + createMockAgentService, + createMockAgentPolicyService, +} from '@kbn/fleet-plugin/server/mocks'; + +import { createPackagePolicyMock } from '@kbn/fleet-plugin/common/mocks'; +import { dataPluginMock } from '@kbn/data-plugin/server/mocks'; +import { CspPlugin } from './plugin'; +import { CspServerPluginStartDeps } from './types'; +import { createFleetAuthzMock, Installation } from '@kbn/fleet-plugin/common'; +import { + ExternalCallback, + FleetStartContract, + PostPackagePolicyPostCreateCallback, +} from '@kbn/fleet-plugin/server'; +import { CLOUD_SECURITY_POSTURE_PACKAGE_NAME } from '../common/constants'; +import Chance from 'chance'; +import type { AwaitedProperties } from '@kbn/utility-types'; +import type { DeeplyMockedKeys } from '@kbn/utility-types/jest'; +import { RequestHandlerContext } from '@kbn/core/server'; + +const chance = new Chance(); + +const mockRouteContext = { + core: { + savedObjects: { + client: savedObjectsClientMock.create(), + }, + }, +} as unknown as AwaitedProperties; + +const createMockFleetStartContract = (): DeeplyMockedKeys => { + return { + authz: { + fromRequest: jest.fn(async (_) => createFleetAuthzMock()), + }, + fleetSetupCompleted: jest.fn().mockResolvedValue(undefined), + esIndexPatternService: { + getESIndexPattern: jest.fn().mockResolvedValue(undefined), + }, + // @ts-expect-error 2322 + agentService: createMockAgentService(), + // @ts-expect-error 2322 + packageService: createMockPackageService(), + agentPolicyService: createMockAgentPolicyService(), + registerExternalCallback: jest.fn((..._: ExternalCallback) => {}), + packagePolicyService: createPackagePolicyServiceMock(), + createArtifactsClient: jest.fn().mockReturnValue(createArtifactsClientMock()), + }; +}; + +describe('Cloud Security Posture Plugin', () => { + describe('start()', () => { + const fleetMock = createMockFleetStartContract(); + const mockPlugins: CspServerPluginStartDeps = { + fleet: fleetMock, + data: dataPluginMock.createStartContract(), + }; + + const contextMock = coreMock.createCustomRequestHandlerContext(mockRouteContext); + const findMock = mockRouteContext.core.savedObjects.client.find as jest.Mock; + findMock.mockReturnValue( + Promise.resolve({ + saved_objects: [], + total: 0, + per_page: 0, + page: 1, + }) + ); + + let plugin: CspPlugin; + + beforeEach(() => jest.clearAllMocks()); + + it('should initialize when package installed', async () => { + fleetMock.packageService.asInternalUser.getInstallation.mockImplementationOnce( + async (): Promise => { + return {} as jest.Mocked; + } + ); + + const context = coreMock.createPluginInitializerContext(); + plugin = new CspPlugin(context); + const spy = jest.spyOn(plugin, 'initialize').mockImplementation(); + + // Act + await plugin.start(coreMock.createStart(), mockPlugins); + await mockPlugins.fleet.fleetSetupCompleted(); + + // Assert + expect(fleetMock.packageService.asInternalUser.getInstallation).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledTimes(1); + }); + + it('should not initialize when package is not installed', async () => { + fleetMock.packageService.asInternalUser.getInstallation.mockImplementationOnce( + async (): Promise => { + return; + } + ); + + const context = coreMock.createPluginInitializerContext(); + plugin = new CspPlugin(context); + const spy = jest.spyOn(plugin, 'initialize').mockImplementation(); + + // Act + await plugin.start(coreMock.createStart(), mockPlugins); + await mockPlugins.fleet.fleetSetupCompleted(); + + // Assert + expect(fleetMock.packageService.asInternalUser.getInstallation).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledTimes(0); + }); + + it('should initialize when new package is created', async () => { + fleetMock.packageService.asInternalUser.getInstallation.mockImplementationOnce( + async (): Promise => { + return; + } + ); + + const packageMock = createPackagePolicyMock(); + packageMock.package!.name = CLOUD_SECURITY_POSTURE_PACKAGE_NAME; + + const packagePolicyPostCreateCallbacks: PostPackagePolicyPostCreateCallback[] = []; + fleetMock.registerExternalCallback.mockImplementation((...args) => { + if (args[0] === 'packagePolicyPostCreate') { + packagePolicyPostCreateCallbacks.push(args[1]); + } + }); + + const context = coreMock.createPluginInitializerContext(); + plugin = new CspPlugin(context); + const spy = jest.spyOn(plugin, 'initialize').mockImplementation(); + + // Act + await plugin.start(coreMock.createStart(), mockPlugins); + await mockPlugins.fleet.fleetSetupCompleted(); + + // Assert + expect(fleetMock.packageService.asInternalUser.getInstallation).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledTimes(0); + + expect(packagePolicyPostCreateCallbacks.length).toBeGreaterThan(0); + + for (const cb of packagePolicyPostCreateCallbacks) { + await cb(packageMock, contextMock, httpServerMock.createKibanaRequest()); + } + + expect(spy).toHaveBeenCalledTimes(1); + }); + + it('should not initialize when other package is created', async () => { + fleetMock.packageService.asInternalUser.getInstallation.mockImplementationOnce( + async (): Promise => { + return; + } + ); + + const packageMock = createPackagePolicyMock(); + packageMock.package!.name = chance.word(); + + const packagePolicyPostCreateCallbacks: PostPackagePolicyPostCreateCallback[] = []; + fleetMock.registerExternalCallback.mockImplementation((...args) => { + if (args[0] === 'packagePolicyPostCreate') { + packagePolicyPostCreateCallbacks.push(args[1]); + } + }); + + const context = coreMock.createPluginInitializerContext(); + plugin = new CspPlugin(context); + const spy = jest.spyOn(plugin, 'initialize').mockImplementation(); + + // Act + await plugin.start(coreMock.createStart(), mockPlugins); + await mockPlugins.fleet.fleetSetupCompleted(); + + // Assert + expect(fleetMock.packageService.asInternalUser.getInstallation).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledTimes(0); + + expect(packagePolicyPostCreateCallbacks.length).toBeGreaterThan(0); + + for (const cb of packagePolicyPostCreateCallbacks) { + await cb(packageMock, contextMock, httpServerMock.createKibanaRequest()); + } + + expect(spy).toHaveBeenCalledTimes(0); + }); + }); +}); diff --git a/x-pack/plugins/cloud_security_posture/server/plugin.ts b/x-pack/plugins/cloud_security_posture/server/plugin.ts index 99900d4aed0d4..d9fdea9488036 100755 --- a/x-pack/plugins/cloud_security_posture/server/plugin.ts +++ b/x-pack/plugins/cloud_security_posture/server/plugin.ts @@ -6,13 +6,14 @@ */ import type { + KibanaRequest, + RequestHandlerContext, PluginInitializerContext, CoreSetup, CoreStart, Plugin, Logger, } from '@kbn/core/server'; -import { KibanaRequest, RequestHandlerContext } from '@kbn/core/server'; import { DeepReadonly } from 'utility-types'; import { DeletePackagePoliciesResponse, PackagePolicy } from '@kbn/fleet-plugin/common'; import { CspAppService } from './lib/csp_app_services'; @@ -27,11 +28,12 @@ import { defineRoutes } from './routes'; import { cspRuleTemplateAssetType } from './saved_objects/csp_rule_template'; import { cspRuleAssetType } from './saved_objects/csp_rule_type'; import { initializeCspTransformsIndices } from './create_indices/create_transforms_indices'; +import { initializeCspTransforms } from './create_transforms/create_transforms'; import { onPackagePolicyPostCreateCallback, onPackagePolicyDeleteCallback, } from './fleet_integration/fleet_integration'; -import { CIS_KUBERNETES_PACKAGE_NAME } from '../common/constants'; +import { CLOUD_SECURITY_POSTURE_PACKAGE_NAME } from '../common/constants'; export interface CspAppContext { logger: Logger; @@ -48,9 +50,11 @@ export class CspPlugin > { private readonly logger: Logger; + constructor(initializerContext: PluginInitializerContext) { this.logger = initializerContext.logger.get(); } + private readonly CspAppService = new CspAppService(); public setup( @@ -78,21 +82,28 @@ export class CspPlugin ...plugins.fleet, }); - initializeCspTransformsIndices(core.elasticsearch.client.asInternalUser, this.logger); - plugins.fleet.fleetSetupCompleted().then(() => { + plugins.fleet.fleetSetupCompleted().then(async () => { + const packageInfo = await plugins.fleet.packageService.asInternalUser.getInstallation( + CLOUD_SECURITY_POSTURE_PACKAGE_NAME + ); + + // If package is installed we want to make sure all needed assets are installed + if (packageInfo) { + // noinspection ES6MissingAwait + this.initialize(core); + } + plugins.fleet.registerExternalCallback( 'packagePolicyPostCreate', async ( packagePolicy: PackagePolicy, context: RequestHandlerContext, - request: KibanaRequest + _: KibanaRequest ): Promise => { - if (packagePolicy.package?.name === CIS_KUBERNETES_PACKAGE_NAME) { - await onPackagePolicyPostCreateCallback( - this.logger, - packagePolicy, - context.core.savedObjects.client - ); + if (packagePolicy.package?.name === CLOUD_SECURITY_POSTURE_PACKAGE_NAME) { + await this.initialize(core); + const soClient = (await context.core).savedObjects.client; + await onPackagePolicyPostCreateCallback(this.logger, packagePolicy, soClient); } return packagePolicy; @@ -103,7 +114,7 @@ export class CspPlugin 'postPackagePolicyDelete', async (deletedPackagePolicies: DeepReadonly) => { for (const deletedPackagePolicy of deletedPackagePolicies) { - if (deletedPackagePolicy.package?.name === CIS_KUBERNETES_PACKAGE_NAME) { + if (deletedPackagePolicy.package?.name === CLOUD_SECURITY_POSTURE_PACKAGE_NAME) { await onPackagePolicyDeleteCallback( this.logger, deletedPackagePolicy, @@ -117,5 +128,12 @@ export class CspPlugin return {}; } + public stop() {} + + async initialize(core: CoreStart): Promise { + this.logger.debug('initialize'); + await initializeCspTransformsIndices(core.elasticsearch.client.asInternalUser, this.logger); + await initializeCspTransforms(core.elasticsearch.client.asInternalUser, this.logger); + } } diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts index f0c1dc6e1bf96..a2cb7d06f1f58 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts @@ -19,7 +19,10 @@ import type { AgentPolicy, ListResult, } from '@kbn/fleet-plugin/common'; -import { BENCHMARKS_ROUTE_PATH, CIS_KUBERNETES_PACKAGE_NAME } from '../../../common/constants'; +import { + BENCHMARKS_ROUTE_PATH, + CLOUD_SECURITY_POSTURE_PACKAGE_NAME, +} from '../../../common/constants'; import { BENCHMARK_PACKAGE_POLICY_PREFIX, benchmarksInputSchema, @@ -146,12 +149,12 @@ export const defineGetBenchmarksRoute = (router: CspRouter, cspContext: CspAppCo validate: { query: benchmarksInputSchema }, }, async (context, request, response) => { - if (!context.fleet.authz.fleet.all) { + if (!(await context.fleet).authz.fleet.all) { return response.forbidden(); } try { - const soClient = context.core.savedObjects.client; + const soClient = (await context.core).savedObjects.client; const { query } = request; const agentService = cspContext.service.agentService; @@ -165,7 +168,7 @@ export const defineGetBenchmarksRoute = (router: CspRouter, cspContext: CspAppCo const packagePolicies = await getPackagePolicies( soClient, packagePolicyService, - CIS_KUBERNETES_PACKAGE_NAME, + CLOUD_SECURITY_POSTURE_PACKAGE_NAME, query ); diff --git a/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/compliance_dashboard.ts b/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/compliance_dashboard.ts index c271208120ae4..1a95737df0ad9 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/compliance_dashboard.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/compliance_dashboard.ts @@ -8,9 +8,9 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; import type { ComplianceDashboardData } from '../../../common/types'; -import { LATEST_FINDINGS_INDEX_PATTERN, STATS_ROUTE_PATH } from '../../../common/constants'; +import { LATEST_FINDINGS_INDEX_DEFAULT_NS, STATS_ROUTE_PATH } from '../../../common/constants'; import { CspAppContext } from '../../plugin'; -import { getResourcesTypes } from './get_resources_types'; +import { getGroupedFindingsEvaluation } from './get_grouped_findings_evaluation'; import { ClusterWithoutTrend, getClusters } from './get_clusters'; import { getStats } from './get_stats'; import { CspRouter } from '../../types'; @@ -44,10 +44,10 @@ export const defineGetComplianceDashboardRoute = ( }, async (context, _, response) => { try { - const esClient = context.core.elasticsearch.client.asCurrentUser; + const esClient = (await context.core).elasticsearch.client.asCurrentUser; const { id: pitId } = await esClient.openPointInTime({ - index: LATEST_FINDINGS_INDEX_PATTERN, + index: LATEST_FINDINGS_INDEX_DEFAULT_NS, keep_alive: '30s', }); @@ -55,12 +55,14 @@ export const defineGetComplianceDashboardRoute = ( match_all: {}, }; - const [stats, resourcesTypes, clustersWithoutTrends, trends] = await Promise.all([ - getStats(esClient, query, pitId), - getResourcesTypes(esClient, query, pitId), - getClusters(esClient, query, pitId), - getTrends(esClient), - ]); + const [stats, groupedFindingsEvaluation, clustersWithoutTrends, trends] = await Promise.all( + [ + getStats(esClient, query, pitId), + getGroupedFindingsEvaluation(esClient, query, pitId), + getClusters(esClient, query, pitId), + getTrends(esClient), + ] + ); // Try closing the PIT, if it fails we can safely ignore the error since it closes itself after the keep alive // ends. Not waiting on the promise returned from the `closePointInTime` call to avoid delaying the request @@ -73,7 +75,7 @@ export const defineGetComplianceDashboardRoute = ( const body: ComplianceDashboardData = { stats, - resourcesTypes, + groupedFindingsEvaluation, clusters, trend, }; diff --git a/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_clusters.test.ts b/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_clusters.test.ts index 1630d4fe3537f..a24e60dd7be8f 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_clusters.test.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_clusters.test.ts @@ -66,7 +66,7 @@ describe('getClustersFromAggs', () => { totalPassed: 6, postureScore: 50.0, }, - resourcesTypes: [ + groupedFindingsEvaluation: [ { name: 'foo_type', totalFindings: 6, diff --git a/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_clusters.ts b/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_clusters.ts index 4a4afda9a12b2..239511f71fea3 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_clusters.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_clusters.ts @@ -12,14 +12,17 @@ import type { SearchRequest, } from '@elastic/elasticsearch/lib/api/types'; import { Cluster } from '../../../common/types'; -import { getResourceTypeFromAggs, resourceTypeAggQuery } from './get_resources_types'; -import type { ResourceTypeQueryResult } from './get_resources_types'; +import { + getFailedFindingsFromAggs, + failedFindingsAggQuery, +} from './get_grouped_findings_evaluation'; +import type { FailedFindingsQueryResult } from './get_grouped_findings_evaluation'; import { findingsEvaluationAggsQuery, getStatsFromFindingsEvaluationsAggs } from './get_stats'; import { KeyDocCount } from './compliance_dashboard'; type UnixEpochTime = number; -export interface ClusterBucket extends ResourceTypeQueryResult, KeyDocCount { +export interface ClusterBucket extends FailedFindingsQueryResult, KeyDocCount { failed_findings: { doc_count: number; }; @@ -59,7 +62,7 @@ export const getClustersQuery = (query: QueryDslQueryContainer, pitId: string): }, }, }, - ...resourceTypeAggQuery, + ...failedFindingsAggQuery, ...findingsEvaluationAggsQuery, }, }, @@ -92,12 +95,12 @@ export const getClustersFromAggs = (clusters: ClusterBucket[]): ClusterWithoutTr const resourcesTypesAggs = cluster.aggs_by_resource_type.buckets; if (!Array.isArray(resourcesTypesAggs)) throw new Error('missing aggs by resource type per cluster'); - const resourcesTypes = getResourceTypeFromAggs(resourcesTypesAggs); + const groupedFindingsEvaluation = getFailedFindingsFromAggs(resourcesTypesAggs); return { meta, stats, - resourcesTypes, + groupedFindingsEvaluation, }; }); diff --git a/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_grouped_findings_evaluation.test.ts b/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_grouped_findings_evaluation.test.ts new file mode 100644 index 0000000000000..46c73c4250157 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_grouped_findings_evaluation.test.ts @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { getFailedFindingsFromAggs, FailedFindingsBucket } from './get_grouped_findings_evaluation'; + +const resourceTypeBuckets: FailedFindingsBucket[] = [ + { + key: 'foo_type', + doc_count: 41, + failed_findings: { + doc_count: 30, + }, + passed_findings: { + doc_count: 11, + }, + }, + { + key: 'boo_type', + doc_count: 11, + failed_findings: { + doc_count: 5, + }, + passed_findings: { + doc_count: 6, + }, + }, +]; + +describe('getFailedFindingsFromAggs', () => { + it('should return value matching ComplianceDashboardData["resourcesTypes"]', async () => { + const resourceTypes = getFailedFindingsFromAggs(resourceTypeBuckets); + expect(resourceTypes).toEqual([ + { + name: 'foo_type', + totalFindings: 41, + totalFailed: 30, + totalPassed: 11, + }, + { + name: 'boo_type', + totalFindings: 11, + totalFailed: 5, + totalPassed: 6, + }, + ]); + }); +}); diff --git a/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_grouped_findings_evaluation.ts b/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_grouped_findings_evaluation.ts new file mode 100644 index 0000000000000..66e5e8e271a26 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_grouped_findings_evaluation.ts @@ -0,0 +1,80 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ElasticsearchClient } from '@kbn/core/server'; +import type { + AggregationsMultiBucketAggregateBase as Aggregation, + QueryDslQueryContainer, + SearchRequest, +} from '@elastic/elasticsearch/lib/api/types'; +import type { ComplianceDashboardData } from '../../../common/types'; +import { KeyDocCount } from './compliance_dashboard'; + +export interface FailedFindingsQueryResult { + aggs_by_resource_type: Aggregation; +} + +export interface FailedFindingsBucket extends KeyDocCount { + failed_findings: { + doc_count: number; + }; + passed_findings: { + doc_count: number; + }; +} + +export const failedFindingsAggQuery = { + aggs_by_resource_type: { + terms: { + field: 'rule.section.keyword', + }, + aggs: { + failed_findings: { + filter: { term: { 'result.evaluation.keyword': 'failed' } }, + }, + passed_findings: { + filter: { term: { 'result.evaluation.keyword': 'passed' } }, + }, + }, + }, +}; + +export const getRisksEsQuery = (query: QueryDslQueryContainer, pitId: string): SearchRequest => ({ + size: 0, + query, + aggs: failedFindingsAggQuery, + pit: { + id: pitId, + }, +}); + +export const getFailedFindingsFromAggs = ( + queryResult: FailedFindingsBucket[] +): ComplianceDashboardData['groupedFindingsEvaluation'] => + queryResult.map((bucket) => ({ + name: bucket.key, + totalFindings: bucket.doc_count, + totalFailed: bucket.failed_findings.doc_count || 0, + totalPassed: bucket.passed_findings.doc_count || 0, + })); + +export const getGroupedFindingsEvaluation = async ( + esClient: ElasticsearchClient, + query: QueryDslQueryContainer, + pitId: string +): Promise => { + const resourceTypesQueryResult = await esClient.search( + getRisksEsQuery(query, pitId) + ); + + const ruleSections = resourceTypesQueryResult.aggregations?.aggs_by_resource_type.buckets; + if (!Array.isArray(ruleSections)) { + return []; + } + + return getFailedFindingsFromAggs(ruleSections); +}; diff --git a/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_resources_types.test.ts b/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_resources_types.test.ts deleted file mode 100644 index 411290738f33e..0000000000000 --- a/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_resources_types.test.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { getResourceTypeFromAggs, ResourceTypeBucket } from './get_resources_types'; - -const resourceTypeBuckets: ResourceTypeBucket[] = [ - { - key: 'foo_type', - doc_count: 41, - failed_findings: { - doc_count: 30, - }, - passed_findings: { - doc_count: 11, - }, - }, - { - key: 'boo_type', - doc_count: 11, - failed_findings: { - doc_count: 5, - }, - passed_findings: { - doc_count: 6, - }, - }, -]; - -describe('getResourceTypeFromAggs', () => { - it('should return value matching ComplianceDashboardData["resourcesTypes"]', async () => { - const resourceTypes = getResourceTypeFromAggs(resourceTypeBuckets); - expect(resourceTypes).toEqual([ - { - name: 'foo_type', - totalFindings: 41, - totalFailed: 30, - totalPassed: 11, - }, - { - name: 'boo_type', - totalFindings: 11, - totalFailed: 5, - totalPassed: 6, - }, - ]); - }); -}); diff --git a/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_resources_types.ts b/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_resources_types.ts deleted file mode 100644 index ecb5ee755fb64..0000000000000 --- a/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_resources_types.ts +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { ElasticsearchClient } from '@kbn/core/server'; -import type { - AggregationsMultiBucketAggregateBase as Aggregation, - QueryDslQueryContainer, - SearchRequest, -} from '@elastic/elasticsearch/lib/api/types'; -import type { ComplianceDashboardData } from '../../../common/types'; -import { KeyDocCount } from './compliance_dashboard'; - -export interface ResourceTypeQueryResult { - aggs_by_resource_type: Aggregation; -} - -export interface ResourceTypeBucket extends KeyDocCount { - failed_findings: { - doc_count: number; - }; - passed_findings: { - doc_count: number; - }; -} - -export const resourceTypeAggQuery = { - aggs_by_resource_type: { - terms: { - field: 'type.keyword', - }, - aggs: { - failed_findings: { - filter: { term: { 'result.evaluation.keyword': 'failed' } }, - }, - passed_findings: { - filter: { term: { 'result.evaluation.keyword': 'passed' } }, - }, - }, - }, -}; - -export const getRisksEsQuery = (query: QueryDslQueryContainer, pitId: string): SearchRequest => ({ - size: 0, - query, - aggs: resourceTypeAggQuery, - pit: { - id: pitId, - }, -}); - -export const getResourceTypeFromAggs = ( - queryResult: ResourceTypeBucket[] -): ComplianceDashboardData['resourcesTypes'] => - queryResult.map((bucket) => ({ - name: bucket.key, - totalFindings: bucket.doc_count, - totalFailed: bucket.failed_findings.doc_count || 0, - totalPassed: bucket.passed_findings.doc_count || 0, - })); - -export const getResourcesTypes = async ( - esClient: ElasticsearchClient, - query: QueryDslQueryContainer, - pitId: string -): Promise => { - const resourceTypesQueryResult = await esClient.search( - getRisksEsQuery(query, pitId) - ); - - const resourceTypes = resourceTypesQueryResult.aggregations?.aggs_by_resource_type.buckets; - if (!Array.isArray(resourceTypes)) throw new Error('missing resources types buckets'); - - return getResourceTypeFromAggs(resourceTypes); -}; diff --git a/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_trends.ts b/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_trends.ts index eba14cb8215c2..08d8cd3553fe2 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_trends.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/get_trends.ts @@ -6,7 +6,7 @@ */ import { ElasticsearchClient } from '@kbn/core/server'; -import { BENCHMARK_SCORE_INDEX_PATTERN } from '../../../common/constants'; +import { BENCHMARK_SCORE_INDEX_DEFAULT_NS } from '../../../common/constants'; import { Stats } from '../../../common/types'; import { calculatePostureScore } from './get_stats'; @@ -26,7 +26,7 @@ export interface ScoreTrendDoc { } export const getTrendsQuery = () => ({ - index: BENCHMARK_SCORE_INDEX_PATTERN, + index: BENCHMARK_SCORE_INDEX_DEFAULT_NS, size: 5, sort: '@timestamp:desc', }); diff --git a/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.test.ts b/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.test.ts index fda7edcf5d877..270466d2e3adf 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.test.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.test.ts @@ -110,9 +110,10 @@ describe('Update rules configuration API', () => { }); it('validate getCspRules input parameters', async () => { + const packagePolicy = createPackagePolicyMock(); mockSoClient = savedObjectsClientMock.create(); mockSoClient.find.mockResolvedValueOnce({} as SavedObjectsFindResponse); - await getCspRules(mockSoClient); + await getCspRules(mockSoClient, packagePolicy); expect(mockSoClient.find).toBeCalledTimes(1); expect(mockSoClient.find).toHaveBeenCalledWith( expect.objectContaining({ type: cspRuleAssetSavedObjectType }) @@ -127,23 +128,21 @@ describe('Update rules configuration API', () => { saved_objects: [ { type: 'csp_rule', - id: '1.1.1', - attributes: { enabled: true }, + rego_rule_id: '1.1.1', + attributes: { enabled: true, rego_rule_id: 'cis_1_1_1' }, }, { type: 'csp_rule', - id: '1.1.2', - attributes: { enabled: false }, + attributes: { enabled: false, rego_rule_id: 'cis_1_1_2' }, }, { type: 'csp_rule', - id: '1.1.3', - attributes: { enabled: true }, + attributes: { enabled: true, rego_rule_id: 'cis_1_1_3' }, }, ], - } as SavedObjectsFindResponse; + } as unknown as SavedObjectsFindResponse; const cspConfig = await createRulesConfig(cspRules); - expect(cspConfig).toMatchObject({ activated_rules: { cis_k8s: ['1.1.1', '1.1.3'] } }); + expect(cspConfig).toMatchObject({ activated_rules: { cis_k8s: ['cis_1_1_1', 'cis_1_1_3'] } }); }); it('create empty csp rules config when all rules are disabled', async () => { @@ -154,16 +153,19 @@ describe('Update rules configuration API', () => { saved_objects: [ { type: 'csp_rule', - id: '1.1.1', - attributes: { enabled: false }, + rego_rule_id: '1.1.1', + attributes: { enabled: false, rego_rule_id: 'cis_1_1_1' }, + }, + { + type: 'csp_rule', + attributes: { enabled: false, rego_rule_id: 'cis_1_1_2' }, }, { type: 'csp_rule', - id: '1.1.2', - attributes: { enabled: false }, + attributes: { enabled: false, rego_rule_id: 'cis_1_1_3' }, }, ], - } as SavedObjectsFindResponse; + } as unknown as SavedObjectsFindResponse; const cspConfig = await createRulesConfig(cspRules); expect(cspConfig).toMatchObject({ activated_rules: { cis_k8s: [] } }); }); diff --git a/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.ts b/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.ts index 91bc47a19dad9..f0e0e3b8a2bb3 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.ts @@ -22,7 +22,7 @@ import { CspAppContext } from '../../plugin'; import { CspRulesConfigSchema } from '../../../common/schemas/csp_configuration'; import { CspRuleSchema, cspRuleAssetSavedObjectType } from '../../../common/schemas/csp_rule'; import { UPDATE_RULES_CONFIG_ROUTE_PATH } from '../../../common/constants'; -import { CIS_KUBERNETES_PACKAGE_NAME } from '../../../common/constants'; +import { CLOUD_SECURITY_POSTURE_PACKAGE_NAME } from '../../../common/constants'; import { CspRouter } from '../../types'; export const getPackagePolicy = async ( @@ -36,18 +36,22 @@ export const getPackagePolicy = async ( if (!packagePolicies || !packagePolicies[0].version) { throw new Error(`package policy Id '${packagePolicyId}' is not exist`); } - if (packagePolicies[0].package?.name !== CIS_KUBERNETES_PACKAGE_NAME) { - // TODO: improve this validator to support any future CSP package - throw new Error(`Package Policy Id '${packagePolicyId}' is not CSP package`); + if (packagePolicies[0].package?.name !== CLOUD_SECURITY_POSTURE_PACKAGE_NAME) { + throw new Error( + `Package Policy Id '${packagePolicyId}' is not of type cloud security posture package` + ); } return packagePolicies![0]; }; -export const getCspRules = async (soClient: SavedObjectsClientContract) => { +export const getCspRules = async ( + soClient: SavedObjectsClientContract, + packagePolicy: PackagePolicy +) => { const cspRules = await soClient.find({ type: cspRuleAssetSavedObjectType, - search: '', + filter: `${cspRuleAssetSavedObjectType}.attributes.package_policy_id: ${packagePolicy.id} AND ${cspRuleAssetSavedObjectType}.attributes.policy_id: ${packagePolicy.policy_id}`, searchFields: ['name'], // TODO: research how to get all rules perPage: 10000, @@ -59,10 +63,9 @@ export const createRulesConfig = ( cspRules: SavedObjectsFindResponse ): CspRulesConfigSchema => { const activatedRules = cspRules.saved_objects.filter((cspRule) => cspRule.attributes.enabled); - const config = { activated_rules: { - cis_k8s: activatedRules.map((activatedRule) => activatedRule.id), + cis_k8s: activatedRules.map((activatedRule) => activatedRule.attributes.rego_rule_id), }, }; return config; @@ -103,18 +106,19 @@ export const defineUpdateRulesConfigRoute = (router: CspRouter, cspContext: CspA router.post( { path: UPDATE_RULES_CONFIG_ROUTE_PATH, - validate: { query: configurationUpdateInputSchema }, + validate: { body: configurationUpdateInputSchema }, }, async (context, request, response) => { - if (!context.fleet.authz.fleet.all) { + if (!(await context.fleet).authz.fleet.all) { return response.forbidden(); } try { - const esClient = context.core.elasticsearch.client.asCurrentUser; - const soClient = context.core.savedObjects.client; + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asCurrentUser; + const soClient = coreContext.savedObjects.client; const packagePolicyService = cspContext.service.packagePolicyService; - const packagePolicyId = request.query.package_policy_id; + const packagePolicyId = request.body.package_policy_id; if (!packagePolicyService) { throw new Error(`Failed to get Fleet services`); @@ -125,7 +129,7 @@ export const defineUpdateRulesConfigRoute = (router: CspRouter, cspContext: CspA packagePolicyId ); - const cspRules = await getCspRules(soClient); + const cspRules = await getCspRules(soClient, packagePolicy); const rulesConfig = createRulesConfig(cspRules); const dataYaml = convertRulesConfigToYaml(rulesConfig); diff --git a/x-pack/plugins/cloud_security_posture/server/routes/findings/findings.test.ts b/x-pack/plugins/cloud_security_posture/server/routes/findings/findings.test.ts deleted file mode 100644 index 35d359929af99..0000000000000 --- a/x-pack/plugins/cloud_security_posture/server/routes/findings/findings.test.ts +++ /dev/null @@ -1,505 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { - elasticsearchClientMock, - ElasticsearchClientMock, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '@kbn/core/server/elasticsearch/client/mocks'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { KibanaRequest } from '@kbn/core/server/http/router/request'; -import { httpServerMock, httpServiceMock, loggingSystemMock } from '@kbn/core/server/mocks'; -import { CspAppService } from '../../lib/csp_app_services'; -import { CspAppContext } from '../../plugin'; -import { - defineFindingsIndexRoute, - findingsInputSchema, - DEFAULT_FINDINGS_PER_PAGE, -} from './findings'; - -export const getMockCspContext = (mockEsClient: ElasticsearchClientMock): KibanaRequest => { - return { - core: { - elasticsearch: { - client: { asCurrentUser: mockEsClient }, - }, - }, - fleet: { authz: { fleet: { all: true } } }, - } as unknown as KibanaRequest; -}; - -describe('findings API', () => { - let logger: ReturnType; - - beforeEach(() => { - logger = loggingSystemMock.createLogger(); - }); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('validate the API route path', async () => { - const router = httpServiceMock.createRouter(); - const cspAppContextService = new CspAppService(); - - const cspContext: CspAppContext = { - logger, - service: cspAppContextService, - }; - defineFindingsIndexRoute(router, cspContext); - - const [config, _] = router.get.mock.calls[0]; - - expect(config.path).toEqual('/internal/cloud_security_posture/findings'); - }); - - it('should accept to a user with fleet.all privilege', async () => { - const router = httpServiceMock.createRouter(); - const cspAppContextService = new CspAppService(); - - const cspContext: CspAppContext = { - logger, - service: cspAppContextService, - }; - defineFindingsIndexRoute(router, cspContext); - const [_, handler] = router.get.mock.calls[0]; - - const mockContext = { - fleet: { authz: { fleet: { all: true } } }, - } as unknown as KibanaRequest; - - const mockResponse = httpServerMock.createResponseFactory(); - const mockRequest = httpServerMock.createKibanaRequest(); - const [context, req, res] = [mockContext, mockRequest, mockResponse]; - - await handler(context, req, res); - - expect(res.forbidden).toHaveBeenCalledTimes(0); - }); - - it('should reject to a user without fleet.all privilege', async () => { - const router = httpServiceMock.createRouter(); - const cspAppContextService = new CspAppService(); - - const cspContext: CspAppContext = { - logger, - service: cspAppContextService, - }; - defineFindingsIndexRoute(router, cspContext); - const [_, handler] = router.get.mock.calls[0]; - - const mockContext = { - fleet: { authz: { fleet: { all: false } } }, - } as unknown as KibanaRequest; - - const mockResponse = httpServerMock.createResponseFactory(); - const mockRequest = httpServerMock.createKibanaRequest(); - const [context, req, res] = [mockContext, mockRequest, mockResponse]; - - await handler(context, req, res); - - expect(res.forbidden).toHaveBeenCalledTimes(1); - }); - - describe('test input schema', () => { - it('expect to find default values', async () => { - const validatedQuery = findingsInputSchema.validate({}); - - expect(validatedQuery).toMatchObject({ - page: 1, - per_page: DEFAULT_FINDINGS_PER_PAGE, - sort_order: expect.stringMatching('desc'), - }); - }); - - it('should throw when page field is not a positive integer', async () => { - expect(() => { - findingsInputSchema.validate({ page: -2 }); - }).toThrow(); - }); - - it('should throw when per_page field is not a positive integer', async () => { - expect(() => { - findingsInputSchema.validate({ per_page: -2 }); - }).toThrow(); - }); - - it('should throw when latest_run is not a boolean', async () => { - expect(() => { - findingsInputSchema.validate({ latest_cycle: 'some string' }); // expects to get boolean - }).toThrow(); - }); - - it('should not throw when latest_run is a boolean', async () => { - expect(() => { - findingsInputSchema.validate({ latest_cycle: true }); - }).not.toThrow(); - }); - - it('should throw when sort_field is not string', async () => { - expect(() => { - findingsInputSchema.validate({ sort_field: true }); - }).toThrow(); - }); - - it('should not throw when sort_field is a string', async () => { - expect(() => { - findingsInputSchema.validate({ sort_field: 'field1' }); - }).not.toThrow(); - }); - - it('should throw when sort_order is not `asc` or `desc`', async () => { - expect(() => { - findingsInputSchema.validate({ sort_order: 'Other Direction' }); - }).toThrow(); - }); - - it('should not throw when `asc` is input for sort_order field', async () => { - expect(() => { - findingsInputSchema.validate({ sort_order: 'asc' }); - }).not.toThrow(); - }); - - it('should not throw when `desc` is input for sort_order field', async () => { - expect(() => { - findingsInputSchema.validate({ sort_order: 'desc' }); - }).not.toThrow(); - }); - - it('should throw when fields is not string', async () => { - expect(() => { - findingsInputSchema.validate({ fields: ['field1', 'field2'] }); - }).toThrow(); - }); - - it('should not throw when fields is a string', async () => { - expect(() => { - findingsInputSchema.validate({ sort_field: 'field1, field2' }); - }).not.toThrow(); - }); - }); - - describe('test query building', () => { - it('takes cycle_id and validate the filter was built right', async () => { - const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - const router = httpServiceMock.createRouter(); - const cspAppContextService = new CspAppService(); - - const cspContext: CspAppContext = { - logger, - service: cspAppContextService, - }; - defineFindingsIndexRoute(router, cspContext); - - const [_, handler] = router.get.mock.calls[0]; - const mockContext = getMockCspContext(mockEsClient); - const mockResponse = httpServerMock.createResponseFactory(); - const mockRequest = httpServerMock.createKibanaRequest({ - query: { latest_cycle: true }, - }); - - mockEsClient.search.mockResolvedValueOnce( - // @ts-expect-error @elastic/elasticsearch Aggregate only allows unknown values - { - aggregations: { - group: { - buckets: [ - { - group_docs: { - hits: { - hits: [{ fields: { 'cycle_id.keyword': ['randomId1'] } }], - }, - }, - }, - ], - }, - }, - } - ); - - const [context, req, res] = [mockContext, mockRequest, mockResponse]; - - await handler(context, req, res); - - expect(mockEsClient.search).toHaveBeenCalledTimes(2); - - const handlerArgs = mockEsClient.search.mock.calls[1][0]; - - expect(handlerArgs).toMatchObject({ - query: { - bool: { - filter: [{ terms: { 'cycle_id.keyword': ['randomId1'] } }], - }, - }, - }); - }); - - it('validate that default sort is timestamp desc', async () => { - const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - const router = httpServiceMock.createRouter(); - const cspAppContextService = new CspAppService(); - - const cspContext: CspAppContext = { - logger, - service: cspAppContextService, - }; - defineFindingsIndexRoute(router, cspContext); - - const [_, handler] = router.get.mock.calls[0]; - const mockContext = getMockCspContext(mockEsClient); - const mockResponse = httpServerMock.createResponseFactory(); - const mockRequest = httpServerMock.createKibanaRequest({ - query: { - sort_order: 'desc', - }, - }); - - const [context, req, res] = [mockContext, mockRequest, mockResponse]; - - await handler(context, req, res); - - const handlerArgs = mockEsClient.search.mock.calls[0][0]; - - expect(handlerArgs).toMatchObject({ - sort: [{ '@timestamp': { order: 'desc' } }], - }); - }); - - it('should build sort request by `sort_field` and `sort_order` - asc', async () => { - const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - const router = httpServiceMock.createRouter(); - const cspAppContextService = new CspAppService(); - - const cspContext: CspAppContext = { - logger, - service: cspAppContextService, - }; - defineFindingsIndexRoute(router, cspContext); - - const [_, handler] = router.get.mock.calls[0]; - const mockContext = getMockCspContext(mockEsClient); - const mockResponse = httpServerMock.createResponseFactory(); - const mockRequest = httpServerMock.createKibanaRequest({ - query: { - sort_field: 'agent.id', - sort_order: 'asc', - }, - }); - - const [context, req, res] = [mockContext, mockRequest, mockResponse]; - - await handler(context, req, res); - - const handlerArgs = mockEsClient.search.mock.calls[0][0]; - - expect(handlerArgs).toMatchObject({ - sort: [{ 'agent.id': 'asc' }], - }); - }); - - it('should build sort request by `sort_field` and `sort_order` - desc', async () => { - const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - const router = httpServiceMock.createRouter(); - const cspAppContextService = new CspAppService(); - - const cspContext: CspAppContext = { - logger, - service: cspAppContextService, - }; - defineFindingsIndexRoute(router, cspContext); - - const [_, handler] = router.get.mock.calls[0]; - const mockContext = getMockCspContext(mockEsClient); - const mockResponse = httpServerMock.createResponseFactory(); - const mockRequest = httpServerMock.createKibanaRequest({ - query: { - sort_field: 'agent.id', - sort_order: 'desc', - }, - }); - - const [context, req, res] = [mockContext, mockRequest, mockResponse]; - - await handler(context, req, res); - - const handlerArgs = mockEsClient.search.mock.calls[0][0]; - - expect(handlerArgs).toMatchObject({ - sort: [{ 'agent.id': 'desc' }], - }); - }); - - it('takes `page` number and `per_page` validate that the requested selected page was called', async () => { - const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - const router = httpServiceMock.createRouter(); - const cspAppContextService = new CspAppService(); - - const cspContext: CspAppContext = { - logger, - service: cspAppContextService, - }; - defineFindingsIndexRoute(router, cspContext); - - const [_, handler] = router.get.mock.calls[0]; - const mockContext = getMockCspContext(mockEsClient); - const mockResponse = httpServerMock.createResponseFactory(); - const mockRequest = httpServerMock.createKibanaRequest({ - query: { - per_page: 10, - page: 3, - }, - }); - - const [context, req, res] = [mockContext, mockRequest, mockResponse]; - await handler(context, req, res); - - expect(mockEsClient.search).toHaveBeenCalledTimes(1); - const handlerArgs = mockEsClient.search.mock.calls[0][0]; - - expect(handlerArgs).toMatchObject({ - from: 20, - size: 10, - }); - }); - - it('should format request by fields filter', async () => { - const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - const router = httpServiceMock.createRouter(); - const cspAppContextService = new CspAppService(); - - const cspContext: CspAppContext = { - logger, - service: cspAppContextService, - }; - defineFindingsIndexRoute(router, cspContext); - - const [_, handler] = router.get.mock.calls[0]; - - const mockContext = getMockCspContext(mockEsClient); - const mockResponse = httpServerMock.createResponseFactory(); - const mockRequest = httpServerMock.createKibanaRequest({ - query: { - fields: 'field1,field2,field3', - }, - }); - - const [context, req, res] = [mockContext, mockRequest, mockResponse]; - - await handler(context, req, res); - - const handlerArgs = mockEsClient.search.mock.calls[0][0]; - - expect(handlerArgs).toMatchObject({ - _source: ['field1', 'field2', 'field3'], - }); - }); - - it('takes dslQuery and validate the conversion to esQuery filter', async () => { - const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - const router = httpServiceMock.createRouter(); - const cspAppContextService = new CspAppService(); - const cspContext: CspAppContext = { - logger, - service: cspAppContextService, - }; - - defineFindingsIndexRoute(router, cspContext); - - const [_, handler] = router.get.mock.calls[0]; - const mockContext = getMockCspContext(mockEsClient); - const mockResponse = httpServerMock.createResponseFactory(); - const mockRequest = httpServerMock.createKibanaRequest({ - query: { - kquery: 'result.evaluation.keyword:failed', - }, - }); - - const [context, req, res] = [mockContext, mockRequest, mockResponse]; - - await handler(context, req, res); - const handlerArgs = mockEsClient.search.mock.calls[0][0]; - - expect(handlerArgs).toMatchObject({ - query: { - bool: { - filter: [ - { - bool: { - minimum_should_match: 1, - should: [{ match: { 'result.evaluation.keyword': 'failed' } }], - }, - }, - ], - }, - }, - }); - }); - - it('takes dslQuery and latest_cycle filter validate the conversion to esQuery filter', async () => { - const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - const router = httpServiceMock.createRouter(); - const cspAppContextService = new CspAppService(); - const cspContext: CspAppContext = { - logger, - service: cspAppContextService, - }; - - defineFindingsIndexRoute(router, cspContext); - const [_, handler] = router.get.mock.calls[0]; - - const mockContext = getMockCspContext(mockEsClient); - const mockResponse = httpServerMock.createResponseFactory(); - const mockRequest = httpServerMock.createKibanaRequest({ - query: { - kquery: 'result.evaluation.keyword:failed', - latest_cycle: true, - }, - }); - - mockEsClient.search.mockResolvedValueOnce( - // @ts-expect-error @elastic/elasticsearch Aggregate only allows unknown values - { - aggregations: { - group: { - buckets: [ - { - group_docs: { - hits: { - hits: [{ fields: { 'cycle_id.keyword': ['randomId1'] } }], - }, - }, - }, - ], - }, - }, - } - ); - - const [context, req, res] = [mockContext, mockRequest, mockResponse]; - - await handler(context, req, res); - - const handlerArgs = mockEsClient.search.mock.calls[1][0]; - // console.log(handlerArgs.query.bool); - expect(handlerArgs).toMatchObject({ - query: { - bool: { - filter: [ - { - bool: { - should: [{ match: { 'result.evaluation.keyword': 'failed' } }], - minimum_should_match: 1, - }, - }, - { terms: { 'cycle_id.keyword': ['randomId1'] } }, - ], - }, - }, - }); - }); - }); -}); diff --git a/x-pack/plugins/cloud_security_posture/server/routes/findings/findings.ts b/x-pack/plugins/cloud_security_posture/server/routes/findings/findings.ts deleted file mode 100644 index 832a9266441ff..0000000000000 --- a/x-pack/plugins/cloud_security_posture/server/routes/findings/findings.ts +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { Logger } from '@kbn/core/server'; -import { SearchRequest, QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; -import { fromKueryExpression, toElasticsearchQuery } from '@kbn/es-query'; -import { QueryDslBoolQuery } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { schema as rt, TypeOf } from '@kbn/config-schema'; -import type { SortOrder } from '@elastic/elasticsearch/lib/api/types'; -import { transformError } from '@kbn/securitysolution-es-utils'; -import { getLatestCycleIds } from './get_latest_cycle_ids'; - -import { CSP_KUBEBEAT_INDEX_PATTERN, FINDINGS_ROUTE_PATH } from '../../../common/constants'; -import { CspAppContext } from '../../plugin'; -import { CspRouter } from '../../types'; - -type FindingsQuerySchema = TypeOf; - -export const DEFAULT_FINDINGS_PER_PAGE = 20; - -export interface FindingsOptions { - size: number; - from?: number; - page?: number; - sortField?: string; - sortOrder?: SortOrder; - fields?: string[]; -} - -const getPointerForFirstDoc = (page: number, perPage: number): number => - page <= 1 ? 0 : page * perPage - perPage; - -const getSort = (sortField: string | undefined, sortOrder: string) => - sortField - ? { sort: [{ [sortField]: sortOrder }] } - : { sort: [{ '@timestamp': { order: sortOrder } }] }; - -const getSearchFields = (fields: string | undefined) => - fields ? { _source: fields.split(',') } : {}; - -const getFindingsEsQuery = ( - query: QueryDslQueryContainer, - options: FindingsOptions -): SearchRequest => { - return { - index: CSP_KUBEBEAT_INDEX_PATTERN, - query, - ...options, - }; -}; - -const buildLatestCycleFilter = ( - filter: QueryDslQueryContainer[], - latestCycleIds?: string[] -): QueryDslQueryContainer[] => { - if (!!latestCycleIds) { - filter.push({ - terms: { 'cycle_id.keyword': latestCycleIds }, - }); - } - return filter; -}; - -const convertKqueryToElasticsearchQuery = ( - kquery: string | undefined, - logger: Logger -): QueryDslQueryContainer[] => { - let dslFilterQuery: QueryDslBoolQuery['filter']; - try { - dslFilterQuery = kquery ? toElasticsearchQuery(fromKueryExpression(kquery)) : []; - if (!Array.isArray(dslFilterQuery)) { - dslFilterQuery = [dslFilterQuery]; - } - } catch (err) { - logger.warn(`Invalid kuery syntax for the filter (${kquery}) error: ${err.message}`); - throw err; - } - return dslFilterQuery; -}; - -const buildQueryRequest = ( - kquery: string | undefined, - latestCycleIds: string[] | undefined, - logger: Logger -): QueryDslQueryContainer => { - const kqueryFilter = convertKqueryToElasticsearchQuery(kquery, logger); - const filter = buildLatestCycleFilter(kqueryFilter, latestCycleIds); - const query = { - bool: { - filter, - }, - }; - return query; -}; - -const buildOptionsRequest = (queryParams: FindingsQuerySchema): FindingsOptions => ({ - size: queryParams.per_page, - from: getPointerForFirstDoc(queryParams.page, queryParams.per_page), - ...getSort(queryParams.sort_field, queryParams.sort_order), - ...getSearchFields(queryParams.fields), -}); - -export const defineFindingsIndexRoute = (router: CspRouter, cspContext: CspAppContext): void => - router.get( - { - path: FINDINGS_ROUTE_PATH, - validate: { query: findingsInputSchema }, - }, - async (context, request, response) => { - if (!context.fleet.authz.fleet.all) { - return response.forbidden(); - } - - try { - const esClient = context.core.elasticsearch.client.asCurrentUser; - const options = buildOptionsRequest(request.query); - - const latestCycleIds = - request.query.latest_cycle === true - ? await getLatestCycleIds(esClient, cspContext.logger) - : undefined; - - if (request.query.latest_cycle === true && latestCycleIds === undefined) { - return response.ok({ body: [] }); - } - - const query = buildQueryRequest(request.query.kquery, latestCycleIds, cspContext.logger); - const esQuery = getFindingsEsQuery(query, options); - - const findings = await esClient.search(esQuery); - const hits = findings.hits.hits; - - return response.ok({ body: hits }); - } catch (err) { - const error = transformError(err); - cspContext.logger.error(`Failed to fetch Findings ${error.message}`); - return response.customError({ - body: { message: error.message }, - statusCode: error.statusCode, - }); - } - } - ); - -export const findingsInputSchema = rt.object({ - /** - * The page of objects to return - */ - page: rt.number({ defaultValue: 1, min: 1 }), - /** - * The number of objects to include in each page - */ - per_page: rt.number({ defaultValue: DEFAULT_FINDINGS_PER_PAGE, min: 0 }), - /** - * Boolean flag to indicate for receiving only the latest findings - */ - latest_cycle: rt.maybe(rt.boolean()), - /** - * The field to use for sorting the found objects. - */ - sort_field: rt.maybe(rt.string()), - /** - * The order to sort by - */ - sort_order: rt.oneOf([rt.literal('asc'), rt.literal('desc')], { defaultValue: 'desc' }), - /** - * The fields in the entity to return in the response - */ - fields: rt.maybe(rt.string()), - /** - * kql query - */ - kquery: rt.maybe(rt.string()), -}); diff --git a/x-pack/plugins/cloud_security_posture/server/routes/findings/get_latest_cycle.test.ts b/x-pack/plugins/cloud_security_posture/server/routes/findings/get_latest_cycle.test.ts deleted file mode 100644 index 38a67e95df4a7..0000000000000 --- a/x-pack/plugins/cloud_security_posture/server/routes/findings/get_latest_cycle.test.ts +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - elasticsearchClientMock, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '@kbn/core/server/elasticsearch/client/mocks'; -import { loggingSystemMock } from '@kbn/core/server/mocks'; -import { getLatestCycleIds } from './get_latest_cycle_ids'; - -const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - -describe('get latest cycle ids', () => { - let logger: ReturnType; - - beforeEach(() => { - logger = loggingSystemMock.createLogger(); - jest.resetAllMocks(); - }); - - it('expect to throw when find empty bucket', async () => { - mockEsClient.search.mockResolvedValueOnce( - // @ts-expect-error @elastic/elasticsearch Aggregate only allows unknown values - { - aggregations: { - group: { - buckets: [{}], - }, - }, - } - ); - expect(getLatestCycleIds(mockEsClient, logger)).rejects.toThrow(); - }); - - it('expect to find 1 cycle id', async () => { - mockEsClient.search.mockResolvedValueOnce( - // @ts-expect-error @elastic/elasticsearch Aggregate only allows unknown values - { - aggregations: { - group: { - buckets: [ - { - group_docs: { - hits: { - hits: [{ fields: { 'cycle_id.keyword': ['randomId1'] } }], - }, - }, - }, - ], - }, - }, - } - ); - const response = await getLatestCycleIds(mockEsClient, logger); - expect(response).toEqual(expect.arrayContaining(['randomId1'])); - }); - - it('expect to find multiple cycle ids', async () => { - mockEsClient.search.mockResolvedValueOnce( - // @ts-expect-error @elastic/elasticsearch Aggregate only allows unknown values - { - aggregations: { - group: { - buckets: [ - { - group_docs: { - hits: { - hits: [{ fields: { 'cycle_id.keyword': ['randomId1'] } }], - }, - }, - }, - { - group_docs: { - hits: { - hits: [{ fields: { 'cycle_id.keyword': ['randomId2'] } }], - }, - }, - }, - { - group_docs: { - hits: { - hits: [{ fields: { 'cycle_id.keyword': ['randomId3'] } }], - }, - }, - }, - ], - }, - }, - } - ); - const response = await getLatestCycleIds(mockEsClient, logger); - expect(response).toEqual(expect.arrayContaining(['randomId1', 'randomId2', 'randomId3'])); - }); -}); diff --git a/x-pack/plugins/cloud_security_posture/server/routes/findings/get_latest_cycle_ids.ts b/x-pack/plugins/cloud_security_posture/server/routes/findings/get_latest_cycle_ids.ts deleted file mode 100644 index 781a60727f596..0000000000000 --- a/x-pack/plugins/cloud_security_posture/server/routes/findings/get_latest_cycle_ids.ts +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import type { Logger } from '@kbn/core/server'; -import { AggregationsFiltersAggregate, SearchRequest } from '@elastic/elasticsearch/lib/api/types'; -import type { ElasticsearchClient } from '@kbn/core/server'; -import { AGENT_LOGS_INDEX_PATTERN } from '../../../common/constants'; - -const getAgentLogsEsQuery = (): SearchRequest => ({ - index: AGENT_LOGS_INDEX_PATTERN, - size: 0, - query: { - bool: { - filter: [{ term: { 'status.keyword': 'end' } }], - }, - }, - aggs: { - group: { - terms: { field: 'agent.id.keyword' }, - aggs: { - group_docs: { - top_hits: { - size: 1, - sort: [{ '@timestamp': { order: 'desc' } }], - }, - }, - }, - }, - }, - fields: ['cycle_id.keyword', 'agent.id.keyword'], - _source: false, -}); - -const getCycleId = (v: any): string => v.group_docs.hits.hits?.[0]?.fields['cycle_id.keyword'][0]; - -export const getLatestCycleIds = async ( - esClient: ElasticsearchClient, - logger: Logger -): Promise => { - try { - const agentLogs = await esClient.search(getAgentLogsEsQuery()); - const aggregations = agentLogs.aggregations; - if (!aggregations) { - return; - } - const buckets = (aggregations.group as Record).buckets; - if (!Array.isArray(buckets)) { - return; - } - - return buckets.map(getCycleId); - } catch (err) { - logger.error('Failed to fetch cycle_ids'); - throw new Error('Failed to fetch cycle_ids'); - } -}; diff --git a/x-pack/plugins/cloud_security_posture/server/routes/index.ts b/x-pack/plugins/cloud_security_posture/server/routes/index.ts index a0981e2a956cd..f5c500f24a0dc 100755 --- a/x-pack/plugins/cloud_security_posture/server/routes/index.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/index.ts @@ -7,14 +7,12 @@ import { defineGetComplianceDashboardRoute } from './compliance_dashboard/compliance_dashboard'; import { defineGetBenchmarksRoute } from './benchmarks/benchmarks'; -import { defineFindingsIndexRoute as defineGetFindingsIndexRoute } from './findings/findings'; import { defineUpdateRulesConfigRoute } from './configuration/update_rules_configuration'; import { CspAppContext } from '../plugin'; import { CspRouter } from '../types'; export function defineRoutes(router: CspRouter, cspContext: CspAppContext) { defineGetComplianceDashboardRoute(router, cspContext); - defineGetFindingsIndexRoute(router, cspContext); defineGetBenchmarksRoute(router, cspContext); defineUpdateRulesConfigRoute(router, cspContext); } diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts index 3fe320fe5bdd4..d01ecb03dbaed 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts @@ -34,7 +34,7 @@ export const registerCreateRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { id, ...rest } = request.body; const body = serializeAutoFollowPattern(rest as AutoFollowPattern); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts index 63ade6d1bd070..95da1239061b1 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts @@ -30,7 +30,7 @@ export const registerDeleteRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { id } = request.params; const ids = id.split(','); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.ts index 7cd9508bd7372..006199673410e 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.ts @@ -23,7 +23,7 @@ export const registerFetchRoute = ({ validate: false, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; try { const { patterns } = await client.asCurrentUser.ccr.getAutoFollowPattern(); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts index a5a70805d518d..0a0c2f4317d77 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts @@ -31,7 +31,7 @@ export const registerGetRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { id } = request.params; try { diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.ts index 1428e33dee660..b355d37fc5919 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.ts @@ -29,7 +29,7 @@ export const registerPauseRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { id } = request.params; const ids = id.split(','); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.ts index 912ecd689054d..79d31f84398f1 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.ts @@ -29,7 +29,7 @@ export const registerResumeRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { id } = request.params; const ids = id.split(','); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts index 98a716eb88cc6..0a0ec51ad44d1 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts @@ -39,7 +39,7 @@ export const registerUpdateRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { id } = request.params; const body = serializeAutoFollowPattern(request.body as AutoFollowPattern); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_permissions_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_permissions_route.ts index dbee279a01336..e4b80b273d4eb 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_permissions_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_permissions_route.ts @@ -22,7 +22,7 @@ export const registerPermissionsRoute = ({ validate: false, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; if (!license.isEsSecurityEnabled) { // If security has been disabled in elasticsearch.yml. we'll just let the user use CCR diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_stats_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_stats_route.ts index bab31c53a83a2..b9bf86d877a69 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_stats_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_stats_route.ts @@ -23,7 +23,7 @@ export const registerStatsRoute = ({ validate: false, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; try { const { auto_follow_stats: autoFollowStats } = await client.asCurrentUser.ccr.stats(); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts index 0aae8f9c115bc..84b6096cb3f5b 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts @@ -44,7 +44,7 @@ export const registerCreateRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { name, ...rest } = request.body; const body = removeEmptyFields(serializeFollowerIndex(rest as FollowerIndex)); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.ts index 7bbe2c8c05d4a..da71d96669efb 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.ts @@ -23,7 +23,7 @@ export const registerFetchRoute = ({ validate: false, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; try { const { follower_indices: followerIndices } = await client.asCurrentUser.ccr.followInfo({ diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts index c33ed97c289f0..44babd1bbcc46 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts @@ -30,7 +30,7 @@ export const registerGetRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { id } = request.params; try { diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.ts index 6c888e0a6e8bd..3d77ffefec9fe 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.ts @@ -27,7 +27,7 @@ export const registerPauseRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { id } = request.params; const ids = id.split(','); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.ts index 206de7d62fb38..da01b3d0e891f 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.ts @@ -27,7 +27,7 @@ export const registerResumeRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { id } = request.params; const ids = id.split(','); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.ts index e240a10df0684..f7987029ebc77 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.ts @@ -27,7 +27,7 @@ export const registerUnfollowRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { id } = request.params; const ids = id.split(','); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts index 0bacbd5fb3450..3c0850ac5984c 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts @@ -44,7 +44,7 @@ export const registerUpdateRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { id } = request.params; // We need to first pause the follower and then resume it by passing the advanced settings diff --git a/x-pack/plugins/data_enhanced/.storybook/main.js b/x-pack/plugins/data_enhanced/.storybook/main.js deleted file mode 100644 index 86b48c32f103e..0000000000000 --- a/x-pack/plugins/data_enhanced/.storybook/main.js +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -module.exports = require('@kbn/storybook').defaultConfig; diff --git a/x-pack/plugins/data_enhanced/README.md b/x-pack/plugins/data_enhanced/README.md deleted file mode 100644 index fba484261fea2..0000000000000 --- a/x-pack/plugins/data_enhanced/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# data_enhanced - -The `data_enhanced` plugin is the x-pack counterpart to the `src/plguins/data` plugin. - -It exists to provide services, or parts of services, which -enhance existing functionality from `src/plugins/data`. - -Currently, the `data_enhanced` plugin doesn't return any APIs which you can -consume directly, however it is possible that you are indirectly relying on the -enhanced functionality that it provides via the `data` plugin from `src/`. - -Here is the functionality it adds: - -## Search Sessions - -Search sessions are handy when you want to enable a user to run something asynchronously (for example, a dashboard over a long period of time), and then quickly restore the results at a later time. The Search Service transparently fetches results from the .async-search index, instead of running each request again. diff --git a/x-pack/plugins/data_enhanced/common/index.ts b/x-pack/plugins/data_enhanced/common/index.ts deleted file mode 100644 index 1fec1c76430eb..0000000000000 --- a/x-pack/plugins/data_enhanced/common/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ diff --git a/x-pack/plugins/data_enhanced/common/search/index.ts b/x-pack/plugins/data_enhanced/common/search/index.ts deleted file mode 100644 index 1fec1c76430eb..0000000000000 --- a/x-pack/plugins/data_enhanced/common/search/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ diff --git a/x-pack/plugins/data_enhanced/common/search/test_data/search_phase_execution_exception.json b/x-pack/plugins/data_enhanced/common/search/test_data/search_phase_execution_exception.json deleted file mode 100644 index b79a396445e3d..0000000000000 --- a/x-pack/plugins/data_enhanced/common/search/test_data/search_phase_execution_exception.json +++ /dev/null @@ -1,229 +0,0 @@ -{ - "error": { - "root_cause": [ - { - "type": "script_exception", - "reason": "compile error", - "script_stack": [ - "invalid", - "^---- HERE" - ], - "script": "invalid", - "lang": "painless", - "position": { - "offset": 0, - "start": 0, - "end": 7 - } - }, - { - "type": "script_exception", - "reason": "compile error", - "script_stack": [ - "invalid", - "^---- HERE" - ], - "script": "invalid", - "lang": "painless", - "position": { - "offset": 0, - "start": 0, - "end": 7 - } - }, - { - "type": "parse_exception", - "reason": "failed to parse date field [2021-01-19T12:2755.047Z] with format [strict_date_optional_time]: [failed to parse date field [2021-01-19T12:2755.047Z] with format [strict_date_optional_time]]" - }, - { - "type": "script_exception", - "reason": "compile error", - "script_stack": [ - "invalid", - "^---- HERE" - ], - "script": "invalid", - "lang": "painless", - "position": { - "offset": 0, - "start": 0, - "end": 7 - } - }, - { - "type": "script_exception", - "reason": "compile error", - "script_stack": [ - "invalid", - "^---- HERE" - ], - "script": "invalid", - "lang": "painless", - "position": { - "offset": 0, - "start": 0, - "end": 7 - } - }, - { - "type": "script_exception", - "reason": "compile error", - "script_stack": [ - "invalid", - "^---- HERE" - ], - "script": "invalid", - "lang": "painless", - "position": { - "offset": 0, - "start": 0, - "end": 7 - } - } - ], - "type": "search_phase_execution_exception", - "reason": "all shards failed", - "phase": "query", - "grouped": true, - "failed_shards": [ - { - "shard": 0, - "index": ".apm-agent-configuration", - "node": "DEfMVCg5R12TRG4CYIxUgQ", - "reason": { - "type": "script_exception", - "reason": "compile error", - "script_stack": [ - "invalid", - "^---- HERE" - ], - "script": "invalid", - "lang": "painless", - "position": { - "offset": 0, - "start": 0, - "end": 7 - }, - "caused_by": { - "type": "illegal_argument_exception", - "reason": "cannot resolve symbol [invalid]" - } - } - }, - { - "shard": 0, - "index": ".apm-custom-link", - "node": "DEfMVCg5R12TRG4CYIxUgQ", - "reason": { - "type": "script_exception", - "reason": "compile error", - "script_stack": [ - "invalid", - "^---- HERE" - ], - "script": "invalid", - "lang": "painless", - "position": { - "offset": 0, - "start": 0, - "end": 7 - }, - "caused_by": { - "type": "illegal_argument_exception", - "reason": "cannot resolve symbol [invalid]" - } - } - }, - { - "shard": 0, - "index": ".kibana-event-log-8.0.0-000001", - "node": "DEfMVCg5R12TRG4CYIxUgQ", - "reason": { - "type": "parse_exception", - "reason": "failed to parse date field [2021-01-19T12:2755.047Z] with format [strict_date_optional_time]: [failed to parse date field [2021-01-19T12:2755.047Z] with format [strict_date_optional_time]]", - "caused_by": { - "type": "illegal_argument_exception", - "reason": "failed to parse date field [2021-01-19T12:2755.047Z] with format [strict_date_optional_time]", - "caused_by": { - "type": "date_time_parse_exception", - "reason": "Text '2021-01-19T12:2755.047Z' could not be parsed, unparsed text found at index 16" - } - } - } - }, - { - "shard": 0, - "index": ".kibana_1", - "node": "DEfMVCg5R12TRG4CYIxUgQ", - "reason": { - "type": "script_exception", - "reason": "compile error", - "script_stack": [ - "invalid", - "^---- HERE" - ], - "script": "invalid", - "lang": "painless", - "position": { - "offset": 0, - "start": 0, - "end": 7 - }, - "caused_by": { - "type": "illegal_argument_exception", - "reason": "cannot resolve symbol [invalid]" - } - } - }, - { - "shard": 0, - "index": ".kibana_task_manager_1", - "node": "DEfMVCg5R12TRG4CYIxUgQ", - "reason": { - "type": "script_exception", - "reason": "compile error", - "script_stack": [ - "invalid", - "^---- HERE" - ], - "script": "invalid", - "lang": "painless", - "position": { - "offset": 0, - "start": 0, - "end": 7 - }, - "caused_by": { - "type": "illegal_argument_exception", - "reason": "cannot resolve symbol [invalid]" - } - } - }, - { - "shard": 0, - "index": ".security-7", - "node": "DEfMVCg5R12TRG4CYIxUgQ", - "reason": { - "type": "script_exception", - "reason": "compile error", - "script_stack": [ - "invalid", - "^---- HERE" - ], - "script": "invalid", - "lang": "painless", - "position": { - "offset": 0, - "start": 0, - "end": 7 - }, - "caused_by": { - "type": "illegal_argument_exception", - "reason": "cannot resolve symbol [invalid]" - } - } - } - ] - }, - "status": 400 -} \ No newline at end of file diff --git a/x-pack/plugins/data_enhanced/config.ts b/x-pack/plugins/data_enhanced/config.ts deleted file mode 100644 index eb3ee0da41839..0000000000000 --- a/x-pack/plugins/data_enhanced/config.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { schema, TypeOf } from '@kbn/config-schema'; -import { searchSessionsConfigSchema } from '@kbn/data-plugin/config'; - -export const configSchema = schema.object({ - search: schema.object({ - sessions: searchSessionsConfigSchema, - }), -}); - -export type ConfigSchema = TypeOf; diff --git a/x-pack/plugins/data_enhanced/jest.config.js b/x-pack/plugins/data_enhanced/jest.config.js deleted file mode 100644 index e48de352c2075..0000000000000 --- a/x-pack/plugins/data_enhanced/jest.config.js +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -module.exports = { - preset: '@kbn/test', - rootDir: '../../..', - roots: ['/x-pack/plugins/data_enhanced'], - coverageDirectory: '/target/kibana-coverage/jest/x-pack/plugins/data_enhanced', - coverageReporters: ['text', 'html'], - collectCoverageFrom: [ - '/x-pack/plugins/data_enhanced/{common,public,server}/**/*.{ts,tsx}', - ], -}; diff --git a/x-pack/plugins/data_enhanced/kibana.json b/x-pack/plugins/data_enhanced/kibana.json deleted file mode 100644 index d89e76013ebd4..0000000000000 --- a/x-pack/plugins/data_enhanced/kibana.json +++ /dev/null @@ -1,29 +0,0 @@ - -{ - "id": "dataEnhanced", - "version": "8.0.0", - "kibanaVersion": "kibana", - "owner": { - "name": "App Services", - "githubTeam": "kibana-app-services" - }, - "configPath": ["xpack", "data_enhanced"], - "requiredPlugins": [ - "bfetch", - "data", - "features", - "management", - "share", - "taskManager", - "screenshotMode" - ], - "optionalPlugins": ["kibanaUtils", "usageCollection", "security"], - "server": true, - "ui": true, - "requiredBundles": ["kibanaUtils", "kibanaReact"], - "owner": { - "name": "App Services", - "githubTeam": "kibana-app-services" - }, - "description": "Enhanced data plugin. (See src/plugins/data.) Enhances the main data plugin with a search session management UI. Includes a reusable search session indicator component to use in other applications. Exposes routes for managing search sessions. Includes a service that monitors, updates, and cleans up search session saved objects." -} diff --git a/x-pack/plugins/data_enhanced/public/index.ts b/x-pack/plugins/data_enhanced/public/index.ts deleted file mode 100644 index 7af1aff1b3106..0000000000000 --- a/x-pack/plugins/data_enhanced/public/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { PluginInitializerContext } from '@kbn/core/public'; -import { DataEnhancedPlugin, DataEnhancedSetup, DataEnhancedStart } from './plugin'; -import { ConfigSchema } from '../config'; - -export const plugin = (initializerContext: PluginInitializerContext) => - new DataEnhancedPlugin(initializerContext); - -export type { DataEnhancedSetup, DataEnhancedStart }; - -export { ENHANCED_ES_SEARCH_STRATEGY, EQL_SEARCH_STRATEGY } from '@kbn/data-plugin/common'; diff --git a/x-pack/plugins/data_enhanced/public/plugin.ts b/x-pack/plugins/data_enhanced/public/plugin.ts deleted file mode 100644 index f1bb9d7b4b4b6..0000000000000 --- a/x-pack/plugins/data_enhanced/public/plugin.ts +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import moment from 'moment'; -import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public'; -import { - DataPublicPluginSetup, - DataPublicPluginStart, - SearchUsageCollector, -} from '@kbn/data-plugin/public'; -import { BfetchPublicSetup } from '@kbn/bfetch-plugin/public'; -import { ManagementSetup } from '@kbn/management-plugin/public'; -import { SharePluginStart } from '@kbn/share-plugin/public'; - -import { toMountPoint } from '@kbn/kibana-react-plugin/public'; -import { Storage } from '@kbn/kibana-utils-plugin/public'; -import { ScreenshotModePluginStart } from '@kbn/screenshot-mode-plugin/public'; -import { registerSearchSessionsMgmt } from './search/sessions_mgmt'; -import { createConnectedSearchSessionIndicator } from './search'; -import { ConfigSchema } from '../config'; - -export interface DataEnhancedSetupDependencies { - bfetch: BfetchPublicSetup; - data: DataPublicPluginSetup; - management: ManagementSetup; -} -export interface DataEnhancedStartDependencies { - data: DataPublicPluginStart; - share: SharePluginStart; - screenshotMode: ScreenshotModePluginStart; -} - -export type DataEnhancedSetup = ReturnType; -export type DataEnhancedStart = ReturnType; - -export class DataEnhancedPlugin - implements Plugin -{ - private config!: ConfigSchema; - private readonly storage = new Storage(window.localStorage); - private usageCollector?: SearchUsageCollector; - - constructor(private initializerContext: PluginInitializerContext) {} - - public setup( - core: CoreSetup, - { bfetch, data, management }: DataEnhancedSetupDependencies - ) { - this.config = this.initializerContext.config.get(); - if (this.config.search.sessions.enabled) { - const sessionsConfig = this.config.search.sessions; - registerSearchSessionsMgmt( - core, - sessionsConfig, - this.initializerContext.env.packageInfo.version, - { data, management } - ); - } - - this.usageCollector = data.search.usageCollector; - } - - public start(core: CoreStart, plugins: DataEnhancedStartDependencies) { - if (this.config.search.sessions.enabled) { - core.chrome.setBreadcrumbsAppendExtension({ - content: toMountPoint( - React.createElement( - createConnectedSearchSessionIndicator({ - sessionService: plugins.data.search.session, - application: core.application, - basePath: core.http.basePath, - storage: this.storage, - disableSaveAfterSessionCompletesTimeout: moment - .duration(this.config.search.sessions.notTouchedTimeout) - .asMilliseconds(), - usageCollector: this.usageCollector, - tourDisabled: plugins.screenshotMode.isScreenshotMode(), - }) - ), - { theme$: core.theme.theme$ } - ), - }); - } - } - - public stop() {} -} diff --git a/x-pack/plugins/data_enhanced/public/search/index.ts b/x-pack/plugins/data_enhanced/public/search/index.ts deleted file mode 100644 index 84e70f41d6746..0000000000000 --- a/x-pack/plugins/data_enhanced/public/search/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export * from './ui'; diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/__mocks__/index.tsx b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/__mocks__/index.tsx deleted file mode 100644 index 7c089c8db9634..0000000000000 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/__mocks__/index.tsx +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { ReactNode } from 'react'; -import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; - -export function LocaleWrapper({ children }: { children?: ReactNode }) { - return {children}; -} diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/application/index.tsx b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/application/index.tsx deleted file mode 100644 index d2be863170a4b..0000000000000 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/application/index.tsx +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { CoreSetup } from '@kbn/core/public'; -import type { ManagementAppMountParams } from '@kbn/management-plugin/public'; -import type { - AppDependencies, - IManagementSectionsPluginsSetup, - IManagementSectionsPluginsStart, - SessionsConfigSchema, -} from '..'; -import { APP } from '..'; -import { SearchSessionsMgmtAPI } from '../lib/api'; -import { AsyncSearchIntroDocumentation } from '../lib/documentation'; -import { renderApp } from './render'; - -export class SearchSessionsMgmtApp { - constructor( - private coreSetup: CoreSetup, - private config: SessionsConfigSchema, - private kibanaVersion: string, - private params: ManagementAppMountParams, - private pluginsSetup: IManagementSectionsPluginsSetup - ) {} - - public async mountManagementSection() { - const { coreSetup, params, pluginsSetup } = this; - const [coreStart, pluginsStart] = await coreSetup.getStartServices(); - - const { - chrome: { docTitle }, - http, - docLinks, - i18n, - notifications, - uiSettings, - application, - } = coreStart; - const { data, share } = pluginsStart; - - const pluginName = APP.getI18nName(); - docTitle.change(pluginName); - params.setBreadcrumbs([{ text: pluginName }]); - - const { sessionsClient } = data.search; - const api = new SearchSessionsMgmtAPI(sessionsClient, this.config, { - notifications, - locators: share.url.locators, - application, - usageCollector: pluginsSetup.data.search.usageCollector, - }); - - const documentation = new AsyncSearchIntroDocumentation(docLinks); - - const dependencies: AppDependencies = { - plugins: pluginsSetup, - config: this.config, - documentation, - core: coreStart, - api, - http, - i18n, - uiSettings, - share, - kibanaVersion: this.kibanaVersion, - }; - - const { element } = params; - const unmountAppCb = renderApp(element, dependencies); - - return () => { - docTitle.reset(); - unmountAppCb(); - }; - } -} - -export { renderApp }; diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/index.tsx b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/index.tsx deleted file mode 100644 index cecd50125e90e..0000000000000 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/index.tsx +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export { PopoverActionsMenu } from './popover_actions'; -export * from './types'; diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/types.ts b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/types.ts deleted file mode 100644 index c808f8469cccf..0000000000000 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/types.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export type OnActionComplete = () => void; -export type OnActionDismiss = () => void; - -export enum ACTION { - INSPECT = 'inspect', - EXTEND = 'extend', - DELETE = 'delete', - RENAME = 'rename', -} diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/index.tsx b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/index.tsx deleted file mode 100644 index 2970c75e651d6..0000000000000 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/index.tsx +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiLinkProps, EuiText, EuiTextProps } from '@elastic/eui'; -import React from 'react'; -import extendSessionIcon from '../icons/extend_session.svg'; - -export type { OnActionComplete } from './actions'; -export { PopoverActionsMenu } from './actions'; - -export const TableText = ({ children, ...props }: EuiTextProps) => { - return ( - - {children} - - ); -}; - -export interface IClickActionDescriptor { - label: React.ReactNode; - iconType: 'trash' | 'cancel' | typeof extendSessionIcon; - onClick: () => Promise | void; -} - -export interface IHrefActionDescriptor { - label: string; - props: EuiLinkProps; -} - -export interface StatusDef { - textColor?: EuiTextProps['color']; - icon?: React.ReactElement; - label: React.ReactElement; - toolTipContent: string; -} diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/main.tsx b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/main.tsx deleted file mode 100644 index e065a20003dd9..0000000000000 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/main.tsx +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiButtonEmpty, EuiPageHeader, EuiSpacer } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n-react'; -import type { CoreStart, HttpStart } from '@kbn/core/public'; -import React from 'react'; -import type { SessionsConfigSchema } from '..'; -import { IManagementSectionsPluginsSetup } from '..'; -import type { SearchSessionsMgmtAPI } from '../lib/api'; -import type { AsyncSearchIntroDocumentation } from '../lib/documentation'; -import { SearchSessionsMgmtTable } from './table'; - -interface Props { - documentation: AsyncSearchIntroDocumentation; - core: CoreStart; - api: SearchSessionsMgmtAPI; - http: HttpStart; - timezone: string; - config: SessionsConfigSchema; - plugins: IManagementSectionsPluginsSetup; - kibanaVersion: string; -} - -export function SearchSessionsMgmtMain({ documentation, ...tableProps }: Props) { - return ( - <> - - } - description={ - - } - bottomBorder - rightSideItems={[ - - - , - ]} - /> - - - - - ); -} diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/status.tsx b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/status.tsx deleted file mode 100644 index 577e89f2c761b..0000000000000 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/status.tsx +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLoadingSpinner, EuiToolTip } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import React, { ReactElement } from 'react'; -import { SearchSessionStatus } from '@kbn/data-plugin/common'; -import { dateString } from '../lib/date_string'; -import { UISession } from '../types'; -import { StatusDef as StatusAttributes, TableText } from '.'; - -// Shared helper function -export const getStatusText = (statusType: string): string => { - switch (statusType) { - case SearchSessionStatus.IN_PROGRESS: - return i18n.translate('xpack.data.mgmt.searchSessions.status.label.inProgress', { - defaultMessage: 'In progress', - }); - case SearchSessionStatus.EXPIRED: - return i18n.translate('xpack.data.mgmt.searchSessions.status.label.expired', { - defaultMessage: 'Expired', - }); - case SearchSessionStatus.CANCELLED: - return i18n.translate('xpack.data.mgmt.searchSessions.status.label.cancelled', { - defaultMessage: 'Cancelled', - }); - case SearchSessionStatus.COMPLETE: - return i18n.translate('xpack.data.mgmt.searchSessions.status.label.complete', { - defaultMessage: 'Complete', - }); - case SearchSessionStatus.ERROR: - return i18n.translate('xpack.data.mgmt.searchSessions.status.label.error', { - defaultMessage: 'Error', - }); - default: - // eslint-disable-next-line no-console - console.error(`Unknown status ${statusType}`); - return statusType; - } -}; - -interface StatusIndicatorProps { - now?: string; - session: UISession; - timezone: string; -} - -// Get the fields needed to show each status type -// can throw errors around date conversions -const getStatusAttributes = ({ - now, - session, - timezone, -}: StatusIndicatorProps): StatusAttributes | null => { - let expireDate: string; - if (session.expires) { - expireDate = dateString(session.expires!, timezone); - } else { - expireDate = i18n.translate('xpack.data.mgmt.searchSessions.status.expireDateUnknown', { - defaultMessage: 'unknown', - }); - } - - switch (session.status) { - case SearchSessionStatus.IN_PROGRESS: - try { - return { - textColor: 'default', - icon: , - label: {getStatusText(session.status)}, - toolTipContent: i18n.translate( - 'xpack.data.mgmt.searchSessions.status.message.createdOn', - { - defaultMessage: 'Expires on {expireDate}', - values: { expireDate }, - } - ), - }; - } catch (err) { - // eslint-disable-next-line no-console - console.error(err); - throw new Error(`Could not instantiate a createdDate object from: ${session.created}`); - } - - case SearchSessionStatus.EXPIRED: - try { - const toolTipContent = i18n.translate( - 'xpack.data.mgmt.searchSessions.status.message.expiredOn', - { - defaultMessage: 'Expired on {expireDate}', - values: { expireDate }, - } - ); - - return { - icon: , - label: {getStatusText(session.status)}, - toolTipContent, - }; - } catch (err) { - // eslint-disable-next-line no-console - console.error(err); - throw new Error(`Could not instantiate an expiration Date object from: ${session.expires}`); - } - - case SearchSessionStatus.CANCELLED: - return { - icon: , - label: {getStatusText(session.status)}, - toolTipContent: i18n.translate('xpack.data.mgmt.searchSessions.status.message.cancelled', { - defaultMessage: 'Cancelled by user', - }), - }; - - case SearchSessionStatus.ERROR: - return { - textColor: 'danger', - icon: , - label: {getStatusText(session.status)}, - toolTipContent: i18n.translate('xpack.data.mgmt.searchSessions.status.message.error', { - defaultMessage: 'Error: {error}', - values: { error: (session as any).error || 'unknown' }, - }), - }; - - case SearchSessionStatus.COMPLETE: - try { - const toolTipContent = i18n.translate('xpack.data.mgmt.searchSessions.status.expiresOn', { - defaultMessage: 'Expires on {expireDate}', - values: { expireDate }, - }); - - return { - textColor: 'success', - icon: , - label: {getStatusText(session.status)}, - toolTipContent, - }; - } catch (err) { - // eslint-disable-next-line no-console - console.error(err); - throw new Error( - `Could not instantiate an expiration Date object for completed session from: ${session.expires}` - ); - } - - // Error was thrown - return null; - - default: - throw new Error(`Unknown status: ${session.status}`); - } -}; - -export const StatusIndicator = (props: StatusIndicatorProps) => { - try { - const statusDef = getStatusAttributes(props); - const { session } = props; - - if (statusDef) { - const { toolTipContent } = statusDef; - let icon: ReactElement | undefined = statusDef.icon; - let label: ReactElement = statusDef.label; - - if (icon && toolTipContent) { - icon = {icon}; - } - if (toolTipContent) { - label = ( - - - {statusDef.label} - - - ); - } - - return ( - - {icon} - - - {label} - - - - ); - } - } catch (err) { - // eslint-disable-next-line no-console - console.error(err); - } - - // Exception has been caught - return {props.session.status}; -}; diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/table/index.ts b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/table/index.ts deleted file mode 100644 index 361261ff65c87..0000000000000 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/table/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export { SearchSessionsMgmtTable } from './table'; diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/table/status_filter.tsx b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/table/status_filter.tsx deleted file mode 100644 index 33e085fbb646d..0000000000000 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/table/status_filter.tsx +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { FieldValueOptionType, SearchFilterConfig } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import React from 'react'; -import { TableText } from '..'; -import { UISession } from '../../types'; -import { getStatusText } from '../status'; - -export const getStatusFilter: (tableData: UISession[]) => SearchFilterConfig = (tableData) => ({ - type: 'field_value_selection', - name: i18n.translate('xpack.data.mgmt.searchSessions.search.filterStatus', { - defaultMessage: 'Status', - }), - field: 'status', - multiSelect: 'or', - options: tableData.reduce((options: FieldValueOptionType[], session) => { - const { status: statusType } = session; - const existingOption = options.find((o) => o.value === statusType); - if (!existingOption) { - const view = {getStatusText(session.status)}; - return [...options, { value: statusType, view }]; - } - - return options; - }, []), -}); diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/index.ts b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/index.ts deleted file mode 100644 index 35eb3cb4e36a4..0000000000000 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/index.ts +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; -import type { CoreStart, HttpStart, I18nStart, IUiSettingsClient } from '@kbn/core/public'; -import { CoreSetup } from '@kbn/core/public'; -import type { DataPublicPluginSetup, DataPublicPluginStart } from '@kbn/data-plugin/public'; -import type { ManagementSetup } from '@kbn/management-plugin/public'; -import type { SharePluginStart } from '@kbn/share-plugin/public'; -import { SEARCH_SESSIONS_MANAGEMENT_ID } from '@kbn/data-plugin/public'; -import type { ConfigSchema } from '../../../config'; -import type { DataEnhancedStartDependencies } from '../../plugin'; -import type { SearchSessionsMgmtAPI } from './lib/api'; -import type { AsyncSearchIntroDocumentation } from './lib/documentation'; - -export interface IManagementSectionsPluginsSetup { - data: DataPublicPluginSetup; - management: ManagementSetup; -} - -export interface IManagementSectionsPluginsStart { - data: DataPublicPluginStart; - share: SharePluginStart; -} - -export interface AppDependencies { - plugins: IManagementSectionsPluginsSetup; - share: SharePluginStart; - uiSettings: IUiSettingsClient; - documentation: AsyncSearchIntroDocumentation; - core: CoreStart; // for RedirectAppLinks - api: SearchSessionsMgmtAPI; - http: HttpStart; - i18n: I18nStart; - config: SessionsConfigSchema; - kibanaVersion: string; -} - -export const APP = { - id: SEARCH_SESSIONS_MANAGEMENT_ID, - getI18nName: (): string => - i18n.translate('xpack.data.mgmt.searchSessions.appTitle', { - defaultMessage: 'Search Sessions', - }), -}; - -export type SessionsConfigSchema = ConfigSchema['search']['sessions']; - -export function registerSearchSessionsMgmt( - coreSetup: CoreSetup, - config: SessionsConfigSchema, - kibanaVersion: string, - services: IManagementSectionsPluginsSetup -) { - services.management.sections.section.kibana.registerApp({ - id: APP.id, - title: APP.getI18nName(), - order: 1.75, - mount: async (params) => { - const { SearchSessionsMgmtApp: MgmtApp } = await import('./application'); - const mgmtApp = new MgmtApp(coreSetup, config, kibanaVersion, params, services); - return mgmtApp.mountManagementSection(); - }, - }); -} diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/documentation.ts b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/documentation.ts deleted file mode 100644 index 03279199912c0..0000000000000 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/documentation.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { DocLinksStart } from '@kbn/core/public'; - -export class AsyncSearchIntroDocumentation { - private docUrl: string = ''; - - constructor(docs: DocLinksStart) { - const { links } = docs; - this.docUrl = links.search.sessions; - } - - public getElasticsearchDocLink() { - return `${this.docUrl}`; - } -} diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/get_expiration_status.ts b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/get_expiration_status.ts deleted file mode 100644 index a220b414ba659..0000000000000 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/get_expiration_status.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; -import moment from 'moment'; -import { SessionsConfigSchema } from '..'; - -export const getExpirationStatus = (config: SessionsConfigSchema, expires: string | null) => { - const tNow = moment.utc().valueOf(); - const tFuture = moment.utc(expires).valueOf(); - - // NOTE this could end up negative. If server time is off from the browser's clock - // and the session was early expired when the browser refreshed the listing - const durationToExpire = moment.duration(tFuture - tNow); - const expiresInDays = Math.floor(durationToExpire.asDays()); - const sufficientDays = Math.ceil(moment.duration(config.management.expiresSoonWarning).asDays()); - - let toolTipContent = i18n.translate('xpack.data.mgmt.searchSessions.status.expiresSoonInDays', { - defaultMessage: 'Expires in {numDays} days', - values: { numDays: expiresInDays }, - }); - let statusContent = i18n.translate( - 'xpack.data.mgmt.searchSessions.status.expiresSoonInDaysTooltip', - { defaultMessage: '{numDays} days', values: { numDays: expiresInDays } } - ); - - if (expiresInDays === 0) { - // switch to show expires in hours - const expiresInHours = Math.floor(durationToExpire.asHours()); - - toolTipContent = i18n.translate('xpack.data.mgmt.searchSessions.status.expiresSoonInHours', { - defaultMessage: 'This session expires in {numHours} hours', - values: { numHours: expiresInHours }, - }); - statusContent = i18n.translate( - 'xpack.data.mgmt.searchSessions.status.expiresSoonInHoursTooltip', - { defaultMessage: '{numHours} hours', values: { numHours: expiresInHours } } - ); - } - - if (durationToExpire.valueOf() > 0 && expiresInDays <= sufficientDays) { - return { toolTipContent, statusContent }; - } -}; diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/types.ts b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/types.ts deleted file mode 100644 index c66290a968240..0000000000000 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/types.ts +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { SearchSessionSavedObjectAttributes, SearchSessionStatus } from '@kbn/data-plugin/common'; -import { ACTION } from './components/actions'; - -export const DATE_STRING_FORMAT = 'D MMM, YYYY, HH:mm:ss'; - -/** - * Some properties are optional for a non-persisted Search Session. - * This interface makes them mandatory, because management only shows persisted search sessions. - */ -export type PersistedSearchSessionSavedObjectAttributes = SearchSessionSavedObjectAttributes & - Required< - Pick< - SearchSessionSavedObjectAttributes, - 'name' | 'appId' | 'locatorId' | 'initialState' | 'restoreState' - > - >; - -export type UISearchSessionState = SearchSessionStatus; - -export interface UISession { - id: string; - name: string; - appId: string; - created: string; - expires: string | null; - status: UISearchSessionState; - numSearches: number; - actions?: ACTION[]; - reloadUrl: string; - restoreUrl: string; - initialState: Record; - restoreState: Record; - version: string; -} diff --git a/x-pack/plugins/data_enhanced/public/search/ui/connected_search_session_indicator/index.ts b/x-pack/plugins/data_enhanced/public/search/ui/connected_search_session_indicator/index.ts deleted file mode 100644 index fec61f8115486..0000000000000 --- a/x-pack/plugins/data_enhanced/public/search/ui/connected_search_session_indicator/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export type { SearchSessionIndicatorDeps } from './connected_search_session_indicator'; -export { createConnectedSearchSessionIndicator } from './connected_search_session_indicator'; diff --git a/x-pack/plugins/data_enhanced/public/search/ui/index.ts b/x-pack/plugins/data_enhanced/public/search/ui/index.ts deleted file mode 100644 index e8f83db6ed98c..0000000000000 --- a/x-pack/plugins/data_enhanced/public/search/ui/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export * from './connected_search_session_indicator'; diff --git a/x-pack/plugins/data_enhanced/public/search/ui/search_session_indicator/components/index.ts b/x-pack/plugins/data_enhanced/public/search/ui/search_session_indicator/components/index.ts deleted file mode 100644 index 9093e1a2535e2..0000000000000 --- a/x-pack/plugins/data_enhanced/public/search/ui/search_session_indicator/components/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export * from './search_session_name'; diff --git a/x-pack/plugins/data_enhanced/public/search/ui/search_session_indicator/components/search_session_name/index.ts b/x-pack/plugins/data_enhanced/public/search/ui/search_session_indicator/components/search_session_name/index.ts deleted file mode 100644 index 9093e1a2535e2..0000000000000 --- a/x-pack/plugins/data_enhanced/public/search/ui/search_session_indicator/components/search_session_name/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export * from './search_session_name'; diff --git a/x-pack/plugins/data_enhanced/public/search/ui/search_session_indicator/index.tsx b/x-pack/plugins/data_enhanced/public/search/ui/search_session_indicator/index.tsx deleted file mode 100644 index fe86ad2fb5cea..0000000000000 --- a/x-pack/plugins/data_enhanced/public/search/ui/search_session_indicator/index.tsx +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiDelayRender, EuiLoadingSpinner } from '@elastic/eui'; -import React from 'react'; -import type { - SearchSessionIndicatorProps, - SearchSessionIndicatorRef, -} from './search_session_indicator'; -export type { SearchSessionIndicatorProps, SearchSessionIndicatorRef }; - -const Fallback = () => ( - - - -); - -const LazySearchSessionIndicator = React.lazy(() => import('./search_session_indicator')); -export const SearchSessionIndicator = React.forwardRef< - SearchSessionIndicatorRef, - SearchSessionIndicatorProps ->((props: SearchSessionIndicatorProps, ref) => ( - }> - - -)); diff --git a/x-pack/plugins/data_enhanced/server/collectors/index.ts b/x-pack/plugins/data_enhanced/server/collectors/index.ts deleted file mode 100644 index 4a82c76e96dee..0000000000000 --- a/x-pack/plugins/data_enhanced/server/collectors/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export { registerUsageCollector } from './register'; diff --git a/x-pack/plugins/data_enhanced/server/index.ts b/x-pack/plugins/data_enhanced/server/index.ts deleted file mode 100644 index a56f7216c4706..0000000000000 --- a/x-pack/plugins/data_enhanced/server/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { PluginConfigDescriptor, PluginInitializerContext } from '@kbn/core/server'; -import { EnhancedDataServerPlugin } from './plugin'; -import { configSchema, ConfigSchema } from '../config'; - -export const config: PluginConfigDescriptor = { - exposeToBrowser: { - search: true, - }, - schema: configSchema, -}; - -export function plugin(initializerContext: PluginInitializerContext) { - return new EnhancedDataServerPlugin(initializerContext); -} - -export { ENHANCED_ES_SEARCH_STRATEGY, EQL_SEARCH_STRATEGY } from '@kbn/data-plugin/common'; - -export { EnhancedDataServerPlugin as Plugin }; diff --git a/x-pack/plugins/data_enhanced/server/plugin.ts b/x-pack/plugins/data_enhanced/server/plugin.ts deleted file mode 100644 index 007764ec95f0c..0000000000000 --- a/x-pack/plugins/data_enhanced/server/plugin.ts +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { CoreSetup, CoreStart, Logger, Plugin, PluginInitializerContext } from '@kbn/core/server'; -import { registerSessionRoutes } from './routes'; -import { searchSessionSavedObjectType } from './saved_objects'; -import type { - DataEnhancedRequestHandlerContext, - DataEnhancedSetupDependencies as SetupDependencies, - DataEnhancedStartDependencies as StartDependencies, -} from './type'; -import { ConfigSchema } from '../config'; -import { registerUsageCollector } from './collectors'; -import { SearchSessionService } from './search'; - -export class EnhancedDataServerPlugin - implements Plugin -{ - private readonly logger: Logger; - private sessionService!: SearchSessionService; - private config: ConfigSchema; - - constructor(private initializerContext: PluginInitializerContext) { - this.logger = initializerContext.logger.get('data_enhanced'); - this.config = this.initializerContext.config.get(); - } - - public setup(core: CoreSetup, deps: SetupDependencies) { - core.savedObjects.registerType(searchSessionSavedObjectType); - - this.sessionService = new SearchSessionService( - this.logger, - this.config, - this.initializerContext.env.packageInfo.version, - deps.security - ); - - deps.data.__enhance({ - search: { - sessionService: this.sessionService, - }, - }); - - const router = core.http.createRouter(); - registerSessionRoutes(router, this.logger); - - this.sessionService.setup(core, { - taskManager: deps.taskManager, - }); - - if (deps.usageCollection) { - registerUsageCollector(deps.usageCollection, core.savedObjects.getKibanaIndex(), this.logger); - } - } - - public start(core: CoreStart, { taskManager }: StartDependencies) { - this.sessionService.start(core, { - taskManager, - }); - } - - public stop() { - this.sessionService.stop(); - } -} - -export { EnhancedDataServerPlugin as Plugin }; diff --git a/x-pack/plugins/data_enhanced/server/routes/index.ts b/x-pack/plugins/data_enhanced/server/routes/index.ts deleted file mode 100644 index 0430d283667d0..0000000000000 --- a/x-pack/plugins/data_enhanced/server/routes/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export * from './session'; diff --git a/x-pack/plugins/data_enhanced/server/saved_objects/index.ts b/x-pack/plugins/data_enhanced/server/saved_objects/index.ts deleted file mode 100644 index 3736eb7e0394b..0000000000000 --- a/x-pack/plugins/data_enhanced/server/saved_objects/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export * from './search_session'; diff --git a/x-pack/plugins/data_enhanced/server/search/index.ts b/x-pack/plugins/data_enhanced/server/search/index.ts deleted file mode 100644 index 0430d283667d0..0000000000000 --- a/x-pack/plugins/data_enhanced/server/search/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export * from './session'; diff --git a/x-pack/plugins/data_enhanced/server/search/session/index.ts b/x-pack/plugins/data_enhanced/server/search/session/index.ts deleted file mode 100644 index 1e6841211bb66..0000000000000 --- a/x-pack/plugins/data_enhanced/server/search/session/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export * from './session_service'; diff --git a/x-pack/plugins/data_enhanced/server/search/session/session_service.ts b/x-pack/plugins/data_enhanced/server/search/session/session_service.ts deleted file mode 100644 index a22e559ecd142..0000000000000 --- a/x-pack/plugins/data_enhanced/server/search/session/session_service.ts +++ /dev/null @@ -1,548 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { notFound } from '@hapi/boom'; -import { debounce } from 'lodash'; -import { nodeBuilder, fromKueryExpression } from '@kbn/es-query'; -import { - CoreSetup, - CoreStart, - KibanaRequest, - SavedObjectsClientContract, - Logger, - SavedObject, - SavedObjectsFindOptions, - SavedObjectsErrorHelpers, -} from '@kbn/core/server'; -import { - IKibanaSearchRequest, - ISearchOptions, - ENHANCED_ES_SEARCH_STRATEGY, - SEARCH_SESSION_TYPE, -} from '@kbn/data-plugin/common'; -import { ISearchSessionService, NoSearchIdInSessionError } from '@kbn/data-plugin/server'; -import { AuthenticatedUser, SecurityPluginSetup } from '@kbn/security-plugin/server'; -import { - TaskManagerSetupContract, - TaskManagerStartContract, -} from '@kbn/task-manager-plugin/server'; -import { - SearchSessionRequestInfo, - SearchSessionSavedObjectAttributes, - SearchSessionStatus, -} from '@kbn/data-plugin/common'; -import { createRequestHash } from './utils'; -import { ConfigSchema } from '../../../config'; -import { - registerSearchSessionsTask, - scheduleSearchSessionsTask, - unscheduleSearchSessionsTask, -} from './setup_task'; -import { SearchSessionsConfig, SearchStatus } from './types'; -import { DataEnhancedStartDependencies } from '../../type'; -import { - checkPersistedSessionsProgress, - SEARCH_SESSIONS_TASK_ID, - SEARCH_SESSIONS_TASK_TYPE, -} from './check_persisted_sessions'; -import { - SEARCH_SESSIONS_CLEANUP_TASK_TYPE, - checkNonPersistedSessions, - SEARCH_SESSIONS_CLEANUP_TASK_ID, -} from './check_non_persisted_sessions'; -import { - SEARCH_SESSIONS_EXPIRE_TASK_TYPE, - SEARCH_SESSIONS_EXPIRE_TASK_ID, - checkPersistedCompletedSessionExpiration, -} from './expire_persisted_sessions'; - -export interface SearchSessionDependencies { - savedObjectsClient: SavedObjectsClientContract; -} -interface SetupDependencies { - taskManager: TaskManagerSetupContract; -} - -interface StartDependencies { - taskManager: TaskManagerStartContract; -} - -const DEBOUNCE_UPDATE_OR_CREATE_WAIT = 1000; -const DEBOUNCE_UPDATE_OR_CREATE_MAX_WAIT = 5000; - -interface UpdateOrCreateQueueEntry { - deps: SearchSessionDependencies; - user: AuthenticatedUser | null; - sessionId: string; - attributes: Partial; - resolve: () => void; - reject: (reason?: unknown) => void; -} - -function sleep(ms: number) { - return new Promise((r) => setTimeout(r, ms)); -} -export class SearchSessionService - implements ISearchSessionService -{ - private sessionConfig: SearchSessionsConfig; - private readonly updateOrCreateBatchQueue: UpdateOrCreateQueueEntry[] = []; - - constructor( - private readonly logger: Logger, - private readonly config: ConfigSchema, - private readonly version: string, - private readonly security?: SecurityPluginSetup - ) { - this.sessionConfig = this.config.search.sessions; - } - - public setup(core: CoreSetup, deps: SetupDependencies) { - const taskDeps = { - config: this.config, - taskManager: deps.taskManager, - logger: this.logger, - }; - - registerSearchSessionsTask( - core, - taskDeps, - SEARCH_SESSIONS_TASK_TYPE, - 'persisted session progress', - checkPersistedSessionsProgress - ); - - registerSearchSessionsTask( - core, - taskDeps, - SEARCH_SESSIONS_CLEANUP_TASK_TYPE, - 'non persisted session cleanup', - checkNonPersistedSessions - ); - - registerSearchSessionsTask( - core, - taskDeps, - SEARCH_SESSIONS_EXPIRE_TASK_TYPE, - 'complete session expiration', - checkPersistedCompletedSessionExpiration - ); - } - - public async start(core: CoreStart, deps: StartDependencies) { - return this.setupMonitoring(core, deps); - } - - public stop() {} - - private setupMonitoring = async (core: CoreStart, deps: StartDependencies) => { - const taskDeps = { - config: this.config, - taskManager: deps.taskManager, - logger: this.logger, - }; - - if (this.sessionConfig.enabled) { - scheduleSearchSessionsTask( - taskDeps, - SEARCH_SESSIONS_TASK_ID, - SEARCH_SESSIONS_TASK_TYPE, - this.sessionConfig.trackingInterval - ); - - scheduleSearchSessionsTask( - taskDeps, - SEARCH_SESSIONS_CLEANUP_TASK_ID, - SEARCH_SESSIONS_CLEANUP_TASK_TYPE, - this.sessionConfig.cleanupInterval - ); - - scheduleSearchSessionsTask( - taskDeps, - SEARCH_SESSIONS_EXPIRE_TASK_ID, - SEARCH_SESSIONS_EXPIRE_TASK_TYPE, - this.sessionConfig.expireInterval - ); - } else { - unscheduleSearchSessionsTask(taskDeps, SEARCH_SESSIONS_TASK_ID); - unscheduleSearchSessionsTask(taskDeps, SEARCH_SESSIONS_CLEANUP_TASK_ID); - unscheduleSearchSessionsTask(taskDeps, SEARCH_SESSIONS_EXPIRE_TASK_ID); - } - }; - - private processUpdateOrCreateBatchQueue = debounce( - () => { - const queue = [...this.updateOrCreateBatchQueue]; - if (queue.length === 0) return; - this.updateOrCreateBatchQueue.length = 0; - const batchedSessionAttributes = queue.reduce((res, next) => { - if (!res[next.sessionId]) { - res[next.sessionId] = next.attributes; - } else { - res[next.sessionId] = { - ...res[next.sessionId], - ...next.attributes, - idMapping: { - ...res[next.sessionId].idMapping, - ...next.attributes.idMapping, - }, - }; - } - return res; - }, {} as { [sessionId: string]: Partial }); - - Object.keys(batchedSessionAttributes).forEach((sessionId) => { - const thisSession = queue.filter((s) => s.sessionId === sessionId); - this.updateOrCreate( - thisSession[0].deps, - thisSession[0].user, - sessionId, - batchedSessionAttributes[sessionId] - ) - .then(() => { - thisSession.forEach((s) => s.resolve()); - }) - .catch((e) => { - thisSession.forEach((s) => s.reject(e)); - }); - }); - }, - DEBOUNCE_UPDATE_OR_CREATE_WAIT, - { maxWait: DEBOUNCE_UPDATE_OR_CREATE_MAX_WAIT } - ); - private scheduleUpdateOrCreate = ( - deps: SearchSessionDependencies, - user: AuthenticatedUser | null, - sessionId: string, - attributes: Partial - ): Promise => { - return new Promise((resolve, reject) => { - this.updateOrCreateBatchQueue.push({ deps, user, sessionId, attributes, resolve, reject }); - // TODO: this would be better if we'd debounce per sessionId - this.processUpdateOrCreateBatchQueue(); - }); - }; - - private updateOrCreate = async ( - deps: SearchSessionDependencies, - user: AuthenticatedUser | null, - sessionId: string, - attributes: Partial, - retry: number = 1 - ): Promise | undefined> => { - const retryOnConflict = async (e: any) => { - this.logger.debug(`Conflict error | ${sessionId}`); - // Randomize sleep to spread updates out in case of conflicts - await sleep(100 + Math.random() * 50); - return await this.updateOrCreate(deps, user, sessionId, attributes, retry + 1); - }; - - this.logger.debug(`updateOrCreate | ${sessionId} | ${retry}`); - try { - return (await this.update( - deps, - user, - sessionId, - attributes - )) as SavedObject; - } catch (e) { - if (SavedObjectsErrorHelpers.isNotFoundError(e)) { - try { - this.logger.debug(`Object not found | ${sessionId}`); - return await this.create(deps, user, sessionId, attributes); - } catch (createError) { - if ( - SavedObjectsErrorHelpers.isConflictError(createError) && - retry < this.sessionConfig.maxUpdateRetries - ) { - return await retryOnConflict(createError); - } else { - this.logger.error(createError); - } - } - } else if ( - SavedObjectsErrorHelpers.isConflictError(e) && - retry < this.sessionConfig.maxUpdateRetries - ) { - return await retryOnConflict(e); - } else { - this.logger.error(e); - } - } - - return undefined; - }; - - public save = async ( - deps: SearchSessionDependencies, - user: AuthenticatedUser | null, - sessionId: string, - { - name, - appId, - locatorId, - initialState = {}, - restoreState = {}, - }: Partial - ) => { - if (!this.sessionConfig.enabled) throw new Error('Search sessions are disabled'); - if (!name) throw new Error('Name is required'); - if (!appId) throw new Error('AppId is required'); - if (!locatorId) throw new Error('locatorId is required'); - - return this.updateOrCreate(deps, user, sessionId, { - name, - appId, - locatorId, - initialState, - restoreState, - persisted: true, - }); - }; - - private create = ( - { savedObjectsClient }: SearchSessionDependencies, - user: AuthenticatedUser | null, - sessionId: string, - attributes: Partial - ) => { - this.logger.debug(`create | ${sessionId}`); - - const realmType = user?.authentication_realm.type; - const realmName = user?.authentication_realm.name; - const username = user?.username; - - return savedObjectsClient.create( - SEARCH_SESSION_TYPE, - { - sessionId, - status: SearchSessionStatus.IN_PROGRESS, - expires: new Date( - Date.now() + this.sessionConfig.defaultExpiration.asMilliseconds() - ).toISOString(), - created: new Date().toISOString(), - touched: new Date().toISOString(), - idMapping: {}, - persisted: false, - version: this.version, - realmType, - realmName, - username, - ...attributes, - }, - { id: sessionId } - ); - }; - - public get = async ( - { savedObjectsClient }: SearchSessionDependencies, - user: AuthenticatedUser | null, - sessionId: string - ) => { - this.logger.debug(`get | ${sessionId}`); - const session = await savedObjectsClient.get( - SEARCH_SESSION_TYPE, - sessionId - ); - this.throwOnUserConflict(user, session); - return session; - }; - - public find = ( - { savedObjectsClient }: SearchSessionDependencies, - user: AuthenticatedUser | null, - options: Omit - ) => { - const userFilters = - user === null - ? [] - : [ - nodeBuilder.is( - `${SEARCH_SESSION_TYPE}.attributes.realmType`, - `${user.authentication_realm.type}` - ), - nodeBuilder.is( - `${SEARCH_SESSION_TYPE}.attributes.realmName`, - `${user.authentication_realm.name}` - ), - nodeBuilder.is(`${SEARCH_SESSION_TYPE}.attributes.username`, `${user.username}`), - ]; - const filterKueryNode = - typeof options.filter === 'string' ? fromKueryExpression(options.filter) : options.filter; - const filter = nodeBuilder.and(userFilters.concat(filterKueryNode ?? [])); - return savedObjectsClient.find({ - ...options, - filter, - type: SEARCH_SESSION_TYPE, - }); - }; - - public update = async ( - deps: SearchSessionDependencies, - user: AuthenticatedUser | null, - sessionId: string, - attributes: Partial - ) => { - this.logger.debug(`update | ${sessionId}`); - if (!this.sessionConfig.enabled) throw new Error('Search sessions are disabled'); - await this.get(deps, user, sessionId); // Verify correct user - return deps.savedObjectsClient.update( - SEARCH_SESSION_TYPE, - sessionId, - { - ...attributes, - touched: new Date().toISOString(), - } - ); - }; - - public async extend( - deps: SearchSessionDependencies, - user: AuthenticatedUser | null, - sessionId: string, - expires: Date - ) { - this.logger.debug(`extend | ${sessionId}`); - return this.update(deps, user, sessionId, { expires: expires.toISOString() }); - } - - public cancel = async ( - deps: SearchSessionDependencies, - user: AuthenticatedUser | null, - sessionId: string - ) => { - this.logger.debug(`delete | ${sessionId}`); - return this.update(deps, user, sessionId, { - status: SearchSessionStatus.CANCELLED, - }); - }; - - public delete = async ( - deps: SearchSessionDependencies, - user: AuthenticatedUser | null, - sessionId: string - ) => { - if (!this.sessionConfig.enabled) throw new Error('Search sessions are disabled'); - this.logger.debug(`delete | ${sessionId}`); - await this.get(deps, user, sessionId); // Verify correct user - return deps.savedObjectsClient.delete(SEARCH_SESSION_TYPE, sessionId); - }; - - /** - * Tracks the given search request/search ID in the saved session. - * @internal - */ - public trackId = async ( - deps: SearchSessionDependencies, - user: AuthenticatedUser | null, - searchRequest: IKibanaSearchRequest, - searchId: string, - { sessionId, strategy = ENHANCED_ES_SEARCH_STRATEGY }: ISearchOptions - ) => { - if (!this.sessionConfig.enabled || !sessionId || !searchId) return; - this.logger.debug(`trackId | ${sessionId} | ${searchId}`); - - let idMapping: Record = {}; - - if (searchRequest.params) { - const requestHash = createRequestHash(searchRequest.params); - const searchInfo = { - id: searchId, - strategy, - status: SearchStatus.IN_PROGRESS, - }; - idMapping = { [requestHash]: searchInfo }; - } - - await this.scheduleUpdateOrCreate(deps, user, sessionId, { idMapping }); - }; - - public async getSearchIdMapping( - deps: SearchSessionDependencies, - user: AuthenticatedUser | null, - sessionId: string - ) { - const searchSession = await this.get(deps, user, sessionId); - const searchIdMapping = new Map(); - Object.values(searchSession.attributes.idMapping).forEach((requestInfo) => { - searchIdMapping.set(requestInfo.id, requestInfo.strategy); - }); - return searchIdMapping; - } - - /** - * Look up an existing search ID that matches the given request in the given session so that the - * request can continue rather than restart. - * @internal - */ - public getId = async ( - deps: SearchSessionDependencies, - user: AuthenticatedUser | null, - searchRequest: IKibanaSearchRequest, - { sessionId, isStored, isRestore }: ISearchOptions - ) => { - if (!this.sessionConfig.enabled) { - throw new Error('Search sessions are disabled'); - } else if (!sessionId) { - throw new Error('Session ID is required'); - } else if (!isStored) { - throw new Error('Cannot get search ID from a session that is not stored'); - } else if (!isRestore) { - throw new Error('Get search ID is only supported when restoring a session'); - } - - const session = await this.get(deps, user, sessionId); - const requestHash = createRequestHash(searchRequest.params); - if (!session.attributes.idMapping.hasOwnProperty(requestHash)) { - this.logger.error(`getId | ${sessionId} | ${requestHash} not found`); - throw new NoSearchIdInSessionError(); - } - this.logger.debug(`getId | ${sessionId} | ${requestHash}`); - - return session.attributes.idMapping[requestHash].id; - }; - - public asScopedProvider = ({ savedObjects }: CoreStart) => { - return (request: KibanaRequest) => { - const user = this.security?.authc.getCurrentUser(request) ?? null; - const savedObjectsClient = savedObjects.getScopedClient(request, { - includedHiddenTypes: [SEARCH_SESSION_TYPE], - }); - const deps = { savedObjectsClient }; - return { - getId: this.getId.bind(this, deps, user), - trackId: this.trackId.bind(this, deps, user), - getSearchIdMapping: this.getSearchIdMapping.bind(this, deps, user), - save: this.save.bind(this, deps, user), - get: this.get.bind(this, deps, user), - find: this.find.bind(this, deps, user), - update: this.update.bind(this, deps, user), - extend: this.extend.bind(this, deps, user), - cancel: this.cancel.bind(this, deps, user), - delete: this.delete.bind(this, deps, user), - getConfig: () => this.config.search.sessions, - }; - }; - }; - - private throwOnUserConflict = ( - user: AuthenticatedUser | null, - session?: SavedObject - ) => { - if (user === null || !session) return; - if ( - user.authentication_realm.type !== session.attributes.realmType || - user.authentication_realm.name !== session.attributes.realmName || - user.username !== session.attributes.username - ) { - this.logger.debug( - `User ${user.username} has no access to search session ${session.attributes.sessionId}` - ); - throw notFound(); - } - }; -} diff --git a/x-pack/plugins/data_enhanced/server/search/session/types.ts b/x-pack/plugins/data_enhanced/server/search/session/types.ts deleted file mode 100644 index 37e1cb2486154..0000000000000 --- a/x-pack/plugins/data_enhanced/server/search/session/types.ts +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - ElasticsearchClient, - Logger, - SavedObjectsClientContract, - SavedObjectsFindResponse, -} from '@kbn/core/server'; -import { Observable } from 'rxjs'; -import { KueryNode, SearchSessionSavedObjectAttributes } from '@kbn/data-plugin/common'; -import { - TaskManagerSetupContract, - TaskManagerStartContract, -} from '@kbn/task-manager-plugin/server'; -import { ConfigSchema } from '../../../config'; - -export enum SearchStatus { - IN_PROGRESS = 'in_progress', - ERROR = 'error', - COMPLETE = 'complete', -} - -export type SearchSessionsConfig = ConfigSchema['search']['sessions']; - -export interface CheckSearchSessionsDeps { - savedObjectsClient: SavedObjectsClientContract; - client: ElasticsearchClient; - logger: Logger; -} - -export interface SearchSessionTaskSetupDeps { - taskManager: TaskManagerSetupContract; - logger: Logger; - config: ConfigSchema; -} - -export interface SearchSessionTaskStartDeps { - taskManager: TaskManagerStartContract; - logger: Logger; - config: ConfigSchema; -} - -export type SearchSessionTaskFn = ( - deps: CheckSearchSessionsDeps, - config: SearchSessionsConfig -) => Observable; - -export type SearchSessionsResponse = SavedObjectsFindResponse< - SearchSessionSavedObjectAttributes, - unknown ->; - -export type CheckSearchSessionsFn = ( - deps: CheckSearchSessionsDeps, - config: SearchSessionsConfig, - filter: KueryNode, - page: number -) => Observable; diff --git a/x-pack/plugins/data_enhanced/server/search/session/utils.test.ts b/x-pack/plugins/data_enhanced/server/search/session/utils.test.ts deleted file mode 100644 index 9e142bf25a56a..0000000000000 --- a/x-pack/plugins/data_enhanced/server/search/session/utils.test.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { createRequestHash } from './utils'; - -describe('data/search/session utils', () => { - describe('createRequestHash', () => { - it('ignores `preference`', () => { - const request = { - foo: 'bar', - }; - - const withPreference = { - ...request, - preference: 1234, - }; - - expect(createRequestHash(request)).toEqual(createRequestHash(withPreference)); - }); - }); -}); diff --git a/x-pack/plugins/data_enhanced/server/search/session/utils.ts b/x-pack/plugins/data_enhanced/server/search/session/utils.ts deleted file mode 100644 index f7f3c3c17505b..0000000000000 --- a/x-pack/plugins/data_enhanced/server/search/session/utils.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { createHash } from 'crypto'; -import stringify from 'json-stable-stringify'; -import { SavedObjectsFindResult } from '@kbn/core/server'; -import moment from 'moment'; -import { SearchSessionSavedObjectAttributes } from '@kbn/data-plugin/common'; - -/** - * Generate the hash for this request so that, in the future, this hash can be used to look up - * existing search IDs for this request. Ignores the `preference` parameter since it generally won't - * match from one request to another identical request. - */ -export function createRequestHash(keys: Record) { - const { preference, ...params } = keys; - return createHash(`sha256`).update(stringify(params)).digest('hex'); -} - -export function isSearchSessionExpired( - session: SavedObjectsFindResult -) { - return moment(session.attributes.expires).isBefore(moment()); -} diff --git a/x-pack/plugins/data_enhanced/server/type.ts b/x-pack/plugins/data_enhanced/server/type.ts deleted file mode 100644 index df465cdbb381d..0000000000000 --- a/x-pack/plugins/data_enhanced/server/type.ts +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { IRouter } from '@kbn/core/server'; -import type { DataRequestHandlerContext } from '@kbn/data-plugin/server'; -import { - TaskManagerSetupContract, - TaskManagerStartContract, -} from '@kbn/task-manager-plugin/server'; -import { - PluginSetup as DataPluginSetup, - PluginStart as DataPluginStart, -} from '@kbn/data-plugin/server'; -import { SecurityPluginSetup } from '@kbn/security-plugin/server'; -import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server'; - -/** - * @internal - */ -export type DataEnhancedRequestHandlerContext = DataRequestHandlerContext; - -/** - * @internal - */ -export type DataEnhancedPluginRouter = IRouter; - -export interface DataEnhancedSetupDependencies { - data: DataPluginSetup; - usageCollection?: UsageCollectionSetup; - taskManager: TaskManagerSetupContract; - security?: SecurityPluginSetup; -} - -export interface DataEnhancedStartDependencies { - data: DataPluginStart; - taskManager: TaskManagerStartContract; -} diff --git a/x-pack/plugins/data_enhanced/tsconfig.json b/x-pack/plugins/data_enhanced/tsconfig.json deleted file mode 100644 index 5627951c3d9eb..0000000000000 --- a/x-pack/plugins/data_enhanced/tsconfig.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "outDir": "./target/types", - "emitDeclarationOnly": true, - "declaration": true, - "declarationMap": true, - }, - "include": [ - "common/**/*", - "public/**/*", - "server/**/*", - "config.ts", - "../../../typings/**/*", - "common/search/test_data/*.json" - ], - "references": [ - { "path": "../../../src/core/tsconfig.json" }, - { "path": "../../../src/plugins/bfetch/tsconfig.json" }, - { "path": "../../../src/plugins/data/tsconfig.json" }, - { "path": "../../../src/plugins/kibana_react/tsconfig.json" }, - { "path": "../../../src/plugins/kibana_utils/tsconfig.json" }, - { "path": "../../../src/plugins/usage_collection/tsconfig.json" }, - { "path": "../../../src/plugins/management/tsconfig.json" }, - { "path": "../../../src/plugins/screenshot_mode/tsconfig.json"}, - { "path": "../security/tsconfig.json" }, - { "path": "../task_manager/tsconfig.json" }, - - { "path": "../features/tsconfig.json" }, - ] -} diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/automated_curation_history.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/automated_curation_history.test.tsx index cd8ba123b5843..7c05a3a6b0f05 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/automated_curation_history.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/automated_curation_history.test.tsx @@ -9,8 +9,14 @@ import React from 'react'; import { shallow } from 'enzyme'; +import { EuiButtonEmpty } from '@elastic/eui'; + +import { nextTick } from '@kbn/test-jest-helpers'; + import { EntSearchLogStream } from '../../../../shared/log_stream'; +import { DataPanel } from '../../data_panel'; + import { AutomatedCurationHistory } from './automated_curation_history'; describe('AutomatedCurationHistory', () => { @@ -20,4 +26,17 @@ describe('AutomatedCurationHistory', () => { 'appsearch.adaptive_relevance.query: some text and event.kind: event and event.dataset: search-relevance-suggestions and appsearch.adaptive_relevance.engine: foo and event.action: curation_suggestion and appsearch.adaptive_relevance.suggestion.new_status: automated' ); }); + + it('sets new endTimestamp when refresh is pressed', async () => { + const wrapper = shallow(); + const initialTimestamp = wrapper.find(EntSearchLogStream).prop('endTimestamp'); + await nextTick(); + + // Find the refresh button and click + shallow(wrapper.find(DataPanel).prop('title')).find(EuiButtonEmpty).simulate('click'); + + wrapper.update(); + + expect(wrapper.find(EntSearchLogStream).prop('endTimestamp')).not.toEqual(initialTimestamp); + }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/automated_curations_history_panel.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/automated_curations_history_panel.test.tsx index 36703dc0d0d85..8e2f3e8eff0af 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/automated_curations_history_panel.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/automated_curations_history_panel.test.tsx @@ -13,6 +13,10 @@ import React from 'react'; import { shallow } from 'enzyme'; +import { EuiButtonEmpty } from '@elastic/eui'; + +import { nextTick } from '@kbn/test-jest-helpers'; + import { EntSearchLogStream } from '../../../../../../shared/log_stream'; import { DataPanel } from '../../../../data_panel'; @@ -32,4 +36,17 @@ describe('AutomatedCurationsHistoryPanel', () => { 'event.kind: event and event.dataset: search-relevance-suggestions and appsearch.adaptive_relevance.engine: some-engine and event.action: curation_suggestion and appsearch.adaptive_relevance.suggestion.new_status: automated' ); }); + + it('sets new endTimestamp when refresh is pressed', async () => { + const wrapper = shallow(); + const initialTimestamp = wrapper.find(EntSearchLogStream).prop('endTimestamp'); + await nextTick(); + + // Find the refresh button and click + shallow(wrapper.find(DataPanel).prop('title')).find(EuiButtonEmpty).simulate('click'); + + wrapper.update(); + + expect(wrapper.find(EntSearchLogStream).prop('endTimestamp')).not.toEqual(initialTimestamp); + }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/ignored_queries_panel/ignored_queries_panel.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/ignored_queries_panel/ignored_queries_panel.test.tsx index 8c1b4212040aa..e9412966d00ef 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/ignored_queries_panel/ignored_queries_panel.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_history/components/ignored_queries_panel/ignored_queries_panel.test.tsx @@ -15,7 +15,9 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { EuiBasicTable } from '@elastic/eui'; +import { EuiBasicTable, EuiButtonEmpty } from '@elastic/eui'; + +import { DataPanel } from '../../../../../data_panel'; import { IgnoredQueriesPanel } from './ignored_queries_panel'; @@ -91,4 +93,13 @@ describe('IgnoredQueriesPanel', () => { expect(mockActions.onPaginate).toHaveBeenCalledWith(1); }); + + it('fetches data on refresh button press', () => { + const wrapper = shallow(); + expect(mockActions.loadIgnoredQueries).toHaveBeenCalledTimes(1); + + shallow(wrapper.find(DataPanel).prop('title')).find(EuiButtonEmpty).simulate('click'); + + expect(mockActions.loadIgnoredQueries).toHaveBeenCalledTimes(2); + }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/audit_logs_modal/audit_logs_modal.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/audit_logs_modal/audit_logs_modal.tsx index 3807234fd5c11..ea5abb74d5ac0 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/audit_logs_modal/audit_logs_modal.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/audit_logs_modal/audit_logs_modal.tsx @@ -92,7 +92,7 @@ export const AuditLogsModal: React.FC = () => { }, { type: 'field', - field: 'outcome', + field: 'event.outcome', header: i18n.translate( 'xpack.enterpriseSearch.appSearch.engines.auditLogsModal.headers.outcome', { @@ -101,7 +101,8 @@ export const AuditLogsModal: React.FC = () => { ), }, { - type: 'message', + type: 'field', + field: 'message', width: '50%', }, ]} diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/index.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/index.ts index 24fa58e60e853..297bbaf36c454 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/index.ts @@ -6,3 +6,4 @@ */ export { searchIndices } from './search_indices.mock'; +export { searchEngines } from './search_engines.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/search_engines.mock.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/search_engines.mock.ts new file mode 100644 index 0000000000000..775f7dde83d87 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/search_engines.mock.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Engine } from '../../app_search/components/engine/types'; + +// TODO populate them +export const searchEngines = [ + { name: 'My First Search Engine' }, + { name: 'Another Search Engine' }, + { name: 'Dharma Initiative Research' }, + { name: 'Flight 815 Customer Feedback' }, + { name: 'The Swan Station Manuals' }, + { name: 'The Hydra Station Manuals' }, +] as Engine[]; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices.test.tsx new file mode 100644 index 0000000000000..ebc8fe1995f5f --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices.test.tsx @@ -0,0 +1,96 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import '../../../__mocks__/shallow_useeffect.mock'; +import { setMockValues, setMockActions } from '../../../__mocks__/kea_logic'; +import { searchIndices, searchEngines } from '../../__mocks__'; + +import React from 'react'; + +import { shallow } from 'enzyme'; + +import { EuiBasicTable } from '@elastic/eui'; + +import { AddContentEmptyPrompt } from '../../../shared/add_content_empty_prompt'; +import { ElasticsearchResources } from '../../../shared/elasticsearch_resources'; +import { GettingStartedSteps } from '../../../shared/getting_started_steps'; + +import { SearchIndices } from './search_indices'; + +const mockActions = { + initPage: jest.fn(), +}; + +describe('SearchIndices', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + describe('Empty state', () => { + it('renders when both Search Indices and Search Engines empty', () => { + setMockValues({ + searchIndices: [], + searchEngines: [], + }); + setMockActions(mockActions); + const wrapper = shallow(); + + expect(wrapper.find(AddContentEmptyPrompt)).toHaveLength(1); + expect(wrapper.find(EuiBasicTable)).toHaveLength(0); + + expect(wrapper.find(GettingStartedSteps)).toHaveLength(1); + expect(wrapper.find(ElasticsearchResources)).toHaveLength(1); + }); + + it('renders complete empty state when only Search Indices empty', () => { + setMockValues({ + searchIndices: [], + searchEngines, + }); + setMockActions(mockActions); + const wrapper = shallow(); + + expect(wrapper.find(AddContentEmptyPrompt)).toHaveLength(1); + expect(wrapper.find(EuiBasicTable)).toHaveLength(0); + + expect(wrapper.find(GettingStartedSteps)).toHaveLength(1); + expect(wrapper.find(ElasticsearchResources)).toHaveLength(1); + }); + + it('renders when only Search Engines empty', () => { + setMockValues({ + searchIndices, + searchEngines: [], + }); + setMockActions(mockActions); + const wrapper = shallow(); + + expect(wrapper.find(AddContentEmptyPrompt)).toHaveLength(0); + expect(wrapper.find(EuiBasicTable)).toHaveLength(1); + + expect(wrapper.find(GettingStartedSteps)).toHaveLength(1); + expect(wrapper.find(ElasticsearchResources)).toHaveLength(1); + }); + }); + + it('renders with Data', () => { + setMockValues({ + searchIndices, + searchEngines, + }); + setMockActions(mockActions); + + const wrapper = shallow(); + + expect(wrapper.find(AddContentEmptyPrompt)).toHaveLength(0); + expect(wrapper.find(EuiBasicTable)).toHaveLength(1); + + expect(wrapper.find(GettingStartedSteps)).toHaveLength(0); + expect(wrapper.find(ElasticsearchResources)).toHaveLength(0); + + expect(mockActions.initPage).toHaveBeenCalledTimes(1); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices.tsx index 6c82d56572cec..3fc8f4abca0c1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices.tsx @@ -5,21 +5,34 @@ * 2.0. */ -import { searchIndices } from '../../__mocks__'; - -import React from 'react'; +import React, { useEffect } from 'react'; import { generatePath } from 'react-router-dom'; -import { EuiBasicTable, EuiButton, HorizontalAlignment } from '@elastic/eui'; +import { useValues, useActions } from 'kea'; + +import { + EuiBasicTable, + EuiButton, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, + EuiTitle, + HorizontalAlignment, +} from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { AddContentEmptyPrompt } from '../../../shared/add_content_empty_prompt'; +import { ElasticsearchResources } from '../../../shared/elasticsearch_resources'; +import { GettingStartedSteps } from '../../../shared/getting_started_steps'; import { EuiLinkTo, EuiButtonIconTo } from '../../../shared/react_router_helpers'; import { SEARCH_INDEX_OVERVIEW_PATH, NEW_INDEX_PATH } from '../../routes'; import { SearchIndex } from '../../types'; import { EnterpriseSearchContentPageTemplate } from '../layout/page_template'; +import { SearchIndicesLogic } from './search_indices_logic'; + export const baseBreadcrumbs = [ i18n.translate('xpack.enterpriseSearch.content.searchIndices.content.breadcrumb', { defaultMessage: 'Content', @@ -30,6 +43,22 @@ export const baseBreadcrumbs = [ ]; export const SearchIndices: React.FC = () => { + const { initPage, searchEnginesLoadSuccess, searchIndicesLoadSuccess } = + useActions(SearchIndicesLogic); + const { searchIndices, searchEngines } = useValues(SearchIndicesLogic); + + useEffect(() => { + initPage(); + }, []); + + // TODO This is for easy testing until we have the backend, please remove this before the release + // @ts-ignore + window.contentActions = { + initPage, + searchIndicesLoadSuccess, + searchEnginesLoadSuccess, + }; + // TODO: Replace with a real list of indices const columns = [ { @@ -114,22 +143,72 @@ export const SearchIndices: React.FC = () => { ); - return ( - + +

+ {i18n.translate('xpack.enterpriseSearch.content.searchIndices.searchIndices.stepsTitle', { + defaultMessage: 'Build beautiful search experiences with Enterprise Search', + })} +

+
+ + + + + + + + + + + ); + + const pageTitle = + searchIndices.length !== 0 + ? i18n.translate('xpack.enterpriseSearch.content.searchIndices.searchIndices.pageTitle', { + defaultMessage: 'Content', + }) + : i18n.translate( + 'xpack.enterpriseSearch.content.searchIndices.searchIndices.emptyPageTitle', { - defaultMessage: 'Search indices', + defaultMessage: 'Welcome to Enterprise Search', } - ), - rightSideItems: [createNewIndexButton], - }} - > - -
+ ); + + return ( + <> + + {searchIndices.length !== 0 ? ( + <> + +

+ {i18n.translate( + 'xpack.enterpriseSearch.content.searchIndices.searchIndices.tableTitle', + { + defaultMessage: 'Search Indices', + } + )} +

+
+ + + + ) : ( + + )} + + {(searchEngines.length === 0 || searchIndices.length === 0) && engineSteps} +
+ ) + ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices_logic.test.ts new file mode 100644 index 0000000000000..36934bf61183d --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices_logic.test.ts @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { LogicMounter } from '../../../__mocks__/kea_logic'; +import { searchIndices, searchEngines } from '../../__mocks__'; + +import { SearchIndicesLogic } from './search_indices_logic'; + +describe('SearchIndicesLogic', () => { + const { mount } = new LogicMounter(SearchIndicesLogic); + + const DEFAULT_VALUES = { + searchEngines: [], + searchIndices: [], + }; + + beforeEach(() => { + jest.clearAllMocks(); + mount(); + }); + + it('has expected default values', () => { + expect(SearchIndicesLogic.values).toEqual(DEFAULT_VALUES); + }); + + describe('actions', () => { + describe('searchIndicesLoadSuccess', () => { + it('should set searchIndices', () => { + SearchIndicesLogic.actions.searchIndicesLoadSuccess(searchIndices); + expect(SearchIndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, + searchIndices, + }); + }); + }); + describe('searchEnginesLoadSuccess', () => { + it('should set searchEngines', () => { + SearchIndicesLogic.actions.searchEnginesLoadSuccess(searchEngines); + expect(SearchIndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, + searchEngines, + }); + }); + }); + }); + + describe.skip('listeners', () => { + describe('loadSearchEngines', () => {}); + describe('loadSearchIndices', () => {}); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices_logic.ts new file mode 100644 index 0000000000000..3ad053b339b63 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices_logic.ts @@ -0,0 +1,79 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + searchIndices as searchIndicesMock, + searchEngines as searchEnginesMock, +} from '../../__mocks__'; + +import { kea, MakeLogicType } from 'kea'; + +import { Engine } from '../../../app_search/components/engine/types'; +import { flashAPIErrors } from '../../../shared/flash_messages'; +import { SearchIndex } from '../../types'; + +export interface SearchIndicesValues { + searchIndices: SearchIndex[]; + searchEngines: Engine[]; +} + +export interface SearchIndicesActions { + initPage(): void; + loadSearchEngines(): void; + searchEnginesLoadSuccess(searchEngines: Engine[]): Engine[]; // TODO proper types when backend ready + loadSearchIndices(): void; + searchIndicesLoadSuccess(searchIndices: SearchIndex[]): SearchIndex[]; // TODO proper types when backend ready +} + +export const SearchIndicesLogic = kea>({ + path: ['enterprise_search', 'content', 'search_indices', 'search_indices_logic'], + actions: { + initPage: true, + loadSearchIndices: true, + searchIndicesLoadSuccess: (searchIndices) => searchIndices, + loadSearchEngines: true, + searchEnginesLoadSuccess: (searchEngines) => searchEngines, + }, + reducers: { + searchIndices: [ + [], + { + searchIndicesLoadSuccess: (_, searchIndices) => searchIndices, + }, + ], + searchEngines: [ + [], + { + searchEnginesLoadSuccess: (_, searchEngines) => searchEngines, + }, + ], + }, + listeners: ({ actions }) => ({ + initPage: async () => { + actions.loadSearchEngines(); + actions.loadSearchIndices(); + }, + loadSearchEngines: async () => { + try { + // TODO replace with actual backend call, add test cases + const response = await Promise.resolve(searchEnginesMock); + actions.searchEnginesLoadSuccess(response); + } catch (e) { + flashAPIErrors(e); + } + }, + loadSearchIndices: async () => { + try { + // TODO replace with actual backend call, add test cases + const response = await Promise.resolve(searchIndicesMock); + actions.searchIndicesLoadSuccess(response); + } catch (e) { + flashAPIErrors(e); + } + }, + }), +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/types.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/types.ts index 48e0b53d35f6c..30af95427fe43 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/types.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/types.ts @@ -6,7 +6,7 @@ */ /** - * As of 2022-04-04, this shapre is still in debate. Specifically, the `source_type` will be changing as we get closer to 8.3. + * As of 2022-04-04, this shape is still in debate. Specifically, the `source_type` will be changing as we get closer to 8.3. * These merely serve as placeholders for static data for now. */ export interface SearchIndex { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_card/elasticsearch_card.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_card/elasticsearch_card.tsx index 0283249ac2890..fd84267ebb8e4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_card/elasticsearch_card.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_card/elasticsearch_card.tsx @@ -11,9 +11,9 @@ import { EuiPanel, EuiFlexGroup, EuiFlexItem, EuiText, EuiTitle, EuiSpacer } fro import { i18n } from '@kbn/i18n'; +import { ElasticsearchResources } from '../../../shared/elasticsearch_resources'; import { EuiButtonTo } from '../../../shared/react_router_helpers'; import { ELASTICSEARCH_GUIDE_PATH } from '../../routes'; -import { ElasticsearchResources } from '../elasticsearch_resources'; export const ElasticsearchCard: React.FC = () => { return ( diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_guide/elasticsearch_guide.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_guide/elasticsearch_guide.tsx index fb1bc7a2820e2..d722cfd637cce 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_guide/elasticsearch_guide.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_guide/elasticsearch_guide.tsx @@ -24,10 +24,10 @@ import { import { i18n } from '@kbn/i18n'; import { docLinks } from '../../../shared/doc_links'; +import { ElasticsearchResources } from '../../../shared/elasticsearch_resources'; import { ElasticsearchClientInstructions } from '../elasticsearch_client_instructions'; import { ElasticsearchCloudId } from '../elasticsearch_cloud_id'; -import { ElasticsearchResources } from '../elasticsearch_resources'; // Replace FormattedMessage with i18n strings diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/index.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/index.ts index 09a1e910fbbda..ea69823f82b87 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/index.ts @@ -7,3 +7,4 @@ export { useEnterpriseSearchOverviewNav } from './nav'; export { EnterpriseSearchOverviewPageTemplate } from './page_template'; +export { EnterpriseSearchOverviewHeaderActions } from './kibana_header_actions'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/kibana_header_actions.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/kibana_header_actions.test.tsx new file mode 100644 index 0000000000000..88f5da60e3627 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/kibana_header_actions.test.tsx @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { mount } from 'enzyme'; + +import { EuiPopover, EuiButtonEmpty } from '@elastic/eui'; + +import { EnterpriseSearchOverviewHeaderActions } from './kibana_header_actions'; + +describe('Enterprise Search overview HeaderActions', () => { + it('renders', () => { + const wrapper = mount(); + const popover = wrapper.find(EuiPopover); + + expect(popover.find(EuiButtonEmpty).text()).toContain('Deployment details'); + expect(popover.prop('isOpen')).toBeFalsy(); + }); + + it('opens popover when clicked', () => { + const wrapper = mount(); + + expect(wrapper.find(EuiPopover).prop('isOpen')).toBeFalsy(); + wrapper.find(EuiPopover).find(EuiButtonEmpty).simulate('click'); + wrapper.update(); + + expect(wrapper.find(EuiPopover).prop('isOpen')).toBeTruthy(); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/kibana_header_actions.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/kibana_header_actions.tsx new file mode 100644 index 0000000000000..0383618ecf87b --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/layout/kibana_header_actions.tsx @@ -0,0 +1,115 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useState } from 'react'; + +import { + EuiHeaderLinks, + EuiIcon, + EuiCopy, + EuiButton, + EuiButtonEmpty, + EuiButtonIcon, + EuiPopover, + EuiFormRow, + EuiFieldText, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, + EuiPopoverTitle, + EuiPopoverFooter, + EuiText, +} from '@elastic/eui'; + +import { i18n } from '@kbn/i18n'; + +export const EnterpriseSearchOverviewHeaderActions: React.FC = () => { + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + // TODO change it with actual value + // TODO make this conditional only for users on cloud, as on-prem users will not have a deployment id to show. + const clientId = 'fgdshjafghj13eshfdjag718yfhjdskf'; + + return ( + + setIsPopoverOpen(!isPopoverOpen)}> + +   + {i18n.translate('xpack.enterpriseSearch.overview.deploymentDetails', { + defaultMessage: 'Deployment details', + })} + + } + isOpen={isPopoverOpen} + closePopover={() => setIsPopoverOpen(false)} + > + + {i18n.translate('xpack.enterpriseSearch.overview.deploymentDetails', { + defaultMessage: 'Deployment details', + })} + + +

+ {i18n.translate('xpack.enterpriseSearch.overview.deploymentDetails.description', { + defaultMessage: + 'Send data to Elastic from your applications by referencing your deployment and Elasticsearch information.', + })} +

+
+ + + + + + + + + {(copy) => ( + + )} + + + + + + {/* TODO need link to Create and manage API keys*/} + + {i18n.translate('xpack.enterpriseSearch.overview.createAndManageButton', { + defaultMessage: 'Create and manage API keys', + })} + + +
+
+ ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/overview_content/index.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/overview_content/index.ts new file mode 100644 index 0000000000000..83d1f526c36cb --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/overview_content/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { OverviewContent } from './overview_content'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/overview_content/overview_content.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/overview_content/overview_content.test.tsx new file mode 100644 index 0000000000000..53c31eaf0498a --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/overview_content/overview_content.test.tsx @@ -0,0 +1,73 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { setMockValues } from '../../../__mocks__/kea_logic'; + +import React from 'react'; + +import { shallow } from 'enzyme'; + +import { EuiEmptyPrompt } from '@elastic/eui'; + +import { AddContentEmptyPrompt } from '../../../shared/add_content_empty_prompt'; +import { GettingStartedSteps } from '../../../shared/getting_started_steps'; + +import { LicenseCallout } from '../license_callout'; +import { SetupGuideCta } from '../setup_guide'; +import { TrialCallout } from '../trial_callout'; + +import { OverviewContent } from '.'; + +describe('OverviewContent', () => { + const props = { + access: {}, + isWorkplaceSearchAdmin: true, + }; + + it('renders the overview page, Getting Started steps & setup guide CTAs with no host set', () => { + setMockValues({ config: { host: '' } }); + const wrapper = shallow(); + + expect(wrapper.find(GettingStartedSteps)).toHaveLength(1); + expect(wrapper.find(AddContentEmptyPrompt)).toHaveLength(1); + expect(wrapper.find(SetupGuideCta)).toHaveLength(1); + expect(wrapper.find(LicenseCallout)).toHaveLength(0); + }); + + it('renders the trial callout', () => { + setMockValues({ config: { host: 'localhost' } }); + const wrapper = shallow(); + + expect(wrapper.find(TrialCallout)).toHaveLength(1); + }); + + // TODO Refactor this and other tests according to the search indices permissions + describe('access checks when host is set', () => { + beforeEach(() => { + setMockValues({ config: { host: 'localhost' } }); + }); + + it('renders the license callout when user has access to a product', () => { + setMockValues({ config: { host: 'localhost' } }); + const wrapper = shallow( + + ); + + expect(wrapper.find(LicenseCallout)).toHaveLength(1); + }); + + it('renders empty prompt and overview or license callout if the user does not have access', () => { + const wrapper = shallow(); + + expect(wrapper.find(EuiEmptyPrompt)).toHaveLength(1); + expect(wrapper.find(GettingStartedSteps)).toHaveLength(0); + expect(wrapper.find(AddContentEmptyPrompt)).toHaveLength(0); + expect(wrapper.find(LicenseCallout)).toHaveLength(0); + expect(wrapper.find(SetupGuideCta)).toHaveLength(0); + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/overview_content/overview_content.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/overview_content/overview_content.tsx new file mode 100644 index 0000000000000..3824a09a0bc1c --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/overview_content/overview_content.tsx @@ -0,0 +1,159 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { useValues } from 'kea'; + +import { + EuiButton, + EuiEmptyPrompt, + EuiFlexGroup, + EuiFlexItem, + EuiImage, + EuiLink, + EuiPageBody, + EuiSpacer, + EuiTitle, +} from '@elastic/eui'; +import { Chat } from '@kbn/cloud-plugin/public'; +import { i18n } from '@kbn/i18n'; + +import { AddContentEmptyPrompt } from '../../../shared/add_content_empty_prompt'; +import { docLinks } from '../../../shared/doc_links'; +import { ElasticsearchResources } from '../../../shared/elasticsearch_resources'; +import { GettingStartedSteps } from '../../../shared/getting_started_steps'; +import { KibanaLogic } from '../../../shared/kibana'; +import { SetEnterpriseSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; +import { SendEnterpriseSearchTelemetry as SendTelemetry } from '../../../shared/telemetry'; + +import { EnterpriseSearchOverviewPageTemplate } from '../layout'; +import { LicenseCallout } from '../license_callout'; +import illustration from '../product_selector/lock_light.svg'; +import { SetupGuideCta } from '../setup_guide'; + +import { TrialCallout } from '../trial_callout'; + +interface OverviewContentProps { + access: { + hasAppSearchAccess?: boolean; + hasWorkplaceSearchAccess?: boolean; + }; + isWorkplaceSearchAdmin: boolean; +} + +export const OverviewContent: React.FC = ({ access }) => { + const { hasAppSearchAccess, hasWorkplaceSearchAccess } = access; + const { config } = useValues(KibanaLogic); + + // TODO Refactor this and the tests according to the search indices permissions + // If Enterprise Search has been set up and the user does not have access to either product, show a message saying they + // need to contact an administrator to get access to one of the products. + const shouldShowEnterpriseSearchOverview = + !config.host || hasAppSearchAccess || hasWorkplaceSearchAccess; + + const enterpriseSearchOverview = ( + <> + + + + + + + + + + + + + {config.host ? : } + + ); + + const insufficientAccessMessage = ( + + } + title={ +

+ {i18n.translate('xpack.enterpriseSearch.overviewContent.insufficientPermissionsTitle', { + defaultMessage: 'Insufficient permissions', + })} +

+ } + layout="horizontal" + color="plain" + body={ + <> +

+ {i18n.translate('xpack.enterpriseSearch.overviewContent.insufficientPermissionsBody', { + defaultMessage: + 'You don’t have access to view this page. If you feel this may be an error, please contact your administrator.', + })} +

+ + } + actions={ + + {i18n.translate( + 'xpack.enterpriseSearch.overviewContent.insufficientPermissionsButtonLabel', + { + defaultMessage: 'Go to the Kibana dashboard', + } + )} + + } + footer={ + <> + + + {i18n.translate( + 'xpack.enterpriseSearch.overviewContent.insufficientPermissionsFooterBody', + { + defaultMessage: 'Go to the Kibana dashboard', + } + )} + + {' '} + + {i18n.translate( + 'xpack.enterpriseSearch.overviewContent.insufficientPermissionsFooterLinkLabel', + { + defaultMessage: 'Read documentation', + } + )} + + + } + /> + ); + return ( + + + + + + {shouldShowEnterpriseSearchOverview ? enterpriseSearchOverview : insufficientAccessMessage} + + + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/add_content_empty_prompt.scss b/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/add_content_empty_prompt.scss new file mode 100644 index 0000000000000..c0fafb151174d --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/add_content_empty_prompt.scss @@ -0,0 +1,7 @@ +.addContentEmptyPrompt { + @include euiBreakpoint('xs','s') { + flex-direction: column-reverse; + } + + border-bottom: $euiBorderThin; +} diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/add_content_empty_prompt.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/add_content_empty_prompt.test.tsx new file mode 100644 index 0000000000000..667a643c13cd4 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/add_content_empty_prompt.test.tsx @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { shallow, ShallowWrapper } from 'enzyme'; + +import { EuiLinkTo } from '../react_router_helpers'; + +import { AddContentEmptyPrompt } from '.'; + +describe('AddContentEmptyPrompt', () => { + let wrapper: ShallowWrapper; + + beforeAll(() => { + wrapper = shallow(); + }); + + it('renders', () => { + expect(wrapper.find('h2').text()).toEqual('Add content to Enterprise Search'); + expect(wrapper.find(EuiLinkTo).prop('to')).toEqual( + '/app/enterprise_search/content/search_indices/new_index' + ); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/add_content_empty_prompt.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/add_content_empty_prompt.tsx new file mode 100644 index 0000000000000..6025fbbdb96c0 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/add_content_empty_prompt.tsx @@ -0,0 +1,96 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { generatePath } from 'react-router-dom'; + +import { + EuiImage, + EuiFlexGroup, + EuiFlexItem, + EuiButton, + EuiLink, + EuiPanel, + EuiTitle, + EuiText, + EuiSpacer, +} from '@elastic/eui'; + +import { i18n } from '@kbn/i18n'; + +import { ENTERPRISE_SEARCH_CONTENT_PLUGIN } from '../../../../common/constants'; +import { NEW_INDEX_PATH } from '../../enterprise_search_content/routes'; +import { EuiLinkTo } from '../react_router_helpers'; + +import searchIndicesIllustration from './search_indices.svg'; +import './add_content_empty_prompt.scss'; + +export const AddContentEmptyPrompt: React.FC = () => { + return ( + + + + + + +

+ {i18n.translate('xpack.enterpriseSearch.overview.emptyState.heading', { + defaultMessage: 'Add content to Enterprise Search', + })} +

+
+ + +

+ {i18n.translate('xpack.enterpriseSearch.emptyState.description', { + defaultMessage: + "Data you add in Enterprise Search is called a Search index and it's searchable in both App and Workplace Search. Now you can use your connectors in App Search and your web crawlers in Workplace Search.", + })} +

+
+
+ + + + + + {i18n.translate('xpack.enterpriseSearch.overview.emptyState.buttonTitle', { + defaultMessage: 'Add content to Enterprise Search', + })} + + + + + {/* TODO need link for Learn More link*/} + + {i18n.translate('xpack.enterpriseSearch.overview.emptyState.footerLinkTitle', { + defaultMessage: 'Learn more', + })} + + + + +
+
+ + + +
+
+ ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/index.ts new file mode 100644 index 0000000000000..1ae85c30a2f5c --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { AddContentEmptyPrompt } from './add_content_empty_prompt'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/product_selector/search_indices.svg b/x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/search_indices.svg similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/product_selector/search_indices.svg rename to x-pack/plugins/enterprise_search/public/applications/shared/add_content_empty_prompt/search_indices.svg diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/elasticsearch_resources/elasticsearch_resources.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/elasticsearch_resources/elasticsearch_resources.test.tsx new file mode 100644 index 0000000000000..3dd3b1c8ddfac --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/elasticsearch_resources/elasticsearch_resources.test.tsx @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +jest.mock('../doc_links', () => ({ + docLinks: { + elasticsearchGettingStarted: 'elasticsearchGettingStarted-link', + elasticsearchCreateIndex: 'elasticsearchCreateIndex-link', + clientsGuide: 'elasticsearchClientsGuide-link', + }, +})); +import React from 'react'; + +import { shallow, ShallowWrapper } from 'enzyme'; + +import { EuiLink } from '@elastic/eui'; + +import { ElasticsearchResources } from '.'; + +describe('ElasticsearchResources', () => { + let wrapper: ShallowWrapper; + + beforeAll(() => { + wrapper = shallow(); + }); + + it('renders', () => { + expect(wrapper.find('h4').text()).toEqual('Resources'); + + expect(wrapper.find(EuiLink).at(0).prop('href')).toEqual('elasticsearchGettingStarted-link'); + expect(wrapper.find(EuiLink).at(0).text()).toEqual('Getting started with Elasticsearch'); + + expect(wrapper.find(EuiLink).at(1).prop('href')).toEqual('elasticsearchCreateIndex-link'); + expect(wrapper.find(EuiLink).at(1).text()).toEqual('Create a new index'); + + expect(wrapper.find(EuiLink).at(2).prop('href')).toEqual('elasticsearchClientsGuide-link'); + expect(wrapper.find(EuiLink).at(2).text()).toEqual('Setup a language client'); + + expect(wrapper.find(EuiLink).at(3).prop('href')).toEqual( + 'https://github.com/elastic/search-ui/tree/master/packages/search-ui-elasticsearch-connector' + ); + expect(wrapper.find(EuiLink).at(3).text()).toEqual('Search UI for Elasticsearch'); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_resources/elasticsearch_resources.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/elasticsearch_resources/elasticsearch_resources.tsx similarity index 92% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_resources/elasticsearch_resources.tsx rename to x-pack/plugins/enterprise_search/public/applications/shared/elasticsearch_resources/elasticsearch_resources.tsx index b7d0390f40077..6a274e75179b1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_resources/elasticsearch_resources.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/elasticsearch_resources/elasticsearch_resources.tsx @@ -10,10 +10,10 @@ import React from 'react'; import { EuiSpacer, EuiPanel, EuiTitle, EuiLink } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { docLinks } from '../../../shared/doc_links'; +import { docLinks } from '../doc_links'; export const ElasticsearchResources: React.FC = () => ( - +

{i18n.translate('xpack.enterpriseSearch.overview.elasticsearchResources.title', { @@ -40,7 +40,7 @@ export const ElasticsearchResources: React.FC = () => ( {i18n.translate( 'xpack.enterpriseSearch.overview.elasticsearchResources.elasticsearchClients', - { defaultMessage: 'Elasticsearch clients' } + { defaultMessage: 'Setup a language client' } )} diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_resources/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/elasticsearch_resources/index.ts similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/elasticsearch_resources/index.ts rename to x-pack/plugins/enterprise_search/public/applications/shared/elasticsearch_resources/index.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/getting_started_steps.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/getting_started_steps.test.tsx new file mode 100644 index 0000000000000..200a93041c087 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/getting_started_steps.test.tsx @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +jest.mock('../doc_links', () => ({ + docLinks: { + elasticsearchGettingStarted: 'elasticsearchGettingStarted-link', + elasticsearchCreateIndex: 'elasticsearchCreateIndex-link', + clientsGuide: 'elasticsearchClientsGuide-link', + }, +})); +import React from 'react'; + +import { shallow, ShallowWrapper } from 'enzyme'; + +import { EuiSteps } from '@elastic/eui'; + +import { ENTERPRISE_SEARCH_OVERVIEW_PLUGIN } from '../../../../common/constants'; + +import { EuiLinkTo } from '../react_router_helpers'; + +import { IconRow } from './icon_row'; + +import { GettingStartedSteps } from '.'; + +describe('GettingStartedSteps', () => { + let wrapper: ShallowWrapper; + + beforeAll(() => { + wrapper = shallow(); + }); + + it('renders', () => { + const steps = wrapper + .find(EuiSteps) + .prop('steps') + .map(({ title, children, status, ...rest }) => ({ + title, + status, + children: shallow(
{children}
), + ...rest, + })); + + expect(steps[0].title).toEqual('Add your documents and data to Enterprise Search'); + expect(steps[0].status).toEqual('current'); + expect(steps[0].children.find(IconRow).length).toEqual(1); + + expect(steps[1].title).toEqual('Build a search experience'); + expect(steps[1].status).toEqual('incomplete'); + expect(steps[1].children.find(EuiLinkTo).prop('to')).toEqual( + ENTERPRISE_SEARCH_OVERVIEW_PLUGIN.URL + '/elasticsearch_guide' + ); + + expect(steps[2].title).toEqual('Tune your search relevance'); + expect(steps[2].status).toEqual('incomplete'); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/getting_started_steps.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/getting_started_steps.tsx new file mode 100644 index 0000000000000..a730fa2e7df2a --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/getting_started_steps.tsx @@ -0,0 +1,190 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useState } from 'react'; + +import { + EuiButton, + EuiFlexGroup, + EuiFlexItem, + EuiIcon, + EuiPopover, + EuiSpacer, + EuiSteps, + EuiText, + EuiContextMenuPanel, + EuiContextMenuItem, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { ENTERPRISE_SEARCH_OVERVIEW_PLUGIN } from '../../../../common/constants'; +import { ELASTICSEARCH_GUIDE_PATH } from '../../enterprise_search_overview/routes'; + +import { EuiLinkTo } from '../react_router_helpers'; + +import { IconRow } from './icon_row'; + +export interface GettingStartedStepsProps { + step?: 'first' | 'second'; +} + +export const GettingStartedSteps: React.FC = ({ step = 'first' }) => { + // TODO replace with logic file + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + + return ( + + + + +

+ {i18n.translate( + 'xpack.enterpriseSearch.overview.gettingStartedSteps.addData.message', + { + defaultMessage: + 'Get started by adding your data to Enterprise Search. You can use the Elastic Web Crawler, API endpoints, existing Elasticsearch indices or third party connectors like Google Drive, Microsoft Sharepoint and more.', + } + )} +

+
+ + + + ), + status: (step === 'first' && 'current') || 'complete', + }, + { + title: i18n.translate( + 'xpack.enterpriseSearch.overview.gettingStartedSteps.buildSearchExperience.title', + { defaultMessage: 'Build a search experience' } + ), + children: ( + <> + +

+ {i18n.translate( + 'xpack.enterpriseSearch.overview.gettingStartedSteps.buildSearchExperience.message', + { + defaultMessage: + 'You can use Search Engines to build customized search experiences for your customers or internal teams with App Search or Workplace Search. Or you can use Search UI to connect directly to an Elasticsearch index to build client-side search experinces for your users.', + } + )} +

+
+ + + + setIsPopoverOpen(!isPopoverOpen)} + > + {i18n.translate( + 'xpack.enterpriseSearch.overview.gettingStartedSteps.createASearchEngineButton', + { defaultMessage: 'Create a search engine' } + )} + + } + isOpen={isPopoverOpen} + closePopover={() => setIsPopoverOpen(false)} + > + {/* TODO add onclick for these links*/} + {}}> + +

+ {i18n.translate( + 'xpack.enterpriseSearch.overview.gettingStartedSteps.createAppSearchEngine.title', + { defaultMessage: 'Create an App Search engine' } + )} +

+ {i18n.translate( + 'xpack.enterpriseSearch.overview.gettingStartedSteps.createAppSearchEngine.description', + { + defaultMessage: + 'All the power of Elasticsearch, without the learning curve.', + } + )} +
+ , + {}}> + +

+ {i18n.translate( + 'xpack.enterpriseSearch.overview.gettingStartedSteps.createWorkplaceSearchGroup.title', + { defaultMessage: 'Create a Workplace Search group' } + )} +

+ {i18n.translate( + 'xpack.enterpriseSearch.overview.gettingStartedSteps.createWorkplaceSearchGroup.description', + { + defaultMessage: 'A secure search experience for internal teams', + } + )} +
+
, + ]} + /> +
+
+ + + +   + {i18n.translate( + 'xpack.enterpriseSearch.overview.gettingStartedSteps.searchWithElasticsearchLink', + { defaultMessage: 'Search with the Elasticsearch API' } + )} + + +
+ + ), + status: (step === 'second' && 'current') || 'incomplete', + }, + { + title: i18n.translate( + 'xpack.enterpriseSearch.overview.gettingStartedSteps.tuneSearchExperience.title', + { defaultMessage: 'Tune your search relevance' } + ), + children: ( + +

+ {i18n.translate( + 'xpack.enterpriseSearch.overview.gettingStartedSteps.tuneSearchExperience.message', + { + defaultMessage: + "Dive into analytics and tune the result settings to help your users find exactly what they're looking for", + } + )} +

+
+ ), + status: 'incomplete', + }, + ]} + /> +
+
+ ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/icon_row.scss b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/icon_row.scss new file mode 100644 index 0000000000000..6992cdead2803 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/icon_row.scss @@ -0,0 +1,13 @@ +.gettingStartedSteps { + .grayscaleSvg { + filter: grayscale(1); + } + + .addManyMoreButton { + border: $euiBorderThin; + } + + .iconTooltip { + border-bottom: $euiBorderThin; + } +} diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/icon_row.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/icon_row.tsx new file mode 100644 index 0000000000000..8ae50183914d3 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/icon_row.tsx @@ -0,0 +1,115 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiBadge, EuiToolTip, EuiText } from '@elastic/eui'; + +import { i18n } from '@kbn/i18n'; + +import { images } from '../../workplace_search/components/shared/assets/source_icons'; + +import './icon_row.scss'; + +const icons = [ + { + icon: 'logoElasticsearch', + title: 'Elasticsearch', + tooltip: i18n.translate('xpack.enterpriseSearch.overview.iconRow.elasticsearch.tooltip', { + defaultMessage: + 'Use App and Workplace Search Search Engines with existing Elasticsearch indices', + }), + }, + { + icon: 'desktop', + title: i18n.translate('xpack.enterpriseSearch.overview.iconRow.api.title', { + defaultMessage: 'API', + }), + tooltip: i18n.translate('xpack.enterpriseSearch.overview.iconRow.api.tooltip', { + defaultMessage: 'POST documents to an API endpoint from your own applications', + }), + }, + { + icon: 'globe', + title: i18n.translate('xpack.enterpriseSearch.overview.iconRow.crawler.title', { + defaultMessage: 'Elastic Web Crawler', + }), + tooltip: i18n.translate('xpack.enterpriseSearch.overview.iconRow.crawler.tooltip', { + defaultMessage: 'Automatically index content from your websites', + }), + }, + { + icon: images.confluence, + title: i18n.translate('xpack.enterpriseSearch.overview.iconRow.confluence.title', { + defaultMessage: 'Confluence', + }), + tooltip: i18n.translate('xpack.enterpriseSearch.overview.iconRow.confluence.tooltip', { + defaultMessage: 'Index content from Atlassian Confluence', + }), + }, + { + icon: images.googleDrive, + title: i18n.translate('xpack.enterpriseSearch.overview.iconRow.googleDrive.title', { + defaultMessage: 'Google Drive', + }), + tooltip: i18n.translate('xpack.enterpriseSearch.overview.iconRow.googleDrive.tooltip', { + defaultMessage: 'Index documents from Google Drive', + }), + }, + { + icon: images.sharePoint, + title: i18n.translate('xpack.enterpriseSearch.overview.iconRow.sharePoint.title', { + defaultMessage: 'Microsoft SharePoint', + }), + tooltip: i18n.translate('xpack.enterpriseSearch.overview.iconRow.sharePoint.tooltip', { + defaultMessage: 'Index content from Microsoft SharePoint', + }), + }, + { + icon: images.github, + title: i18n.translate('xpack.enterpriseSearch.overview.iconRow.github.title', { + defaultMessage: 'GitHub', + }), + tooltip: i18n.translate('xpack.enterpriseSearch.overview.iconRow.github.tooltip', { + defaultMessage: 'Index issues, pull requests, and more from GitHub', + }), + }, +]; + +export const IconRow: React.FC = () => { + return ( + + + + {icons.map((item, index) => { + return ( + + +

{item.title}

+ {item.tooltip} + + } + > + +
+
+ ); + })} +
+
+ + + {i18n.translate('xpack.enterpriseSearch.overview.iconRow.manyMoreBadge', { + defaultMessage: 'And many more', + })} + + +
+ ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/index.ts new file mode 100644 index 0000000000000..71ad56d84cb09 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started_steps/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { GettingStartedSteps } from './getting_started_steps'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts index 19263f057e40f..984e6664681b4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts @@ -30,8 +30,6 @@ export interface Group { createdAt: string; updatedAt: string; contentSources: ContentSource[]; - users: User[]; - usersCount: number; color?: string; } diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/__mocks__/groups_logic.mock.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/__mocks__/groups_logic.mock.ts index 0e072210d2489..02e80d9f8c5b5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/__mocks__/groups_logic.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/__mocks__/groups_logic.mock.ts @@ -6,12 +6,11 @@ */ import { DEFAULT_META } from '../../../../shared/constants'; -import { ContentSource, User, Group } from '../../../types'; +import { ContentSource, Group } from '../../../types'; export const mockGroupsValues = { groups: [] as Group[], contentSources: [] as ContentSource[], - users: [] as User[], groupsDataLoading: true, groupListLoading: true, newGroupModalOpen: false, @@ -21,10 +20,6 @@ export const mockGroupsValues = { newGroupNameErrors: [], filterSourcesDropdownOpen: false, filteredSources: [], - filterUsersDropdownOpen: false, - filteredUsers: [], - allGroupUsersLoading: false, - allGroupUsers: [], filterValue: '', groupsMeta: DEFAULT_META, }; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_overview.test.tsx index e1ecc47f02669..97b2879ceef53 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_overview.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_overview.test.tsx @@ -91,7 +91,6 @@ describe('GroupOverview', () => { ...mockValues, group: { ...groups[0], - users: [], contentSources: [], }, }); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row.tsx index effacfa3aa4f8..d118037a2d80c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row.tsx @@ -28,12 +28,6 @@ export const NO_SOURCES_MESSAGE = i18n.translate( defaultMessage: 'No organizational content sources', } ); -export const NO_USERS_MESSAGE = i18n.translate( - 'xpack.enterpriseSearch.workplaceSearch.groups.noUsersMessage', - { - defaultMessage: 'No users', - } -); const dateDisplay = (date: string) => moment(date).isAfter(moment().subtract(DAYS_CUTOFF, 'days')) diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups.tsx index 7af93490b2eb2..5b8b01a4bb1ef 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups.tsx @@ -38,7 +38,6 @@ export const Groups: React.FC = () => { page: { total_results: numGroups }, }, filteredSources, - filteredUsers, filterValue, } = useValues(GroupsLogic); @@ -47,7 +46,7 @@ export const Groups: React.FC = () => { useEffect(() => { getSearchResults(true); return resetGroups; - }, [filteredSources, filteredUsers, filterValue]); + }, [filteredSources, filterValue]); if (newGroup && hasMessages) { messages[0].description = ( diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.test.ts index 97163f1529938..bc82c95871676 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.test.ts @@ -12,7 +12,6 @@ import { } from '../../../__mocks__/kea_logic'; import { contentSources } from '../../__mocks__/content_sources.mock'; import { groups } from '../../__mocks__/groups.mock'; -import { users } from '../../__mocks__/users.mock'; import { mockGroupsValues } from './__mocks__/groups_logic.mock'; import { nextTick } from '@kbn/test-jest-helpers'; @@ -49,13 +48,12 @@ describe('GroupsLogic', () => { describe('actions', () => { describe('onInitializeGroups', () => { it('sets reducers', () => { - GroupsLogic.actions.onInitializeGroups({ contentSources, users }); + GroupsLogic.actions.onInitializeGroups({ contentSources }); expect(GroupsLogic.values).toEqual({ ...mockGroupsValues, groupsDataLoading: false, contentSources, - users, }); }); }); @@ -103,59 +101,6 @@ describe('GroupsLogic', () => { }); }); - describe('addFilteredUser', () => { - it('sets reducers', () => { - GroupsLogic.actions.addFilteredUser('foo'); - GroupsLogic.actions.addFilteredUser('bar'); - GroupsLogic.actions.addFilteredUser('baz'); - - expect(GroupsLogic.values).toEqual({ - ...mockGroupsValues, - hasFiltersSet: true, - filteredUsers: ['bar', 'baz', 'foo'], - }); - }); - }); - - describe('removeFilteredUser', () => { - it('sets reducers', () => { - GroupsLogic.actions.addFilteredUser('foo'); - GroupsLogic.actions.addFilteredUser('bar'); - GroupsLogic.actions.addFilteredUser('baz'); - GroupsLogic.actions.removeFilteredUser('foo'); - - expect(GroupsLogic.values).toEqual({ - ...mockGroupsValues, - hasFiltersSet: true, - filteredUsers: ['bar', 'baz'], - }); - }); - }); - - describe('setGroupUsers', () => { - it('sets reducers', () => { - GroupsLogic.actions.setGroupUsers(users); - - expect(GroupsLogic.values).toEqual({ - ...mockGroupsValues, - allGroupUsersLoading: false, - allGroupUsers: users, - }); - }); - }); - - describe('setAllGroupLoading', () => { - it('sets reducer', () => { - GroupsLogic.actions.setAllGroupLoading(true); - - expect(GroupsLogic.values).toEqual({ - ...mockGroupsValues, - allGroupUsersLoading: true, - allGroupUsers: [], - }); - }); - }); - describe('setFilterValue', () => { it('sets reducer', () => { GroupsLogic.actions.setFilterValue('foo'); @@ -190,7 +135,6 @@ describe('GroupsLogic', () => { newGroup: groups[0], newGroupNameErrors: [], filteredSources: [], - filteredUsers: [], groupsMeta: DEFAULT_META, }); }); @@ -234,19 +178,6 @@ describe('GroupsLogic', () => { }); }); - describe('closeFilterUsersDropdown', () => { - it('sets reducer', () => { - // Open dropdown first - GroupsLogic.actions.toggleFilterUsersDropdown(); - GroupsLogic.actions.closeFilterUsersDropdown(); - - expect(GroupsLogic.values).toEqual({ - ...mockGroupsValues, - filterUsersDropdownOpen: false, - }); - }); - }); - describe('setGroupsLoading', () => { it('sets reducer', () => { // Set to false first @@ -294,7 +225,6 @@ describe('GroupsLogic', () => { const search = { query: '', content_source_ids: [], - user_ids: [], }; const payload = { @@ -352,22 +282,6 @@ describe('GroupsLogic', () => { }); }); - describe('fetchGroupUsers', () => { - it('calls API and sets values', async () => { - const setGroupUsersSpy = jest.spyOn(GroupsLogic.actions, 'setGroupUsers'); - http.get.mockReturnValue(Promise.resolve(users)); - - GroupsLogic.actions.fetchGroupUsers('123'); - expect(http.get).toHaveBeenCalledWith('/internal/workplace_search/groups/123/group_users'); - await nextTick(); - expect(setGroupUsersSpy).toHaveBeenCalledWith(users); - }); - - itShowsServerErrorAsFlashMessage(http.get, () => { - GroupsLogic.actions.fetchGroupUsers('123'); - }); - }); - describe('saveNewGroup', () => { it('calls API and sets values', async () => { const GROUP_NAME = 'new group'; @@ -430,7 +344,6 @@ describe('GroupsLogic', () => { expect(GroupsLogic.values).toEqual({ ...mockGroupsValues, filteredSources: [], - filteredUsers: [], filterValue: '', groupsMeta: DEFAULT_META, }); @@ -449,17 +362,5 @@ describe('GroupsLogic', () => { expect(clearFlashMessages).toHaveBeenCalled(); }); }); - - describe('toggleFilterUsersDropdown', () => { - it('sets reducer and clears flash messages', () => { - GroupsLogic.actions.toggleFilterUsersDropdown(); - - expect(GroupsLogic.values).toEqual({ - ...mockGroupsValues, - filterUsersDropdownOpen: true, - }); - expect(clearFlashMessages).toHaveBeenCalled(); - }); - }); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.ts index c14538346ad31..3e137ea8a6713 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.ts @@ -18,13 +18,12 @@ import { flashSuccessToast, } from '../../../shared/flash_messages'; import { HttpLogic } from '../../../shared/http'; -import { ContentSource, Group, User } from '../../types'; +import { ContentSource, Group } from '../../types'; export const MAX_NAME_LENGTH = 40; interface GroupsServerData { contentSources: ContentSource[]; - users: User[]; } interface GroupsSearchResponse { @@ -37,10 +36,6 @@ interface GroupsActions { setSearchResults(data: GroupsSearchResponse): GroupsSearchResponse; addFilteredSource(sourceId: string): string; removeFilteredSource(sourceId: string): string; - addFilteredUser(userId: string): string; - removeFilteredUser(userId: string): string; - setGroupUsers(allGroupUsers: User[]): User[]; - setAllGroupLoading(allGroupUsersLoading: boolean): boolean; setFilterValue(filterValue: string): string; setActivePage(activePage: number): number; setNewGroupName(newGroupName: string): string; @@ -49,22 +44,18 @@ interface GroupsActions { openNewGroupModal(): void; closeNewGroupModal(): void; closeFilterSourcesDropdown(): void; - closeFilterUsersDropdown(): void; toggleFilterSourcesDropdown(): void; - toggleFilterUsersDropdown(): void; setGroupsLoading(): void; resetGroupsFilters(): void; resetGroups(): void; initializeGroups(): void; getSearchResults(resetPagination?: boolean): { resetPagination: boolean | undefined }; - fetchGroupUsers(groupId: string): { groupId: string }; saveNewGroup(): void; } interface GroupsValues { groups: Group[]; contentSources: ContentSource[]; - users: User[]; groupsDataLoading: boolean; groupListLoading: boolean; newGroupModalOpen: boolean; @@ -73,10 +64,6 @@ interface GroupsValues { newGroupNameErrors: string[]; filterSourcesDropdownOpen: boolean; filteredSources: string[]; - filterUsersDropdownOpen: boolean; - filteredUsers: string[]; - allGroupUsersLoading: boolean; - allGroupUsers: User[]; filterValue: string; groupsMeta: Meta; hasFiltersSet: boolean; @@ -89,10 +76,6 @@ export const GroupsLogic = kea>({ setSearchResults: (data) => data, addFilteredSource: (sourceId) => sourceId, removeFilteredSource: (sourceId) => sourceId, - addFilteredUser: (userId) => userId, - removeFilteredUser: (userId) => userId, - setGroupUsers: (allGroupUsers) => allGroupUsers, - setAllGroupLoading: (allGroupUsersLoading: boolean) => allGroupUsersLoading, setFilterValue: (filterValue) => filterValue, setActivePage: (activePage) => activePage, setNewGroupName: (newGroupName) => newGroupName, @@ -101,15 +84,12 @@ export const GroupsLogic = kea>({ openNewGroupModal: () => true, closeNewGroupModal: () => true, closeFilterSourcesDropdown: () => true, - closeFilterUsersDropdown: () => true, toggleFilterSourcesDropdown: () => true, - toggleFilterUsersDropdown: () => true, setGroupsLoading: () => true, resetGroupsFilters: () => true, resetGroups: () => true, initializeGroups: () => true, getSearchResults: (resetPagination) => ({ resetPagination }), - fetchGroupUsers: (groupId) => ({ groupId }), saveNewGroup: () => true, }, reducers: { @@ -125,12 +105,6 @@ export const GroupsLogic = kea>({ onInitializeGroups: (_, { contentSources }) => contentSources, }, ], - users: [ - [], - { - onInitializeGroups: (_, { users }) => users, - }, - ], groupsDataLoading: [ true, { @@ -193,36 +167,6 @@ export const GroupsLogic = kea>({ removeFilteredSource: (state, sourceId) => state.filter((id) => id !== sourceId), }, ], - filterUsersDropdownOpen: [ - false, - { - toggleFilterUsersDropdown: (state) => !state, - closeFilterUsersDropdown: () => false, - }, - ], - filteredUsers: [ - [], - { - resetGroupsFilters: () => [], - setNewGroup: () => [], - addFilteredUser: (state, userId) => [...state, userId].sort(), - removeFilteredUser: (state, userId) => state.filter((id) => id !== userId), - }, - ], - allGroupUsersLoading: [ - false, - { - setAllGroupLoading: (_, allGroupUsersLoading) => allGroupUsersLoading, - setGroupUsers: () => false, - }, - ], - allGroupUsers: [ - [], - { - setGroupUsers: (_, allGroupUsers) => allGroupUsers, - setAllGroupLoading: () => [], - }, - ], filterValue: [ '', { @@ -248,8 +192,8 @@ export const GroupsLogic = kea>({ }, selectors: ({ selectors }) => ({ hasFiltersSet: [ - () => [selectors.filteredUsers, selectors.filteredSources], - (filteredUsers, filteredSources) => filteredUsers.length > 0 || filteredSources.length > 0, + () => [selectors.filteredSources], + (filteredSources) => filteredSources.length > 0, ], }), listeners: ({ actions, values }) => ({ @@ -275,7 +219,6 @@ export const GroupsLogic = kea>({ }, filterValue, filteredSources, - filteredUsers, } = values; // Is the user changes the query while on a different page, we want to start back over at 1. @@ -286,7 +229,6 @@ export const GroupsLogic = kea>({ const search = { query: filterValue, content_source_ids: filteredSources, - user_ids: filteredUsers, }; try { @@ -306,17 +248,6 @@ export const GroupsLogic = kea>({ flashAPIErrors(e); } }, - fetchGroupUsers: async ({ groupId }) => { - actions.setAllGroupLoading(true); - try { - const response = await HttpLogic.values.http.get( - `/internal/workplace_search/groups/${groupId}/group_users` - ); - actions.setGroupUsers(response); - } catch (e) { - flashAPIErrors(e); - } - }, saveNewGroup: async () => { try { const response = await HttpLogic.values.http.post( @@ -354,8 +285,5 @@ export const GroupsLogic = kea>({ toggleFilterSourcesDropdown: () => { clearFlashMessages(); }, - toggleFilterUsersDropdown: () => { - clearFlashMessages(); - }, }), }); diff --git a/x-pack/plugins/enterprise_search/public/assets/source_icons/network_drive.svg b/x-pack/plugins/enterprise_search/public/assets/source_icons/network_drive.svg new file mode 100644 index 0000000000000..cc07fbbc50877 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/assets/source_icons/network_drive.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/x-pack/plugins/enterprise_search/public/assets/source_icons/outlook.svg b/x-pack/plugins/enterprise_search/public/assets/source_icons/outlook.svg new file mode 100644 index 0000000000000..932a3756a522b --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/assets/source_icons/outlook.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/x-pack/plugins/enterprise_search/public/assets/source_icons/teams.svg b/x-pack/plugins/enterprise_search/public/assets/source_icons/teams.svg new file mode 100644 index 0000000000000..bf3aef9277eb6 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/assets/source_icons/teams.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/x-pack/plugins/enterprise_search/public/assets/source_icons/zoom.svg b/x-pack/plugins/enterprise_search/public/assets/source_icons/zoom.svg new file mode 100644 index 0000000000000..d7498817bc62d --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/assets/source_icons/zoom.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/x-pack/plugins/enterprise_search/server/integrations.ts b/x-pack/plugins/enterprise_search/server/integrations.ts index 2a5ed4be69cfa..d2d3b5d4d6829 100644 --- a/x-pack/plugins/enterprise_search/server/integrations.ts +++ b/x-pack/plugins/enterprise_search/server/integrations.ts @@ -162,6 +162,21 @@ const workplaceSearchIntegrations: WorkplaceSearchIntegration[] = [ ), categories: ['productivity'], }, + { + id: 'network_drive', + title: i18n.translate('xpack.enterpriseSearch.workplaceSearch.integrations.networkDriveName', { + defaultMessage: 'Network Drive', + }), + description: i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.integrations.networkDriveDescription', + { + defaultMessage: + 'Search over your files and folders stored on network drives with Enterprise Search.', + } + ), + categories: ['enterprise_search', 'file_storage'], + uiInternalPath: '/app/enterprise_search/workplace_search/sources/add/network_drive', + }, { id: 'onedrive', title: i18n.translate('xpack.enterpriseSearch.workplaceSearch.integrations.onedriveName', { @@ -176,6 +191,20 @@ const workplaceSearchIntegrations: WorkplaceSearchIntegration[] = [ categories: ['file_storage'], uiInternalPath: '/app/enterprise_search/workplace_search/sources/add/one_drive', }, + { + id: 'outlook', + title: i18n.translate('xpack.enterpriseSearch.workplaceSearch.integrations.outlookName', { + defaultMessage: 'Outlook', + }), + description: i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.integrations.outlookDescription', + { + defaultMessage: 'Search over your email and calendars with Enterprise Search.', + } + ), + categories: ['enterprise_search', 'microsoft_365', 'communications', 'productivity'], + uiInternalPath: '/app/enterprise_search/workplace_search/sources/add/outlook', + }, { id: 'salesforce', title: i18n.translate('xpack.enterpriseSearch.workplaceSearch.integrations.salesforceName', { @@ -266,6 +295,21 @@ const workplaceSearchIntegrations: WorkplaceSearchIntegration[] = [ ), categories: ['communications'], }, + { + id: 'teams', + title: i18n.translate('xpack.enterpriseSearch.workplaceSearch.integrations.teamsName', { + defaultMessage: 'Teams', + }), + description: i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.integrations.teamsDescription', + { + defaultMessage: + 'Search over meeting recordings, chats and other communications with Enterprise Search.', + } + ), + categories: ['enterprise_search', 'microsoft_365', 'communications', 'productivity'], + uiInternalPath: '/app/enterprise_search/workplace_search/sources/add/teams', + }, { id: 'zendesk', title: i18n.translate('xpack.enterpriseSearch.workplaceSearch.integrations.zendeskName', { @@ -279,6 +323,21 @@ const workplaceSearchIntegrations: WorkplaceSearchIntegration[] = [ ), categories: ['communications'], }, + { + id: 'zoom', + title: i18n.translate('xpack.enterpriseSearch.workplaceSearch.integrations.zoomName', { + defaultMessage: 'Zoom', + }), + description: i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.integrations.zoomDescription', + { + defaultMessage: + 'Search over meeting recordings, chats and other communications with Enterprise Search.', + } + ), + categories: ['enterprise_search', 'communications', 'productivity'], + uiInternalPath: '/app/enterprise_search/workplace_search/sources/add/zoom', + }, { id: 'custom_api_source', title: i18n.translate( diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts index 28359bc90052f..65868e4d17935 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts @@ -12,7 +12,7 @@ export function registerListRoute({ router }: RouteDependencies) { router.get( { path: '/internal/enterprise_search/indices', validate: false }, async (context, _, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; try { const indices = await fetchIndices(client); return response.ok({ diff --git a/x-pack/plugins/enterprise_search/server/routes/workplace_search/groups.test.ts b/x-pack/plugins/enterprise_search/server/routes/workplace_search/groups.test.ts index 40ee46c7a9ffd..dc1308a4140d3 100644 --- a/x-pack/plugins/enterprise_search/server/routes/workplace_search/groups.test.ts +++ b/x-pack/plugins/enterprise_search/server/routes/workplace_search/groups.test.ts @@ -107,7 +107,6 @@ describe('groups routes', () => { search: { query: 'foo', content_source_ids: ['123', '234'], - user_ids: ['345', '456'], }, }, }; diff --git a/x-pack/plugins/enterprise_search/server/routes/workplace_search/groups.ts b/x-pack/plugins/enterprise_search/server/routes/workplace_search/groups.ts index c5c161cf7b2f8..8dc153e7a2923 100644 --- a/x-pack/plugins/enterprise_search/server/routes/workplace_search/groups.ts +++ b/x-pack/plugins/enterprise_search/server/routes/workplace_search/groups.ts @@ -51,7 +51,6 @@ export function registerSearchGroupsRoute({ search: schema.object({ query: schema.string(), content_source_ids: schema.arrayOf(schema.string()), - user_ids: schema.arrayOf(schema.string()), }), }), }, diff --git a/x-pack/plugins/event_log/common/index.ts b/x-pack/plugins/event_log/common/index.ts index 5910dbe2c5ad7..562a1e4298251 100644 --- a/x-pack/plugins/event_log/common/index.ts +++ b/x-pack/plugins/event_log/common/index.ts @@ -6,3 +6,4 @@ */ export const BASE_EVENT_LOG_API_PATH = '/internal/event_log'; +export { millisToNanos, nanosToMillis } from './lib'; diff --git a/x-pack/plugins/event_log/common/lib/index.ts b/x-pack/plugins/event_log/common/lib/index.ts new file mode 100644 index 0000000000000..40d3fb26189e6 --- /dev/null +++ b/x-pack/plugins/event_log/common/lib/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { millisToNanos } from './millis_to_nanos'; +export { nanosToMillis } from './nanos_to_millis'; diff --git a/x-pack/plugins/event_log/common/lib/millis_to_nanos.test.ts b/x-pack/plugins/event_log/common/lib/millis_to_nanos.test.ts new file mode 100644 index 0000000000000..4845d79305007 --- /dev/null +++ b/x-pack/plugins/event_log/common/lib/millis_to_nanos.test.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { millisToNanos } from './millis_to_nanos'; + +describe('millisToNanos', () => { + test('should return "0" when passing 0 millis', () => { + expect(millisToNanos(0)).toEqual('0'); + }); + + test('should return "1000000" when passing in 1 millis', () => { + expect(millisToNanos(1)).toEqual('1000000'); + }); + + test('should return "9007199254740991000000" when passing in 9007199254740991 (Number.MAX_SAFE_INTEGER)', () => { + expect(millisToNanos(9007199254740991)).toEqual('9007199254740991000000'); + }); + + test('should round to "1000000" wheen passing in 0.75 millis', () => { + expect(millisToNanos(0.75)).toEqual('1000000'); + }); +}); diff --git a/x-pack/plugins/event_log/common/lib/millis_to_nanos.ts b/x-pack/plugins/event_log/common/lib/millis_to_nanos.ts new file mode 100644 index 0000000000000..acb9e07f6c5a6 --- /dev/null +++ b/x-pack/plugins/event_log/common/lib/millis_to_nanos.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export function millisToNanos(millis: number): string { + const roundedMillis = Math.round(millis); + if (roundedMillis === 0) { + return '0'; + } + return `${roundedMillis}000000`; +} diff --git a/x-pack/plugins/event_log/common/lib/nanos_to_millis.test.ts b/x-pack/plugins/event_log/common/lib/nanos_to_millis.test.ts new file mode 100644 index 0000000000000..3a04c57b9edbf --- /dev/null +++ b/x-pack/plugins/event_log/common/lib/nanos_to_millis.test.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { nanosToMillis } from './nanos_to_millis'; + +describe('nanosToMillis', () => { + test('should return 0 when passing in "0" nanos', () => { + expect(nanosToMillis('0')).toEqual(0); + }); + + test('should drop decimals when passing in "1" nanos', () => { + expect(nanosToMillis('1')).toEqual(0); + }); + + test('should drop decimals when passing in "1000001" nanos', () => { + expect(nanosToMillis('1000001')).toEqual(1); + }); + + test('should return 9007199254740991 (Number.MAX_SAFE_INTEGER) when passing in "9007199254740991000000" nanos', () => { + expect(nanosToMillis('9007199254740991000000')).toEqual(9007199254740991); + }); + + test('should work when numbers are passed in', () => { + expect(nanosToMillis(0)).toEqual(0); + expect(nanosToMillis(1)).toEqual(0); + expect(nanosToMillis(1000001)).toEqual(1); + }); +}); diff --git a/x-pack/plugins/event_log/common/lib/nanos_to_millis.ts b/x-pack/plugins/event_log/common/lib/nanos_to_millis.ts new file mode 100644 index 0000000000000..a0512fb528a91 --- /dev/null +++ b/x-pack/plugins/event_log/common/lib/nanos_to_millis.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +const ONE_MILLION = BigInt(1000 * 1000); + +export function nanosToMillis(nanos: string | number): number { + return Number(BigInt(nanos) / ONE_MILLION); +} diff --git a/x-pack/plugins/event_log/generated/mappings.json b/x-pack/plugins/event_log/generated/mappings.json index 982699274e1e3..f2022d78f4aee 100644 --- a/x-pack/plugins/event_log/generated/mappings.json +++ b/x-pack/plugins/event_log/generated/mappings.json @@ -299,6 +299,18 @@ "number_of_generated_actions": { "type": "long" }, + "number_of_new_alerts": { + "type": "long" + }, + "number_of_active_alerts": { + "type": "long" + }, + "number_of_recovered_alerts": { + "type": "long" + }, + "total_number_of_alerts": { + "type": "long" + }, "number_of_searches": { "type": "long" }, @@ -364,4 +376,4 @@ } } } -} +} \ No newline at end of file diff --git a/x-pack/plugins/event_log/generated/schemas.ts b/x-pack/plugins/event_log/generated/schemas.ts index e030a0ce1e99c..fc8bc1c9022d7 100644 --- a/x-pack/plugins/event_log/generated/schemas.ts +++ b/x-pack/plugins/event_log/generated/schemas.ts @@ -52,7 +52,7 @@ export const EventSchema = schema.maybe( code: ecsString(), created: ecsDate(), dataset: ecsString(), - duration: ecsNumber(), + duration: ecsStringOrNumber(), end: ecsDate(), hash: ecsString(), id: ecsString(), @@ -66,8 +66,8 @@ export const EventSchema = schema.maybe( reference: ecsString(), risk_score: ecsNumber(), risk_score_norm: ecsNumber(), - sequence: ecsNumber(), - severity: ecsNumber(), + sequence: ecsStringOrNumber(), + severity: ecsStringOrNumber(), start: ecsDate(), timezone: ecsString(), type: ecsStringMulti(), @@ -106,7 +106,7 @@ export const EventSchema = schema.maybe( schema.object({ id: ecsString(), scheduled: ecsDate(), - schedule_delay: ecsNumber(), + schedule_delay: ecsStringOrNumber(), }) ), alerting: schema.maybe( @@ -126,16 +126,20 @@ export const EventSchema = schema.maybe( schema.object({ uuid: ecsString(), status: ecsString(), - status_order: ecsNumber(), + status_order: ecsStringOrNumber(), metrics: schema.maybe( schema.object({ - number_of_triggered_actions: ecsNumber(), - number_of_generated_actions: ecsNumber(), - number_of_searches: ecsNumber(), - total_indexing_duration_ms: ecsNumber(), - es_search_duration_ms: ecsNumber(), - total_search_duration_ms: ecsNumber(), - execution_gap_duration_s: ecsNumber(), + number_of_triggered_actions: ecsStringOrNumber(), + number_of_generated_actions: ecsStringOrNumber(), + number_of_new_alerts: ecsStringOrNumber(), + number_of_active_alerts: ecsStringOrNumber(), + number_of_recovered_alerts: ecsStringOrNumber(), + total_number_of_alerts: ecsStringOrNumber(), + number_of_searches: ecsStringOrNumber(), + total_indexing_duration_ms: ecsStringOrNumber(), + es_search_duration_ms: ecsStringOrNumber(), + total_search_duration_ms: ecsStringOrNumber(), + execution_gap_duration_s: ecsStringOrNumber(), }) ), }) @@ -175,6 +179,10 @@ function ecsNumber() { return schema.maybe(schema.number()); } +function ecsStringOrNumber() { + return schema.maybe(schema.oneOf([schema.string(), schema.number()])); +} + function ecsDate() { return schema.maybe(schema.string({ validate: validateDate })); } diff --git a/x-pack/plugins/event_log/scripts/create_schemas.js b/x-pack/plugins/event_log/scripts/create_schemas.js index c86722ccd76c6..1a775b44add8d 100755 --- a/x-pack/plugins/event_log/scripts/create_schemas.js +++ b/x-pack/plugins/event_log/scripts/create_schemas.js @@ -115,7 +115,8 @@ function writeEventLogConfigSchema(elSchema, ecsVersion) { } const StringTypes = new Set(['string', 'keyword', 'text', 'ip']); -const NumberTypes = new Set(['long', 'integer', 'float']); +const NumberTypes = new Set(['integer', 'float']); +const StringOrNumberTypes = new Set(['long']); function augmentMappings(mappings, multiValuedProperties) { for (const prop of multiValuedProperties) { @@ -145,6 +146,11 @@ function generateSchemaLines(lineWriter, prop, mappings) { return; } + if (StringOrNumberTypes.has(mappings.type)) { + lineWriter.addLine(`${propKey}: ecsStringOrNumber(),`); + return; + } + if (mappings.type === 'date') { lineWriter.addLine(`${propKey}: ecsDate(),`); return; @@ -310,6 +316,10 @@ function ecsNumber() { return schema.maybe(schema.number()); } +function ecsStringOrNumber() { + return schema.maybe(schema.oneOf([schema.string(), schema.number()])); +} + function ecsDate() { return schema.maybe(schema.string({ validate: validateDate })); } diff --git a/x-pack/plugins/event_log/scripts/mappings.js b/x-pack/plugins/event_log/scripts/mappings.js index b4bb17eba42a1..4c21329863269 100644 --- a/x-pack/plugins/event_log/scripts/mappings.js +++ b/x-pack/plugins/event_log/scripts/mappings.js @@ -81,6 +81,18 @@ exports.EcsCustomPropertyMappings = { number_of_generated_actions: { type: 'long', }, + number_of_new_alerts: { + type: 'long', + }, + number_of_active_alerts: { + type: 'long', + }, + number_of_recovered_alerts: { + type: 'long', + }, + total_number_of_alerts: { + type: 'long', + }, number_of_searches: { type: 'long', }, diff --git a/x-pack/plugins/event_log/server/event_log_client.test.ts b/x-pack/plugins/event_log/server/event_log_client.test.ts index a0d086ceaece4..89f6df538aca5 100644 --- a/x-pack/plugins/event_log/server/event_log_client.test.ts +++ b/x-pack/plugins/event_log/server/event_log_client.test.ts @@ -250,7 +250,7 @@ function fakeEvent(overrides = {}) { action: 'execute', start: '2020-03-30T14:55:47.054Z', end: '2020-03-30T14:55:47.055Z', - duration: 1000000, + duration: '1000000', }, kibana: { namespace: 'default', diff --git a/x-pack/plugins/event_log/server/event_logger.test.ts b/x-pack/plugins/event_log/server/event_logger.test.ts index 636e377ed6636..f1f849bd3b17b 100644 --- a/x-pack/plugins/event_log/server/event_logger.test.ts +++ b/x-pack/plugins/event_log/server/event_logger.test.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { nanosToMillis } from '../common'; import { IEvent, IEventLogger, IEventLogService } from '.'; import { ECS_VERSION } from './types'; import { EventLogService } from './event_log_service'; @@ -137,9 +138,9 @@ describe('EventLogger', () => { expect(timeStopValue).toBeGreaterThanOrEqual(timeStartValue); - const duration = event.event!.duration!; + const duration = Number(event.event!.duration!); expect(duration).toBeGreaterThan(0.95 * delayMS * 1000 * 1000); - expect(duration / (1000 * 1000)).toBeCloseTo(timeStopValue - timeStartValue); + expect(nanosToMillis(duration)).toBeCloseTo(timeStopValue - timeStartValue); }); test('timing method endTiming() method works when startTiming() is not called', async () => { diff --git a/x-pack/plugins/event_log/server/event_logger.ts b/x-pack/plugins/event_log/server/event_logger.ts index 89d0cbc9ab94d..67d9dc61f4e18 100644 --- a/x-pack/plugins/event_log/server/event_logger.ts +++ b/x-pack/plugins/event_log/server/event_logger.ts @@ -13,6 +13,7 @@ import { coerce } from 'semver'; import { Plugin } from './plugin'; import { EsContext } from './es'; import { EventLogService } from './event_log_service'; +import { millisToNanos } from '../common'; import { IEvent, IValidatedEvent, @@ -61,7 +62,7 @@ export class EventLogger implements IEventLogger { const end = Date.now(); event.event.end = new Date(end).toISOString(); - event.event.duration = (end - start) * 1000 * 1000; // nanoseconds + event.event.duration = millisToNanos(end - start); } // non-blocking, but spawns an async task to do the work diff --git a/x-pack/plugins/event_log/server/index.ts b/x-pack/plugins/event_log/server/index.ts index c69d7780a6204..cd386483fef8f 100644 --- a/x-pack/plugins/event_log/server/index.ts +++ b/x-pack/plugins/event_log/server/index.ts @@ -9,6 +9,8 @@ import { PluginInitializerContext, PluginConfigDescriptor } from '@kbn/core/serv import { ConfigSchema, IEventLogConfig } from './types'; import { Plugin } from './plugin'; +export { millisToNanos, nanosToMillis } from '../common'; + export type { IEventLogService, IEventLogger, diff --git a/x-pack/plugins/event_log/server/routes/_mock_handler_arguments.ts b/x-pack/plugins/event_log/server/routes/_mock_handler_arguments.ts index 78c0917929c7a..7da8defa9d856 100644 --- a/x-pack/plugins/event_log/server/routes/_mock_handler_arguments.ts +++ b/x-pack/plugins/event_log/server/routes/_mock_handler_arguments.ts @@ -50,7 +50,7 @@ export function fakeEvent(overrides = {}) { action: 'execute', start: '2020-03-30T14:55:47.054Z', end: '2020-03-30T14:55:47.055Z', - duration: 1000000, + duration: '1000000', }, kibana: { saved_objects: [ diff --git a/x-pack/plugins/event_log/server/routes/find.ts b/x-pack/plugins/event_log/server/routes/find.ts index fd940d0f64ad5..4c9ab70bbe3a5 100644 --- a/x-pack/plugins/event_log/server/routes/find.ts +++ b/x-pack/plugins/event_log/server/routes/find.ts @@ -38,7 +38,7 @@ export const findRoute = (router: EventLogRouter, systemLogger: Logger) => { if (!context.eventLog) { return res.badRequest({ body: 'RouteHandlerContext is not registered for eventLog' }); } - const eventLogClient = context.eventLog.getEventLogClient(); + const eventLogClient = (await context.eventLog).getEventLogClient(); const { params: { id, type }, query, diff --git a/x-pack/plugins/event_log/server/routes/find_by_ids.ts b/x-pack/plugins/event_log/server/routes/find_by_ids.ts index 85346b1e87be5..a33a03c8242c4 100644 --- a/x-pack/plugins/event_log/server/routes/find_by_ids.ts +++ b/x-pack/plugins/event_log/server/routes/find_by_ids.ts @@ -44,7 +44,7 @@ export const findByIdsRoute = (router: EventLogRouter, systemLogger: Logger) => if (!context.eventLog) { return res.badRequest({ body: 'RouteHandlerContext is not registered for eventLog' }); } - const eventLogClient = context.eventLog.getEventLogClient(); + const eventLogClient = (await context.eventLog).getEventLogClient(); const { params: { type }, body: { ids, legacyIds }, diff --git a/x-pack/plugins/event_log/server/types.ts b/x-pack/plugins/event_log/server/types.ts index 10a472e802b9f..1336245741bd6 100644 --- a/x-pack/plugins/event_log/server/types.ts +++ b/x-pack/plugins/event_log/server/types.ts @@ -6,7 +6,7 @@ */ import { schema, TypeOf } from '@kbn/config-schema'; -import type { IRouter, KibanaRequest, RequestHandlerContext } from '@kbn/core/server'; +import type { IRouter, KibanaRequest, CustomRequestHandlerContext } from '@kbn/core/server'; export type { IEvent, IValidatedEvent } from '../generated/schemas'; export { EventSchema, ECS_VERSION } from '../generated/schemas'; @@ -16,6 +16,7 @@ import { AggregateEventsBySavedObjectResult, QueryEventsBySavedObjectResult, } from './es/cluster_client_adapter'; + export type { QueryEventsBySavedObjectResult, AggregateEventsBySavedObjectResult, @@ -79,9 +80,9 @@ export interface EventLogApiRequestHandlerContext { /** * @internal */ -export interface EventLogRequestHandlerContext extends RequestHandlerContext { +export type EventLogRequestHandlerContext = CustomRequestHandlerContext<{ eventLog: EventLogApiRequestHandlerContext; -} +}>; /** * @internal diff --git a/x-pack/plugins/event_log/tsconfig.json b/x-pack/plugins/event_log/tsconfig.json index e0e72fdbf6581..28dd8f244a3da 100644 --- a/x-pack/plugins/event_log/tsconfig.json +++ b/x-pack/plugins/event_log/tsconfig.json @@ -12,7 +12,7 @@ "generated/*", // have to declare *.json explicitly due to https://github.com/microsoft/TypeScript/issues/25636 "generated/*.json", - "common/*" + "common/**/*" ], "references": [ { "path": "../../../src/core/tsconfig.json" }, diff --git a/x-pack/plugins/features/server/routes/index.test.ts b/x-pack/plugins/features/server/routes/index.test.ts index 4d61d131cc0ac..31cb1358f63fa 100644 --- a/x-pack/plugins/features/server/routes/index.test.ts +++ b/x-pack/plugins/features/server/routes/index.test.ts @@ -15,10 +15,9 @@ import { RequestHandler } from '@kbn/core/server'; import { FeatureKibanaPrivileges, KibanaFeatureConfig, SubFeatureConfig } from '../../common'; function createContextMock(licenseType: LicenseType = 'platinum') { - return { - core: coreMock.createRequestHandlerContext(), + return coreMock.createCustomRequestHandlerContext({ licensing: licensingMock.createRequestHandlerContext({ license: { type: licenseType } }), - }; + }); } function createPrivilege(partial: Partial = {}): FeatureKibanaPrivileges { @@ -138,7 +137,7 @@ describe('GET /api/features', () => { it('returns a list of available features, sorted by their configured order', async () => { const mockResponse = httpServerMock.createResponseFactory(); - routeHandler(createContextMock(), { query: {} } as any, mockResponse); + await routeHandler(createContextMock(), { query: {} } as any, mockResponse); expect(mockResponse.ok).toHaveBeenCalledTimes(1); const [call] = mockResponse.ok.mock.calls; @@ -173,7 +172,7 @@ describe('GET /api/features', () => { it(`by default does not return features that arent allowed by current license`, async () => { const mockResponse = httpServerMock.createResponseFactory(); - routeHandler(createContextMock('basic'), { query: {} } as any, mockResponse); + await routeHandler(createContextMock('basic'), { query: {} } as any, mockResponse); expect(mockResponse.ok).toHaveBeenCalledTimes(1); const [call] = mockResponse.ok.mock.calls; @@ -204,7 +203,7 @@ describe('GET /api/features', () => { it(`ignoreValidLicenses=false does not return features that arent allowed by current license`, async () => { const mockResponse = httpServerMock.createResponseFactory(); - routeHandler( + await routeHandler( createContextMock('basic'), { query: { ignoreValidLicenses: false } } as any, mockResponse @@ -239,7 +238,7 @@ describe('GET /api/features', () => { it(`ignoreValidLicenses=true returns features that arent allowed by current license`, async () => { const mockResponse = httpServerMock.createResponseFactory(); - routeHandler( + await routeHandler( createContextMock('basic'), { query: { ignoreValidLicenses: true } } as any, mockResponse diff --git a/x-pack/plugins/features/server/routes/index.ts b/x-pack/plugins/features/server/routes/index.ts index 1f2b833663f1a..bb78f07bc56cc 100644 --- a/x-pack/plugins/features/server/routes/index.ts +++ b/x-pack/plugins/features/server/routes/index.ts @@ -26,8 +26,8 @@ export function defineRoutes({ router, featureRegistry }: RouteDefinitionParams) query: schema.object({ ignoreValidLicenses: schema.boolean({ defaultValue: false }) }), }, }, - (context, request, response) => { - const currentLicense = context.licensing!.license; + async (context, request, response) => { + const { license: currentLicense } = await context.licensing; const allFeatures = featureRegistry.getAllKibanaFeatures( currentLicense, diff --git a/x-pack/plugins/features/server/types.ts b/x-pack/plugins/features/server/types.ts index 826d4282cc425..99a6c96e43322 100644 --- a/x-pack/plugins/features/server/types.ts +++ b/x-pack/plugins/features/server/types.ts @@ -5,15 +5,15 @@ * 2.0. */ -import type { RequestHandlerContext, IRouter } from '@kbn/core/server'; +import type { CustomRequestHandlerContext, IRouter } from '@kbn/core/server'; import type { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server'; /** * @internal */ -export interface FeaturesRequestHandlerContext extends RequestHandlerContext { +export type FeaturesRequestHandlerContext = CustomRequestHandlerContext<{ licensing: LicensingApiRequestHandlerContext; -} +}>; /** * @internal diff --git a/x-pack/plugins/file_upload/server/routes.ts b/x-pack/plugins/file_upload/server/routes.ts index 0abab34ebef7b..76d6443f47f54 100644 --- a/x-pack/plugins/file_upload/server/routes.ts +++ b/x-pack/plugins/file_upload/server/routes.ts @@ -102,11 +102,8 @@ export function fileUploadRoutes(coreSetup: CoreSetup, logge }, async (context, request, response) => { try { - const result = await analyzeFile( - context.core.elasticsearch.client, - request.body, - request.query - ); + const esClient = (await context.core).elasticsearch.client; + const result = await analyzeFile(esClient, request.body, request.query); return response.ok({ body: result }); } catch (e) { return response.customError(wrapError(e)); @@ -142,6 +139,7 @@ export function fileUploadRoutes(coreSetup: CoreSetup, logge try { const { id } = request.query; const { index, data, settings, mappings, ingestPipeline } = request.body; + const esClient = (await context.core).elasticsearch.client; // `id` being `undefined` tells us that this is a new import due to create a new index. // follow-up import calls to just add additional data will include the `id` of the created @@ -151,7 +149,7 @@ export function fileUploadRoutes(coreSetup: CoreSetup, logge } const result = await importData( - context.core.elasticsearch.client, + esClient, id, index, settings, @@ -182,9 +180,8 @@ export function fileUploadRoutes(coreSetup: CoreSetup, logge }, async (context, request, response) => { try { - const indexExists = await context.core.elasticsearch.client.asCurrentUser.indices.exists( - request.body - ); + const esClient = (await context.core).elasticsearch.client; + const indexExists = await esClient.asCurrentUser.indices.exists(request.body); return response.ok({ body: { exists: indexExists } }); } catch (e) { return response.customError(wrapError(e)); @@ -225,8 +222,9 @@ export function fileUploadRoutes(coreSetup: CoreSetup, logge async (context, request, response) => { try { const { index, timeFieldName, query, runtimeMappings } = request.body; + const esClient = (await context.core).elasticsearch.client; const resp = await getTimeFieldRange( - context.core.elasticsearch.client, + esClient, index, timeFieldName, query, diff --git a/x-pack/plugins/fleet/.storybook/context/cloud.ts b/x-pack/plugins/fleet/.storybook/context/cloud.ts index 1291f94cea788..eccb41d6aa8c0 100644 --- a/x-pack/plugins/fleet/.storybook/context/cloud.ts +++ b/x-pack/plugins/fleet/.storybook/context/cloud.ts @@ -11,9 +11,9 @@ export const getCloud = ({ isCloudEnabled }: { isCloudEnabled: boolean }) => { const cloud: CloudSetup = { isCloudEnabled, baseUrl: 'https://base.url', - cloudId: 'cloud-id', + cloudId: isCloudEnabled ? 'cloud-id' : undefined, cname: 'found.io', - deploymentUrl: 'https://deployment.url', + deploymentUrl: isCloudEnabled ? 'https://deployment.url' : undefined, organizationUrl: 'https://organization.url', profileUrl: 'https://profile.url', snapshotsUrl: 'https://snapshots.url', diff --git a/x-pack/plugins/fleet/.storybook/context/http.ts b/x-pack/plugins/fleet/.storybook/context/http.ts index 5167ad5500364..ff5b36a82aa66 100644 --- a/x-pack/plugins/fleet/.storybook/context/http.ts +++ b/x-pack/plugins/fleet/.storybook/context/http.ts @@ -27,7 +27,7 @@ export const getHttp = (basepath = BASE_PATH) => { serverBasePath: basepath, }, get: (async (path: string, options: HttpFetchOptions) => { - action('get')(path, options); + action('get')(path, JSON.stringify(options)); // TODO: all of this needs revision, as it's far too clunky... but it works for now, // with the few paths we're supporting. if (path === '/api/fleet/agents/setup') { @@ -35,7 +35,7 @@ export const getHttp = (basepath = BASE_PATH) => { isReady = true; return { isReady: false, missing_requirements: ['api_keys', 'fleet_server'] }; } - return { isInitialized: true, nonFatalErrors: [] }; + return { isReady: true, isInitialized: true, nonFatalErrors: [], missing_requirements: [] }; } if (path === '/api/fleet/epm/categories') { @@ -79,9 +79,59 @@ export const getHttp = (basepath = BASE_PATH) => { return { success: true }; } - action(path)('KP: UNSUPPORTED ROUTE'); + if (path.match('/api/fleet/agent_policies')) { + return { items: [] }; + } + + if (path.match('/api/fleet/settings')) { + return { item: { fleet_server_hosts: [] } }; + } + + if (path.match('/api/fleet/outputs')) { + return { + items: [{ name: 'Default Output', is_default: true, hosts: ['https://test.es:9200'] }], + }; + } + + action(path)(`UNSUPPORTED ROUTE: GET ${path}`); return {}; }) as HttpHandler, + post: (async (path: string, options: HttpFetchOptions) => { + action('post')(path, JSON.stringify(options)); + + if (path.match('/api/fleet/settings')) { + return { items: [] }; + } + + if (path.match('/api/fleet/service_tokens')) { + return { + name: 'test-token', + value: 'test-token-value', + }; + } + + if (path.match('/api/fleet/agent_policies')) { + return { + item: { + id: 'test-policy', + name: 'Test Policy', + namespace: 'default', + description: 'Test Policy', + monitoring_enabled: ['metrics'], + data_output_id: 'test-output', + monitoring_output_id: 'test-output', + status: 'active', + packagePolicies: ['test-package-policy'], + updated_on: new Date(), + updated_by: 'elastic', + revision: 0, + agents: 0, + }, + }; + } + + action(path)(`UNSUPPORTED ROUTE: POST ${path}`); + }) as HttpHandler, } as unknown as HttpStart; return http; diff --git a/x-pack/plugins/fleet/.storybook/context/index.tsx b/x-pack/plugins/fleet/.storybook/context/index.tsx index a60ecaf5a1572..15ee77506cc0e 100644 --- a/x-pack/plugins/fleet/.storybook/context/index.tsx +++ b/x-pack/plugins/fleet/.storybook/context/index.tsx @@ -66,7 +66,7 @@ export const StorybookContext: React.FC<{ storyContext?: StoryContext }> = ({ chrome: getChrome(), cloud: { ...getCloud({ isCloudEnabled }), - CloudContextProvider: () => <>, + CloudContextProvider: ({ children }) => <>{children}, }, customIntegrations: { ContextProvider: getStorybookContextProvider(), diff --git a/x-pack/plugins/fleet/.storybook/context/stubs.tsx b/x-pack/plugins/fleet/.storybook/context/stubs.tsx index 0f4f81b58f95d..092ab680b819f 100644 --- a/x-pack/plugins/fleet/.storybook/context/stubs.tsx +++ b/x-pack/plugins/fleet/.storybook/context/stubs.tsx @@ -11,6 +11,7 @@ type Stubs = | 'licensing' | 'storage' | 'data' + | 'unifiedSearch' | 'deprecations' | 'fatalErrors' | 'navigation' @@ -23,6 +24,7 @@ export const stubbedStartServices: StubbedStartServices = { licensing: {} as FleetStartServices['licensing'], storage: {} as FleetStartServices['storage'], data: {} as FleetStartServices['data'], + unifiedSearch: {} as FleetStartServices['unifiedSearch'], deprecations: {} as FleetStartServices['deprecations'], fatalErrors: {} as FleetStartServices['fatalErrors'], navigation: {} as FleetStartServices['navigation'], diff --git a/x-pack/plugins/fleet/common/experimental_features.ts b/x-pack/plugins/fleet/common/experimental_features.ts new file mode 100644 index 0000000000000..3398de60c0786 --- /dev/null +++ b/x-pack/plugins/fleet/common/experimental_features.ts @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type ExperimentalFeatures = typeof allowedExperimentalValues; + +/** + * A list of allowed values that can be used in `xpack.fleet.enableExperimental`. + * This object is then used to validate and parse the value entered. + */ +export const allowedExperimentalValues = Object.freeze({ + addIntegrationStepsPage: false, +}); + +type ExperimentalConfigKeys = Array; +type Mutable = { -readonly [P in keyof T]: T[P] }; + +const FleetInvalidExperimentalValue = class extends Error {}; +const allowedKeys = Object.keys(allowedExperimentalValues) as Readonly; + +/** + * Parses the string value used in `xpack.fleet.enableExperimental` kibana configuration, + * which should be a string of values delimited by a comma (`,`) + * + * @param configValue + * @throws FleetInvalidExperimentalValue + */ +export const parseExperimentalConfigValue = (configValue: string[]): ExperimentalFeatures => { + const enabledFeatures: Mutable> = {}; + + for (const value of configValue) { + if (!isValidExperimentalValue(value)) { + throw new FleetInvalidExperimentalValue(`[${value}] is not a supported experimental feature`); + } + + enabledFeatures[value as keyof ExperimentalFeatures] = true; + } + + return { + ...allowedExperimentalValues, + ...enabledFeatures, + }; +}; + +export const isValidExperimentalValue = (value: string) => { + return allowedKeys.includes(value as keyof ExperimentalFeatures); +}; + +export const getExperimentalAllowedValues = (): string[] => [...allowedKeys]; diff --git a/x-pack/plugins/fleet/common/index.ts b/x-pack/plugins/fleet/common/index.ts index 46a8e2d01fc96..60bbcafc48842 100644 --- a/x-pack/plugins/fleet/common/index.ts +++ b/x-pack/plugins/fleet/common/index.ts @@ -11,6 +11,7 @@ export * from './constants'; export * from './services'; export * from './types'; +export * from './experimental_features'; export type { FleetAuthz } from './authz'; export { calculateAuthz } from './authz'; export { createFleetAuthzMock } from './mocks'; diff --git a/x-pack/plugins/fleet/common/openapi/bundled.json b/x-pack/plugins/fleet/common/openapi/bundled.json index 77dd66a5c20d1..b3c37f5e567c3 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.json +++ b/x-pack/plugins/fleet/common/openapi/bundled.json @@ -115,7 +115,10 @@ "type": "string" } }, - "required": ["name", "version"] + "required": [ + "name", + "version" + ] } } } @@ -292,7 +295,17 @@ }, "operationId": "list-all-packages" }, - "parameters": [] + "parameters": [ + { + "in": "query", + "name": "excludeInstallStatus", + "schema": { + "type": "boolean", + "default": false + }, + "description": "Whether to exclude the install status of each package. Enabling this option will opt in to caching for the response via `cache-control` headers. If you don't need up-to-date installation info for a package, and are querying for a list of available packages, providing this flag can improve performance substantially." + } + ] }, "/epm/packages/_bulk": { "post": { @@ -337,13 +350,21 @@ "properties": { "status": { "type": "string", - "enum": ["installed", "installing", "install_failed", "not_installed"] + "enum": [ + "installed", + "installing", + "install_failed", + "not_installed" + ] }, "savedObject": { "type": "string" } }, - "required": ["status", "savedObject"] + "required": [ + "status", + "savedObject" + ] } ] } @@ -399,11 +420,16 @@ ] } }, - "required": ["id", "type"] + "required": [ + "id", + "type" + ] } } }, - "required": ["response"] + "required": [ + "response" + ] } } } @@ -462,11 +488,16 @@ ] } }, - "required": ["id", "type"] + "required": [ + "id", + "type" + ] } } }, - "required": ["response"] + "required": [ + "response" + ] } } } @@ -518,13 +549,21 @@ "properties": { "status": { "type": "string", - "enum": ["installed", "installing", "install_failed", "not_installed"] + "enum": [ + "installed", + "installing", + "install_failed", + "not_installed" + ] }, "savedObject": { "type": "string" } }, - "required": ["status", "savedObject"] + "required": [ + "status", + "savedObject" + ] } ] } @@ -587,7 +626,10 @@ ] } }, - "required": ["id", "type"] + "required": [ + "id", + "type" + ] } }, "_meta": { @@ -595,12 +637,18 @@ "properties": { "install_source": { "type": "string", - "enum": ["registry", "upload", "bundled"] + "enum": [ + "registry", + "upload", + "bundled" + ] } } } }, - "required": ["items"] + "required": [ + "items" + ] } } } @@ -661,11 +709,16 @@ ] } }, - "required": ["id", "type"] + "required": [ + "id", + "type" + ] } } }, - "required": ["items"] + "required": [ + "items" + ] } } } @@ -736,11 +789,16 @@ ] } }, - "required": ["id", "type"] + "required": [ + "id", + "type" + ] } } }, - "required": ["items"] + "required": [ + "items" + ] } } } @@ -840,7 +898,9 @@ "$ref": "#/components/schemas/package_usage_stats" } }, - "required": ["response"] + "required": [ + "response" + ] } } } @@ -915,7 +975,10 @@ "type": "string" } }, - "required": ["admin_username", "admin_password"] + "required": [ + "admin_username", + "admin_password" + ] } } } @@ -1156,7 +1219,9 @@ "type": "string" } }, - "required": ["success"] + "required": [ + "success" + ] } } } @@ -1217,7 +1282,9 @@ "$ref": "#/components/schemas/agent" } }, - "required": ["item"] + "required": [ + "item" + ] } } } @@ -1240,7 +1307,9 @@ "$ref": "#/components/schemas/agent" } }, - "required": ["item"] + "required": [ + "item" + ] } } } @@ -1266,10 +1335,14 @@ "properties": { "action": { "type": "string", - "enum": ["deleted"] + "enum": [ + "deleted" + ] } }, - "required": ["action"] + "required": [ + "action" + ] } } } @@ -1389,7 +1462,9 @@ "type": "string" } }, - "required": ["policy_id"] + "required": [ + "policy_id" + ] } } } @@ -1436,7 +1511,9 @@ }, "statusCode": { "type": "number", - "enum": [400] + "enum": [ + 400 + ] } } } @@ -1544,7 +1621,9 @@ "type": "string" } }, - "required": ["success"] + "required": [ + "success" + ] } } } @@ -1580,7 +1659,10 @@ ] } }, - "required": ["policy_id", "agents"] + "required": [ + "policy_id", + "agents" + ] } } } @@ -1608,7 +1690,9 @@ "type": "string" } }, - "required": ["success"] + "required": [ + "success" + ] } } } @@ -1647,7 +1731,9 @@ ] } }, - "required": ["agents"] + "required": [ + "agents" + ] } } } @@ -1682,7 +1768,12 @@ "type": "number" } }, - "required": ["items", "total", "page", "perPage"] + "required": [ + "items", + "total", + "page", + "perPage" + ] } } } @@ -1766,7 +1857,9 @@ "$ref": "#/components/schemas/agent_policy" } }, - "required": ["item"] + "required": [ + "item" + ] } } } @@ -1791,7 +1884,9 @@ "$ref": "#/components/schemas/agent_policy" } }, - "required": ["item"] + "required": [ + "item" + ] } } } @@ -1845,7 +1940,9 @@ "$ref": "#/components/schemas/agent_policy" } }, - "required": ["item"] + "required": [ + "item" + ] } } } @@ -1864,7 +1961,9 @@ "type": "string" } }, - "required": ["name"] + "required": [ + "name" + ] } } }, @@ -1891,7 +1990,10 @@ "type": "boolean" } }, - "required": ["id", "success"] + "required": [ + "id", + "success" + ] } } } @@ -1907,7 +2009,9 @@ "type": "string" } }, - "required": ["agentPolicyId"] + "required": [ + "agentPolicyId" + ] } } } @@ -1983,7 +2087,12 @@ "type": "number" } }, - "required": ["items", "page", "perPage", "total"] + "required": [ + "items", + "page", + "perPage", + "total" + ] } } } @@ -2009,7 +2118,9 @@ }, "action": { "type": "string", - "enum": ["created"] + "enum": [ + "created" + ] } } } @@ -2052,7 +2163,9 @@ "$ref": "#/components/schemas/enrollment_api_key" } }, - "required": ["item"] + "required": [ + "item" + ] } } } @@ -2074,10 +2187,14 @@ "properties": { "action": { "type": "string", - "enum": ["deleted"] + "enum": [ + "deleted" + ] } }, - "required": ["action"] + "required": [ + "action" + ] } } } @@ -2127,7 +2244,12 @@ "type": "number" } }, - "required": ["items", "page", "perPage", "total"] + "required": [ + "items", + "page", + "perPage", + "total" + ] } } } @@ -2152,7 +2274,9 @@ }, "action": { "type": "string", - "enum": ["created"] + "enum": [ + "created" + ] } } } @@ -2194,7 +2318,9 @@ "$ref": "#/components/schemas/enrollment_api_key" } }, - "required": ["item"] + "required": [ + "item" + ] } } } @@ -2215,10 +2341,14 @@ "properties": { "action": { "type": "string", - "enum": ["deleted"] + "enum": [ + "deleted" + ] } }, - "required": ["action"] + "required": [ + "action" + ] } } } @@ -2260,7 +2390,9 @@ "type": "number" } }, - "required": ["items"] + "required": [ + "items" + ] } } } @@ -2286,7 +2418,9 @@ "$ref": "#/components/schemas/package_policy" } }, - "required": ["item"] + "required": [ + "item" + ] } } } @@ -2348,7 +2482,9 @@ "type": "boolean" } }, - "required": ["packagePolicyIds"] + "required": [ + "packagePolicyIds" + ] } } } @@ -2373,7 +2509,10 @@ "type": "boolean" } }, - "required": ["id", "success"] + "required": [ + "id", + "success" + ] } } } @@ -2404,7 +2543,9 @@ } } }, - "required": ["packagePolicyIds"] + "required": [ + "packagePolicyIds" + ] } } } @@ -2429,7 +2570,10 @@ "type": "boolean" } }, - "required": ["id", "success"] + "required": [ + "id", + "success" + ] } } } @@ -2458,7 +2602,9 @@ "type": "string" } }, - "required": ["packagePolicyIds"] + "required": [ + "packagePolicyIds" + ] } } } @@ -2483,7 +2629,9 @@ "$ref": "#/components/schemas/upgrade_agent_diff" } }, - "required": ["hasErrors"] + "required": [ + "hasErrors" + ] } } } @@ -2508,7 +2656,9 @@ "$ref": "#/components/schemas/package_policy" } }, - "required": ["item"] + "required": [ + "item" + ] } } } @@ -2553,7 +2703,10 @@ "type": "boolean" } }, - "required": ["item", "sucess"] + "required": [ + "item", + "sucess" + ] } } } @@ -2636,7 +2789,9 @@ }, "type": { "type": "string", - "enum": ["elasticsearch"] + "enum": [ + "elasticsearch" + ] }, "is_default": { "type": "boolean" @@ -2657,7 +2812,10 @@ "type": "string" } }, - "required": ["name", "type"] + "required": [ + "name", + "type" + ] } } } @@ -2681,7 +2839,9 @@ "$ref": "#/components/schemas/output" } }, - "required": ["item"] + "required": [ + "item" + ] } } } @@ -2714,7 +2874,9 @@ "type": "string" } }, - "required": ["id"] + "required": [ + "id" + ] } } } @@ -2740,7 +2902,9 @@ }, "type": { "type": "string", - "enum": ["elasticsearch"] + "enum": [ + "elasticsearch" + ] }, "is_default": { "type": "boolean" @@ -2764,7 +2928,10 @@ "type": "string" } }, - "required": ["name", "type"] + "required": [ + "name", + "type" + ] } } } @@ -2781,7 +2948,9 @@ "$ref": "#/components/schemas/output" } }, - "required": ["item"] + "required": [ + "item" + ] } } } @@ -2900,11 +3069,17 @@ "type": "string" } }, - "required": ["name", "message"] + "required": [ + "name", + "message" + ] } } }, - "required": ["isInitialized", "nonFatalErrors"] + "required": [ + "isInitialized", + "nonFatalErrors" + ] }, "preconfigured_agent_policies": { "title": "Preconfigured agent policies", @@ -2926,7 +3101,10 @@ "type": "array", "items": { "type": "string", - "enum": ["logs", "metrics"] + "enum": [ + "logs", + "metrics" + ] } }, "namespace": { @@ -3023,14 +3201,20 @@ } } }, - "required": ["type"] + "required": [ + "type" + ] } } } } } }, - "required": ["name", "namespace", "package_policies"] + "required": [ + "name", + "namespace", + "package_policies" + ] }, "settings": { "title": "Settings", @@ -3052,7 +3236,10 @@ } } }, - "required": ["fleet_server_hosts", "id"] + "required": [ + "fleet_server_hosts", + "id" + ] }, "fleet_settings_response": { "title": "Fleet settings response", @@ -3062,7 +3249,9 @@ "$ref": "#/components/schemas/settings" } }, - "required": ["item"] + "required": [ + "item" + ] }, "get_categories_response": { "title": "Get categories response", @@ -3084,7 +3273,11 @@ "type": "number" } }, - "required": ["id", "title", "count"] + "required": [ + "id", + "title", + "count" + ] } }, "items": { @@ -3102,11 +3295,17 @@ "type": "number" } }, - "required": ["id", "title", "count"] + "required": [ + "id", + "title", + "count" + ] } } }, - "required": ["items"] + "required": [ + "items" + ] }, "search_result": { "title": "Search result", @@ -3173,7 +3372,9 @@ } } }, - "required": ["items"] + "required": [ + "items" + ] }, "bulk_install_packages_response": { "title": "Bulk install packages response", @@ -3209,7 +3410,9 @@ } } }, - "required": ["items"] + "required": [ + "items" + ] }, "package_info": { "title": "Package information", @@ -3289,7 +3492,10 @@ "type": "string" } }, - "required": ["src", "path"] + "required": [ + "src", + "path" + ] } }, "icons": { @@ -3339,7 +3545,10 @@ "type": "string" } }, - "required": ["name", "default"] + "required": [ + "name", + "default" + ] } }, "type": { @@ -3349,7 +3558,14 @@ "type": "string" } }, - "required": ["title", "name", "release", "ingeset_pipeline", "type", "package"] + "required": [ + "title", + "name", + "release", + "ingeset_pipeline", + "type", + "package" + ] } }, "download": { @@ -3411,7 +3627,9 @@ "type": "integer" } }, - "required": ["agent_policy_count"] + "required": [ + "agent_policy_count" + ] }, "fleet_status_response": { "title": "Fleet status response", @@ -3424,23 +3642,38 @@ "type": "array", "items": { "type": "string", - "enum": ["tls_required", "api_keys", "fleet_admin_user", "fleet_server"] + "enum": [ + "tls_required", + "api_keys", + "fleet_admin_user", + "fleet_server" + ] } }, "missing_optional_features": { "type": "array", "items": { "type": "string", - "enum": ["encrypted_saved_object_encryption_key_required"] + "enum": [ + "encrypted_saved_object_encryption_key_required" + ] } } }, - "required": ["isReady", "missing_requirements", "missing_optional_features"] + "required": [ + "isReady", + "missing_requirements", + "missing_optional_features" + ] }, "agent_type": { "type": "string", "title": "Agent type", - "enum": ["PERMANENT", "EPHEMERAL", "TEMPORARY"] + "enum": [ + "PERMANENT", + "EPHEMERAL", + "TEMPORARY" + ] }, "agent_metadata": { "title": "Agent metadata", @@ -3449,7 +3682,13 @@ "agent_status": { "type": "string", "title": "Agent status", - "enum": ["offline", "error", "online", "inactive", "warning"] + "enum": [ + "offline", + "error", + "online", + "inactive", + "warning" + ] }, "agent": { "title": "Agent", @@ -3504,7 +3743,13 @@ "type": "string" } }, - "required": ["type", "active", "enrolled_at", "id", "status"] + "required": [ + "type", + "active", + "enrolled_at", + "id", + "status" + ] }, "get_agents_response": { "title": "Get Agent response", @@ -3533,7 +3778,12 @@ "type": "number" } }, - "required": ["items", "total", "page", "perPage"] + "required": [ + "items", + "total", + "page", + "perPage" + ] }, "bulk_upgrade_agents": { "title": "Bulk upgrade agents", @@ -3559,7 +3809,10 @@ ] } }, - "required": ["agents", "version"] + "required": [ + "agents", + "version" + ] }, "upgrade_agent": { "title": "Upgrade agent", @@ -3571,7 +3824,9 @@ "type": "string" } }, - "required": ["version"] + "required": [ + "version" + ] }, { "type": "object", @@ -3583,7 +3838,9 @@ "type": "string" } }, - "required": ["version"] + "required": [ + "version" + ] } ] }, @@ -3600,7 +3857,12 @@ }, "type": { "type": "string", - "enum": ["POLICY_CHANGE", "UNENROLL", "UPGRADE", "POLICY_REASSIGN"] + "enum": [ + "POLICY_CHANGE", + "UNENROLL", + "UPGRADE", + "POLICY_REASSIGN" + ] } } }, @@ -3614,7 +3876,12 @@ "properties": { "log_level": { "type": "string", - "enum": ["debug", "info", "warning", "error"] + "enum": [ + "debug", + "info", + "warning", + "error" + ] } } } @@ -3642,7 +3909,10 @@ "type": "array", "items": { "type": "string", - "enum": ["metrics", "logs"] + "enum": [ + "metrics", + "logs" + ] } }, "data_output_id": { @@ -3654,7 +3924,10 @@ "nullable": true } }, - "required": ["name", "namespace"] + "required": [ + "name", + "namespace" + ] }, "new_package_policy": { "title": "New package policy", @@ -3677,7 +3950,10 @@ "type": "string" } }, - "required": ["name", "version"] + "required": [ + "name", + "version" + ] }, "namespace": { "type": "string" @@ -3713,7 +3989,10 @@ "type": "object" } }, - "required": ["type", "enabled"] + "required": [ + "type", + "enabled" + ] } }, "policy_id": { @@ -3726,7 +4005,10 @@ "type": "string" } }, - "required": ["inputs", "name"] + "required": [ + "inputs", + "name" + ] }, "package_policy": { "title": "Package policy", @@ -3745,7 +4027,10 @@ "items": {} } }, - "required": ["id", "revision"] + "required": [ + "id", + "revision" + ] }, { "$ref": "#/components/schemas/new_package_policy" @@ -3765,7 +4050,10 @@ }, "status": { "type": "string", - "enum": ["active", "inactive"] + "enum": [ + "active", + "inactive" + ] }, "packagePolicies": { "oneOf": [ @@ -3803,7 +4091,10 @@ "type": "number" } }, - "required": ["id", "status"] + "required": [ + "id", + "status" + ] } ] }, @@ -3880,7 +4171,13 @@ "type": "string" } }, - "required": ["id", "api_key_id", "api_key", "active", "created_at"] + "required": [ + "id", + "api_key_id", + "api_key", + "active", + "created_at" + ] }, "upgrade_diff": { "title": "Package policy Upgrade dryrun", @@ -3946,10 +4243,16 @@ "type": "string" } }, - "required": ["dataset", "type"] + "required": [ + "dataset", + "type" + ] } }, - "required": ["id", "data_stream"] + "required": [ + "id", + "data_stream" + ] } ] }, @@ -3979,7 +4282,9 @@ "type": "string" } }, - "required": ["namespace"] + "required": [ + "namespace" + ] }, "use_output": { "type": "string" @@ -3998,7 +4303,10 @@ "type": "string" } }, - "required": ["name", "version"] + "required": [ + "name", + "version" + ] } } }, @@ -4006,7 +4314,14 @@ "$ref": "#/components/schemas/full_agent_policy_input_stream" } }, - "required": ["id", "name", "revision", "type", "data_stream", "use_output"] + "required": [ + "id", + "name", + "revision", + "type", + "data_stream", + "use_output" + ] } ] }, @@ -4044,7 +4359,11 @@ "type": "string" } }, - "required": ["name", "title", "version"] + "required": [ + "name", + "title", + "version" + ] }, "namespace": { "type": "string" @@ -4080,7 +4399,11 @@ "type": "object" } }, - "required": ["type", "enabled", "streams"] + "required": [ + "type", + "enabled", + "streams" + ] } }, "policy_id": { @@ -4096,7 +4419,12 @@ "type": "boolean" } }, - "required": ["name", "namespace", "policy_id", "enabled"] + "required": [ + "name", + "namespace", + "policy_id", + "enabled" + ] }, "output": { "title": "Output", @@ -4116,7 +4444,9 @@ }, "type": { "type": "string", - "enum": ["elasticsearch"] + "enum": [ + "elasticsearch" + ] }, "hosts": { "type": "array", @@ -4154,7 +4484,12 @@ } } }, - "required": ["id", "is_default", "name", "type"] + "required": [ + "id", + "is_default", + "name", + "type" + ] } } }, @@ -4163,4 +4498,4 @@ "basicAuth": [] } ] -} +} \ No newline at end of file diff --git a/x-pack/plugins/fleet/common/openapi/bundled.yaml b/x-pack/plugins/fleet/common/openapi/bundled.yaml index 1592f4124fbb7..36175ffc59a88 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.yaml +++ b/x-pack/plugins/fleet/common/openapi/bundled.yaml @@ -184,7 +184,18 @@ paths: schema: $ref: '#/components/schemas/get_packages_response' operationId: list-all-packages - parameters: [] + parameters: + - in: query + name: excludeInstallStatus + schema: + type: boolean + default: false + description: >- + Whether to exclude the install status of each package. Enabling this + option will opt in to caching for the response via `cache-control` + headers. If you don't need up-to-date installation info for a package, + and are querying for a list of available packages, providing this flag + can improve performance substantially. /epm/packages/_bulk: post: summary: Packages - Bulk install diff --git a/x-pack/plugins/fleet/common/openapi/paths/epm@packages.yaml b/x-pack/plugins/fleet/common/openapi/paths/epm@packages.yaml index fe1aadedbcd1c..9c29b9d18357c 100644 --- a/x-pack/plugins/fleet/common/openapi/paths/epm@packages.yaml +++ b/x-pack/plugins/fleet/common/openapi/paths/epm@packages.yaml @@ -9,4 +9,14 @@ get: schema: $ref: ../components/schemas/get_packages_response.yaml operationId: list-all-packages -parameters: [] +parameters: + - in: query + name: excludeInstallStatus + schema: + type: boolean + default: false + description: >- + Whether to exclude the install status of each package. Enabling this option will opt in to + caching for the response via `cache-control` headers. If you don't need up-to-date installation + info for a package, and are querying for a list of available packages, providing this flag can + improve performance substantially. diff --git a/x-pack/plugins/fleet/common/types/index.ts b/x-pack/plugins/fleet/common/types/index.ts index d04855480dd62..ce1cb5a294f80 100644 --- a/x-pack/plugins/fleet/common/types/index.ts +++ b/x-pack/plugins/fleet/common/types/index.ts @@ -32,6 +32,7 @@ export interface FleetConfigType { packages?: PreconfiguredPackage[]; outputs?: PreconfiguredOutput[]; agentIdVerificationEnabled?: boolean; + enableExperimental?: string[]; developer?: { disableRegistryVersionCheck?: boolean; allowAgentUpgradeSourceUri?: boolean; diff --git a/x-pack/plugins/fleet/common/types/models/epm.ts b/x-pack/plugins/fleet/common/types/models/epm.ts index 41564fdb10b3b..5217a6232a18c 100644 --- a/x-pack/plugins/fleet/common/types/models/epm.ts +++ b/x-pack/plugins/fleet/common/types/models/epm.ts @@ -427,12 +427,17 @@ export interface PackageUsageStats { } export type Installable = + | InstallStatusExcluded | InstalledRegistry | Installing | NotInstalled | InstallFailed | InstalledBundled; +export type InstallStatusExcluded = T & { + status: undefined; +}; + export type InstalledRegistry = T & { status: InstallationStatus['Installed']; savedObject: SavedObject; diff --git a/x-pack/plugins/fleet/common/types/rest_spec/epm.ts b/x-pack/plugins/fleet/common/types/rest_spec/epm.ts index f1ccaae05487b..e12bdbb202321 100644 --- a/x-pack/plugins/fleet/common/types/rest_spec/epm.ts +++ b/x-pack/plugins/fleet/common/types/rest_spec/epm.ts @@ -32,6 +32,7 @@ export interface GetPackagesRequest { query: { category?: string; experimental?: boolean; + excludeInstallStatus?: boolean; }; } diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_settings.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_settings.spec.ts index 76c8f129584bd..338030e91f3da 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_settings.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_settings.spec.ts @@ -30,20 +30,20 @@ describe('Edit settings', () => { it('should update Fleet server hosts', () => { cy.getBySel('editHostsBtn').click(); - cy.get('[placeholder="Specify host URL"').type('http://localhost:8220'); + cy.get('[placeholder="Specify host URL"').type('https://localhost:8220'); cy.intercept('/api/fleet/settings', { - item: { id: 'fleet-default-settings', fleet_server_hosts: ['http://localhost:8220'] }, + item: { id: 'fleet-default-settings', fleet_server_hosts: ['https://localhost:8220'] }, }); cy.intercept('PUT', '/api/fleet/settings', { - fleet_server_hosts: ['http://localhost:8220'], + fleet_server_hosts: ['https://localhost:8220'], }).as('updateSettings'); cy.getBySel('saveApplySettingsBtn').click(); cy.getBySel(CONFIRM_MODAL_BTN).click(); cy.wait('@updateSettings').then((interception) => { - expect(interception.request.body.fleet_server_hosts[0]).to.equal('http://localhost:8220'); + expect(interception.request.body.fleet_server_hosts[0]).to.equal('https://localhost:8220'); }); }); diff --git a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts index 4f7f4378c0fc2..c269d1fe2ba2d 100644 --- a/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/fleet_startup.spec.ts @@ -77,12 +77,15 @@ describe('Fleet startup', () => { }); it('should create Fleet Server policy', () => { + cy.getBySel('fleetServerFlyoutTab-advanced').click(); cy.getBySel('createFleetServerPolicyBtn').click(); // verify policy is created and has fleet server and system package verifyPolicy('Fleet Server policy 1', ['Fleet Server', 'System']); navigateToTab(AGENTS_TAB); + cy.getBySel('fleetServerFlyoutTab-advanced').click(); + // verify create button changed to dropdown cy.getBySel('agentPolicyDropdown'); diff --git a/x-pack/plugins/fleet/cypress/integration/integrations_real.spec.ts b/x-pack/plugins/fleet/cypress/integration/integrations_real.spec.ts index e06b3d3ed5670..9bfd725497ffc 100644 --- a/x-pack/plugins/fleet/cypress/integration/integrations_real.spec.ts +++ b/x-pack/plugins/fleet/cypress/integration/integrations_real.spec.ts @@ -50,7 +50,19 @@ describe('Add Integration - Real API', () => { }); function addAndVerifyIntegration() { - cy.intercept('GET', '/api/fleet/epm/packages?*').as('packages'); + cy.intercept( + '/api/fleet/epm/packages?*', + { + middleware: true, + }, + (req) => { + req.on('before:response', (res) => { + // force all API responses to not be cached + res.headers['cache-control'] = 'no-store'; + }); + } + ).as('packages'); + navigateTo(INTEGRATIONS); cy.wait('@packages'); cy.get('.euiLoadingSpinner').should('not.exist'); @@ -75,7 +87,20 @@ describe('Add Integration - Real API', () => { .map((policy: any) => policy.id); cy.visit(`/app/fleet/policies/${agentPolicyId}`); - cy.intercept('GET', '/api/fleet/epm/packages?*').as('packages'); + + cy.intercept( + '/api/fleet/epm/packages?*', + { + middleware: true, + }, + (req) => { + req.on('before:response', (res) => { + // force all API responses to not be cached + res.headers['cache-control'] = 'no-store'; + }); + } + ).as('packages'); + cy.getBySel(ADD_PACKAGE_POLICY_BTN).click(); cy.wait('@packages'); cy.get('.euiLoadingSpinner').should('not.exist'); diff --git a/x-pack/plugins/fleet/kibana.json b/x-pack/plugins/fleet/kibana.json index 66301f6b6fb9c..0a45b03803fc3 100644 --- a/x-pack/plugins/fleet/kibana.json +++ b/x-pack/plugins/fleet/kibana.json @@ -8,7 +8,7 @@ "server": true, "ui": true, "configPath": ["xpack", "fleet"], - "requiredPlugins": ["licensing", "data", "encryptedSavedObjects", "navigation", "customIntegrations", "share", "spaces", "security"], + "requiredPlugins": ["licensing", "data", "encryptedSavedObjects", "navigation", "customIntegrations", "share", "spaces", "security", "unifiedSearch"], "optionalPlugins": ["features", "cloud", "usageCollection", "home", "globalSearch", "telemetry"], "extraPublicDirs": ["common"], "requiredBundles": ["kibanaReact", "cloud", "esUiShared", "infra", "kibanaUtils", "usageCollection", "unifiedSearch"] diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/advanced_tab.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/advanced_tab.tsx new file mode 100644 index 0000000000000..87b4a1bda7ff7 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/advanced_tab.tsx @@ -0,0 +1,66 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { EuiSteps } from '@elastic/eui'; +import React from 'react'; + +import { useAdvancedForm } from './hooks'; + +import { + getAddFleetServerHostStep, + getSelectAgentPolicyStep, + getGenerateServiceTokenStep, + getSetDeploymentModeStep, + getInstallFleetServerStep, + getConfirmFleetServerConnectionStep, +} from './steps'; + +export const AdvancedTab: React.FunctionComponent = () => { + const { + eligibleFleetServerPolicies, + refreshEligibleFleetServerPolicies, + fleetServerPolicyId, + setFleetServerPolicyId, + isFleetServerReady, + serviceToken, + isLoadingServiceToken, + generateServiceToken, + fleetServerHostForm, + deploymentMode, + setDeploymentMode, + } = useAdvancedForm(); + + const steps = [ + getSelectAgentPolicyStep({ + policyId: fleetServerPolicyId, + setPolicyId: setFleetServerPolicyId, + eligibleFleetServerPolicies, + refreshEligibleFleetServerPolicies, + }), + getSetDeploymentModeStep({ + deploymentMode, + setDeploymentMode, + disabled: !Boolean(fleetServerPolicyId), + }), + getAddFleetServerHostStep({ fleetServerHostForm, disabled: !Boolean(fleetServerPolicyId) }), + getGenerateServiceTokenStep({ + serviceToken, + generateServiceToken, + isLoadingServiceToken, + disabled: !Boolean(fleetServerHostForm.isFleetServerHostSubmitted), + }), + getInstallFleetServerStep({ + isFleetServerReady, + serviceToken, + fleetServerHost: fleetServerHostForm.fleetServerHost, + fleetServerPolicyId, + disabled: !Boolean(serviceToken), + }), + getConfirmFleetServerConnectionStep({ isFleetServerReady, disabled: !Boolean(serviceToken) }), + ]; + + return ; +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/components/fleet_server_host_combobox.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/components/fleet_server_host_combobox.tsx new file mode 100644 index 0000000000000..0508bd9108d3a --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/components/fleet_server_host_combobox.tsx @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { useState } from 'react'; +import type { EuiComboBoxOptionOption } from '@elastic/eui'; +import { EuiComboBox, EuiText } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { i18n } from '@kbn/i18n'; + +interface Props { + fleetServerHost: string | undefined; + fleetServerHostSettings: string[]; + isDisabled: boolean; + isInvalid: boolean; + onFleetServerHostChange: (host: string) => void; +} + +export const FleetServerHostComboBox: React.FunctionComponent = ({ + fleetServerHost, + fleetServerHostSettings, + isDisabled = false, + isInvalid = false, + onFleetServerHostChange, +}) => { + // Track options that are created inline + const [createdOptions, setCreatedOptions] = useState([]); + + const options = [...createdOptions, ...fleetServerHostSettings].map((option) => ({ + label: option, + value: option, + })); + + const handleChange = (selectedOptions: Array>) => { + const host = selectedOptions[0].value ?? ''; + onFleetServerHostChange(host); + }; + + const handleCreateOption = (option: string) => { + setCreatedOptions([...createdOptions, option]); + onFleetServerHostChange(option); + }; + + return ( + + fullWidth + isClearable={false} + singleSelection={{ asPlainText: true }} + placeholder="https://fleet-server-host.com:8220" + options={options} + customOptionText={i18n.translate( + 'xpack.fleet.fleetServerSetup.addFleetServerHostCustomOptionText', + { + defaultMessage: 'Add {searchValuePlaceholder} as a new Fleet Server host', + values: { searchValuePlaceholder: '{searchValue}' }, + } + )} + selectedOptions={fleetServerHost ? [{ label: fleetServerHost, value: fleetServerHost }] : []} + prepend={ + + + + } + noSuggestions={fleetServerHostSettings.length === 0} + data-test-subj="fleetServerHostInput" + isDisabled={isDisabled} + isInvalid={isInvalid} + onChange={handleChange} + onCreateOption={handleCreateOption} + /> + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/components/index.ts b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/components/index.ts new file mode 100644 index 0000000000000..904271187dc8b --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/components/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +export * from './fleet_server_host_combobox'; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/flyout.stories.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/flyout.stories.tsx new file mode 100644 index 0000000000000..b08c965d084c8 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/flyout.stories.tsx @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiButton } from '@elastic/eui'; + +import { FleetServerFlyout as FleetServerFlyoutComponent } from '.'; + +export const FleetServerFlyout = () => { + const [isOpen, setIsOpen] = React.useState(false); + + return ( +
+ setIsOpen(true)}> + Show flyout + + {isOpen && setIsOpen(false)} />} +
+ ); +}; + +FleetServerFlyout.args = { + isCloudEnabled: false, +}; + +export default { + component: FleetServerFlyout, + title: 'Sections/Fleet/Agents/Fleet Server Instructions/In Flyout', +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/index.ts b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/index.ts new file mode 100644 index 0000000000000..6c702d5433ce0 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +// These hooks are tightly coupled to each tab of the Fleet server instructions component, and provide +// all necessary data to drive those UI's +export * from './use_advanced_form'; +export * from './use_quick_start_form'; + +// These are individual hooks for one-off consumption. These are typically composed in the hooks above, +// but exported here to support individual usage. +export * from './use_wait_for_fleet_server'; +export * from './use_select_fleet_server_policy'; +export * from './use_service_token'; +export * from './use_fleet_server_host'; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_advanced_form.ts b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_advanced_form.ts new file mode 100644 index 0000000000000..5ed9f9faa0372 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_advanced_form.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useState } from 'react'; + +import type { DeploymentMode } from '../steps'; + +import { useFleetServerHost } from './use_fleet_server_host'; +import { useSelectFleetServerPolicy } from './use_select_fleet_server_policy'; +import { useServiceToken } from './use_service_token'; +import { useWaitForFleetServer } from './use_wait_for_fleet_server'; + +/** + * Provides all data/state required for the "advanced" tab in the Fleet Server instructions/flyout + */ +export const useAdvancedForm = (defaultAgentPolicyId?: string) => { + const { + eligibleFleetServerPolicies, + refreshEligibleFleetServerPolicies, + fleetServerPolicyId, + setFleetServerPolicyId, + } = useSelectFleetServerPolicy(defaultAgentPolicyId); + const { isFleetServerReady } = useWaitForFleetServer(); + const { serviceToken, isLoadingServiceToken, generateServiceToken } = useServiceToken(); + const fleetServerHostForm = useFleetServerHost(); + + const [deploymentMode, setDeploymentMode] = useState('quickstart'); + + return { + eligibleFleetServerPolicies, + refreshEligibleFleetServerPolicies, + fleetServerPolicyId, + setFleetServerPolicyId, + isFleetServerReady, + serviceToken, + isLoadingServiceToken, + generateServiceToken, + fleetServerHostForm, + deploymentMode, + setDeploymentMode, + }; +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_fleet_server_host.ts b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_fleet_server_host.ts new file mode 100644 index 0000000000000..05eeccf4a9312 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_fleet_server_host.ts @@ -0,0 +1,103 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { useCallback, useEffect, useState } from 'react'; + +import { sendPutSettings, useGetSettings } from '../../../hooks'; + +const URL_REGEX = /^(https):\/\/[^\s$.?#].[^\s]*$/gm; + +export interface FleetServerHostForm { + saveFleetServerHost: () => Promise; + fleetServerHost?: string; + fleetServerHostSettings: string[]; + isFleetServerHostSubmitted: boolean; + setFleetServerHost: React.Dispatch>; + error?: string; + validateFleetServerHost: () => boolean; +} + +export const useFleetServerHost = (): FleetServerHostForm => { + const [fleetServerHost, setFleetServerHost] = useState(); + const [isFleetServerHostSubmitted, setIsFleetServerHostSubmitted] = useState(false); + const [error, setError] = useState(); + + const { data: settings } = useGetSettings(); + + useEffect(() => { + const settingsFleetServerHosts = settings?.item.fleet_server_hosts ?? []; + + if (settingsFleetServerHosts.length) { + setFleetServerHost(settingsFleetServerHosts[0]); + } + }, [settings?.item.fleet_server_hosts]); + + const validateFleetServerHost = useCallback(() => { + if (!fleetServerHost) { + setError( + i18n.translate('xpack.fleet.fleetServerHost.requiredError', { + defaultMessage: 'Fleet server host is required.', + }) + ); + + return false; + } else if (!fleetServerHost.startsWith('https')) { + setError( + i18n.translate('xpack.fleet.fleetServerHost.requiresHttpsError', { + defaultMessage: 'Fleet server host must begin with "https"', + }) + ); + + return false; + } else if (!fleetServerHost.match(URL_REGEX)) { + setError( + i18n.translate('xpack.fleet.fleetServerSetup.addFleetServerHostInvalidUrlError', { + defaultMessage: 'Invalid URL', + }) + ); + + return false; + } + + return true; + }, [fleetServerHost]); + + const saveFleetServerHost = useCallback(async () => { + setIsFleetServerHostSubmitted(false); + + if (!validateFleetServerHost()) { + return; + } + + // If the Fleet Server host provided already exists in settings, don't submit it + if (settings?.item.fleet_server_hosts.includes(fleetServerHost!)) { + setIsFleetServerHostSubmitted(true); + return; + } + + const res = await sendPutSettings({ + fleet_server_hosts: [fleetServerHost!, ...(settings?.item.fleet_server_hosts || [])], + }); + + if (res.error) { + throw res.error; + } + + setIsFleetServerHostSubmitted(true); + }, [fleetServerHost, settings?.item.fleet_server_hosts, validateFleetServerHost]); + + return { + saveFleetServerHost, + fleetServerHost, + fleetServerHostSettings: settings?.item.fleet_server_hosts ?? [], + isFleetServerHostSubmitted, + setFleetServerHost, + error, + validateFleetServerHost, + }; +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_quick_start_form.ts b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_quick_start_form.ts new file mode 100644 index 0000000000000..84fd39aeec378 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_quick_start_form.ts @@ -0,0 +1,140 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useState, useCallback, useEffect } from 'react'; +import { i18n } from '@kbn/i18n'; + +import { sendCreateAgentPolicy, sendGetOneAgentPolicy, useStartServices } from '../../../hooks'; + +import type { NewAgentPolicy } from '../../../types'; + +import { useSelectFleetServerPolicy } from './use_select_fleet_server_policy'; +import { useServiceToken } from './use_service_token'; +import { useFleetServerHost } from './use_fleet_server_host'; + +const QUICK_START_FLEET_SERVER_POLICY_FIELDS: NewAgentPolicy = { + id: 'fleet-server-policy', + name: 'Fleet Server Policy', + description: 'Fleet Server policy generated by Kibana', + namespace: 'default', + has_fleet_server: true, + monitoring_enabled: ['logs', 'metrics'], + is_default_fleet_server: true, +}; + +export type QuickStartCreateFormStatus = 'initial' | 'loading' | 'error' | 'success'; + +export interface QuickStartCreateForm { + status: QuickStartCreateFormStatus; + error?: string; + submit: () => void; + fleetServerHost?: string; + fleetServerHostSettings: string[]; + isFleetServerHostSubmitted: boolean; + onFleetServerHostChange: (value: string) => void; + fleetServerPolicyId?: string; + serviceToken?: string; +} + +/** + * Provides a unified interface that combines the following operations: + * 1. Setting a Fleet Server host in Fleet's settings + * 2. Creating an agent policy that contains the `fleet_server` integration + * 3. Generating a service token used by Fleet Server + */ +export const useQuickStartCreateForm = (): QuickStartCreateForm => { + const [status, setStatus] = useState<'initial' | 'loading' | 'error' | 'success'>('initial'); + const [error, setError] = useState(); + + const { + fleetServerHost, + fleetServerHostSettings, + isFleetServerHostSubmitted, + setFleetServerHost, + validateFleetServerHost, + saveFleetServerHost, + error: fleetServerError, + } = useFleetServerHost(); + + // When a validation error is surfaced from the Fleet Server host form, we want to treat it + // the same way we do errors from the service token or policy creation steps + useEffect(() => { + setStatus('error'); + setError(fleetServerError); + }, [fleetServerError]); + + const { notifications } = useStartServices(); + const { fleetServerPolicyId, setFleetServerPolicyId } = useSelectFleetServerPolicy(); + const { serviceToken, generateServiceToken } = useServiceToken(); + + const onFleetServerHostChange = useCallback( + (value: string) => { + setFleetServerHost(value); + }, + [setFleetServerHost] + ); + + const submit = useCallback(async () => { + try { + if (validateFleetServerHost()) { + setStatus('loading'); + await saveFleetServerHost(); + await generateServiceToken(); + + const existingPolicy = await sendGetOneAgentPolicy( + QUICK_START_FLEET_SERVER_POLICY_FIELDS.id! + ); + + // Don't attempt to create the policy if it's already been created in a previous quick start flow + if (existingPolicy.data?.item) { + setFleetServerPolicyId(existingPolicy.data?.item.id); + } else { + const createPolicyResponse = await sendCreateAgentPolicy( + QUICK_START_FLEET_SERVER_POLICY_FIELDS, + { + withSysMonitoring: true, + } + ); + + setFleetServerPolicyId(createPolicyResponse.data?.item.id); + } + + setFleetServerHost(fleetServerHost); + setStatus('success'); + } + } catch (err) { + notifications.toasts.addError(err, { + title: i18n.translate('xpack.fleet.fleetServerSetup.errorAddingFleetServerHostTitle', { + defaultMessage: 'Error adding Fleet Server host', + }), + }); + + setStatus('error'); + setError(err.message); + } + }, [ + validateFleetServerHost, + saveFleetServerHost, + generateServiceToken, + setFleetServerHost, + fleetServerHost, + setFleetServerPolicyId, + notifications.toasts, + ]); + + return { + status, + error, + submit, + fleetServerPolicyId, + fleetServerHost, + fleetServerHostSettings, + isFleetServerHostSubmitted, + onFleetServerHostChange, + serviceToken, + }; +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_select_fleet_server_policy.ts b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_select_fleet_server_policy.ts new file mode 100644 index 0000000000000..add318e85a7ae --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_select_fleet_server_policy.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useEffect, useMemo, useState } from 'react'; + +import { useGetAgentPolicies } from '../../../hooks'; +import { policyHasFleetServer } from '../../../services'; + +export const useSelectFleetServerPolicy = (defaultAgentPolicyId?: string) => { + const [fleetServerPolicyId, setFleetServerPolicyId] = useState( + defaultAgentPolicyId + ); + const { data: agentPoliciesData, resendRequest } = useGetAgentPolicies({ + full: true, + }); + + const eligibleFleetServerPolicies = useMemo( + () => + agentPoliciesData + ? agentPoliciesData.items?.filter((item) => policyHasFleetServer(item)) + : [], + [agentPoliciesData] + ); + + useEffect(() => { + // Default to the first policy found with a fleet server integration installed + if (eligibleFleetServerPolicies.length && !fleetServerPolicyId) { + setFleetServerPolicyId(eligibleFleetServerPolicies[0].id); + } + }, [eligibleFleetServerPolicies, fleetServerPolicyId]); + + return { + fleetServerPolicyId, + setFleetServerPolicyId, + eligibleFleetServerPolicies, + refreshEligibleFleetServerPolicies: resendRequest, + }; +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_service_token.ts b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_service_token.ts new file mode 100644 index 0000000000000..3b729a6776b52 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_service_token.ts @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useState, useCallback } from 'react'; +import { i18n } from '@kbn/i18n'; + +import { useStartServices, sendGenerateServiceToken } from '../../../hooks'; + +export const useServiceToken = () => { + const { notifications } = useStartServices(); + const [serviceToken, setServiceToken] = useState(); + const [isLoadingServiceToken, setIsLoadingServiceToken] = useState(false); + + const generateServiceToken = useCallback(async () => { + setIsLoadingServiceToken(true); + try { + const { data } = await sendGenerateServiceToken(); + if (data?.value) { + setServiceToken(data?.value); + } + } catch (err) { + notifications.toasts.addError(err, { + title: i18n.translate('xpack.fleet.fleetServerSetup.errorGeneratingTokenTitleText', { + defaultMessage: 'Error generating token', + }), + }); + } finally { + setIsLoadingServiceToken(false); + } + }, [notifications.toasts]); + + return { serviceToken, isLoadingServiceToken, generateServiceToken }; +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_wait_for_fleet_server.ts b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_wait_for_fleet_server.ts new file mode 100644 index 0000000000000..4da59560e408e --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_wait_for_fleet_server.ts @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { useEffect, useState } from 'react'; + +import { sendGetFleetStatus, useStartServices } from '../../../hooks'; + +const REFRESH_INTERVAL = 10000; + +/** + * Polls the Fleet status endpoint until the `fleet_server` requirement does not appear + * in the `missing_requirements` list. + */ +export const useWaitForFleetServer = () => { + const [isFleetServerReady, setIsFleetServerReady] = useState(false); + const { notifications } = useStartServices(); + + useEffect(() => { + let interval: ReturnType | null = null; + + if (!isFleetServerReady) { + interval = setInterval(async () => { + try { + const res = await sendGetFleetStatus(); + + if (res.error) { + throw res.error; + } + if (res.data?.isReady && !res.data?.missing_requirements?.includes('fleet_server')) { + setIsFleetServerReady(true); + + if (interval) { + clearInterval(interval); + } + } + } catch (err) { + notifications.toasts.addError(err, { + title: i18n.translate('xpack.fleet.fleetServerSetup.errorRefreshingFleetServerStatus', { + defaultMessage: 'Error refreshing Fleet Server status', + }), + }); + } + }, REFRESH_INTERVAL); + } + + const cleanup = () => { + if (interval) { + clearInterval(interval); + } + }; + + return cleanup; + }, [notifications.toasts, isFleetServerReady]); + + return { isFleetServerReady }; +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/index.tsx new file mode 100644 index 0000000000000..6c48b499b9553 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/index.tsx @@ -0,0 +1,154 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useState } from 'react'; +import { + EuiFlexGroup, + EuiFlyout, + EuiFlyoutBody, + EuiFlyoutHeader, + EuiLink, + EuiSpacer, + EuiTab, + EuiTabs, + EuiText, + EuiTitle, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import styled from 'styled-components'; + +import { useStartServices } from '../../hooks'; + +import { QuickStartTab } from './quick_start_tab'; +import { AdvancedTab } from './advanced_tab'; + +const ContentWrapper = styled(EuiFlexGroup)` + height: 100%; + margin: 0 auto; +`; + +interface Props { + onClose: () => void; +} + +const useFleetServerTabs = () => { + const [currentTab, setCurrentTab] = useState('quickStart'); + + const quickStartTab = { + id: 'quickStart', + name: 'Quick Start', + content: , + }; + + const advancedTab = { + id: 'advanced', + name: 'Advanced', + content: , + }; + + const currentTabContent = + currentTab === 'quickStart' ? quickStartTab.content : advancedTab.content; + + return { tabs: [quickStartTab, advancedTab], currentTab, setCurrentTab, currentTabContent }; +}; + +const Header: React.FunctionComponent<{ + isFlyout?: boolean; + currentTab: string; + tabs: Array<{ id: string; name: string; content: React.ReactNode }>; + onTabClick: (id: string) => void; +}> = ({ isFlyout = false, currentTab: currentTabId, tabs, onTabClick }) => { + const { docLinks } = useStartServices(); + + return ( + <> + +

+ +

+
+ + + + + + + + ), + }} + /> + + + + + + {tabs.map((tab) => ( + onTabClick(tab.id)} + > + {tab.name} + + ))} + + + ); +}; + +// Renders instructions inside of a flyout +export const FleetServerFlyout: React.FunctionComponent = ({ onClose }) => { + const { tabs, currentTab, setCurrentTab, currentTabContent } = useFleetServerTabs(); + + return ( + + +
setCurrentTab(id)} + isFlyout + /> + + + {currentTabContent} + + ); +}; + +// Renders instructions directly +export const FleetServerInstructions: React.FunctionComponent = () => { + const { tabs, currentTab, setCurrentTab, currentTabContent } = useFleetServerTabs(); + + return ( + +
setCurrentTab(id)} /> + + + + {currentTabContent} + + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/instructions.stories.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/instructions.stories.tsx new file mode 100644 index 0000000000000..9993fab723a44 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/instructions.stories.tsx @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { FleetServerInstructions as FleetServerInstructionsComponent } from '.'; + +export const FleetServerInstructions = () => { + return ; +}; + +FleetServerInstructions.args = { + isCloudEnabled: false, +}; + +export default { + component: FleetServerInstructions, + title: 'Sections/Fleet/Agents/Fleet Server Instructions/Without Flyout', +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/quick_start_tab.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/quick_start_tab.tsx new file mode 100644 index 0000000000000..cf8abc2fe9e16 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/quick_start_tab.tsx @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiSteps } from '@elastic/eui'; + +import { useQuickStartCreateForm, useWaitForFleetServer } from './hooks'; + +import { + getGettingStartedStep, + getConfirmFleetServerConnectionStep, + getInstallFleetServerStep, +} from './steps'; + +export const QuickStartTab: React.FunctionComponent = () => { + const quickStartCreateForm = useQuickStartCreateForm(); + const { isFleetServerReady } = useWaitForFleetServer(); + + const steps = [ + getGettingStartedStep({ + quickStartCreateForm, + }), + getInstallFleetServerStep({ + isFleetServerReady, + fleetServerHost: quickStartCreateForm.fleetServerHost, + fleetServerPolicyId: quickStartCreateForm.fleetServerPolicyId, + serviceToken: quickStartCreateForm.serviceToken, + disabled: quickStartCreateForm.status !== 'success', + }), + getConfirmFleetServerConnectionStep({ + isFleetServerReady, + disabled: quickStartCreateForm.status !== 'success', + }), + ]; + + return ; +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/add_fleet_server_host.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/add_fleet_server_host.tsx new file mode 100644 index 0000000000000..e64e23f039f89 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/add_fleet_server_host.tsx @@ -0,0 +1,165 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useState, useCallback } from 'react'; +import type { EuiStepProps } from '@elastic/eui'; +import { + EuiButton, + EuiCallOut, + EuiCode, + EuiFlexGroup, + EuiFlexItem, + EuiForm, + EuiFormErrorText, + EuiLink, + EuiSpacer, + EuiText, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import { useStartServices, useLink } from '../../../hooks'; +import type { FleetServerHostForm } from '../hooks'; +import { FleetServerHostComboBox } from '../components'; + +export const getAddFleetServerHostStep = ({ + fleetServerHostForm, + disabled, +}: { + fleetServerHostForm: FleetServerHostForm; + disabled: boolean; +}): EuiStepProps => { + return { + title: i18n.translate('xpack.fleet.fleetServerSetup.addFleetServerHostStepTitle', { + defaultMessage: 'Add your Fleet Server host', + }), + status: disabled ? 'disabled' : undefined, + children: disabled ? null : ( + + ), + }; +}; + +export const AddFleetServerHostStepContent = ({ + fleetServerHostForm, +}: { + fleetServerHostForm: FleetServerHostForm; +}) => { + const { + fleetServerHost, + fleetServerHostSettings, + setFleetServerHost, + validateFleetServerHost, + saveFleetServerHost, + error, + } = fleetServerHostForm; + + const [isLoading, setIsLoading] = useState(false); + const [submittedFleetServerHost, setSubmittedFleetServerHost] = useState(); + const { notifications } = useStartServices(); + const { getHref } = useLink(); + + const onSubmit = useCallback(async () => { + try { + setSubmittedFleetServerHost(''); + setIsLoading(true); + + if (validateFleetServerHost()) { + await saveFleetServerHost(); + setSubmittedFleetServerHost(fleetServerHost); + } + } catch (err) { + notifications.toasts.addError(err, { + title: i18n.translate('xpack.fleet.fleetServerSetup.errorAddingFleetServerHostTitle', { + defaultMessage: 'Error adding Fleet Server host', + }), + }); + } finally { + setIsLoading(false); + } + }, [validateFleetServerHost, saveFleetServerHost, fleetServerHost, notifications.toasts]); + + const onChange = useCallback( + (host: string) => { + setFleetServerHost(host); + + if (error) { + validateFleetServerHost(); + } + }, + [error, setFleetServerHost, validateFleetServerHost] + ); + + return ( + + + 8220 }} + /> + + + + + + {error && {error}} + + + + + + + + {submittedFleetServerHost && ( + <> + + + } + > + + + + ), + }} + /> + + + )} + + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/confirm_fleet_server_connection.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/confirm_fleet_server_connection.tsx new file mode 100644 index 0000000000000..5aa5c01a108a4 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/confirm_fleet_server_connection.tsx @@ -0,0 +1,66 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useContext } from 'react'; + +import type { EuiStepProps } from '@elastic/eui'; +import { EuiButton, EuiLoadingSpinner, EuiSpacer } from '@elastic/eui'; +import { EuiText } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import { agentFlyoutContext } from '../../../sections/agents'; + +export function getConfirmFleetServerConnectionStep({ + disabled, + isFleetServerReady, +}: { + disabled: boolean; + isFleetServerReady: boolean; +}): EuiStepProps { + return { + title: isFleetServerReady + ? i18n.translate('xpack.fleet.fleetServerFlyout.confirmConnectionSuccessTitle', { + defaultMessage: 'Fleet Server connected', + }) + : i18n.translate('xpack.fleet.fleetServerFlyout.confirmConnectionTitle', { + defaultMessage: 'Confirm connection', + }), + status: isFleetServerReady ? 'complete' : 'disabled', + children: !disabled && ( + + ), + }; +} + +const ConfirmFleetServerConnectionStepContent: React.FunctionComponent<{ + isFleetServerReady: boolean; +}> = ({ isFleetServerReady }) => { + const addAgentFlyout = useContext(agentFlyoutContext); + + return isFleetServerReady ? ( + <> + + + + + + + + + + + ) : ( + + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/create_service_token.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/create_service_token.tsx new file mode 100644 index 0000000000000..dcfa150c2d32c --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/create_service_token.tsx @@ -0,0 +1,136 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import styled from 'styled-components'; + +import type { EuiStepProps } from '@elastic/eui'; +import { + EuiButton, + EuiCallOut, + EuiCodeBlock, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, + EuiText, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; + +const FlexItemWithMinWidth = styled(EuiFlexItem)` + min-width: 0px; + max-width: 100%; +`; + +export const ContentWrapper = styled(EuiFlexGroup)` + height: 100%; + margin: 0 auto; + max-width: 800px; +`; + +// Otherwise the copy button is over the text +const CommandCode = styled.div.attrs(() => { + return { + className: 'eui-textBreakAll', + }; +})` + margin-right: ${(props) => props.theme.eui.paddingSizes.m}; +`; + +export const getGenerateServiceTokenStep = ({ + disabled = false, + serviceToken, + generateServiceToken, + isLoadingServiceToken, +}: { + disabled?: boolean; + serviceToken?: string; + generateServiceToken: () => void; + isLoadingServiceToken: boolean; +}): EuiStepProps => { + return { + title: i18n.translate('xpack.fleet.fleetServerSetup.stepGenerateServiceTokenTitle', { + defaultMessage: 'Generate a service token', + }), + status: disabled ? 'disabled' : undefined, + children: !disabled && ( + + ), + }; +}; + +const ServiceTokenStepContent: React.FunctionComponent<{ + serviceToken?: string; + generateServiceToken: () => void; + isLoadingServiceToken: boolean; +}> = ({ serviceToken, generateServiceToken, isLoadingServiceToken }) => { + return ( + <> + + + + + {!serviceToken ? ( + + + { + generateServiceToken(); + }} + data-test-subj="fleetServerGenerateServiceTokenBtn" + > + + + + + ) : ( + <> + + } + /> + + + + + + + + + + {serviceToken} + + + + + )} + + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/get_started.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/get_started.tsx new file mode 100644 index 0000000000000..50e9b6b72002c --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/get_started.tsx @@ -0,0 +1,130 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import type { EuiStepProps } from '@elastic/eui'; +import { + EuiButton, + EuiCallOut, + EuiCode, + EuiFlexGroup, + EuiFlexItem, + EuiForm, + EuiFormErrorText, + EuiLink, + EuiSpacer, + EuiText, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import { useLink } from '../../../hooks'; + +import type { QuickStartCreateForm } from '../hooks'; +import { FleetServerHostComboBox } from '../components'; + +export function getGettingStartedStep({ + quickStartCreateForm, +}: { + quickStartCreateForm: QuickStartCreateForm; +}): EuiStepProps { + return { + title: i18n.translate('xpack.fleet.fleetServerFlyout.getStartedTitle', { + defaultMessage: 'Get started with Fleet Server', + }), + status: quickStartCreateForm.status === 'success' ? 'complete' : 'current', + children: , + }; +} + +const GettingStartedStepContent: React.FunctionComponent<{ + quickStartCreateForm: QuickStartCreateForm; +}> = ({ quickStartCreateForm }) => { + const { getHref } = useLink(); + + const { fleetServerHost, fleetServerHostSettings, onFleetServerHostChange } = + quickStartCreateForm; + + if (quickStartCreateForm.status === 'success') { + return ( + + + {fleetServerHost}, + fleetSettingsLink: ( + + + + ), + }} + /> + + + ); + } + + return ( + <> + + 8220 }} + /> + + + + + + + + + + {quickStartCreateForm.status === 'error' && ( + {quickStartCreateForm.error} + )} + + + + + + + + + + + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/index.ts b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/index.ts new file mode 100644 index 0000000000000..11adf2693927b --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './add_fleet_server_host'; +export * from './confirm_fleet_server_connection'; +export * from './create_service_token'; +export * from './get_started'; +export * from './install_fleet_server'; +export * from './select_agent_policy'; +export * from './set_deployment_mode'; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/install_fleet_server.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/install_fleet_server.tsx new file mode 100644 index 0000000000000..dac9555ba3149 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/install_fleet_server.tsx @@ -0,0 +1,97 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import type { EuiStepProps } from '@elastic/eui'; +import { EuiSpacer, EuiText } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import type { PLATFORM_TYPE } from '../../../hooks'; +import { useDefaultOutput, useKibanaVersion } from '../../../hooks'; + +import { PlatformSelector } from '../..'; + +import { getInstallCommandForPlatform } from '../utils'; + +export function getInstallFleetServerStep({ + isFleetServerReady, + disabled, + serviceToken, + fleetServerHost, + fleetServerPolicyId, +}: { + isFleetServerReady: boolean; + disabled: boolean; + serviceToken?: string; + fleetServerHost?: string; + fleetServerPolicyId?: string; +}): EuiStepProps { + return { + title: i18n.translate('xpack.fleet.fleetServerFlyout.installFleetServerTitle', { + defaultMessage: 'Install Fleet Server to a centralized host', + }), + status: disabled ? 'disabled' : isFleetServerReady ? 'complete' : 'incomplete', + children: !disabled && ( + + ), + }; +} + +const InstallFleetServerStepContent: React.FunctionComponent<{ + serviceToken?: string; + fleetServerHost?: string; + fleetServerPolicyId?: string; +}> = ({ serviceToken, fleetServerHost, fleetServerPolicyId }) => { + const kibanaVersion = useKibanaVersion(); + const { output } = useDefaultOutput(); + + const installCommands = (['linux', 'mac', 'windows', 'deb', 'rpm'] as PLATFORM_TYPE[]).reduce( + (acc, platform) => { + acc[platform] = getInstallCommandForPlatform( + platform, + output?.hosts?.[0] ?? '', + serviceToken ?? '', + fleetServerPolicyId, + fleetServerHost, + false, + output?.ca_trusted_fingerprint, + kibanaVersion + ); + + return acc; + }, + {} as Record + ); + + return ( + <> + + + + + + + + + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/select_agent_policy.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/select_agent_policy.tsx new file mode 100644 index 0000000000000..778716bacb02e --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/select_agent_policy.tsx @@ -0,0 +1,81 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { EuiStepProps } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React, { useEffect } from 'react'; + +import { SelectCreateAgentPolicy } from '../..'; + +import type { GetAgentPoliciesResponseItem } from '../../../types'; + +export const getSelectAgentPolicyStep = ({ + policyId, + setPolicyId, + eligibleFleetServerPolicies, + refreshEligibleFleetServerPolicies, +}: { + policyId?: string; + setPolicyId: (v?: string) => void; + eligibleFleetServerPolicies: GetAgentPoliciesResponseItem[]; + refreshEligibleFleetServerPolicies: () => void; +}): EuiStepProps => { + return { + title: + eligibleFleetServerPolicies.length === 0 + ? i18n.translate('xpack.fleet.fleetServerSetup.stepCreateAgentPolicyTitle', { + defaultMessage: 'Create a policy for Fleet Server', + }) + : i18n.translate('xpack.fleet.fleetServerSetup.stepSelectAgentPolicyTitle', { + defaultMessage: 'Select a policy for Fleet Server', + }), + status: policyId ? 'complete' : undefined, + children: ( + + ), + }; +}; + +const SelectAgentPolicyStepContent: React.FunctionComponent<{ + policyId?: string; + setPolicyId: (v?: string) => void; + eligibleFleetServerPolicies: GetAgentPoliciesResponseItem[]; + refreshEligibleFleetServerPolicies: () => void; +}> = ({ + policyId, + setPolicyId, + eligibleFleetServerPolicies, + refreshEligibleFleetServerPolicies, +}) => { + useEffect(() => { + // Select default value + if (eligibleFleetServerPolicies.length && !policyId) { + setPolicyId(eligibleFleetServerPolicies[0].id); + } + }, [eligibleFleetServerPolicies, policyId, setPolicyId]); + + const setSelectedPolicyId = (agentPolicyId?: string) => { + setPolicyId(agentPolicyId); + }; + + return ( + + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/set_deployment_mode.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/set_deployment_mode.tsx new file mode 100644 index 0000000000000..9833fc1d4527f --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/set_deployment_mode.tsx @@ -0,0 +1,117 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useMemo } from 'react'; + +import type { EuiStepProps } from '@elastic/eui'; +import { EuiRadioGroup, EuiSpacer } from '@elastic/eui'; +import { EuiText } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; + +export type DeploymentMode = 'production' | 'quickstart'; + +export const getSetDeploymentModeStep = ({ + deploymentMode, + setDeploymentMode, + disabled, +}: { + deploymentMode: DeploymentMode; + setDeploymentMode: (v: DeploymentMode) => void; + disabled: boolean; +}): EuiStepProps => { + return { + title: i18n.translate('xpack.fleet.fleetServerSetup.stepDeploymentModeTitle', { + defaultMessage: 'Choose a deployment mode for security', + }), + status: disabled ? 'disabled' : undefined, + children: disabled ? null : ( + + ), + }; +}; + +const DeploymentModeStepContent = ({ + deploymentMode, + setDeploymentMode, +}: { + deploymentMode: DeploymentMode; + setDeploymentMode: (v: DeploymentMode) => void; +}) => { + const onChangeCallback = useCallback( + (v: string) => { + const value = v.split('_')[0]; + if (value === 'production' || value === 'quickstart') { + setDeploymentMode(value); + } + }, + [setDeploymentMode] + ); + + // radio id has to be unique so that the component works even if appears twice in DOM (Agents tab, Add agent flyout) + const radioSuffix = useMemo(() => Date.now(), []); + + return ( + <> + + + + + + + + ), + }} + /> + ), + }, + { + id: `production_${radioSuffix}`, + label: ( + + + + ), + }} + /> + ), + }, + ]} + idSelected={`${deploymentMode}_${radioSuffix}`} + onChange={onChangeCallback} + name={`radio group ${radioSuffix}`} + /> + + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/utils/index.ts b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/utils/index.ts new file mode 100644 index 0000000000000..fcbab4728cbe2 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/utils/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './install_command_utils'; diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/utils/install_command_utils.test.ts b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/utils/install_command_utils.test.ts new file mode 100644 index 0000000000000..89a246c5c6265 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/utils/install_command_utils.test.ts @@ -0,0 +1,343 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { getInstallCommandForPlatform } from './install_command_utils'; + +describe('getInstallCommandForPlatform', () => { + describe('without policy id', () => { + it('should return the correct command if the the policyId is not set for linux', () => { + const res = getInstallCommandForPlatform( + 'linux', + 'http://elasticsearch:9200', + 'service-token-1' + ); + + expect(res).toMatchInlineSnapshot(` + "curl -L -O https://artifacts.elastic.co/downloads/beats/elastic-agent/elastic-agent--linux-x86_64.zip \\\\ + tar xzvf elastic-agent--linux-x86_64.zip \\\\ + cd elastic-agent--linux-x86_64 \\\\ + sudo ./elastic-agent install \\\\ + --fleet-server-es=http://elasticsearch:9200 \\\\ + --fleet-server-service-token=service-token-1" + `); + }); + + it('should return the correct command if the the policyId is not set for mac', () => { + const res = getInstallCommandForPlatform( + 'mac', + 'http://elasticsearch:9200', + 'service-token-1' + ); + + expect(res).toMatchInlineSnapshot(` + "curl -L -O https://artifacts.elastic.co/downloads/beats/elastic-agent/elastic-agent--darwin-x86_64.tar.gz \\\\ + tar xzvf elastic-agent--darwin-x86_64.tar.gz \\\\ + cd elastic-agent--darwin-x86_64 \\\\ + sudo ./elastic-agent install \\\\ + --fleet-server-es=http://elasticsearch:9200 \\\\ + --fleet-server-service-token=service-token-1" + `); + }); + + it('should return the correct command if the the policyId is not set for windows', () => { + const res = getInstallCommandForPlatform( + 'windows', + 'http://elasticsearch:9200', + 'service-token-1' + ); + + expect(res).toMatchInlineSnapshot(` + "wget https://artifacts.elastic.co/downloads/beats/elastic-agent/elastic-agent--windows-x86_64.tar.gz -OutFile elastic-agent--windows-x86_64.tar.gz \` + Expand-Archive .\\\\elastic-agent--windows-x86_64.tar.gz \` + cd elastic-agent--windows-x86_64\` + .\\\\elastic-agent.exe install \` + --fleet-server-es=http://elasticsearch:9200 \` + --fleet-server-service-token=service-token-1" + `); + }); + + it('should return the correct command if the the policyId is not set for rpm', () => { + const res = getInstallCommandForPlatform( + 'rpm', + 'http://elasticsearch:9200', + 'service-token-1' + ); + + expect(res).toMatchInlineSnapshot(` + "curl -L -O https://artifacts.elastic.co/downloads/beats/elastic-agent/elastic-agent--x86_64.rpm \\\\ + tar xzvf elastic-agent--x86_64.rpm \\\\ + cd elastic-agent--x86_64 \\\\ + sudo elastic-agent enroll \\\\ + --fleet-server-es=http://elasticsearch:9200 \\\\ + --fleet-server-service-token=service-token-1" + `); + }); + + it('should return the correct command if the the policyId is not set for deb', () => { + const res = getInstallCommandForPlatform( + 'deb', + 'http://elasticsearch:9200', + 'service-token-1' + ); + + expect(res).toMatchInlineSnapshot(` + "curl -L -O https://artifacts.elastic.co/downloads/beats/elastic-agent/elastic-agent--amd64.deb \\\\ + tar xzvf elastic-agent--amd64.deb \\\\ + cd elastic-agent--amd64 \\\\ + sudo elastic-agent enroll \\\\ + --fleet-server-es=http://elasticsearch:9200 \\\\ + --fleet-server-service-token=service-token-1" + `); + }); + + it('should return the correct command sslCATrustedFingerprint option is passed', () => { + const res = getInstallCommandForPlatform( + 'linux', + 'http://elasticsearch:9200', + 'service-token-1', + undefined, + undefined, + false, + 'fingerprint123456' + ); + + expect(res).toMatchInlineSnapshot(` + "curl -L -O https://artifacts.elastic.co/downloads/beats/elastic-agent/elastic-agent--linux-x86_64.zip \\\\ + tar xzvf elastic-agent--linux-x86_64.zip \\\\ + cd elastic-agent--linux-x86_64 \\\\ + sudo ./elastic-agent install \\\\ + --fleet-server-es=http://elasticsearch:9200 \\\\ + --fleet-server-service-token=service-token-1 \\\\ + --fleet-server-es-ca-trusted-fingerprint=fingerprint123456" + `); + }); + }); + + describe('with policy id', () => { + it('should return the correct command if the the policyId is set for linux', () => { + const res = getInstallCommandForPlatform( + 'linux', + 'http://elasticsearch:9200', + 'service-token-1', + 'policy-1' + ); + + expect(res).toMatchInlineSnapshot(` + "curl -L -O https://artifacts.elastic.co/downloads/beats/elastic-agent/elastic-agent--linux-x86_64.zip \\\\ + tar xzvf elastic-agent--linux-x86_64.zip \\\\ + cd elastic-agent--linux-x86_64 \\\\ + sudo ./elastic-agent install \\\\ + --fleet-server-es=http://elasticsearch:9200 \\\\ + --fleet-server-service-token=service-token-1 \\\\ + --fleet-server-policy=policy-1" + `); + }); + + it('should return the correct command if the the policyId is set for mac', () => { + const res = getInstallCommandForPlatform( + 'mac', + 'http://elasticsearch:9200', + 'service-token-1', + 'policy-1' + ); + + expect(res).toMatchInlineSnapshot(` + "curl -L -O https://artifacts.elastic.co/downloads/beats/elastic-agent/elastic-agent--darwin-x86_64.tar.gz \\\\ + tar xzvf elastic-agent--darwin-x86_64.tar.gz \\\\ + cd elastic-agent--darwin-x86_64 \\\\ + sudo ./elastic-agent install \\\\ + --fleet-server-es=http://elasticsearch:9200 \\\\ + --fleet-server-service-token=service-token-1 \\\\ + --fleet-server-policy=policy-1" + `); + }); + + it('should return the correct command if the the policyId is set for windows', () => { + const res = getInstallCommandForPlatform( + 'windows', + 'http://elasticsearch:9200', + 'service-token-1', + 'policy-1' + ); + + expect(res).toMatchInlineSnapshot(` + "wget https://artifacts.elastic.co/downloads/beats/elastic-agent/elastic-agent--windows-x86_64.tar.gz -OutFile elastic-agent--windows-x86_64.tar.gz \` + Expand-Archive .\\\\elastic-agent--windows-x86_64.tar.gz \` + cd elastic-agent--windows-x86_64\` + .\\\\elastic-agent.exe install \` + --fleet-server-es=http://elasticsearch:9200 \` + --fleet-server-service-token=service-token-1 \` + --fleet-server-policy=policy-1" + `); + }); + + it('should return the correct command if the the policyId is set for rpm', () => { + const res = getInstallCommandForPlatform( + 'rpm', + 'http://elasticsearch:9200', + 'service-token-1', + 'policy-1' + ); + + expect(res).toMatchInlineSnapshot(` + "curl -L -O https://artifacts.elastic.co/downloads/beats/elastic-agent/elastic-agent--x86_64.rpm \\\\ + tar xzvf elastic-agent--x86_64.rpm \\\\ + cd elastic-agent--x86_64 \\\\ + sudo elastic-agent enroll \\\\ + --fleet-server-es=http://elasticsearch:9200 \\\\ + --fleet-server-service-token=service-token-1 \\\\ + --fleet-server-policy=policy-1" + `); + }); + + it('should return the correct command if the the policyId is set for deb', () => { + const res = getInstallCommandForPlatform( + 'deb', + 'http://elasticsearch:9200', + 'service-token-1', + 'policy-1' + ); + + expect(res).toMatchInlineSnapshot(` + "curl -L -O https://artifacts.elastic.co/downloads/beats/elastic-agent/elastic-agent--amd64.deb \\\\ + tar xzvf elastic-agent--amd64.deb \\\\ + cd elastic-agent--amd64 \\\\ + sudo elastic-agent enroll \\\\ + --fleet-server-es=http://elasticsearch:9200 \\\\ + --fleet-server-service-token=service-token-1 \\\\ + --fleet-server-policy=policy-1" + `); + }); + }); + + describe('with policy id and fleet server host and production deployment', () => { + it('should return the correct command if the the policyId is set for linux', () => { + const res = getInstallCommandForPlatform( + 'linux', + 'http://elasticsearch:9200', + 'service-token-1', + 'policy-1', + 'http://fleetserver:8220', + true + ); + + expect(res).toMatchInlineSnapshot(` + "curl -L -O https://artifacts.elastic.co/downloads/beats/elastic-agent/elastic-agent--linux-x86_64.zip \\\\ + tar xzvf elastic-agent--linux-x86_64.zip \\\\ + cd elastic-agent--linux-x86_64 \\\\ + sudo ./elastic-agent install--url=http://fleetserver:8220 \\\\ + --fleet-server-es=http://elasticsearch:9200 \\\\ + --fleet-server-service-token=service-token-1 \\\\ + --fleet-server-policy=policy-1 \\\\ + --certificate-authorities= \\\\ + --fleet-server-es-ca= \\\\ + --fleet-server-cert= \\\\ + --fleet-server-cert-key=" + `); + }); + + it('should return the correct command if the the policyId is set for mac', () => { + const res = getInstallCommandForPlatform( + 'mac', + 'http://elasticsearch:9200', + 'service-token-1', + 'policy-1', + 'http://fleetserver:8220', + true + ); + + expect(res).toMatchInlineSnapshot(` + "curl -L -O https://artifacts.elastic.co/downloads/beats/elastic-agent/elastic-agent--darwin-x86_64.tar.gz \\\\ + tar xzvf elastic-agent--darwin-x86_64.tar.gz \\\\ + cd elastic-agent--darwin-x86_64 \\\\ + sudo ./elastic-agent install --url=http://fleetserver:8220 \\\\ + --fleet-server-es=http://elasticsearch:9200 \\\\ + --fleet-server-service-token=service-token-1 \\\\ + --fleet-server-policy=policy-1 \\\\ + --certificate-authorities= \\\\ + --fleet-server-es-ca= \\\\ + --fleet-server-cert= \\\\ + --fleet-server-cert-key=" + `); + }); + + it('should return the correct command if the the policyId is set for windows', () => { + const res = getInstallCommandForPlatform( + 'windows', + 'http://elasticsearch:9200', + 'service-token-1', + 'policy-1', + 'http://fleetserver:8220', + true + ); + + expect(res).toMatchInlineSnapshot(` + "wget https://artifacts.elastic.co/downloads/beats/elastic-agent/elastic-agent--windows-x86_64.tar.gz -OutFile elastic-agent--windows-x86_64.tar.gz \` + Expand-Archive .\\\\elastic-agent--windows-x86_64.tar.gz \` + cd elastic-agent--windows-x86_64\` + .\\\\elastic-agent.exe install --url=http://fleetserver:8220 \` + --fleet-server-es=http://elasticsearch:9200 \` + --fleet-server-service-token=service-token-1 \` + --fleet-server-policy=policy-1 \` + --certificate-authorities= \` + --fleet-server-es-ca= \` + --fleet-server-cert= \` + --fleet-server-cert-key=" + `); + }); + + it('should return the correct command if the the policyId is set for rpm', () => { + const res = getInstallCommandForPlatform( + 'rpm', + 'http://elasticsearch:9200', + 'service-token-1', + 'policy-1', + 'http://fleetserver:8220', + true + ); + + expect(res).toMatchInlineSnapshot(` + "curl -L -O https://artifacts.elastic.co/downloads/beats/elastic-agent/elastic-agent--x86_64.rpm \\\\ + tar xzvf elastic-agent--x86_64.rpm \\\\ + cd elastic-agent--x86_64 \\\\ + sudo elastic-agent enroll --url=http://fleetserver:8220 \\\\ + --fleet-server-es=http://elasticsearch:9200 \\\\ + --fleet-server-service-token=service-token-1 \\\\ + --fleet-server-policy=policy-1 \\\\ + --certificate-authorities= \\\\ + --fleet-server-es-ca= \\\\ + --fleet-server-cert= \\\\ + --fleet-server-cert-key=" + `); + }); + + it('should return the correct command if the the policyId is set for deb', () => { + const res = getInstallCommandForPlatform( + 'deb', + 'http://elasticsearch:9200', + 'service-token-1', + 'policy-1', + 'http://fleetserver:8220', + true + ); + + expect(res).toMatchInlineSnapshot(` + "curl -L -O https://artifacts.elastic.co/downloads/beats/elastic-agent/elastic-agent--amd64.deb \\\\ + tar xzvf elastic-agent--amd64.deb \\\\ + cd elastic-agent--amd64 \\\\ + sudo elastic-agent enroll --url=http://fleetserver:8220 \\\\ + --fleet-server-es=http://elasticsearch:9200 \\\\ + --fleet-server-service-token=service-token-1 \\\\ + --fleet-server-policy=policy-1 \\\\ + --certificate-authorities= \\\\ + --fleet-server-es-ca= \\\\ + --fleet-server-cert= \\\\ + --fleet-server-cert-key=" + `); + }); + }); +}); diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/utils/install_command_utils.ts b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/utils/install_command_utils.ts new file mode 100644 index 0000000000000..525af7cf95103 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/utils/install_command_utils.ts @@ -0,0 +1,119 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { PLATFORM_TYPE } from '../../../hooks'; + +export type CommandsByPlatform = { + [key in PLATFORM_TYPE]: string; +}; + +function getArtifact(platform: PLATFORM_TYPE, kibanaVersion: string) { + const ARTIFACT_BASE_URL = 'https://artifacts.elastic.co/downloads/beats/elastic-agent'; + + const artifactMap: Record< + PLATFORM_TYPE, + { fullUrl: string; filename: string; unpackedDir: string } + > = { + linux: { + fullUrl: `${ARTIFACT_BASE_URL}/elastic-agent-${kibanaVersion}-linux-x86_64.zip`, + filename: `elastic-agent-${kibanaVersion}-linux-x86_64.zip`, + unpackedDir: `elastic-agent-${kibanaVersion}-linux-x86_64`, + }, + mac: { + fullUrl: `${ARTIFACT_BASE_URL}/elastic-agent-${kibanaVersion}-darwin-x86_64.tar.gz`, + filename: `elastic-agent-${kibanaVersion}-darwin-x86_64.tar.gz`, + unpackedDir: `elastic-agent-${kibanaVersion}-darwin-x86_64`, + }, + windows: { + fullUrl: `${ARTIFACT_BASE_URL}/elastic-agent-${kibanaVersion}-windows-x86_64.tar.gz`, + filename: `elastic-agent-${kibanaVersion}-windows-x86_64.tar.gz`, + unpackedDir: `elastic-agent-${kibanaVersion}-windows-x86_64`, + }, + deb: { + fullUrl: `${ARTIFACT_BASE_URL}/elastic-agent-${kibanaVersion}-amd64.deb`, + filename: `elastic-agent-${kibanaVersion}-amd64.deb`, + unpackedDir: `elastic-agent-${kibanaVersion}-amd64`, + }, + rpm: { + fullUrl: `${ARTIFACT_BASE_URL}/elastic-agent-${kibanaVersion}-x86_64.rpm`, + filename: `elastic-agent-${kibanaVersion}-x86_64.rpm`, + unpackedDir: `elastic-agent-${kibanaVersion}-x86_64`, + }, + }; + + return artifactMap[platform]; +} + +export function getInstallCommandForPlatform( + platform: PLATFORM_TYPE, + esHost: string, + serviceToken: string, + policyId?: string, + fleetServerHost?: string, + isProductionDeployment?: boolean, + sslCATrustedFingerprint?: string, + kibanaVersion?: string +): string { + const newLineSeparator = platform === 'windows' ? '`\n' : '\\\n'; + + const artifact = getArtifact(platform, kibanaVersion ?? ''); + const downloadCommand = + platform === 'windows' + ? [ + `wget ${artifact.fullUrl} -OutFile ${artifact.filename}`, + `Expand-Archive .\\${artifact.filename}`, + `cd ${artifact.unpackedDir}`, + ].join(` ${newLineSeparator}`) + : [ + `curl -L -O ${artifact.fullUrl}`, + `tar xzvf ${artifact.filename}`, + `cd ${artifact.unpackedDir}`, + ].join(` ${newLineSeparator}`); + + const commandArguments = []; + + if (isProductionDeployment && fleetServerHost) { + commandArguments.push(['url', fleetServerHost]); + } + + commandArguments.push(['fleet-server-es', esHost]); + commandArguments.push(['fleet-server-service-token', serviceToken]); + if (policyId) { + commandArguments.push(['fleet-server-policy', policyId]); + } + + if (sslCATrustedFingerprint) { + commandArguments.push(['fleet-server-es-ca-trusted-fingerprint', sslCATrustedFingerprint]); + } + + if (isProductionDeployment) { + commandArguments.push(['certificate-authorities', '']); + if (!sslCATrustedFingerprint) { + commandArguments.push(['fleet-server-es-ca', '']); + } + commandArguments.push(['fleet-server-cert', '']); + commandArguments.push(['fleet-server-cert-key', '']); + } + + const commandArgumentsStr = commandArguments.reduce((acc, [key, val]) => { + if (acc === '' && key === 'url') { + return `--${key}=${val}`; + } + const valOrEmpty = val ? `=${val}` : ''; + return (acc += ` ${newLineSeparator} --${key}${valOrEmpty}`); + }, ''); + + const commands = { + linux: `${downloadCommand} ${newLineSeparator}sudo ./elastic-agent install${commandArgumentsStr}`, + mac: `${downloadCommand} ${newLineSeparator}sudo ./elastic-agent install ${commandArgumentsStr}`, + windows: `${downloadCommand}${newLineSeparator}.\\elastic-agent.exe install ${commandArgumentsStr}`, + deb: `${downloadCommand} ${newLineSeparator}sudo elastic-agent enroll ${commandArgumentsStr}`, + rpm: `${downloadCommand} ${newLineSeparator}sudo elastic-agent enroll ${commandArgumentsStr}`, + }; + + return commands[platform]; +} diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/index.ts b/x-pack/plugins/fleet/public/applications/fleet/components/index.ts index 5e927c5b0e3d6..a299013ab547e 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/components/index.ts +++ b/x-pack/plugins/fleet/public/applications/fleet/components/index.ts @@ -8,3 +8,4 @@ export * from '../../../components'; export * from './search_bar'; +export * from './fleet_server_instructions'; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields/index.tsx index 9fdcc0f73297f..e1c6bbafa21a7 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields/index.tsx @@ -28,11 +28,11 @@ import { useStartServices } from '../../../../hooks'; import { AgentPolicyPackageBadge } from '../../../../components'; -import { policyHasFleetServer } from '../../../agents/services/has_fleet_server'; - import { AgentPolicyDeleteProvider } from '../agent_policy_delete_provider'; import type { ValidationResults } from '../agent_policy_validation'; +import { policyHasFleetServer } from '../../../../services'; + import { useOutputOptions, DEFAULT_OUTPUT_VALUE } from './hooks'; interface Props { diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/actions_menu.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/actions_menu.tsx index e9b04aacecb68..44e87d7fb4e63 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/actions_menu.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/actions_menu.tsx @@ -18,8 +18,7 @@ import { AgentUpgradeAgentModal, } from '../../components'; import { useAgentRefresh } from '../hooks'; -import { isAgentUpgradeable } from '../../../../services'; -import { policyHasFleetServer } from '../../services/has_fleet_server'; +import { isAgentUpgradeable, policyHasFleetServer } from '../../../../services'; export const AgentDetailsActionMenu: React.FunctionComponent<{ agent: Agent; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/agent_logs.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/agent_logs.tsx index 14fc3eb1d24c3..cc7a9bec975ef 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/agent_logs.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/agent_logs.tsx @@ -84,25 +84,27 @@ const AgentPolicyLogsNotEnabledCallout: React.FunctionComponent<{ agentPolicy: A /> } > - - - - ), - }} - /> + {agentPolicy.is_managed ? null : ( + + + + ), + }} + /> + )} ); @@ -278,9 +280,9 @@ export const AgentLogsUI: React.FunctionComponent = memo( return ( - {agentPolicy && - !agentPolicy.monitoring_enabled?.includes('logs') && - !agentPolicy.is_managed && } + {agentPolicy && !agentPolicy.monitoring_enabled?.includes('logs') && ( + + )} diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_dataset.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_dataset.tsx index 865c360a47bd9..f49d4910ab9f9 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_dataset.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_dataset.tsx @@ -17,7 +17,7 @@ export const DatasetFilter: React.FunctionComponent<{ selectedDatasets: string[]; onToggleDataset: (dataset: string) => void; }> = memo(({ selectedDatasets, onToggleDataset }) => { - const { data } = useStartServices(); + const { unifiedSearch } = useStartServices(); const [isOpen, setIsOpen] = useState(false); const [isLoading, setIsLoading] = useState(false); const [datasetValues, setDatasetValues] = useState([AGENT_DATASET]); @@ -29,7 +29,7 @@ export const DatasetFilter: React.FunctionComponent<{ const fetchValues = async () => { setIsLoading(true); try { - const values = await data.autocomplete.getValueSuggestions({ + const values = await unifiedSearch.autocomplete.getValueSuggestions({ indexPattern: { title: AGENT_LOG_INDEX_PATTERN, fields: [DATASET_FIELD], @@ -44,7 +44,7 @@ export const DatasetFilter: React.FunctionComponent<{ setIsLoading(false); }; fetchValues(); - }, [data.autocomplete]); + }, [unifiedSearch.autocomplete]); return ( void; }> = memo(({ selectedLevels, onToggleLevel }) => { - const { data } = useStartServices(); + const { unifiedSearch } = useStartServices(); const [isOpen, setIsOpen] = useState(false); const [isLoading, setIsLoading] = useState(false); const [levelValues, setLevelValues] = useState([]); @@ -40,7 +40,7 @@ export const LogLevelFilter: React.FunctionComponent<{ const fetchValues = async () => { setIsLoading(true); try { - const values: string[] = await data.autocomplete.getValueSuggestions({ + const values: string[] = await unifiedSearch.autocomplete.getValueSuggestions({ indexPattern: { title: AGENT_LOG_INDEX_PATTERN, fields: [LOG_LEVEL_FIELD], @@ -55,7 +55,7 @@ export const LogLevelFilter: React.FunctionComponent<{ setIsLoading(false); }; fetchValues(); - }, [data.autocomplete]); + }, [unifiedSearch.autocomplete]); const noLogsFound = (
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agents_selection_status.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agents_selection_status.tsx new file mode 100644 index 0000000000000..57728f275ccb5 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agents_selection_status.tsx @@ -0,0 +1,134 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import styled from 'styled-components'; +import { EuiFlexGroup, EuiFlexItem, EuiText, EuiButtonEmpty } from '@elastic/eui'; +import { FormattedMessage, FormattedNumber } from '@kbn/i18n-react'; + +import { SO_SEARCH_LIMIT } from '../../../../constants'; +import type { Agent } from '../../../../types'; + +import type { SelectionMode } from './types'; + +const Divider = styled.div` + width: 0; + height: ${(props) => props.theme.eui.euiSizeL}; + border-left: ${(props) => props.theme.eui.euiBorderThin}; +`; + +const FlexItem = styled(EuiFlexItem)` + height: ${(props) => props.theme.eui.euiSizeL}; +`; + +const Button = styled(EuiButtonEmpty)` + .euiButtonEmpty__text { + font-size: ${(props) => props.theme.eui.euiFontSizeXS}; + } +`; + +export const AgentsSelectionStatus: React.FunctionComponent<{ + totalAgents: number; + selectableAgents: number; + selectionMode: SelectionMode; + setSelectionMode: (mode: SelectionMode) => void; + selectedAgents: Agent[]; + setSelectedAgents: (agents: Agent[]) => void; +}> = ({ + totalAgents, + selectableAgents, + selectionMode, + setSelectionMode, + selectedAgents, + setSelectedAgents, +}) => { + const showSelectEverything = + selectionMode === 'manual' && + selectedAgents.length === selectableAgents && + selectableAgents < totalAgents; + + return ( + <> + + + + {totalAgents > SO_SEARCH_LIMIT ? ( + , + total: , + }} + /> + ) : ( + + )} + + + {(selectionMode === 'manual' && selectedAgents.length) || + (selectionMode === 'query' && totalAgents > 0) ? ( + <> + + + + + + + + + {showSelectEverything ? ( + <> + + + + + + + + ) : null} + + + + + + + + ) : ( + + )} + + + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/bulk_actions.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/bulk_actions.test.tsx new file mode 100644 index 0000000000000..9ddf8608fc015 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/bulk_actions.test.tsx @@ -0,0 +1,89 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { ThemeProvider } from 'styled-components'; + +import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; + +import { coreMock } from '@kbn/core/public/mocks'; +import { registerTestBed } from '@kbn/test-jest-helpers'; + +import type { Agent } from '../../../../types'; + +import { FleetStatusProvider, ConfigContext, KibanaVersionContext } from '../../../../../../hooks'; + +import { getMockTheme } from '../../../../../../mocks'; + +import { AgentBulkActions } from './bulk_actions'; +import type { Props } from './bulk_actions'; + +const mockTheme = getMockTheme({ + eui: { + euiSize: '10px', + }, +}); + +const TestComponent = (props: Props) => ( + + + + + + + + + + + +); + +describe('AgentBulkActions', () => { + it('should show no Actions button when no agent is selected', async () => { + const selectedAgents: Agent[] = []; + const props: Props = { + totalAgents: 10, + totalInactiveAgents: 2, + selectionMode: 'manual', + currentQuery: '', + selectedAgents, + refreshAgents: () => undefined, + }; + const testBed = registerTestBed(TestComponent)(props); + const { exists } = testBed; + + expect(exists('agentBulkActionsButton')).toBe(false); + }); + + it('should show an Actions button when at least an agent is selected', async () => { + const selectedAgents: Agent[] = [ + { + id: 'Agent1', + status: 'online', + packages: ['system'], + type: 'PERMANENT', + active: true, + enrolled_at: `${Date.now()}`, + user_provided_metadata: {}, + local_metadata: {}, + }, + ]; + const props: Props = { + totalAgents: 10, + totalInactiveAgents: 2, + selectionMode: 'manual', + currentQuery: '', + selectedAgents, + refreshAgents: () => undefined, + }; + const testBed = registerTestBed(TestComponent)(props); + const { exists } = testBed; + + expect(exists('agentBulkActionsButton')).not.toBeNull(); + }); +}); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/bulk_actions.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/bulk_actions.tsx index 6fd34f0239996..a2515b51814ee 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/bulk_actions.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/bulk_actions.tsx @@ -10,16 +10,14 @@ import styled from 'styled-components'; import { EuiFlexGroup, EuiFlexItem, - EuiText, EuiPopover, EuiContextMenu, - EuiButtonEmpty, + EuiButton, EuiIcon, EuiPortal, } from '@elastic/eui'; -import { FormattedMessage, FormattedNumber } from '@kbn/i18n-react'; +import { FormattedMessage } from '@kbn/i18n-react'; -import { SO_SEARCH_LIMIT } from '../../../../constants'; import type { Agent } from '../../../../types'; import { AgentReassignAgentPolicyModal, @@ -28,43 +26,26 @@ import { } from '../../components'; import { useKibanaVersion } from '../../../../hooks'; -const Divider = styled.div` - width: 0; - height: ${(props) => props.theme.eui.euiSizeL}; - border-left: ${(props) => props.theme.eui.euiBorderThin}; -`; +import type { SelectionMode } from './types'; const FlexItem = styled(EuiFlexItem)` height: ${(props) => props.theme.eui.euiSizeL}; `; - -const Button = styled(EuiButtonEmpty)` - .euiButtonEmpty__text { - font-size: ${(props) => props.theme.eui.euiFontSizeXS}; - } -`; - -export type SelectionMode = 'manual' | 'query'; - -export const AgentBulkActions: React.FunctionComponent<{ +export interface Props { totalAgents: number; totalInactiveAgents: number; - selectableAgents: number; selectionMode: SelectionMode; - setSelectionMode: (mode: SelectionMode) => void; currentQuery: string; selectedAgents: Agent[]; - setSelectedAgents: (agents: Agent[]) => void; refreshAgents: () => void; -}> = ({ +} + +export const AgentBulkActions: React.FunctionComponent = ({ totalAgents, totalInactiveAgents, - selectableAgents, selectionMode, - setSelectionMode, currentQuery, selectedAgents, - setSelectedAgents, refreshAgents, }) => { const kibanaVersion = useKibanaVersion(); @@ -92,6 +73,7 @@ export const AgentBulkActions: React.FunctionComponent<{ name: ( ), @@ -106,6 +88,7 @@ export const AgentBulkActions: React.FunctionComponent<{ name: ( ), @@ -120,6 +103,7 @@ export const AgentBulkActions: React.FunctionComponent<{ name: ( ), @@ -130,29 +114,10 @@ export const AgentBulkActions: React.FunctionComponent<{ setIsUpgradeModalOpen(true); }, }, - { - name: ( - - ), - icon: , - onClick: () => { - closeMenu(); - setSelectionMode('manual'); - setSelectedAgents([]); - }, - }, ], }, ]; - const showSelectEverything = - selectionMode === 'manual' && - selectedAgents.length === selectableAgents && - selectableAgents < totalAgents; - const totalActiveAgents = totalAgents - totalInactiveAgents; const agentCount = selectionMode === 'manual' ? selectedAgents.length : totalActiveAgents; const agents = selectionMode === 'manual' ? selectedAgents : currentQuery; @@ -196,51 +161,25 @@ export const AgentBulkActions: React.FunctionComponent<{ )} - - - {totalAgents > SO_SEARCH_LIMIT ? ( - , - total: , - }} - /> - ) : ( - - )} - - {(selectionMode === 'manual' && selectedAgents.length) || (selectionMode === 'query' && totalAgents > 0) ? ( <> - - - - + } isOpen={isMenuOpen} closePopover={closeMenu} @@ -250,22 +189,6 @@ export const AgentBulkActions: React.FunctionComponent<{ - {showSelectEverything ? ( - - - - ) : null} ) : ( diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/empty_prompt.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/empty_prompt.tsx new file mode 100644 index 0000000000000..256ab2a0bacd1 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/empty_prompt.tsx @@ -0,0 +1,44 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiButton, EuiEmptyPrompt } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; + +export const EmptyPrompt: React.FunctionComponent<{ + hasFleetAllPrivileges: boolean; + setEnrollmentFlyoutState: ( + value: React.SetStateAction<{ + isOpen: boolean; + selectedPolicyId?: string | undefined; + }> + ) => void; +}> = ({ hasFleetAllPrivileges, setEnrollmentFlyoutState }) => { + return ( + + +

+ } + actions={ + hasFleetAllPrivileges ? ( + setEnrollmentFlyoutState({ isOpen: true })} + > + + + ) : null + } + /> + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/search_and_filter_bar.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/search_and_filter_bar.tsx index 8965ae9bbc44f..a511c2dc9f3da 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/search_and_filter_bar.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/search_and_filter_bar.tsx @@ -19,10 +19,13 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import type { AgentPolicy } from '../../../../types'; +import type { Agent, AgentPolicy } from '../../../../types'; import { AgentEnrollmentFlyout, SearchBar } from '../../../../components'; import { AGENTS_INDEX } from '../../../../constants'; +import { AgentBulkActions } from './bulk_actions'; +import type { SelectionMode } from './types'; + const statusFilters = [ { status: 'healthy', @@ -67,6 +70,12 @@ export const SearchAndFilterBar: React.FunctionComponent<{ onSelectedStatusChange: (selectedStatus: string[]) => void; showUpgradeable: boolean; onShowUpgradeableChange: (showUpgradeable: boolean) => void; + totalAgents: number; + totalInactiveAgents: number; + selectionMode: SelectionMode; + currentQuery: string; + selectedAgents: Agent[]; + refreshAgents: () => void; }> = ({ agentPolicies, draftKuery, @@ -78,6 +87,12 @@ export const SearchAndFilterBar: React.FunctionComponent<{ onSelectedStatusChange, showUpgradeable, onShowUpgradeableChange, + totalAgents, + totalInactiveAgents, + selectionMode, + currentQuery, + selectedAgents, + refreshAgents, }) => { const [isEnrollmentFlyoutOpen, setIsEnrollmentFlyoutOpen] = useState(false); @@ -230,6 +245,16 @@ export const SearchAndFilterBar: React.FunctionComponent<{ + + + diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/table_header.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/table_header.tsx index ff809d360e744..4e2f058596cf0 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/table_header.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/table_header.tsx @@ -11,51 +11,41 @@ import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; import type { Agent, SimplifiedAgentStatus } from '../../../../types'; import { AgentStatusBar } from './status_bar'; -import { AgentBulkActions } from './bulk_actions'; +import { AgentsSelectionStatus } from './agents_selection_status'; import {} from '@elastic/eui'; import { AgentStatusBadges } from './status_badges'; - -export type SelectionMode = 'manual' | 'query'; +import type { SelectionMode } from './types'; export const AgentTableHeader: React.FunctionComponent<{ agentStatus?: { [k in SimplifiedAgentStatus]: number }; showInactive: boolean; totalAgents: number; - totalInactiveAgents: number; selectableAgents: number; selectionMode: SelectionMode; setSelectionMode: (mode: SelectionMode) => void; - currentQuery: string; selectedAgents: Agent[]; setSelectedAgents: (agents: Agent[]) => void; - refreshAgents: () => void; }> = ({ agentStatus, totalAgents, - totalInactiveAgents, selectableAgents, selectionMode, setSelectionMode, - currentQuery, selectedAgents, setSelectedAgents, - refreshAgents, showInactive, }) => { return ( <> - diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/table_row_actions.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/table_row_actions.tsx new file mode 100644 index 0000000000000..be620f0044cd1 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/table_row_actions.tsx @@ -0,0 +1,95 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useState } from 'react'; +import { EuiContextMenuItem } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import type { Agent, AgentPolicy } from '../../../../types'; +import { useAuthz, useLink, useKibanaVersion } from '../../../../hooks'; +import { ContextMenuActions } from '../../../../components'; +import { isAgentUpgradeable } from '../../../../services'; + +export const TableRowActions: React.FunctionComponent<{ + agent: Agent; + agentPolicy?: AgentPolicy; + onReassignClick: () => void; + onUnenrollClick: () => void; + onUpgradeClick: () => void; +}> = ({ agent, agentPolicy, onReassignClick, onUnenrollClick, onUpgradeClick }) => { + const { getHref } = useLink(); + const hasFleetAllPrivileges = useAuthz().fleet.all; + + const isUnenrolling = agent.status === 'unenrolling'; + const kibanaVersion = useKibanaVersion(); + const [isMenuOpen, setIsMenuOpen] = useState(false); + const menuItems = [ + + + , + ]; + + if (agentPolicy?.is_managed === false) { + menuItems.push( + { + onReassignClick(); + }} + disabled={!agent.active} + key="reassignPolicy" + > + + , + { + onUnenrollClick(); + }} + > + {isUnenrolling ? ( + + ) : ( + + )} + , + { + onUpgradeClick(); + }} + > + + + ); + } + return ( + setIsMenuOpen(isOpen)} + items={menuItems} + /> + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/types.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/types.tsx new file mode 100644 index 0000000000000..7e22c67b09acb --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/types.tsx @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type SelectionMode = 'manual' | 'query'; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx index 8e8091d13a794..5776a163fd6a3 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx @@ -5,17 +5,14 @@ * 2.0. */ -import React, { useState, useMemo, useCallback, useRef, useEffect } from 'react'; +import React, { useState, useMemo, useCallback, useRef, useEffect, useContext } from 'react'; import { EuiBasicTable, - EuiButton, - EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem, EuiLink, EuiSpacer, EuiText, - EuiContextMenuItem, EuiIcon, EuiPortal, } from '@elastic/eui'; @@ -32,15 +29,10 @@ import { useUrlParams, useLink, useBreadcrumbs, - useLicense, useKibanaVersion, useStartServices, } from '../../../hooks'; -import { - AgentEnrollmentFlyout, - AgentPolicySummaryLine, - ContextMenuActions, -} from '../../../components'; +import { AgentEnrollmentFlyout, AgentPolicySummaryLine } from '../../../components'; import { AgentStatusKueryHelper, isAgentUpgradeable } from '../../../services'; import { AGENTS_PREFIX, FLEET_SERVER_PACKAGE } from '../../../constants'; import { @@ -53,93 +45,16 @@ import { } from '../components'; import { useFleetServerUnhealthy } from '../hooks/use_fleet_server_unhealthy'; +import { agentFlyoutContext } from '..'; + import { AgentTableHeader } from './components/table_header'; -import type { SelectionMode } from './components/bulk_actions'; +import type { SelectionMode } from './components/types'; import { SearchAndFilterBar } from './components/search_and_filter_bar'; +import { TableRowActions } from './components/table_row_actions'; +import { EmptyPrompt } from './components/empty_prompt'; const REFRESH_INTERVAL_MS = 30000; -const RowActions = React.memo<{ - agent: Agent; - agentPolicy?: AgentPolicy; - refresh: () => void; - onReassignClick: () => void; - onUnenrollClick: () => void; - onUpgradeClick: () => void; -}>(({ agent, agentPolicy, refresh, onReassignClick, onUnenrollClick, onUpgradeClick }) => { - const { getHref } = useLink(); - const hasFleetAllPrivileges = useAuthz().fleet.all; - - const isUnenrolling = agent.status === 'unenrolling'; - const kibanaVersion = useKibanaVersion(); - const [isMenuOpen, setIsMenuOpen] = useState(false); - const menuItems = [ - - - , - ]; - - if (agentPolicy?.is_managed === false) { - menuItems.push( - { - onReassignClick(); - }} - disabled={!agent.active} - key="reassignPolicy" - > - - , - { - onUnenrollClick(); - }} - > - {isUnenrolling ? ( - - ) : ( - - )} - , - { - onUpgradeClick(); - }} - > - - - ); - } - return ( - setIsMenuOpen(isOpen)} - items={menuItems} - /> - ); -}); - function safeMetadata(val: any) { if (typeof val !== 'string') { return '-'; @@ -153,7 +68,6 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { const { getHref } = useLink(); const defaultKuery: string = (useUrlParams().urlParams.kuery as string) || ''; const hasFleetAllPrivileges = useAuthz().fleet.all; - const isGoldPlus = useLicense().isGoldPlus(); const kibanaVersion = useKibanaVersion(); // Agent data states @@ -203,6 +117,8 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { isOpen: false, }); + const flyoutContext = useContext(agentFlyoutContext); + // Agent actions states const [agentToReassign, setAgentToReassign] = useState(undefined); const [agentToUnenroll, setAgentToUnenroll] = useState(undefined); @@ -380,11 +296,8 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { // Fleet server unhealthy status const { isUnhealthy: isFleetServerUnhealthy } = useFleetServerUnhealthy(); const onClickAddFleetServer = useCallback(() => { - setEnrollmentFlyoutState({ - isOpen: true, - selectedPolicyId: agentPolicies.length > 0 ? agentPolicies[0].id : undefined, - }); - }, [agentPolicies]); + flyoutContext?.openFleetServerFlyout(); + }, [flyoutContext]); const columns = [ { @@ -480,10 +393,9 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { ? agentPoliciesIndexedById[agent.policy_id] : undefined; return ( - fetchData()} onReassignClick={() => setAgentToReassign(agent)} onUnenrollClick={() => setAgentToUnenroll(agent)} onUpgradeClick={() => setAgentToUpgrade(agent)} @@ -496,30 +408,6 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { }, ]; - const emptyPrompt = ( - - - - } - actions={ - hasFleetAllPrivileges ? ( - setEnrollmentFlyoutState({ isOpen: true })} - > - - - ) : null - } - /> - ); - return ( <> {enrollmentFlyout.isOpen ? ( @@ -593,6 +481,12 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { onSelectedStatusChange={setSelectedStatus} showUpgradeable={showUpgradeable} onShowUpgradeableChange={setShowUpgradeable} + totalAgents={totalAgents} + totalInactiveAgents={totalInactiveAgents} + selectionMode={selectionMode} + currentQuery={kuery} + selectedAgents={selectedAgents} + refreshAgents={() => fetchData()} /> @@ -600,12 +494,10 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { { if (tableRef?.current) { @@ -613,7 +505,6 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { setSelectionMode('manual'); } }} - refreshAgents={() => fetchData()} /> @@ -646,7 +537,10 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { }} /> ) : ( - emptyPrompt + ) } items={ @@ -667,27 +561,23 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { pageSizeOptions, }} isSelectable={true} - selection={ - isGoldPlus - ? { - onSelectionChange: (newAgents: Agent[]) => { - setSelectedAgents(newAgents); - setSelectionMode('manual'); - }, - selectable: isAgentSelectable, - selectableMessage: (selectable, agent) => { - if (selectable) return ''; - if (!agent.active) { - return 'This agent is not active'; - } - if (agent.policy_id && agentPoliciesIndexedById[agent.policy_id].is_managed) { - return 'This action is not available for agents enrolled in an externally managed agent policy'; - } - return ''; - }, - } - : undefined - } + selection={{ + onSelectionChange: (newAgents: Agent[]) => { + setSelectedAgents(newAgents); + setSelectionMode('manual'); + }, + selectable: isAgentSelectable, + selectableMessage: (selectable, agent) => { + if (selectable) return ''; + if (!agent.active) { + return 'This agent is not active'; + } + if (agent.policy_id && agentPoliciesIndexedById[agent.policy_id].is_managed) { + return 'This action is not available for agents enrolled in an externally managed agent policy'; + } + return ''; + }, + }} onChange={({ page }: { page: { index: number; size: number } }) => { const newPagination = { ...pagination, diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/enrollment_recommendation.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/enrollment_recommendation.tsx new file mode 100644 index 0000000000000..86990d84d5130 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/enrollment_recommendation.tsx @@ -0,0 +1,104 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useContext } from 'react'; +import { + EuiButton, + EuiButtonEmpty, + EuiFlexGroup, + EuiFlexItem, + EuiLink, + EuiSpacer, + EuiText, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import { useStartServices } from '../../../../hooks'; + +import { agentFlyoutContext } from '../..'; + +export const EnrollmentRecommendation: React.FunctionComponent<{ + showStandaloneTab: () => void; +}> = ({ showStandaloneTab }) => { + const flyoutContext = useContext(agentFlyoutContext); + + const { docLinks } = useStartServices(); + + return ( + <> + + + + + + + +
    +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + + + + ), + }} + /> +
  • +
+
+ + + + + + + + + + + + + + + + + + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx deleted file mode 100644 index 93547bba36de8..0000000000000 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions.tsx +++ /dev/null @@ -1,748 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useState, useMemo, useCallback, useEffect } from 'react'; -import { - EuiButton, - EuiFlexGroup, - EuiFlexItem, - EuiSpacer, - EuiText, - EuiLink, - EuiSteps, - EuiCode, - EuiCodeBlock, - EuiCallOut, - EuiRadioGroup, - EuiFieldText, - EuiForm, - EuiFormErrorText, -} from '@elastic/eui'; -import type { EuiStepProps } from '@elastic/eui/src/components/steps/step'; -import styled from 'styled-components'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n-react'; - -import { DownloadStep, SelectCreateAgentPolicy } from '../../../../components'; -import { - useStartServices, - useDefaultOutput, - sendGenerateServiceToken, - usePlatform, - useGetAgentPolicies, - useGetSettings, - sendPutSettings, - sendGetFleetStatus, - useFleetStatus, - useLink, -} from '../../../../hooks'; -import type { PLATFORM_TYPE } from '../../../../hooks'; -import type { AgentPolicy } from '../../../../types'; -import { FleetServerOnPremRequiredCallout } from '../../components'; - -import { policyHasFleetServer } from '../../services/has_fleet_server'; - -import { PlatformSelector } from '../../../../../../components/enrollment_instructions/manual/platform_selector'; - -import type { CommandsByPlatform } from './install_command_utils'; -import { getInstallCommandForPlatform } from './install_command_utils'; - -const URL_REGEX = /^(https):\/\/[^\s$.?#].[^\s]*$/gm; -const REFRESH_INTERVAL = 10000; - -type DeploymentMode = 'production' | 'quickstart'; - -const FlexItemWithMinWidth = styled(EuiFlexItem)` - min-width: 0px; - max-width: 100%; -`; - -export const ContentWrapper = styled(EuiFlexGroup)` - height: 100%; - margin: 0 auto; - max-width: 800px; -`; - -// Otherwise the copy button is over the text -const CommandCode = styled.div.attrs(() => { - return { - className: 'eui-textBreakAll', - }; -})` - margin-right: ${(props) => props.theme.eui.paddingSizes.m}; -`; - -export const ServiceTokenStep = ({ - disabled = false, - serviceToken, - getServiceToken, - isLoadingServiceToken, -}: { - disabled?: boolean; - serviceToken?: string; - getServiceToken: () => void; - isLoadingServiceToken: boolean; -}): EuiStepProps => { - return { - title: i18n.translate('xpack.fleet.fleetServerSetup.stepGenerateServiceTokenTitle', { - defaultMessage: 'Generate a service token', - }), - status: disabled ? 'disabled' : undefined, - children: !disabled && ( - <> - - - - - {!serviceToken ? ( - - - { - getServiceToken(); - }} - data-test-subj="fleetServerGenerateServiceTokenBtn" - > - - - - - ) : ( - <> - - } - /> - - - - - - - - - - {serviceToken} - - - - - )} - - ), - }; -}; - -export const FleetServerCommandStep = ({ - serviceToken, - installCommand, - platform, - setPlatform, -}: { - serviceToken?: string; - installCommand: CommandsByPlatform; - platform: string; - setPlatform: (platform: PLATFORM_TYPE) => void; -}): EuiStepProps => { - const { docLinks } = useStartServices(); - - return { - title: i18n.translate('xpack.fleet.fleetServerSetup.stepInstallAgentTitle', { - defaultMessage: 'Start Fleet Server', - }), - status: !serviceToken ? 'disabled' : undefined, - children: serviceToken ? ( - <> - - - - - ), - }} - /> - - - - - ) : null, - }; -}; - -export const useFleetServerInstructions = (policyId?: string) => { - const { output } = useDefaultOutput(); - const { notifications } = useStartServices(); - const [serviceToken, setServiceToken] = useState(); - const [isLoadingServiceToken, setIsLoadingServiceToken] = useState(false); - const { platform, setPlatform } = usePlatform(); - const [deploymentMode, setDeploymentMode] = useState('production'); - const { data: settings, resendRequest: refreshSettings } = useGetSettings(); - const fleetServerHost = settings?.item.fleet_server_hosts?.[0]; - const esHost = output?.hosts?.[0]; - const sslCATrustedFingerprint: string | undefined = output?.ca_trusted_fingerprint; - - const installCommand = useMemo((): CommandsByPlatform => { - if (!serviceToken || !esHost) { - return { - linux: '', - mac: '', - windows: '', - deb: '', - rpm: '', - }; - } - - return getInstallCommandForPlatform( - esHost, - serviceToken, - policyId, - fleetServerHost, - deploymentMode === 'production', - sslCATrustedFingerprint - ); - }, [serviceToken, esHost, policyId, fleetServerHost, deploymentMode, sslCATrustedFingerprint]); - - const getServiceToken = useCallback(async () => { - setIsLoadingServiceToken(true); - try { - const { data } = await sendGenerateServiceToken(); - if (data?.value) { - setServiceToken(data?.value); - } - } catch (err) { - notifications.toasts.addError(err, { - title: i18n.translate('xpack.fleet.fleetServerSetup.errorGeneratingTokenTitleText', { - defaultMessage: 'Error generating token', - }), - }); - } - - setIsLoadingServiceToken(false); - }, [notifications.toasts]); - - const addFleetServerHost = useCallback( - async (host: string) => { - const res = await sendPutSettings({ - fleet_server_hosts: [host, ...(settings?.item.fleet_server_hosts || [])], - }); - if (res.error) { - throw res.error; - } - await refreshSettings(); - }, - [refreshSettings, settings?.item.fleet_server_hosts] - ); - - return { - addFleetServerHost, - fleetServerHost, - deploymentMode, - setDeploymentMode, - serviceToken, - getServiceToken, - isLoadingServiceToken, - installCommand, - platform, - setPlatform, - }; -}; - -const AgentPolicySelectionStep = ({ - selectedPolicy, - setPolicyId, - agentPolicies, - refreshAgentPolicies, -}: { - selectedPolicy?: AgentPolicy; - setPolicyId: (v?: string) => void; - agentPolicies: AgentPolicy[]; - refreshAgentPolicies: () => void; -}): EuiStepProps => { - return { - title: - agentPolicies.length === 0 - ? i18n.translate('xpack.fleet.fleetServerSetup.stepCreateAgentPolicyTitle', { - defaultMessage: 'Create an agent policy to host Fleet Server', - }) - : i18n.translate('xpack.fleet.fleetServerSetup.stepSelectAgentPolicyTitle', { - defaultMessage: 'Select an agent policy to host Fleet Server', - }), - status: undefined, - children: ( - <> - - - ), - }; -}; - -export const addFleetServerHostStep = ({ - addFleetServerHost, -}: { - addFleetServerHost: (v: string) => Promise; -}): EuiStepProps => { - return { - title: i18n.translate('xpack.fleet.fleetServerSetup.addFleetServerHostStepTitle', { - defaultMessage: 'Add your Fleet Server host', - }), - status: undefined, - children: , - }; -}; - -export const AddFleetServerHostStepContent = ({ - addFleetServerHost, -}: { - addFleetServerHost: (v: string) => Promise; -}) => { - const [calloutHost, setCalloutHost] = useState(); - const [isLoading, setIsLoading] = useState(false); - const [fleetServerHost, setFleetServerHost] = useState(''); - const [error, setError] = useState(); - const { notifications } = useStartServices(); - - const { getHref } = useLink(); - - const validate = useCallback( - (host: string) => { - if (host.match(URL_REGEX)) { - setError(undefined); - return true; - } else { - setError( - i18n.translate('xpack.fleet.fleetServerSetup.addFleetServerHostInvalidUrlError', { - defaultMessage: 'Valid https URL required.', - }) - ); - return false; - } - }, - [setError] - ); - - const onSubmit = useCallback(async () => { - try { - setIsLoading(true); - if (validate(fleetServerHost)) { - await addFleetServerHost(fleetServerHost); - setCalloutHost(fleetServerHost); - setFleetServerHost(''); - } else { - setCalloutHost(''); - } - } catch (err) { - notifications.toasts.addError(err, { - title: i18n.translate('xpack.fleet.fleetServerSetup.errorAddingFleetServerHostTitle', { - defaultMessage: 'Error adding Fleet Server host', - }), - }); - } finally { - setIsLoading(false); - } - }, [fleetServerHost, addFleetServerHost, validate, notifications.toasts]); - - const onChange = useCallback( - (e: React.ChangeEvent) => { - setFleetServerHost(e.target.value); - if (error) { - validate(e.target.value); - } - }, - [error, validate, setFleetServerHost] - ); - - return ( - - - 8220 }} - /> - - - - - - - - } - data-test-subj="fleetServerHostInput" - /> - {error && {error}} - - - - - - - - {calloutHost && ( - <> - - - } - > - - - - ), - }} - /> - - - )} - - ); -}; - -export const deploymentModeStep = ({ - deploymentMode, - setDeploymentMode, -}: { - deploymentMode: DeploymentMode; - setDeploymentMode: (v: DeploymentMode) => void; -}): EuiStepProps => { - return { - title: i18n.translate('xpack.fleet.fleetServerSetup.stepDeploymentModeTitle', { - defaultMessage: 'Choose a deployment mode for security', - }), - status: undefined, - children: ( - - ), - }; -}; - -const DeploymentModeStepContent = ({ - deploymentMode, - setDeploymentMode, -}: { - deploymentMode: DeploymentMode; - setDeploymentMode: (v: DeploymentMode) => void; -}) => { - const onChangeCallback = useCallback( - (v: string) => { - const value = v.split('_')[0]; - if (value === 'production' || value === 'quickstart') { - setDeploymentMode(value); - } - }, - [setDeploymentMode] - ); - - // radio id has to be unique so that the component works even if appears twice in DOM (Agents tab, Add agent flyout) - const radioSuffix = useMemo(() => Date.now(), []); - - return ( - <> - - - - - - - - ), - }} - /> - ), - }, - { - id: `production_${radioSuffix}`, - label: ( - - - - ), - }} - /> - ), - }, - ]} - idSelected={`${deploymentMode}_${radioSuffix}`} - onChange={onChangeCallback} - name={`radio group ${radioSuffix}`} - /> - - ); -}; - -const WaitingForFleetServerStep = ({ - status, -}: { - status: 'loading' | 'disabled' | 'complete'; -}): EuiStepProps => { - return { - title: i18n.translate('xpack.fleet.fleetServerSetup.stepWaitingForFleetServerTitle', { - defaultMessage: 'Waiting for Fleet Server to connect...', - }), - status, - children: undefined, - }; -}; - -const CompleteStep = (): EuiStepProps => { - const fleetStatus = useFleetStatus(); - - const onContinueClick = () => { - fleetStatus.refresh(); - }; - - return { - title: i18n.translate('xpack.fleet.fleetServerSetup.stepFleetServerCompleteTitle', { - defaultMessage: 'Fleet Server connected', - }), - status: 'complete', - children: ( - <> - - - - - - - ), - }; -}; - -const findPolicyById = (policies: AgentPolicy[], id: string | undefined) => { - if (!id) return undefined; - return policies.find((p) => p.id === id); -}; - -export const OnPremInstructions: React.FC = () => { - const { notifications } = useStartServices(); - - const { data, resendRequest: refreshAgentPolicies } = useGetAgentPolicies({ full: true }); - - const agentPolicies = useMemo( - () => (data ? data.items.filter((item) => policyHasFleetServer(item)) : []), - [data] - ); - - // Select default value - let defaultValue = ''; - if (agentPolicies.length) { - defaultValue = agentPolicies[0].id; - } - const [policyId, setPolicyId] = useState(defaultValue); - const selectedPolicy = findPolicyById(agentPolicies, policyId); - - const { - serviceToken, - getServiceToken, - isLoadingServiceToken, - installCommand, - platform, - setPlatform, - deploymentMode, - setDeploymentMode, - fleetServerHost, - addFleetServerHost, - } = useFleetServerInstructions(policyId); - - const { docLinks } = useStartServices(); - - const [isWaitingForFleetServer, setIsWaitingForFleetServer] = useState(true); - - useEffect(() => { - const interval = setInterval(async () => { - try { - const res = await sendGetFleetStatus(); - if (res.error) { - throw res.error; - } - if (res.data?.isReady && !res.data?.missing_requirements?.includes('fleet_server')) { - setIsWaitingForFleetServer(false); - } - } catch (err) { - notifications.toasts.addError(err, { - title: i18n.translate('xpack.fleet.fleetServerSetup.errorRefreshingFleetServerStatus', { - defaultMessage: 'Error refreshing Fleet Server status', - }), - }); - } - }, REFRESH_INTERVAL); - - return () => clearInterval(interval); - }, [notifications.toasts]); - - return ( - <> - - - -

- -

- - - - - ), - }} - /> -
- - - - ); -}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/index.tsx index 3118fda75400f..293be6d8b98e4 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/index.tsx @@ -6,4 +6,4 @@ */ export { CloudInstructions } from './fleet_server_cloud_instructions'; -export * from './fleet_server_on_prem_instructions'; +export { EnrollmentRecommendation } from './enrollment_recommendation'; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/install_command_utils.test.ts b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/install_command_utils.test.ts deleted file mode 100644 index 774b7871f0353..0000000000000 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/install_command_utils.test.ts +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { getInstallCommandForPlatform } from './install_command_utils'; - -describe('getInstallCommandForPlatform', () => { - describe('without policy id', () => { - it('should return the correct command if the the policyId is not set for linux', () => { - const res = getInstallCommandForPlatform('http://elasticsearch:9200', 'service-token-1'); - - expect(res.linux).toMatchInlineSnapshot(` - "sudo ./elastic-agent install \\\\ - --fleet-server-es=http://elasticsearch:9200 \\\\ - --fleet-server-service-token=service-token-1" - `); - }); - - it('should return the correct command if the the policyId is not set for mac', () => { - const res = getInstallCommandForPlatform('http://elasticsearch:9200', 'service-token-1'); - - expect(res.mac).toMatchInlineSnapshot(` - "sudo ./elastic-agent install \\\\ - --fleet-server-es=http://elasticsearch:9200 \\\\ - --fleet-server-service-token=service-token-1" - `); - }); - - it('should return the correct command if the the policyId is not set for windows', () => { - const res = getInstallCommandForPlatform('http://elasticsearch:9200', 'service-token-1'); - - expect(res.windows).toMatchInlineSnapshot(` - ".\\\\elastic-agent.exe install \` - --fleet-server-es=http://elasticsearch:9200 \` - --fleet-server-service-token=service-token-1" - `); - }); - - it('should return the correct command if the the policyId is not set for rpm', () => { - const res = getInstallCommandForPlatform('http://elasticsearch:9200', 'service-token-1'); - - expect(res.rpm).toMatchInlineSnapshot(` - "sudo elastic-agent enroll \\\\ - --fleet-server-es=http://elasticsearch:9200 \\\\ - --fleet-server-service-token=service-token-1" - `); - }); - - it('should return the correct command if the the policyId is not set for deb', () => { - const res = getInstallCommandForPlatform('http://elasticsearch:9200', 'service-token-1'); - - expect(res.deb).toMatchInlineSnapshot(` - "sudo elastic-agent enroll \\\\ - --fleet-server-es=http://elasticsearch:9200 \\\\ - --fleet-server-service-token=service-token-1" - `); - }); - - it('should return the correct command sslCATrustedFingerprint option is passed', () => { - const res = getInstallCommandForPlatform( - 'http://elasticsearch:9200', - 'service-token-1', - undefined, - undefined, - false, - 'fingerprint123456' - ); - - expect(res.linux).toMatchInlineSnapshot(` - "sudo ./elastic-agent install \\\\ - --fleet-server-es=http://elasticsearch:9200 \\\\ - --fleet-server-service-token=service-token-1 \\\\ - --fleet-server-es-ca-trusted-fingerprint=fingerprint123456" - `); - }); - }); - - describe('with policy id', () => { - it('should return the correct command if the the policyId is set for linux', () => { - const res = getInstallCommandForPlatform( - 'http://elasticsearch:9200', - 'service-token-1', - 'policy-1' - ); - - expect(res.linux).toMatchInlineSnapshot(` - "sudo ./elastic-agent install \\\\ - --fleet-server-es=http://elasticsearch:9200 \\\\ - --fleet-server-service-token=service-token-1 \\\\ - --fleet-server-policy=policy-1" - `); - }); - - it('should return the correct command if the the policyId is set for mac', () => { - const res = getInstallCommandForPlatform( - 'http://elasticsearch:9200', - 'service-token-1', - 'policy-1' - ); - - expect(res.mac).toMatchInlineSnapshot(` - "sudo ./elastic-agent install \\\\ - --fleet-server-es=http://elasticsearch:9200 \\\\ - --fleet-server-service-token=service-token-1 \\\\ - --fleet-server-policy=policy-1" - `); - }); - - it('should return the correct command if the the policyId is set for windows', () => { - const res = getInstallCommandForPlatform( - 'http://elasticsearch:9200', - 'service-token-1', - 'policy-1' - ); - - expect(res.windows).toMatchInlineSnapshot(` - ".\\\\elastic-agent.exe install \` - --fleet-server-es=http://elasticsearch:9200 \` - --fleet-server-service-token=service-token-1 \` - --fleet-server-policy=policy-1" - `); - }); - - it('should return the correct command if the the policyId is set for rpm', () => { - const res = getInstallCommandForPlatform( - 'http://elasticsearch:9200', - 'service-token-1', - 'policy-1' - ); - - expect(res.rpm).toMatchInlineSnapshot(` - "sudo elastic-agent enroll \\\\ - --fleet-server-es=http://elasticsearch:9200 \\\\ - --fleet-server-service-token=service-token-1 \\\\ - --fleet-server-policy=policy-1" - `); - }); - - it('should return the correct command if the the policyId is set for deb', () => { - const res = getInstallCommandForPlatform( - 'http://elasticsearch:9200', - 'service-token-1', - 'policy-1' - ); - - expect(res.deb).toMatchInlineSnapshot(` - "sudo elastic-agent enroll \\\\ - --fleet-server-es=http://elasticsearch:9200 \\\\ - --fleet-server-service-token=service-token-1 \\\\ - --fleet-server-policy=policy-1" - `); - }); - }); - - describe('with policy id and fleet server host and production deployment', () => { - it('should return the correct command if the the policyId is set for linux', () => { - const res = getInstallCommandForPlatform( - 'http://elasticsearch:9200', - 'service-token-1', - 'policy-1', - 'http://fleetserver:8220', - true - ); - - expect(res.linux).toMatchInlineSnapshot(` - "sudo ./elastic-agent install --url=http://fleetserver:8220 \\\\ - --fleet-server-es=http://elasticsearch:9200 \\\\ - --fleet-server-service-token=service-token-1 \\\\ - --fleet-server-policy=policy-1 \\\\ - --certificate-authorities= \\\\ - --fleet-server-es-ca= \\\\ - --fleet-server-cert= \\\\ - --fleet-server-cert-key=" - `); - }); - - it('should return the correct command if the the policyId is set for mac', () => { - const res = getInstallCommandForPlatform( - 'http://elasticsearch:9200', - 'service-token-1', - 'policy-1', - 'http://fleetserver:8220', - true - ); - - expect(res.mac).toMatchInlineSnapshot(` - "sudo ./elastic-agent install --url=http://fleetserver:8220 \\\\ - --fleet-server-es=http://elasticsearch:9200 \\\\ - --fleet-server-service-token=service-token-1 \\\\ - --fleet-server-policy=policy-1 \\\\ - --certificate-authorities= \\\\ - --fleet-server-es-ca= \\\\ - --fleet-server-cert= \\\\ - --fleet-server-cert-key=" - `); - }); - - it('should return the correct command if the the policyId is set for windows', () => { - const res = getInstallCommandForPlatform( - 'http://elasticsearch:9200', - 'service-token-1', - 'policy-1', - 'http://fleetserver:8220', - true - ); - - expect(res.windows).toMatchInlineSnapshot(` - ".\\\\elastic-agent.exe install --url=http://fleetserver:8220 \` - --fleet-server-es=http://elasticsearch:9200 \` - --fleet-server-service-token=service-token-1 \` - --fleet-server-policy=policy-1 \` - --certificate-authorities= \` - --fleet-server-es-ca= \` - --fleet-server-cert= \` - --fleet-server-cert-key=" - `); - }); - - it('should return the correct command if the the policyId is set for rpm', () => { - const res = getInstallCommandForPlatform( - 'http://elasticsearch:9200', - 'service-token-1', - 'policy-1', - 'http://fleetserver:8220', - true - ); - - expect(res.rpm).toMatchInlineSnapshot(` - "sudo elastic-agent enroll --url=http://fleetserver:8220 \\\\ - --fleet-server-es=http://elasticsearch:9200 \\\\ - --fleet-server-service-token=service-token-1 \\\\ - --fleet-server-policy=policy-1 \\\\ - --certificate-authorities= \\\\ - --fleet-server-es-ca= \\\\ - --fleet-server-cert= \\\\ - --fleet-server-cert-key=" - `); - }); - - it('should return the correct command if the the policyId is set for deb', () => { - const res = getInstallCommandForPlatform( - 'http://elasticsearch:9200', - 'service-token-1', - 'policy-1', - 'http://fleetserver:8220', - true - ); - - expect(res.deb).toMatchInlineSnapshot(` - "sudo elastic-agent enroll --url=http://fleetserver:8220 \\\\ - --fleet-server-es=http://elasticsearch:9200 \\\\ - --fleet-server-service-token=service-token-1 \\\\ - --fleet-server-policy=policy-1 \\\\ - --certificate-authorities= \\\\ - --fleet-server-es-ca= \\\\ - --fleet-server-cert= \\\\ - --fleet-server-cert-key=" - `); - }); - }); -}); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/install_command_utils.ts b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/install_command_utils.ts deleted file mode 100644 index b73eb547b6ddf..0000000000000 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/components/install_command_utils.ts +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { PLATFORM_TYPE } from '../../../../hooks'; - -export type CommandsByPlatform = { - [key in PLATFORM_TYPE]: string; -}; - -export function getInstallCommandForPlatform( - esHost: string, - serviceToken: string, - policyId?: string, - fleetServerHost?: string, - isProductionDeployment?: boolean, - sslCATrustedFingerprint?: string -): CommandsByPlatform { - const commandArguments: Array<[string, string] | [string]> = []; - - if (isProductionDeployment && fleetServerHost) { - commandArguments.push(['url', fleetServerHost]); - } - - commandArguments.push(['fleet-server-es', esHost]); - commandArguments.push(['fleet-server-service-token', serviceToken]); - if (policyId) { - commandArguments.push(['fleet-server-policy', policyId]); - } - - if (sslCATrustedFingerprint) { - commandArguments.push(['fleet-server-es-ca-trusted-fingerprint', sslCATrustedFingerprint]); - } - - if (isProductionDeployment) { - commandArguments.push(['certificate-authorities', '']); - if (!sslCATrustedFingerprint) { - commandArguments.push(['fleet-server-es-ca', '']); - } - commandArguments.push(['fleet-server-cert', '']); - commandArguments.push(['fleet-server-cert-key', '']); - } - - const commandArgumentsStr = (platform?: string) => { - const newLineSeparator = platform === 'windows' ? '`\n' : '\\\n'; - return commandArguments.reduce((acc, [key, val]) => { - if (acc === '' && key === 'url') { - return `--${key}=${val}`; - } - const valOrEmpty = val ? `=${val}` : ''; - return (acc += ` ${newLineSeparator} --${key}${valOrEmpty}`); - }, ''); - }; - - return { - linux: `sudo ./elastic-agent install ${commandArgumentsStr()}`, - mac: `sudo ./elastic-agent install ${commandArgumentsStr()}`, - windows: `.\\elastic-agent.exe install ${commandArgumentsStr('windows')}`, - deb: `sudo elastic-agent enroll ${commandArgumentsStr()}`, - rpm: `sudo elastic-agent enroll ${commandArgumentsStr()}`, - }; -} diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/fleet_server_requirement_page.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/fleet_server_requirement_page.tsx index bee7fbfd85371..b4818a6908adf 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/fleet_server_requirement_page.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/fleet_server_requirement_page.tsx @@ -13,9 +13,11 @@ import { useStartServices, sendGetPermissionsCheck } from '../../../hooks'; import { FleetServerMissingPrivileges } from '../components/fleet_server_callouts'; -import { Loading } from '../../../components'; +import { Loading } from '../components'; -import { CloudInstructions, OnPremInstructions } from './components'; +import { FleetServerInstructions } from '../../../components'; + +import { CloudInstructions, EnrollmentRecommendation } from './components'; const FlexItemWithMinWidth = styled(EuiFlexItem)` min-width: 0px; @@ -27,7 +29,16 @@ const ContentWrapper = styled(EuiFlexGroup)` margin: 0 auto; `; -export const FleetServerRequirementPage = () => { +export const FleetServerRequirementPage: React.FunctionComponent< + | { + showEnrollmentRecommendation?: false; + showStandaloneTab?: never; + } + | { + showEnrollmentRecommendation?: true; + showStandaloneTab: () => void; + } +> = ({ showStandaloneTab = () => {}, showEnrollmentRecommendation = true }) => { const startService = useStartServices(); const deploymentUrl = startService.cloud?.deploymentUrl; @@ -56,12 +67,7 @@ export const FleetServerRequirementPage = () => { return ( <> - + {deploymentUrl ? ( @@ -69,8 +75,10 @@ export const FleetServerRequirementPage = () => { ) : permissionsError ? ( + ) : showEnrollmentRecommendation ? ( + ) : ( - + )} diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_reassign_policy_modal/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_reassign_policy_modal/index.tsx index 566bc7f4363ab..5e74b86728247 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_reassign_policy_modal/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_reassign_policy_modal/index.tsx @@ -99,6 +99,7 @@ export const AgentReassignAgentPolicyModal: React.FunctionComponent = ({ return ( = ({ return ( = ({ return ( diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/index.tsx index d2434e109ca31..57da2fcf36d76 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/index.tsx @@ -5,13 +5,13 @@ * 2.0. */ -import React, { useCallback, useEffect, useState } from 'react'; +import React, { createContext, useCallback, useEffect, useState } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { Router, Route, Switch, useHistory } from 'react-router-dom'; import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiPortal } from '@elastic/eui'; import { FLEET_ROUTING_PATHS } from '../../constants'; -import { Loading, Error, AgentEnrollmentFlyout } from '../../components'; +import { Loading, Error, AgentEnrollmentFlyout, FleetServerFlyout } from '../../components'; import { useConfig, useFleetStatus, useBreadcrumbs, useAuthz, useGetSettings } from '../../hooks'; import { DefaultLayout, WithoutHeaderLayout } from '../../layouts'; @@ -21,6 +21,18 @@ import { AgentDetailsPage } from './agent_details_page'; import { NoAccessPage } from './error_pages/no_access'; import { FleetServerUpgradeModal } from './components/fleet_server_upgrade_modal'; +// TODO: Move all instances of toggling these flyouts to a global context object to avoid cases in which +// we can render duplicate "stacked" flyouts +export const agentFlyoutContext = createContext< + | { + openEnrollmentFlyout: () => void; + closeEnrollmentFlyout: () => void; + openFleetServerFlyout: () => void; + closeFleetServerFlyout: () => void; + } + | undefined +>(undefined); + export const AgentsApp: React.FunctionComponent = () => { useBreadcrumbs('agent_list'); const history = useHistory(); @@ -31,6 +43,8 @@ export const AgentsApp: React.FunctionComponent = () => { const settings = useGetSettings(); const [isEnrollmentFlyoutOpen, setIsEnrollmentFlyoutOpen] = useState(false); + const [isFleetServerFlyoutOpen, setIsFleetServerFlyoutOpen] = useState(false); + const [fleetServerModalVisible, setFleetServerModalVisible] = useState(false); const onCloseFleetServerModal = useCallback(() => { setFleetServerModalVisible(false); @@ -81,15 +95,6 @@ export const AgentsApp: React.FunctionComponent = () => { const rightColumn = hasOnlyFleetServerMissingRequirement ? ( <> - {isEnrollmentFlyoutOpen && ( - - setIsEnrollmentFlyoutOpen(false)} - /> - - )} { ) : undefined; return ( - - - - - - - - {fleetServerModalVisible && ( - - )} - {hasOnlyFleetServerMissingRequirement ? ( - - ) : ( - - )} - - - - + setIsEnrollmentFlyoutOpen(true), + closeEnrollmentFlyout: () => setIsEnrollmentFlyoutOpen(false), + openFleetServerFlyout: () => setIsFleetServerFlyoutOpen(true), + closeFleetServerFlyout: () => setIsFleetServerFlyoutOpen(false), + }} + > + + + + + + + + {fleetServerModalVisible && ( + + )} + {hasOnlyFleetServerMissingRequirement ? ( + + ) : ( + + )} + + + + + {isEnrollmentFlyoutOpen && ( + + setIsEnrollmentFlyoutOpen(false)} + /> + + )} + + {isFleetServerFlyoutOpen && ( + + setIsFleetServerFlyoutOpen(false)} /> + + )} + + ); }; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/fleet_server_hosts_flyout/use_fleet_server_host_form.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/fleet_server_hosts_flyout/use_fleet_server_host_form.test.tsx index 151a3d5354c17..aeb49928f3d1e 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/fleet_server_hosts_flyout/use_fleet_server_host_form.test.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/fleet_server_hosts_flyout/use_fleet_server_host_form.test.tsx @@ -27,7 +27,7 @@ describe('useFleetServerHostsForm', () => { const { result } = testRenderer.renderHook(() => useFleetServerHostsForm([], onSucess)); act(() => - result.current.fleetServerHostsInput.props.onChange(['http://test.fr', 'http://test.fr']) + result.current.fleetServerHostsInput.props.onChange(['https://test.fr', 'https://test.fr']) ); await act(() => result.current.submit()); @@ -54,7 +54,7 @@ describe('useFleetServerHostsForm', () => { testRenderer.startServices.http.post.mockResolvedValue({}); const { result } = testRenderer.renderHook(() => useFleetServerHostsForm([], onSucess)); - act(() => result.current.fleetServerHostsInput.props.onChange(['http://test.fr'])); + act(() => result.current.fleetServerHostsInput.props.onChange(['https://test.fr'])); await act(() => result.current.submit()); expect(onSucess).toBeCalled(); @@ -67,14 +67,14 @@ describe('useFleetServerHostsForm', () => { const { result } = testRenderer.renderHook(() => useFleetServerHostsForm([], onSucess)); act(() => - result.current.fleetServerHostsInput.props.onChange(['http://test.fr', 'http://test.fr']) + result.current.fleetServerHostsInput.props.onChange(['https://test.fr', 'https://test.fr']) ); await act(() => result.current.submit()); expect(onSucess).not.toBeCalled(); expect(result.current.isDisabled).toBeTruthy(); - act(() => result.current.fleetServerHostsInput.props.onChange(['http://test.fr'])); + act(() => result.current.fleetServerHostsInput.props.onChange(['https://test.fr'])); expect(result.current.isDisabled).toBeFalsy(); await act(() => result.current.submit()); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/fleet_server_hosts_flyout/use_fleet_server_host_form.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/fleet_server_hosts_flyout/use_fleet_server_host_form.tsx index ac196576ba889..b19e8ddda0427 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/fleet_server_hosts_flyout/use_fleet_server_host_form.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/fleet_server_hosts_flyout/use_fleet_server_host_form.tsx @@ -15,7 +15,7 @@ import { isDiffPathProtocol } from '../../../../../../../common'; import { useConfirmModal } from '../../hooks/use_confirm_modal'; import { getAgentAndPolicyCount } from '../../services/agent_and_policies_count'; -const URL_REGEX = /^(https?):\/\/[^\s$.?#].[^\s]*$/gm; +const URL_REGEX = /^(https):\/\/[^\s$.?#].[^\s]*$/gm; const ConfirmTitle = () => ( {
API Key
{logstashApiKey.apiKey} - - {(copy) => ( -
-
+ +
+
+ + {(copy) => ( { } )} /> -
-
- )} - + )} + +
+
) : ( + ) : ( + + ), + } + : undefined; + + return ( + onClick(e)} + data-test-subj="addIntegrationPolicyButton" + tooltip={tooltip} + > + + + ); +} diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/components/index.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/components/index.tsx index 8716d78dfb7bd..c0438bf6dfe8d 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/components/index.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/components/index.tsx @@ -4,6 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +export { AddIntegrationButton } from './add_integration_button'; export { UpdateIcon } from './update_icon'; export { IntegrationAgentPolicyCount } from './integration_agent_policy_count'; export { IconPanel, LoadingIconPanel } from './icon_panel'; diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx index 5ac2836876351..d17b24a4dcdb0 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx @@ -35,26 +35,25 @@ import { useAuthz, usePermissionCheck, } from '../../../../hooks'; -import { - PLUGIN_ID, - INTEGRATIONS_PLUGIN_ID, - INTEGRATIONS_ROUTING_PATHS, - pagePathGetters, -} from '../../../../constants'; +import { INTEGRATIONS_ROUTING_PATHS } from '../../../../constants'; import { useGetPackageInfoByKey, useLink, useAgentPolicyContext } from '../../../../hooks'; import { pkgKeyFromPackageInfo } from '../../../../services'; -import type { - CreatePackagePolicyRouteState, - DetailViewPanelName, - PackageInfo, -} from '../../../../types'; +import type { DetailViewPanelName, PackageInfo } from '../../../../types'; import { InstallStatus } from '../../../../types'; -import { Error, EuiButtonWithTooltip, Loading } from '../../../../components'; +import { Error, Loading } from '../../../../components'; import type { WithHeaderLayoutProps } from '../../../../layouts'; import { WithHeaderLayout } from '../../../../layouts'; import { RELEASE_BADGE_DESCRIPTION, RELEASE_BADGE_LABEL } from '../../components/release_badge'; -import { IntegrationAgentPolicyCount, UpdateIcon, IconPanel, LoadingIconPanel } from './components'; +import { getInstallPkgRouteOptions } from './utils'; + +import { + IntegrationAgentPolicyCount, + UpdateIcon, + IconPanel, + LoadingIconPanel, + AddIntegrationButton, +} from './components'; import { AssetsPage } from './assets'; import { OverviewPage } from './overview'; import { PackagePoliciesPage } from './policies'; @@ -257,7 +256,6 @@ export function Detail() { const handleAddIntegrationPolicyClick = useCallback( (ev) => { ev.preventDefault(); - // The object below, given to `createHref` is explicitly accessing keys of `location` in order // to ensure that dependencies to this `useCallback` is set correctly (because `location` is mutable) const currentPath = history.createHref({ @@ -266,65 +264,14 @@ export function Detail() { hash, }); - const path = pagePathGetters.add_integration_to_policy({ + const navigateOptions = getInstallPkgRouteOptions({ + currentPath, + integration, + agentPolicyId: agentPolicyIdFromContext, pkgkey, - ...(integration ? { integration } : {}), - ...(agentPolicyIdFromContext ? { agentPolicyId: agentPolicyIdFromContext } : {}), - })[1]; - - let redirectToPath: CreatePackagePolicyRouteState['onSaveNavigateTo'] & - CreatePackagePolicyRouteState['onCancelNavigateTo']; - let onSaveQueryParams: CreatePackagePolicyRouteState['onSaveQueryParams']; - if (agentPolicyIdFromContext) { - redirectToPath = [ - PLUGIN_ID, - { - path: pagePathGetters.policy_details({ - policyId: agentPolicyIdFromContext, - })[1], - }, - ]; - - onSaveQueryParams = { - showAddAgentHelp: true, - openEnrollmentFlyout: true, - }; - } else { - redirectToPath = [ - INTEGRATIONS_PLUGIN_ID, - { - path: pagePathGetters.integration_details_policies({ - pkgkey, - ...(integration ? { integration } : {}), - })[1], - }, - ]; - - onSaveQueryParams = { - showAddAgentHelp: { renameKey: 'showAddAgentHelpForPolicyId', policyIdAsValue: true }, - openEnrollmentFlyout: { renameKey: 'addAgentToPolicyId', policyIdAsValue: true }, - }; - } - - const redirectBackRouteState: CreatePackagePolicyRouteState = { - onSaveNavigateTo: redirectToPath, - onSaveQueryParams, - onCancelNavigateTo: [ - INTEGRATIONS_PLUGIN_ID, - { - path: pagePathGetters.integration_details_overview({ - pkgkey, - ...(integration ? { integration } : {}), - })[1], - }, - ], - onCancelUrl: currentPath, - }; - - services.application.navigateToApp(PLUGIN_ID, { - path, - state: redirectBackRouteState, }); + + services.application.navigateToApp(...navigateOptions); }, [ history, @@ -375,10 +322,8 @@ export function Detail() { { isDivider: true }, { content: ( - - ) : ( - - ), - } - : undefined - } - > - - + /> ), }, ].map((item, index) => ( diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/utils/get_install_route_options.test.ts b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/utils/get_install_route_options.test.ts new file mode 100644 index 0000000000000..4ee67874e61c1 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/utils/get_install_route_options.test.ts @@ -0,0 +1,69 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { getInstallPkgRouteOptions } from '.'; + +// this is always the same +const expectedOnCancelNavigateTo = [ + 'integrations', + { + path: '/detail/myintegration-1.0.0/overview?integration=myintegration', + }, +]; + +describe('getInstallPkgRouteOptions', () => { + it('should redirect to integrations app on save if no agentPolicyId present', () => { + const opts = { + currentPath: 'currentPath', + integration: 'myintegration', + pkgkey: 'myintegration-1.0.0', + }; + + const expectedRedirectURl = '/detail/myintegration-1.0.0/policies?integration=myintegration'; + + const expectedOptions = { + path: '/integrations/myintegration-1.0.0/add-integration/myintegration', + state: { + onCancelUrl: 'currentPath', + onCancelNavigateTo: expectedOnCancelNavigateTo, + onSaveNavigateTo: ['integrations', { path: expectedRedirectURl }], + onSaveQueryParams: { + showAddAgentHelp: { renameKey: 'showAddAgentHelpForPolicyId', policyIdAsValue: true }, + openEnrollmentFlyout: { renameKey: 'addAgentToPolicyId', policyIdAsValue: true }, + }, + }, + }; + + expect(getInstallPkgRouteOptions(opts)).toEqual(['fleet', expectedOptions]); + }); + + it('should redirect to fleet app on save if agentPolicyId present', () => { + const opts = { + currentPath: 'currentPath', + integration: 'myintegration', + pkgkey: 'myintegration-1.0.0', + agentPolicyId: '12345', + }; + + const expectedRedirectURl = '/policies/12345'; + + const expectedOptions = { + path: '/integrations/myintegration-1.0.0/add-integration/myintegration?policyId=12345', + state: { + onCancelUrl: 'currentPath', + onCancelNavigateTo: expectedOnCancelNavigateTo, + onSaveNavigateTo: ['fleet', { path: expectedRedirectURl }], + onSaveQueryParams: { + showAddAgentHelp: true, + openEnrollmentFlyout: true, + }, + }, + }; + + expect(getInstallPkgRouteOptions(opts)).toEqual(['fleet', expectedOptions]); + }); +}); diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/utils/get_install_route_options.ts b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/utils/get_install_route_options.ts new file mode 100644 index 0000000000000..dc34ac91447f6 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/utils/get_install_route_options.ts @@ -0,0 +1,82 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import type { CreatePackagePolicyRouteState } from '../../../../../types'; +import { PLUGIN_ID, INTEGRATIONS_PLUGIN_ID, pagePathGetters } from '../../../../../constants'; + +/* + * When the install package button is pressed, this fn decides which page to navigate to + * by generating the options to be passed to `services.application.navigateToApp`. + */ +export const getInstallPkgRouteOptions = ({ + currentPath, + integration, + agentPolicyId, + pkgkey, +}: { + currentPath: string; + integration: string | null; + agentPolicyId?: string; + pkgkey: string; +}): [string, { path: string; state: unknown }] => { + const integrationOpts: { integration?: string } = integration ? { integration } : {}; + const path = pagePathGetters.add_integration_to_policy({ + pkgkey, + ...integrationOpts, + ...(agentPolicyId ? { agentPolicyId } : {}), + })[1]; + + let redirectToPath: CreatePackagePolicyRouteState['onSaveNavigateTo'] & + CreatePackagePolicyRouteState['onCancelNavigateTo']; + let onSaveQueryParams: CreatePackagePolicyRouteState['onSaveQueryParams']; + if (agentPolicyId) { + redirectToPath = [ + PLUGIN_ID, + { + path: pagePathGetters.policy_details({ + policyId: agentPolicyId, + })[1], + }, + ]; + + onSaveQueryParams = { + showAddAgentHelp: true, + openEnrollmentFlyout: true, + }; + } else { + redirectToPath = [ + INTEGRATIONS_PLUGIN_ID, + { + path: pagePathGetters.integration_details_policies({ + pkgkey, + ...integrationOpts, + })[1], + }, + ]; + + onSaveQueryParams = { + showAddAgentHelp: { renameKey: 'showAddAgentHelpForPolicyId', policyIdAsValue: true }, + openEnrollmentFlyout: { renameKey: 'addAgentToPolicyId', policyIdAsValue: true }, + }; + } + + const state: CreatePackagePolicyRouteState = { + onSaveNavigateTo: redirectToPath, + onSaveQueryParams, + onCancelNavigateTo: [ + INTEGRATIONS_PLUGIN_ID, + { + path: pagePathGetters.integration_details_overview({ + pkgkey, + ...integrationOpts, + })[1], + }, + ], + onCancelUrl: currentPath, + }; + + return [PLUGIN_ID, { path, state }]; +}; diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/utils/index.ts b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/utils/index.ts new file mode 100644 index 0000000000000..020e115f2309a --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/utils/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { getInstallPkgRouteOptions } from './get_install_route_options'; diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx index 88343528afa0c..154669409b457 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx @@ -214,6 +214,7 @@ export const AvailablePackages: React.FC = memo(() => { error: eprPackageLoadingError, } = useGetPackages({ category: '', + excludeInstallStatus: true, }); const eprIntegrationList = useMemo( () => packageListToIntegrationsList(eprPackages?.items || []), diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.mocks.ts b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.mocks.ts index 408f884116e26..5b70d8a56ebde 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.mocks.ts +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.mocks.ts @@ -18,7 +18,6 @@ jest.mock('../../hooks/use_request', () => { return { ...module, useGetSettings: jest.fn(), - sendGetFleetStatus: jest.fn(), sendGetOneAgentPolicy: jest.fn(), useGetAgents: jest.fn(), useGetAgentPolicies: jest.fn(), @@ -36,14 +35,14 @@ jest.mock('../../applications/fleet/sections/agents/hooks/use_fleet_server_unhea }); jest.mock( - '../../applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions', + '../../applications/fleet/components/fleet_server_instructions/hooks/use_advanced_form', () => { const module = jest.requireActual( - '../../applications/fleet/sections/agents/agent_requirements_page/components/fleet_server_on_prem_instructions' + '../../applications/fleet/components/fleet_server_instructions/hooks/use_advanced_form' ); return { ...module, - useFleetServerInstructions: jest.fn(), + useAdvancedForm: jest.fn(), }; } ); @@ -82,6 +81,9 @@ jest.mock('./steps', () => { }; }); -jest.mock('../../applications/fleet/sections/agents/services/has_fleet_server', () => { - return { policyHasFleetServer: jest.fn().mockReturnValue(true) }; +jest.mock('../../services', () => { + return { + ...jest.requireActual('../../services'), + policyHasFleetServer: jest.fn().mockReturnValue(true), + }; }); diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.tsx index b2680129dd7d5..6e46ec90d5faf 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.tsx @@ -25,8 +25,7 @@ import { useFleetStatus, } from '../../hooks'; -import { useFleetServerInstructions } from '../../applications/fleet/sections/agents/agent_requirements_page/components'; - +import { useAdvancedForm } from '../../applications/fleet/components/fleet_server_instructions/hooks'; import { useFleetServerUnhealthy } from '../../applications/fleet/sections/agents/hooks/use_fleet_server_unhealthy'; import type { FlyOutProps } from './types'; @@ -44,8 +43,8 @@ const TestComponent = (props: FlyOutProps) => ( ); -const setup = async (props?: FlyOutProps) => { - const testBed = await registerTestBed(TestComponent)(props); +const setup = (props?: FlyOutProps) => { + const testBed = registerTestBed(TestComponent)(props); const { find, component } = testBed; return { @@ -78,7 +77,7 @@ const testAgentPolicy: AgentPolicy = { describe('', () => { let testBed: TestBed; - beforeEach(async () => { + beforeEach(() => { (useGetSettings as jest.Mock).mockReturnValue({ data: { item: { fleet_server_hosts: ['test'] } }, }); @@ -93,13 +92,24 @@ describe('', () => { data: { item: { package_policies: [] } }, }); - (useFleetServerInstructions as jest.Mock).mockReturnValue({ + (useAdvancedForm as jest.Mock).mockReturnValue({ + eligibleFleetServerPolicies: [{ name: 'test', id: 'test' }], + refreshEligibleFleetServerPolicies: jest.fn(), + fleetServerPolicyId: 'test', + setFleetServerPolicyId: jest.fn(), + isFleetServerReady: true, serviceToken: 'test', - getServiceToken: jest.fn(), isLoadingServiceToken: false, - installCommand: jest.fn(), - platform: 'test', - setPlatform: jest.fn(), + generateServiceToken: jest.fn(), + fleetServerHostForm: { + saveFleetServerHost: jest.fn(), + fleetServerHost: 'https://test.server:8220', + setFleetServerHost: jest.fn(), + error: '', + validateFleetServerHost: jest.fn(), + }, + deploymentMode: 'quickstart', + setDeploymentMode: jest.fn(), }); (useGetAgents as jest.Mock).mockReturnValue({ @@ -111,8 +121,8 @@ describe('', () => { refreshAgentPolicies: jest.fn(), }); - await act(async () => { - testBed = await setup({ + act(() => { + testBed = setup({ onClose: jest.fn(), }); testBed.component.update(); @@ -123,15 +133,15 @@ describe('', () => { jest.clearAllMocks(); }); - it('should show loading when agent policies are loading', async () => { + it('should show loading when agent policies are loading', () => { (useAgentEnrollmentFlyoutData as jest.Mock).mockReturnValue?.({ agentPolicies: [], refreshAgentPolicies: jest.fn(), isLoadingInitialAgentPolicies: true, }); - await act(async () => { - testBed = await setup({ + act(() => { + testBed = setup({ onClose: jest.fn(), }); testBed.component.update(); @@ -143,7 +153,7 @@ describe('', () => { }); describe('managed instructions', () => { - it('uses the agent policy selection step', async () => { + it('uses the agent policy selection step', () => { const { exists } = testBed; expect(exists('agentEnrollmentFlyout')).toBe(true); @@ -152,10 +162,10 @@ describe('', () => { }); describe('with a specific policy', () => { - beforeEach(async () => { + beforeEach(() => { jest.clearAllMocks(); - await act(async () => { - testBed = await setup({ + act(() => { + testBed = setup({ agentPolicy: testAgentPolicy, onClose: jest.fn(), }); @@ -172,10 +182,10 @@ describe('', () => { }); describe('with a specific policy when no agentPolicies set', () => { - beforeEach(async () => { + beforeEach(() => { jest.clearAllMocks(); - await act(async () => { - testBed = await setup({ + act(() => { + testBed = setup({ agentPolicy: testAgentPolicy, onClose: jest.fn(), }); @@ -189,41 +199,41 @@ describe('', () => { expect(exists('agent-enrollment-key-selection-step')).toBe(true); }); }); - }); - // Skipped due to UI changing in https://github.com/elastic/kibana/issues/125534. These tests should be rethought overall - // to provide value around the new flyout structure - describe.skip('standalone instructions', () => { - it('uses the agent policy selection step', async () => { - const { exists, actions } = testBed; - actions.goToStandaloneTab(); + // Skipped due to UI changing in https://github.com/elastic/kibana/issues/125534. These tests should be rethought overall + // to provide value around the new flyout structure + describe.skip('standalone instructions', () => { + it('uses the agent policy selection step', async () => { + const { exists, actions } = testBed; + actions.goToStandaloneTab(); - expect(exists('agentEnrollmentFlyout')).toBe(true); - expect(exists('agent-policy-selection-step')).toBe(true); - expect(exists('agent-enrollment-key-selection-step')).toBe(false); - }); + expect(exists('agentEnrollmentFlyout')).toBe(true); + expect(exists('agent-policy-selection-step')).toBe(true); + expect(exists('agent-enrollment-key-selection-step')).toBe(false); + }); - describe('with a specific policy', () => { - beforeEach(async () => { - jest.clearAllMocks(); - await act(async () => { - testBed = await setup({ - agentPolicy: testAgentPolicy, - onClose: jest.fn(), + describe('with a specific policy', () => { + beforeEach(() => { + jest.clearAllMocks(); + act(() => { + testBed = setup({ + agentPolicy: testAgentPolicy, + onClose: jest.fn(), + }); + testBed.component.update(); }); - testBed.component.update(); }); - }); - it('does not use either of the agent policy selection or enrollment key steps', () => { - const { exists, actions } = testBed; - jest.clearAllMocks(); + it('does not use either of the agent policy selection or enrollment key steps', () => { + const { exists, actions } = testBed; + jest.clearAllMocks(); - actions.goToStandaloneTab(); + actions.goToStandaloneTab(); - expect(exists('agentEnrollmentFlyout')).toBe(true); - expect(exists('agent-policy-selection-step')).toBe(false); - expect(exists('agent-enrollment-key-selection-step')).toBe(false); + expect(exists('agentEnrollmentFlyout')).toBe(true); + expect(exists('agent-policy-selection-step')).toBe(false); + expect(exists('agent-enrollment-key-selection-step')).toBe(false); + }); }); }); }); diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_select_create.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_select_create.tsx index 81ec1236920b8..304239ac77dad 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_select_create.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_select_create.tsx @@ -20,7 +20,7 @@ import { AgentPolicySelection } from '.'; interface Props { agentPolicies: AgentPolicy[]; - selectedPolicy?: AgentPolicy; + selectedPolicyId?: string; setSelectedPolicyId: (agentPolicyId?: string) => void; excludeFleetServer?: boolean; withKeySelection: boolean; @@ -34,7 +34,7 @@ export const SelectCreateAgentPolicy: React.FC = ({ agentPolicies, excludeFleetServer, setSelectedPolicyId, - selectedPolicy, + selectedPolicyId, withKeySelection, selectedApiKeyId, onKeyChange, @@ -111,7 +111,7 @@ export const SelectCreateAgentPolicy: React.FC = ({ onKeyChange={onKeyChange} excludeFleetServer={excludeFleetServer} onClickCreatePolicy={onClickCreatePolicy} - selectedPolicy={selectedPolicy} + selectedPolicyId={selectedPolicyId} setSelectedPolicyId={setSelectedPolicyId} isFleetServerPolicy={isFleetServerPolicy} /> diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.test.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.test.tsx index c5a6076308525..4c02ddeeaaf27 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.test.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_policy_selection.test.tsx @@ -23,7 +23,7 @@ describe('step select agent policy', () => { (renderResult = testRenderer.render( void; excludeFleetServer?: boolean; onClickCreatePolicy: () => void; @@ -50,23 +50,10 @@ type Props = { } ); -const resolveAgentId = ( - agentPolicies: AgentPolicy[], - selectedAgentPolicyId?: string -): undefined | string => { - if (agentPolicies.length && !selectedAgentPolicyId) { - if (agentPolicies.length === 1) { - return agentPolicies[0].id; - } - } - - return selectedAgentPolicyId; -}; - export const AgentPolicySelection: React.FC = (props) => { const { agentPolicies, - selectedPolicy, + selectedPolicyId, setSelectedPolicyId, excludeFleetServer, onClickCreatePolicy, @@ -75,17 +62,6 @@ export const AgentPolicySelection: React.FC = (props) => { const hasFleetAllPrivileges = useAuthz().fleet.all; - useEffect( - function useDefaultAgentPolicyEffect() { - const resolvedId = resolveAgentId(agentPolicies, selectedPolicy?.id); - // find AgentPolicy - if (resolvedId !== selectedPolicy?.id) { - setSelectedPolicyId(resolvedId); - } - }, - [agentPolicies, setSelectedPolicyId, selectedPolicy] - ); - const onChangeCallback = (event: React.ChangeEvent) => { const { value } = event.target; setSelectedPolicyId(value); @@ -144,7 +120,7 @@ export const AgentPolicySelection: React.FC = (props) => { value: agentPolicy.id, text: agentPolicy.name, }))} - value={selectedPolicy?.id} + value={selectedPolicyId} onChange={onChangeCallback} aria-label={i18n.translate( 'xpack.fleet.enrollmentStepAgentPolicy.policySelectAriaLabel', @@ -152,28 +128,28 @@ export const AgentPolicySelection: React.FC = (props) => { defaultMessage: 'Agent policy', } )} - hasNoInitialSelection={!selectedPolicy?.id} + hasNoInitialSelection={!selectedPolicyId} data-test-subj="agentPolicyDropdown" - isInvalid={!selectedPolicy?.id} + isInvalid={!selectedPolicyId} /> - {selectedPolicy?.id && !isFleetServerPolicy && ( + {selectedPolicyId && !isFleetServerPolicy && ( <> )} - {props.withKeySelection && props.onKeyChange && selectedPolicy?.id && ( + {props.withKeySelection && props.onKeyChange && selectedPolicyId && ( <> )} diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/instructions.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/instructions.tsx index 5e6ea53261cd8..7dba93e5ddd3e 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/instructions.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/instructions.tsx @@ -13,17 +13,19 @@ import { useFleetStatus, useGetAgents } from '../../hooks'; import { FleetServerRequirementPage } from '../../applications/fleet/sections/agents/agent_requirements_page'; -import { policyHasFleetServer } from '../../applications/fleet/sections/agents/services/has_fleet_server'; - import { FLEET_SERVER_PACKAGE } from '../../constants'; import { useFleetServerUnhealthy } from '../../applications/fleet/sections/agents/hooks/use_fleet_server_unhealthy'; import { Loading } from '..'; +import { policyHasFleetServer } from '../../services'; + +import { AdvancedTab } from '../../applications/fleet/components/fleet_server_instructions/advanced_tab'; + import type { InstructionProps } from './types'; -import { ManagedSteps, StandaloneSteps, FleetServerSteps } from './steps'; +import { ManagedSteps, StandaloneSteps } from './steps'; import { DefaultMissingRequirements } from './default_missing_requirements'; export const Instructions = (props: InstructionProps) => { @@ -35,6 +37,7 @@ export const Instructions = (props: InstructionProps) => { selectionType, setSelectionType, mode, + setMode, isIntegrationFlow, } = props; const fleetStatus = useFleetStatus(); @@ -86,7 +89,7 @@ export const Instructions = (props: InstructionProps) => { if (mode === 'managed') { if (showFleetServerEnrollment) { - return ; + return setMode('standalone')} />; } else if (showAgentEnrollment) { return ( <> @@ -101,11 +104,7 @@ export const Instructions = (props: InstructionProps) => { )} - {isFleetServerPolicySelected ? ( - - ) : ( - - )} + {isFleetServerPolicySelected ? : } ); } diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/agent_policy_selection_step.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/agent_policy_selection_step.tsx index c26bfd3f0e2b8..a0828bb72f489 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/agent_policy_selection_step.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/agent_policy_selection_step.tsx @@ -40,7 +40,7 @@ export const AgentPolicySelectionStep = ({ <> = ({ return ; }; - -export const FleetServerSteps: React.FunctionComponent = ({ - agentPolicy, - agentPolicies, - selectedPolicy, - setSelectedPolicyId, - refreshAgentPolicies, -}) => { - const [selectedApiKeyId, setSelectedAPIKeyId] = useState(); - - const apiKey = useGetOneEnrollmentAPIKey(selectedApiKeyId); - const apiKeyData = apiKey?.data; - const fleetServerInstructions = useFleetServerInstructions(apiKeyData?.item?.policy_id); - - const fleetServerSteps = useMemo(() => { - const { - serviceToken, - getServiceToken, - isLoadingServiceToken, - installCommand: managedInstallCommands, - platform, - setPlatform, - deploymentMode, - setDeploymentMode, - addFleetServerHost, - } = fleetServerInstructions; - - return [ - deploymentModeStep({ deploymentMode, setDeploymentMode }), - addFleetServerHostStep({ addFleetServerHost }), - ServiceTokenStep({ serviceToken, getServiceToken, isLoadingServiceToken }), - FleetServerCommandStep({ - serviceToken, - installCommand: managedInstallCommands, - platform, - setPlatform, - }), - ]; - }, [fleetServerInstructions]); - - const instructionsSteps = useMemo(() => { - const steps: EuiContainedStepProps[] = !agentPolicy - ? [ - AgentPolicySelectionStep({ - selectedPolicy, - agentPolicies, - selectedApiKeyId, - setSelectedAPIKeyId, - setSelectedPolicyId, - refreshAgentPolicies, - }), - ] - : [ - AgentEnrollmentKeySelectionStep({ - selectedPolicy, - selectedApiKeyId, - setSelectedAPIKeyId, - }), - ]; - - steps.push(...fleetServerSteps); - - return steps; - }, [ - agentPolicy, - selectedPolicy, - agentPolicies, - selectedApiKeyId, - setSelectedPolicyId, - refreshAgentPolicies, - fleetServerSteps, - ]); - - return ; -}; diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/install_managed_agent_step.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/install_managed_agent_step.tsx index 59f6fdeafe727..bbb3d8d4794c3 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/install_managed_agent_step.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/install_managed_agent_step.tsx @@ -14,7 +14,7 @@ import type { EuiContainedStepProps } from '@elastic/eui/src/components/steps/st import type { GetOneEnrollmentAPIKeyResponse } from '../../../../common/types/rest_spec/enrollment_api_key'; import { InstallSection } from '../../enrollment_instructions/install_section'; -import type { CommandsByPlatform } from '../../../applications/fleet/sections/agents/agent_requirements_page/components/install_command_utils'; +import type { CommandsByPlatform } from '../../../applications/fleet/components/fleet_server_instructions/utils/install_command_utils'; import type { K8sMode } from '../types'; diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/install_standalone_agent_step.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/install_standalone_agent_step.tsx index fb6ddfd393dcc..74ce555f7c2e8 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/install_standalone_agent_step.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/install_standalone_agent_step.tsx @@ -10,7 +10,8 @@ import { i18n } from '@kbn/i18n'; import type { EuiContainedStepProps } from '@elastic/eui/src/components/steps/steps'; -import type { CommandsByPlatform } from '../../../applications/fleet/sections/agents/agent_requirements_page/components/install_command_utils'; +import type { CommandsByPlatform } from '../../../applications/fleet/components/fleet_server_instructions/utils/install_command_utils'; + import { InstallSection } from '../../enrollment_instructions/install_section'; import type { K8sMode } from '../types'; diff --git a/x-pack/plugins/fleet/public/components/enrollment_instructions/install_section.tsx b/x-pack/plugins/fleet/public/components/enrollment_instructions/install_section.tsx index 0cf43902db7e2..1ebe68b8c5282 100644 --- a/x-pack/plugins/fleet/public/components/enrollment_instructions/install_section.tsx +++ b/x-pack/plugins/fleet/public/components/enrollment_instructions/install_section.tsx @@ -7,13 +7,12 @@ import React from 'react'; +import type { CommandsByPlatform } from '../../applications/fleet/components/fleet_server_instructions/utils'; + import { InstallationMessage } from '../agent_enrollment_flyout/installation_message'; import type { K8sMode } from '../agent_enrollment_flyout/types'; - -import type { CommandsByPlatform } from '../../applications/fleet/sections/agents/agent_requirements_page/components/install_command_utils'; - -import { PlatformSelector } from './manual/platform_selector'; +import { PlatformSelector } from '../platform_selector'; interface Props { installCommand: CommandsByPlatform; diff --git a/x-pack/plugins/fleet/public/components/enrollment_instructions/standalone/index.tsx b/x-pack/plugins/fleet/public/components/enrollment_instructions/standalone/index.tsx index 89c1dfe3cac37..75378cdc86378 100644 --- a/x-pack/plugins/fleet/public/components/enrollment_instructions/standalone/index.tsx +++ b/x-pack/plugins/fleet/public/components/enrollment_instructions/standalone/index.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { CommandsByPlatform } from '../../../applications/fleet/sections/agents/agent_requirements_page/components/install_command_utils'; +import type { CommandsByPlatform } from '../../../applications/fleet/components/fleet_server_instructions/utils/install_command_utils'; import type { K8sMode } from '../../agent_enrollment_flyout/types'; export const StandaloneInstructions = ( diff --git a/x-pack/plugins/fleet/public/components/index.ts b/x-pack/plugins/fleet/public/components/index.ts index 9df4182bc8a4e..723b376699e07 100644 --- a/x-pack/plugins/fleet/public/components/index.ts +++ b/x-pack/plugins/fleet/public/components/index.ts @@ -23,3 +23,4 @@ export { AddAgentHelpPopover } from './add_agent_help_popover'; export { EuiButtonWithTooltip } from './eui_button_with_tooltip'; export * from './link_and_revision'; export * from './agent_enrollment_flyout'; +export * from './platform_selector'; diff --git a/x-pack/plugins/fleet/public/components/enrollment_instructions/manual/platform_selector.tsx b/x-pack/plugins/fleet/public/components/platform_selector.tsx similarity index 96% rename from x-pack/plugins/fleet/public/components/enrollment_instructions/manual/platform_selector.tsx rename to x-pack/plugins/fleet/public/components/platform_selector.tsx index e03e43907f829..ae18f56b4b3ac 100644 --- a/x-pack/plugins/fleet/public/components/enrollment_instructions/manual/platform_selector.tsx +++ b/x-pack/plugins/fleet/public/components/platform_selector.tsx @@ -10,8 +10,8 @@ import styled from 'styled-components'; import { EuiSpacer, EuiCodeBlock, EuiButtonGroup, EuiCallOut } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import type { PLATFORM_TYPE } from '../../../hooks'; -import { PLATFORM_OPTIONS, usePlatform } from '../../../hooks'; +import type { PLATFORM_TYPE } from '../hooks'; +import { PLATFORM_OPTIONS, usePlatform } from '../hooks'; interface Props { linuxCommand: string; diff --git a/x-pack/plugins/fleet/public/mock/plugin_dependencies.ts b/x-pack/plugins/fleet/public/mock/plugin_dependencies.ts index e86503e0216db..3f5ce4a53d1f8 100644 --- a/x-pack/plugins/fleet/public/mock/plugin_dependencies.ts +++ b/x-pack/plugins/fleet/public/mock/plugin_dependencies.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { licensingMock } from '@kbn/licensing-plugin/public/mocks'; import { cloudMock } from '@kbn/cloud-plugin/public/mocks'; @@ -27,6 +28,7 @@ export const createStartDepsMock = () => { return { licensing: licensingMock.createStart(), data: dataPluginMock.createStartContract(), + unifiedSearch: unifiedSearchPluginMock.createStartContract(), navigation: navigationPluginMock.createStartContract(), customIntegrations: customIntegrationsMock.createStart(), share: sharePluginMock.createStartContract(), diff --git a/x-pack/plugins/fleet/public/mocks.ts b/x-pack/plugins/fleet/public/mocks.ts index 92b002a437649..8088f430ee81e 100644 --- a/x-pack/plugins/fleet/public/mocks.ts +++ b/x-pack/plugins/fleet/public/mocks.ts @@ -5,8 +5,14 @@ * 2.0. */ +import type { EuiTheme } from '@kbn/kibana-react-plugin/common'; +import type { RecursivePartial } from '@elastic/eui/src/components/common'; + import { createStartMock } from './mock'; +export const getMockTheme = (partialTheme: RecursivePartial): EuiTheme => + partialTheme as EuiTheme; + export const fleetMock = { createStartMock, }; diff --git a/x-pack/plugins/fleet/public/plugin.ts b/x-pack/plugins/fleet/public/plugin.ts index b84562098fc76..34fa9d2cbcfc8 100644 --- a/x-pack/plugins/fleet/public/plugin.ts +++ b/x-pack/plugins/fleet/public/plugin.ts @@ -41,14 +41,22 @@ import type { LicensingPluginStart } from '@kbn/licensing-plugin/public'; import type { CloudSetup } from '@kbn/cloud-plugin/public'; import type { GlobalSearchPluginSetup } from '@kbn/global-search-plugin/public'; +import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; + import { PLUGIN_ID, INTEGRATIONS_PLUGIN_ID, setupRouteService, appRoutesService, calculateAuthz, + parseExperimentalConfigValue, +} from '../common'; +import type { + CheckPermissionsResponse, + PostFleetSetupResponse, + FleetAuthz, + ExperimentalFeatures, } from '../common'; -import type { CheckPermissionsResponse, PostFleetSetupResponse, FleetAuthz } from '../common'; import type { FleetConfigType } from '../common/types'; @@ -58,6 +66,7 @@ import { setHttpClient } from './hooks/use_request'; import { createPackageSearchProvider } from './search_provider'; import { TutorialDirectoryHeaderLink, TutorialModuleNotice } from './components/home_integration'; import { createExtensionRegistrationCallback } from './services/ui_extensions'; +import { ExperimentalFeaturesService } from './services/experimental_features'; import type { UIExtensionRegistrationCallback, UIExtensionsStorage } from './types'; import { LazyCustomLogsAssetsExtension } from './lazy_custom_logs_assets_extension'; @@ -92,6 +101,7 @@ export interface FleetSetupDeps { export interface FleetStartDeps { licensing: LicensingPluginStart; data: DataPublicPluginStart; + unifiedSearch: UnifiedSearchPublicPluginStart; navigation: NavigationPublicPluginStart; customIntegrations: CustomIntegrationsStart; share: SharePluginStart; @@ -110,10 +120,12 @@ export class FleetPlugin implements Plugin(); + this.experimentalFeatures = parseExperimentalConfigValue(this.config.enableExperimental || []); this.kibanaVersion = initializerContext.env.packageInfo.version; } @@ -248,6 +260,7 @@ export class FleetPlugin implements Plugin core.http.get(appRoutesService.getCheckPermissionsPath()) diff --git a/x-pack/plugins/fleet/public/services/experimental_features.ts b/x-pack/plugins/fleet/public/services/experimental_features.ts new file mode 100644 index 0000000000000..afe5d0d65e3fd --- /dev/null +++ b/x-pack/plugins/fleet/public/services/experimental_features.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ExperimentalFeatures } from '../../common/experimental_features'; + +export class ExperimentalFeaturesService { + private static experimentalFeatures?: ExperimentalFeatures; + + public static init(experimentalFeatures: ExperimentalFeatures) { + this.experimentalFeatures = experimentalFeatures; + } + + public static get(): ExperimentalFeatures { + if (!this.experimentalFeatures) { + this.throwUninitializedError(); + } + + return this.experimentalFeatures; + } + + private static throwUninitializedError(): never { + throw new Error('Experimental features services not initialized'); + } +} diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/services/has_fleet_server.ts b/x-pack/plugins/fleet/public/services/has_fleet_server.ts similarity index 79% rename from x-pack/plugins/fleet/public/applications/fleet/sections/agents/services/has_fleet_server.ts rename to x-pack/plugins/fleet/public/services/has_fleet_server.ts index c10049303234c..e1100d6447aa2 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/services/has_fleet_server.ts +++ b/x-pack/plugins/fleet/public/services/has_fleet_server.ts @@ -5,8 +5,8 @@ * 2.0. */ -import type { AgentPolicy, PackagePolicy } from '../../../types'; -import { FLEET_SERVER_PACKAGE } from '../../../constants'; +import { FLEET_SERVER_PACKAGE } from '../constants'; +import type { AgentPolicy, PackagePolicy } from '../types'; export function policyHasFleetServer(agentPolicy: AgentPolicy) { return agentPolicy.package_policies?.some( diff --git a/x-pack/plugins/fleet/public/services/index.ts b/x-pack/plugins/fleet/public/services/index.ts index 306b081dce6c4..2c1bedeaef82c 100644 --- a/x-pack/plugins/fleet/public/services/index.ts +++ b/x-pack/plugins/fleet/public/services/index.ts @@ -12,6 +12,7 @@ export type { PackagePolicyConfigValidationResults, PackagePolicyInputValidationResults, } from '../../common'; +export { ExperimentalFeaturesService } from './experimental_features'; export { AgentStatusKueryHelper, agentPolicyRouteService, @@ -44,3 +45,4 @@ export { export * from './pkg_key_from_package_info'; export * from './ui_extensions'; export * from './increment_policy_name'; +export * from './has_fleet_server'; diff --git a/x-pack/plugins/fleet/server/index.ts b/x-pack/plugins/fleet/server/index.ts index 3228c03959322..97ff8ade05859 100644 --- a/x-pack/plugins/fleet/server/index.ts +++ b/x-pack/plugins/fleet/server/index.ts @@ -11,6 +11,9 @@ import { schema } from '@kbn/config-schema'; import type { TypeOf } from '@kbn/config-schema'; import type { PluginConfigDescriptor, PluginInitializerContext } from '@kbn/core/server'; +import { getExperimentalAllowedValues, isValidExperimentalValue } from '../common'; +const allowedExperimentalValues = getExperimentalAllowedValues(); + import { PreconfiguredPackagesSchema, PreconfiguredAgentPoliciesSchema, @@ -139,6 +142,27 @@ export const config: PluginConfigDescriptor = { allowAgentUpgradeSourceUri: schema.boolean({ defaultValue: false }), bundledPackageLocation: schema.string({ defaultValue: DEFAULT_BUNDLED_PACKAGE_LOCATION }), }), + /** + * For internal use. A list of string values (comma delimited) that will enable experimental + * type of functionality that is not yet released. + * + * @example + * xpack.fleet.enableExperimental: + * - feature1 + * - feature2 + */ + enableExperimental: schema.arrayOf(schema.string(), { + defaultValue: () => [], + validate(list) { + for (const key of list) { + if (!isValidExperimentalValue(key)) { + return `[${key}] is not allowed. Allowed values are: ${allowedExperimentalValues.join( + ', ' + )}`; + } + } + }, + }), }), }; diff --git a/x-pack/plugins/fleet/server/mocks/index.ts b/x-pack/plugins/fleet/server/mocks/index.ts index 8fd23dfbbac83..f3423fb3f1c0f 100644 --- a/x-pack/plugins/fleet/server/mocks/index.ts +++ b/x-pack/plugins/fleet/server/mocks/index.ts @@ -22,7 +22,7 @@ import type { PackagePolicyServiceInterface } from '../services/package_policy'; import type { AgentPolicyServiceInterface } from '../services'; import type { FleetAppContext } from '../plugin'; import { createMockTelemetryEventsSender } from '../telemetry/__mocks__'; -import type { FleetConfigType } from '../../common'; +import type { FleetConfigType, ExperimentalFeatures } from '../../common'; import { createFleetAuthzMock } from '../../common'; import { agentServiceMock } from '../services/agents/agent_service.mock'; import type { FleetRequestHandlerContext } from '../types'; @@ -61,6 +61,7 @@ export const createAppContextStartContractMock = ( securitySetup: securityMock.createSetup(), securityStart: securityMock.createStart(), logger: loggingSystemMock.create().get(), + experimentalFeatures: {} as ExperimentalFeatures, isProductionMode: true, configInitialValue: { agents: { enabled: true, elasticsearch: {} }, @@ -75,7 +76,7 @@ export const createAppContextStartContractMock = ( }; export const createFleetRequestHandlerContextMock = (): jest.Mocked< - FleetRequestHandlerContext['fleet'] + Awaited > => { return { authz: createFleetAuthzMock(), diff --git a/x-pack/plugins/fleet/server/plugin.ts b/x-pack/plugins/fleet/server/plugin.ts index 20d55409e50d2..ea38068a7613c 100644 --- a/x-pack/plugins/fleet/server/plugin.ts +++ b/x-pack/plugins/fleet/server/plugin.ts @@ -42,8 +42,8 @@ import type { CloudSetup } from '@kbn/cloud-plugin/server'; import type { SpacesPluginStart } from '@kbn/spaces-plugin/server'; -import type { FleetConfigType, FleetAuthz } from '../common'; -import { INTEGRATIONS_PLUGIN_ID } from '../common'; +import type { FleetConfigType, FleetAuthz, ExperimentalFeatures } from '../common'; +import { INTEGRATIONS_PLUGIN_ID, parseExperimentalConfigValue } from '../common'; import { PLUGIN_ID, @@ -119,6 +119,7 @@ export interface FleetAppContext { securityStart: SecurityPluginStart; config$?: Observable; configInitialValue: FleetConfigType; + experimentalFeatures: ExperimentalFeatures; savedObjects: SavedObjectsServiceStart; isProductionMode: PluginInitializerContext['env']['mode']['prod']; kibanaVersion: PluginInitializerContext['env']['packageInfo']['version']; @@ -319,12 +320,11 @@ export class FleetPlugin PLUGIN_ID, async (context, request) => { const plugin = this; + const esClient = (await context.core).elasticsearch.client; return { get agentClient() { - const agentService = plugin.setupAgentService( - context.core.elasticsearch.client.asInternalUser - ); + const agentService = plugin.setupAgentService(esClient.asInternalUser); return { asCurrentUser: agentService.asScoped(request), @@ -382,6 +382,7 @@ export class FleetPlugin this.telemetryEventsSender.setup(deps.telemetry); } + public start(core: CoreStart, plugins: FleetStartDeps): FleetStartContract { appContextService.start({ elasticsearch: core.elasticsearch, @@ -392,6 +393,9 @@ export class FleetPlugin securityStart: plugins.security, configInitialValue: this.configInitialValue, config$: this.config$, + experimentalFeatures: parseExperimentalConfigValue( + this.configInitialValue.enableExperimental || [] + ), savedObjects: core.savedObjects, isProductionMode: this.isProductionMode, kibanaVersion: this.kibanaVersion, diff --git a/x-pack/plugins/fleet/server/routes/agent/actions_handlers.ts b/x-pack/plugins/fleet/server/routes/agent/actions_handlers.ts index 265fe4d9e4221..4f3cad9edab26 100644 --- a/x-pack/plugins/fleet/server/routes/agent/actions_handlers.ts +++ b/x-pack/plugins/fleet/server/routes/agent/actions_handlers.ts @@ -24,7 +24,7 @@ export const postNewAgentActionHandlerBuilder = function ( > { return async (context, request, response) => { try { - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; const agent = await actionsService.getAgent(esClient, request.params.agentId); diff --git a/x-pack/plugins/fleet/server/routes/agent/handlers.ts b/x-pack/plugins/fleet/server/routes/agent/handlers.ts index b0c6a975dfead..b9e82e844e81b 100644 --- a/x-pack/plugins/fleet/server/routes/agent/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/agent/handlers.ts @@ -32,8 +32,9 @@ import * as AgentService from '../../services/agents'; export const getAgentHandler: RequestHandler< TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { const body: GetOneAgentResponse = { @@ -55,7 +56,8 @@ export const getAgentHandler: RequestHandler< export const deleteAgentHandler: RequestHandler< TypeOf > = async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { await AgentService.deleteAgent(esClient, request.params.agentId); @@ -82,7 +84,8 @@ export const updateAgentHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { await AgentService.updateAgent(esClient, request.params.agentId, { @@ -108,7 +111,8 @@ export const getAgentsHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { const { agents, total, page, perPage } = await AgentService.getAgentsByKuery(esClient, { @@ -143,8 +147,9 @@ export const putAgentsReassignHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { await AgentService.reassignAgent( soClient, @@ -172,8 +177,9 @@ export const postBulkAgentsReassignHandler: RequestHandler< }); } - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; const agentOptions = Array.isArray(request.body.agents) ? { agentIds: request.body.agents } : { kuery: request.body.agents }; @@ -204,7 +210,8 @@ export const getAgentStatusForAgentPolicyHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { const results = await AgentService.getAgentStatusForAgentPolicy( esClient, @@ -224,7 +231,8 @@ export const getAgentDataHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asCurrentUser; + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asCurrentUser; try { let items; diff --git a/x-pack/plugins/fleet/server/routes/agent/unenroll_handler.ts b/x-pack/plugins/fleet/server/routes/agent/unenroll_handler.ts index 57752ae5caf6e..f9d27ff71ed9d 100644 --- a/x-pack/plugins/fleet/server/routes/agent/unenroll_handler.ts +++ b/x-pack/plugins/fleet/server/routes/agent/unenroll_handler.ts @@ -25,8 +25,9 @@ export const postAgentUnenrollHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { await AgentService.unenrollAgent(soClient, esClient, request.params.agentId, { force: request.body?.force, @@ -52,8 +53,9 @@ export const postBulkAgentsUnenrollHandler: RequestHandler< }); } - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; const agentOptions = Array.isArray(request.body.agents) ? { agentIds: request.body.agents } : { kuery: request.body.agents }; diff --git a/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts b/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts index dd33752574690..13df9222c9524 100644 --- a/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts +++ b/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts @@ -22,8 +22,9 @@ export const postAgentUpgradeHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; const { version, source_uri: sourceUri, force } = request.body; const kibanaVersion = appContextService.getKibanaVersion(); try { @@ -77,8 +78,9 @@ export const postBulkAgentsUpgradeHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; const { version, source_uri: sourceUri, agents, force } = request.body; const kibanaVersion = appContextService.getKibanaVersion(); try { diff --git a/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts b/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts index 34dc29d89e6c4..7b6c2dce0ef04 100644 --- a/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts @@ -45,8 +45,10 @@ export const getAgentPoliciesHandler: FleetRequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.fleet.epm.internalSoClient; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const fleetContext = await context.fleet; + const soClient = fleetContext.epm.internalSoClient; + const esClient = coreContext.elasticsearch.client.asInternalUser; const { full: withPackagePolicies = false, ...restOfQuery } = request.query; try { const { items, total, page, perPage } = await agentPolicyService.list(soClient, { @@ -81,7 +83,8 @@ export const getAgentPoliciesHandler: FleetRequestHandler< export const getOneAgentPolicyHandler: RequestHandler< TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; try { const agentPolicy = await agentPolicyService.get(soClient, request.params.agentPolicyId); if (agentPolicy) { @@ -107,13 +110,15 @@ export const createAgentPolicyHandler: FleetRequestHandler< TypeOf, TypeOf > = async (context, request, response) => { - const soClient = context.fleet.epm.internalSoClient; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const fleetContext = await context.fleet; + const soClient = fleetContext.epm.internalSoClient; + const esClient = coreContext.elasticsearch.client.asInternalUser; const user = (await appContextService.getSecurity()?.authc.getCurrentUser(request)) || undefined; const withSysMonitoring = request.query.sys_monitoring ?? false; const monitoringEnabled = request.body.monitoring_enabled; const { has_fleet_server: hasFleetServer, ...newPolicy } = request.body; - const spaceId = context.fleet.spaceId; + const spaceId = fleetContext.spaceId; try { const body: CreateAgentPolicyResponse = { item: await createAgentPolicyWithPackages({ @@ -141,8 +146,9 @@ export const updateAgentPolicyHandler: RequestHandler< unknown, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; const user = await appContextService.getSecurity()?.authc.getCurrentUser(request); const { force, ...data } = request.body; try { @@ -170,8 +176,9 @@ export const copyAgentPolicyHandler: RequestHandler< unknown, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; const user = await appContextService.getSecurity()?.authc.getCurrentUser(request); try { const agentPolicy = await agentPolicyService.copy( @@ -198,8 +205,9 @@ export const deleteAgentPoliciesHandler: RequestHandler< unknown, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { const body: DeleteAgentPolicyResponse = await agentPolicyService.delete( soClient, @@ -218,7 +226,8 @@ export const getFullAgentPolicy: FleetRequestHandler< TypeOf, TypeOf > = async (context, request, response) => { - const soClient = context.fleet.epm.internalSoClient; + const fleetContext = await context.fleet; + const soClient = fleetContext.epm.internalSoClient; if (request.query.kubernetes === true) { try { @@ -273,7 +282,8 @@ export const downloadFullAgentPolicy: FleetRequestHandler< TypeOf, TypeOf > = async (context, request, response) => { - const soClient = context.fleet.epm.internalSoClient; + const fleetContext = await context.fleet; + const soClient = fleetContext.epm.internalSoClient; const { params: { agentPolicyId }, } = request; diff --git a/x-pack/plugins/fleet/server/routes/app/index.ts b/x-pack/plugins/fleet/server/routes/app/index.ts index fa4841c50e5bf..9afa422d2511e 100644 --- a/x-pack/plugins/fleet/server/routes/app/index.ts +++ b/x-pack/plugins/fleet/server/routes/app/index.ts @@ -28,7 +28,8 @@ export const getCheckPermissionsHandler: FleetRequestHandler< if (!appContextService.getSecurityLicense().isEnabled()) { return response.ok({ body: missingSecurityBody }); } else { - if (!context.fleet.authz.fleet.all) { + const fleetContext = await context.fleet; + if (!fleetContext.authz.fleet.all) { return response.ok({ body: { success: false, @@ -38,7 +39,7 @@ export const getCheckPermissionsHandler: FleetRequestHandler< } // check the manage_service_account cluster privilege else if (request.query.fleetServerSetup) { - const esClient = context.core.elasticsearch.client.asCurrentUser; + const esClient = (await context.core).elasticsearch.client.asCurrentUser; const { has_all_requested: hasAllPrivileges } = await esClient.security.hasPrivileges({ body: { cluster: ['manage_service_account'] }, }); @@ -59,7 +60,7 @@ export const getCheckPermissionsHandler: FleetRequestHandler< export const generateServiceTokenHandler: RequestHandler = async (context, request, response) => { // Generate the fleet server service token as the current user as the internal user do not have the correct permissions - const esClient = context.core.elasticsearch.client.asCurrentUser; + const esClient = (await context.core).elasticsearch.client.asCurrentUser; try { const tokenResponse = await esClient.transport.request<{ created?: boolean; diff --git a/x-pack/plugins/fleet/server/routes/data_streams/handlers.ts b/x-pack/plugins/fleet/server/routes/data_streams/handlers.ts index d7081a91453f9..2d01344a930aa 100644 --- a/x-pack/plugins/fleet/server/routes/data_streams/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/data_streams/handlers.ts @@ -39,7 +39,8 @@ interface ESDataStreamInfo { export const getListHandler: RequestHandler = async (context, request, response) => { // Query datastreams as the current user as the Kibana internal user may not have all the required permission - const esClient = context.core.elasticsearch.client.asCurrentUser; + const { savedObjects, elasticsearch } = await context.core; + const esClient = elasticsearch.client.asCurrentUser; const body: GetDataStreamsResponse = { data_streams: [], @@ -54,7 +55,7 @@ export const getListHandler: RequestHandler = async (context, request, response) ] = await Promise.all([ esClient.indices.getDataStream({ name: DATA_STREAM_INDEX_PATTERN }), esClient.indices.dataStreamsStats({ name: DATA_STREAM_INDEX_PATTERN, human: true }), - getPackageSavedObjects(context.core.savedObjects.client), + getPackageSavedObjects(savedObjects.client), ]); const dataStreamsInfoByName = keyBy(dataStreamsInfo, 'name'); @@ -81,7 +82,7 @@ export const getListHandler: RequestHandler = async (context, request, response) allDashboards[pkgSavedObject.id] = dashboards; return allDashboards; }, {}); - const allDashboardSavedObjectsResponse = await context.core.savedObjects.client.bulkGet<{ + const allDashboardSavedObjectsResponse = await savedObjects.client.bulkGet<{ title?: string; }>( Object.values(dashboardIdsByPackageName).flatMap((dashboardIds) => diff --git a/x-pack/plugins/fleet/server/routes/enrollment_api_key/handler.ts b/x-pack/plugins/fleet/server/routes/enrollment_api_key/handler.ts index 1dc088cfe9a3e..613bf1ad99be9 100644 --- a/x-pack/plugins/fleet/server/routes/enrollment_api_key/handler.ts +++ b/x-pack/plugins/fleet/server/routes/enrollment_api_key/handler.ts @@ -29,7 +29,7 @@ export const getEnrollmentApiKeysHandler: RequestHandler< TypeOf > = async (context, request, response) => { // Use kibana_system and depend on authz checks on HTTP layer to prevent abuse - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; try { const { items, total, page, perPage } = await APIKeyService.listEnrollmentApiKeys(esClient, { @@ -55,8 +55,9 @@ export const postEnrollmentApiKeyHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const { elasticsearch, savedObjects } = await context.core; + const soClient = savedObjects.client; + const esClient = elasticsearch.client.asInternalUser; try { // validate policy id await agentPolicyService.get(soClient, request.body.policy_id).catch((err) => { @@ -84,7 +85,7 @@ export const postEnrollmentApiKeyHandler: RequestHandler< export const deleteEnrollmentApiKeyHandler: RequestHandler< TypeOf > = async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; try { await APIKeyService.deleteEnrollmentApiKey(esClient, request.params.keyId); @@ -105,7 +106,7 @@ export const getOneEnrollmentApiKeyHandler: RequestHandler< TypeOf > = async (context, request, response) => { // Use kibana_system and depend on authz checks on HTTP layer to prevent abuse - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; try { const apiKey = await APIKeyService.getEnrollmentAPIKey(esClient, request.params.keyId); const body: GetOneEnrollmentAPIKeyResponse = { item: apiKey }; diff --git a/x-pack/plugins/fleet/server/routes/epm/handlers.ts b/x-pack/plugins/fleet/server/routes/epm/handlers.ts index 62a9661c328ab..38c5042b6987e 100644 --- a/x-pack/plugins/fleet/server/routes/epm/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/epm/handlers.ts @@ -10,7 +10,7 @@ import path from 'path'; import type { TypeOf } from '@kbn/config-schema'; import mime from 'mime-types'; import semverValid from 'semver/functions/valid'; -import type { ResponseHeaders, KnownHeaders } from '@kbn/core/server'; +import type { ResponseHeaders, KnownHeaders, HttpResponseOptions } from '@kbn/core/server'; import type { GetInfoResponse, @@ -43,7 +43,7 @@ import { getCategories, getPackages, getFile, - getPackageInfoFromRegistry, + getPackageInfo, isBulkInstallError, installPackage, removeInstallation, @@ -62,6 +62,10 @@ import { getAsset } from '../../services/epm/archive/storage'; import { getPackageUsageStats } from '../../services/epm/packages/get'; import { updatePackage } from '../../services/epm/packages/update'; +const CACHE_CONTROL_10_MINUTES_HEADER: HttpResponseOptions['headers'] = { + 'cache-control': 'max-age=600', +}; + export const getCategoriesHandler: FleetRequestHandler< undefined, TypeOf @@ -72,7 +76,7 @@ export const getCategoriesHandler: FleetRequestHandler< items: res, response: res, }; - return response.ok({ body }); + return response.ok({ body, headers: { ...CACHE_CONTROL_10_MINUTES_HEADER } }); } catch (error) { return defaultIngestErrorHandler({ error, response }); } @@ -83,7 +87,7 @@ export const getListHandler: FleetRequestHandler< TypeOf > = async (context, request, response) => { try { - const savedObjectsClient = context.fleet.epm.internalSoClient; + const savedObjectsClient = (await context.fleet).epm.internalSoClient; const res = await getPackages({ savedObjectsClient, ...request.query, @@ -94,6 +98,9 @@ export const getListHandler: FleetRequestHandler< }; return response.ok({ body, + // Only cache responses where the installation status is excluded, otherwise the request + // needs up-to-date information on whether the package is installed so we can't cache it + headers: request.query.excludeInstallStatus ? { ...CACHE_CONTROL_10_MINUTES_HEADER } : {}, }); } catch (error) { return defaultIngestErrorHandler({ error, response }); @@ -102,7 +109,7 @@ export const getListHandler: FleetRequestHandler< export const getLimitedListHandler: FleetRequestHandler = async (context, request, response) => { try { - const savedObjectsClient = context.fleet.epm.internalSoClient; + const savedObjectsClient = (await context.fleet).epm.internalSoClient; const res = await getLimitedPackages({ savedObjectsClient }); const body: GetLimitedPackagesResponse = { items: res, @@ -121,7 +128,7 @@ export const getFileHandler: FleetRequestHandler< > = async (context, request, response) => { try { const { pkgName, pkgVersion, filePath } = request.params; - const savedObjectsClient = context.fleet.epm.internalSoClient; + const savedObjectsClient = (await context.fleet).epm.internalSoClient; const installation = await getInstallation({ savedObjectsClient, pkgName }); const useLocalFile = pkgVersion === installation?.version; @@ -164,13 +171,13 @@ export const getFileHandler: FleetRequestHandler< body: buffer, statusCode: 200, headers: { - 'cache-control': 'max-age=10, public', + ...CACHE_CONTROL_10_MINUTES_HEADER, 'content-type': contentType, }, }); } else { const registryResponse = await getFile(pkgName, pkgVersion, filePath); - const headersToProxy: KnownHeaders[] = ['content-type', 'cache-control']; + const headersToProxy: KnownHeaders[] = ['content-type']; const proxiedHeaders = headersToProxy.reduce((headers, knownHeader) => { const value = registryResponse.headers.get(knownHeader); if (value !== null) { @@ -182,7 +189,7 @@ export const getFileHandler: FleetRequestHandler< return response.custom({ body: registryResponse.body, statusCode: registryResponse.status, - headers: proxiedHeaders, + headers: { ...CACHE_CONTROL_10_MINUTES_HEADER, ...proxiedHeaders }, }); } } catch (error) { @@ -194,15 +201,16 @@ export const getInfoHandler: FleetRequestHandler< TypeOf > = async (context, request, response) => { try { - const savedObjectsClient = context.fleet.epm.internalSoClient; + const savedObjectsClient = (await context.fleet).epm.internalSoClient; const { pkgName, pkgVersion } = request.params; if (pkgVersion && !semverValid(pkgVersion)) { throw new IngestManagerError('Package version is not a valid semver'); } - const res = await getPackageInfoFromRegistry({ + const res = await getPackageInfo({ savedObjectsClient, pkgName, pkgVersion: pkgVersion || '', + skipArchive: true, }); const body: GetInfoResponse = { item: res, @@ -219,7 +227,7 @@ export const updatePackageHandler: FleetRequestHandler< TypeOf > = async (context, request, response) => { try { - const savedObjectsClient = context.fleet.epm.internalSoClient; + const savedObjectsClient = (await context.fleet).epm.internalSoClient; const { pkgName } = request.params; const res = await updatePackage({ savedObjectsClient, pkgName, ...request.body }); @@ -238,7 +246,7 @@ export const getStatsHandler: FleetRequestHandler< > = async (context, request, response) => { try { const { pkgName } = request.params; - const savedObjectsClient = context.fleet.epm.internalSoClient; + const savedObjectsClient = (await context.fleet).epm.internalSoClient; const body: GetStatsResponse = { response: await getPackageUsageStats({ savedObjectsClient, pkgName }), }; @@ -253,11 +261,13 @@ export const installPackageFromRegistryHandler: FleetRequestHandler< undefined, TypeOf > = async (context, request, response) => { - const savedObjectsClient = context.fleet.epm.internalSoClient; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const fleetContext = await context.fleet; + const savedObjectsClient = fleetContext.epm.internalSoClient; + const esClient = coreContext.elasticsearch.client.asInternalUser; const { pkgName, pkgVersion } = request.params; - const spaceId = context.fleet.spaceId; + const spaceId = fleetContext.spaceId; const res = await installPackage({ installSource: 'registry', savedObjectsClient, @@ -301,9 +311,11 @@ export const bulkInstallPackagesFromRegistryHandler: FleetRequestHandler< undefined, TypeOf > = async (context, request, response) => { - const savedObjectsClient = context.fleet.epm.internalSoClient; - const esClient = context.core.elasticsearch.client.asInternalUser; - const spaceId = context.fleet.spaceId; + const coreContext = await context.core; + const fleetContext = await context.fleet; + const savedObjectsClient = fleetContext.epm.internalSoClient; + const esClient = coreContext.elasticsearch.client.asInternalUser; + const spaceId = fleetContext.spaceId; const bulkInstalledResponses = await bulkInstallPackages({ savedObjectsClient, esClient, @@ -329,11 +341,13 @@ export const installPackageByUploadHandler: FleetRequestHandler< body: { message: 'Requires Enterprise license' }, }); } - const savedObjectsClient = context.fleet.epm.internalSoClient; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const fleetContext = await context.fleet; + const savedObjectsClient = fleetContext.epm.internalSoClient; + const esClient = coreContext.elasticsearch.client.asInternalUser; const contentType = request.headers['content-type'] as string; // from types it could also be string[] or undefined but this is checked later const archiveBuffer = Buffer.from(request.body); - const spaceId = context.fleet.spaceId; + const spaceId = fleetContext.spaceId; const res = await installPackage({ installSource: 'upload', savedObjectsClient, @@ -363,8 +377,10 @@ export const deletePackageHandler: FleetRequestHandler< > = async (context, request, response) => { try { const { pkgName, pkgVersion } = request.params; - const savedObjectsClient = context.fleet.epm.internalSoClient; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const fleetContext = await context.fleet; + const savedObjectsClient = fleetContext.epm.internalSoClient; + const esClient = coreContext.elasticsearch.client.asInternalUser; const res = await removeInstallation({ savedObjectsClient, pkgName, diff --git a/x-pack/plugins/fleet/server/routes/output/handler.ts b/x-pack/plugins/fleet/server/routes/output/handler.ts index 7f97477d89306..a995a3eeb41dc 100644 --- a/x-pack/plugins/fleet/server/routes/output/handler.ts +++ b/x-pack/plugins/fleet/server/routes/output/handler.ts @@ -26,7 +26,7 @@ import { agentPolicyService } from '../../services'; import { generateLogstashApiKey, canCreateLogstashApiKey } from '../../services/api_keys'; export const getOutputsHandler: RequestHandler = async (context, request, response) => { - const soClient = context.core.savedObjects.client; + const soClient = (await context.core).savedObjects.client; try { const outputs = await outputService.list(soClient); @@ -46,7 +46,7 @@ export const getOutputsHandler: RequestHandler = async (context, request, respon export const getOneOuputHandler: RequestHandler< TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; + const soClient = (await context.core).savedObjects.client; try { const output = await outputService.get(soClient, request.params.outputId); @@ -71,8 +71,9 @@ export const putOuputHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { await outputService.update(soClient, request.params.outputId, request.body); const output = await outputService.get(soClient, request.params.outputId); @@ -103,8 +104,9 @@ export const postOuputHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { const { id, ...data } = request.body; const output = await outputService.create(soClient, data, { id }); @@ -125,7 +127,7 @@ export const postOuputHandler: RequestHandler< export const deleteOutputHandler: RequestHandler< TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; + const soClient = (await context.core).savedObjects.client; try { await outputService.delete(soClient, request.params.outputId); @@ -146,7 +148,7 @@ export const deleteOutputHandler: RequestHandler< }; export const postLogstashApiKeyHandler: RequestHandler = async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asCurrentUser; + const esClient = (await context.core).elasticsearch.client.asCurrentUser; try { const hasCreatePrivileges = await canCreateLogstashApiKey(esClient); if (!hasCreatePrivileges) { diff --git a/x-pack/plugins/fleet/server/routes/package_policy/handlers.test.ts b/x-pack/plugins/fleet/server/routes/package_policy/handlers.test.ts index 1041dcc0579aa..222408c6e0524 100644 --- a/x-pack/plugins/fleet/server/routes/package_policy/handlers.test.ts +++ b/x-pack/plugins/fleet/server/routes/package_policy/handlers.test.ts @@ -85,7 +85,7 @@ jest.mock( jest.mock('../../services/epm/packages', () => { return { ensureInstalledPackage: jest.fn(() => Promise.resolve()), - getPackageInfoFromRegistry: jest.fn(() => Promise.resolve()), + getPackageInfo: jest.fn(() => Promise.resolve()), }; }); @@ -93,7 +93,7 @@ describe('When calling package policy', () => { let routerMock: jest.Mocked; let routeHandler: FleetRequestHandler; let routeConfig: RouteConfig; - let context: jest.Mocked; + let context: FleetRequestHandlerContext; let response: ReturnType; beforeEach(() => { diff --git a/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts b/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts index e0dc77fc57dcb..ad46f25ff91de 100644 --- a/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts @@ -35,7 +35,7 @@ export const getPackagePoliciesHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; + const soClient = (await context.core).savedObjects.client; try { const { items, total, page, perPage } = await packagePolicyService.list( soClient, @@ -57,7 +57,7 @@ export const getPackagePoliciesHandler: RequestHandler< export const getOnePackagePolicyHandler: RequestHandler< TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; + const soClient = (await context.core).savedObjects.client; const { packagePolicyId } = request.params; const notFoundResponse = () => response.notFound({ body: { message: `Package policy ${packagePolicyId} not found` } }); @@ -87,11 +87,13 @@ export const createPackagePolicyHandler: FleetRequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.fleet.epm.internalSoClient; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const fleetContext = await context.fleet; + const soClient = fleetContext.epm.internalSoClient; + const esClient = coreContext.elasticsearch.client.asInternalUser; const user = appContextService.getSecurity()?.authc.getCurrentUser(request) || undefined; const { force, ...newPolicy } = request.body; - const spaceId = context.fleet.spaceId; + const spaceId = fleetContext.spaceId; try { const newPackagePolicy = await packagePolicyService.enrichPolicyWithDefaultsFromPackage( soClient, @@ -140,8 +142,9 @@ export const updatePackagePolicyHandler: RequestHandler< unknown, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; const user = appContextService.getSecurity()?.authc.getCurrentUser(request) || undefined; const packagePolicy = await packagePolicyService.get(soClient, request.params.packagePolicyId); @@ -206,8 +209,9 @@ export const deletePackagePolicyHandler: RequestHandler< unknown, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; const user = appContextService.getSecurity()?.authc.getCurrentUser(request) || undefined; try { const body: DeletePackagePoliciesResponse = await packagePolicyService.delete( @@ -241,8 +245,9 @@ export const upgradePackagePolicyHandler: RequestHandler< unknown, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; const user = appContextService.getSecurity()?.authc.getCurrentUser(request) || undefined; try { const body: UpgradePackagePolicyResponse = await packagePolicyService.upgrade( @@ -273,7 +278,7 @@ export const dryRunUpgradePackagePolicyHandler: RequestHandler< unknown, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; + const soClient = (await context.core).savedObjects.client; try { const body: UpgradePackagePolicyDryRunResponse = []; const { packagePolicyIds } = request.body; diff --git a/x-pack/plugins/fleet/server/routes/preconfiguration/handler.ts b/x-pack/plugins/fleet/server/routes/preconfiguration/handler.ts index aa9d6acbbc472..bd0ed690ec6fe 100644 --- a/x-pack/plugins/fleet/server/routes/preconfiguration/handler.ts +++ b/x-pack/plugins/fleet/server/routes/preconfiguration/handler.ts @@ -23,10 +23,12 @@ export const updatePreconfigurationHandler: FleetRequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const fleetContext = await context.fleet; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; const defaultOutput = await outputService.ensureDefaultOutput(soClient); - const spaceId = context.fleet.spaceId; + const spaceId = fleetContext.spaceId; const { agentPolicies, packages } = request.body; try { @@ -49,8 +51,9 @@ export const resetOnePreconfigurationHandler: FleetRequestHandler< undefined, undefined > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { await resetPreconfiguredAgentPolicies(soClient, esClient, request.params.agentPolicyId); @@ -65,8 +68,9 @@ export const resetPreconfigurationHandler: FleetRequestHandler< undefined, undefined > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { await resetPreconfiguredAgentPolicies(soClient, esClient); diff --git a/x-pack/plugins/fleet/server/routes/settings/index.ts b/x-pack/plugins/fleet/server/routes/settings/index.ts index a6203de097c7b..07bd3342ade1d 100644 --- a/x-pack/plugins/fleet/server/routes/settings/index.ts +++ b/x-pack/plugins/fleet/server/routes/settings/index.ts @@ -15,7 +15,7 @@ import { settingsService, agentPolicyService, appContextService } from '../../se import type { FleetAuthzRouter } from '../security'; export const getSettingsHandler: FleetRequestHandler = async (context, request, response) => { - const soClient = context.fleet.epm.internalSoClient; + const soClient = (await context.fleet).epm.internalSoClient; try { const settings = await settingsService.getSettings(soClient); @@ -39,8 +39,8 @@ export const putSettingsHandler: FleetRequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.fleet.epm.internalSoClient; - const esClient = context.core.elasticsearch.client.asInternalUser; + const soClient = (await context.fleet).epm.internalSoClient; + const esClient = (await context.core).elasticsearch.client.asInternalUser; const user = await appContextService.getSecurity()?.authc.getCurrentUser(request); try { diff --git a/x-pack/plugins/fleet/server/routes/setup/handlers.test.ts b/x-pack/plugins/fleet/server/routes/setup/handlers.test.ts index 971684daff650..400c18e85415b 100644 --- a/x-pack/plugins/fleet/server/routes/setup/handlers.test.ts +++ b/x-pack/plugins/fleet/server/routes/setup/handlers.test.ts @@ -5,7 +5,8 @@ * 2.0. */ -import { httpServerMock, savedObjectsClientMock } from '@kbn/core/server/mocks'; +import type { AwaitedProperties } from '@kbn/utility-types'; +import { httpServerMock, savedObjectsClientMock, coreMock } from '@kbn/core/server/mocks'; import type { PostFleetSetupResponse } from '../../../common'; import { RegistryError } from '../../errors'; @@ -29,7 +30,7 @@ jest.mock('../../services/setup', () => { const mockSetupFleet = setupFleet as jest.MockedFunction; describe('FleetSetupHandler', () => { - let context: FleetRequestHandlerContext; + let context: AwaitedProperties>; let response: ReturnType; let request: ReturnType; @@ -69,7 +70,7 @@ describe('FleetSetupHandler', () => { nonFatalErrors: [], }) ); - await fleetSetupHandler(context, request, response); + await fleetSetupHandler(coreMock.createCustomRequestHandlerContext(context), request, response); const expectedBody: PostFleetSetupResponse = { isInitialized: true, @@ -81,7 +82,7 @@ describe('FleetSetupHandler', () => { it('POST /setup fails w/500 on custom error', async () => { mockSetupFleet.mockImplementation(() => Promise.reject(new Error('SO method mocked to throw'))); - await fleetSetupHandler(context, request, response); + await fleetSetupHandler(coreMock.createCustomRequestHandlerContext(context), request, response); expect(response.customError).toHaveBeenCalledTimes(1); expect(response.customError).toHaveBeenCalledWith({ @@ -97,7 +98,7 @@ describe('FleetSetupHandler', () => { Promise.reject(new RegistryError('Registry method mocked to throw')) ); - await fleetSetupHandler(context, request, response); + await fleetSetupHandler(coreMock.createCustomRequestHandlerContext(context), request, response); expect(response.customError).toHaveBeenCalledTimes(1); expect(response.customError).toHaveBeenCalledWith({ statusCode: 502, diff --git a/x-pack/plugins/fleet/server/routes/setup/handlers.ts b/x-pack/plugins/fleet/server/routes/setup/handlers.ts index dac5828329a22..59a3516aac83a 100644 --- a/x-pack/plugins/fleet/server/routes/setup/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/setup/handlers.ts @@ -17,8 +17,9 @@ export const getFleetStatusHandler: FleetRequestHandler = async (context, reques const isApiKeysEnabled = await appContextService .getSecurity() .authc.apiKeys.areAPIKeysEnabled(); + const coreContext = await context.core; const isFleetServerSetup = await hasFleetServers( - context.core.elasticsearch.client.asInternalUser + coreContext.elasticsearch.client.asInternalUser ); const missingRequirements: GetFleetStatusResponse['missing_requirements'] = []; @@ -52,8 +53,8 @@ export const getFleetStatusHandler: FleetRequestHandler = async (context, reques export const fleetSetupHandler: FleetRequestHandler = async (context, request, response) => { try { - const soClient = context.fleet.epm.internalSoClient; - const esClient = context.core.elasticsearch.client.asInternalUser; + const soClient = (await context.fleet).epm.internalSoClient; + const esClient = (await context.core).elasticsearch.client.asInternalUser; const setupStatus = await setupFleet(soClient, esClient); const body: PostFleetSetupResponse = { ...setupStatus, diff --git a/x-pack/plugins/fleet/server/services/app_context.ts b/x-pack/plugins/fleet/server/services/app_context.ts index 71409f8d115c6..088e4d7c8b3f0 100644 --- a/x-pack/plugins/fleet/server/services/app_context.ts +++ b/x-pack/plugins/fleet/server/services/app_context.ts @@ -26,7 +26,7 @@ import type { SecurityPluginStart, SecurityPluginSetup } from '@kbn/security-plu import type { CloudSetup } from '@kbn/cloud-plugin/server'; -import type { FleetConfigType } from '../../common'; +import type { FleetConfigType, ExperimentalFeatures } from '../../common'; import type { ExternalCallback, ExternalCallbacksStorage, @@ -43,6 +43,7 @@ class AppContextService { private encryptedSavedObjectsSetup: EncryptedSavedObjectsPluginSetup | undefined; private data: DataPluginStart | undefined; private esClient: ElasticsearchClient | undefined; + private experimentalFeatures?: ExperimentalFeatures; private securitySetup: SecurityPluginSetup | undefined; private securityStart: SecurityPluginStart | undefined; private config$?: Observable; @@ -65,6 +66,7 @@ class AppContextService { this.securitySetup = appContext.securitySetup; this.securityStart = appContext.securityStart; this.savedObjects = appContext.savedObjects; + this.experimentalFeatures = appContext.experimentalFeatures; this.isProductionMode = appContext.isProductionMode; this.cloud = appContext.cloud; this.logger = appContext.logger; @@ -126,6 +128,13 @@ class AppContextService { return this.config$; } + public getExperimentalFeatures() { + if (!this.experimentalFeatures) { + throw new Error('experimentalFeatures not set.'); + } + return this.experimentalFeatures; + } + public getSavedObjects() { if (!this.savedObjects) { throw new Error('Saved objects start service not set.'); diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/default_settings.test.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/default_settings.test.ts index 1ade871b27ef6..df1c87105bcf2 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/default_settings.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/default_settings.test.ts @@ -36,6 +36,18 @@ describe('buildDefaultSettings', () => { name: 'field2Boolean', type: 'boolean', }, + { + name: 'field3Text', + type: 'text', + }, + { + name: 'field4MatchOnlyText', + type: 'match_only_text', + }, + { + name: 'field5Wildcard', + type: 'wildcard', + }, ], }); @@ -49,6 +61,9 @@ describe('buildDefaultSettings', () => { "query": Object { "default_field": Array [ "field1Keyword", + "field3Text", + "field4MatchOnlyText", + "field5Wildcard", ], }, }, diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/default_settings.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/default_settings.ts index 7f8e8e8544109..5accf7b120f9e 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/default_settings.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/default_settings.ts @@ -8,7 +8,7 @@ import { appContextService } from '../../../app_context'; import type { Field, Fields } from '../../fields/field'; -const QUERY_DEFAULT_FIELD_TYPES = ['keyword', 'text']; +const QUERY_DEFAULT_FIELD_TYPES = ['keyword', 'text', 'match_only_text', 'wildcard']; const QUERY_DEFAULT_FIELD_LIMIT = 1024; const flattenFieldsToNameAndType = ( diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/remove_legacy.test.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/remove_legacy.test.ts new file mode 100644 index 0000000000000..4877d28cbead0 --- /dev/null +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/remove_legacy.test.ts @@ -0,0 +1,262 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { + ClusterComponentTemplate, + IndicesGetIndexTemplateIndexTemplateItem, +} from '@elastic/elasticsearch/lib/api/types'; + +import type { Logger } from '@kbn/core/server'; + +import uuid from 'uuid'; + +import { loggingSystemMock } from '@kbn/core/server/mocks'; + +import type { InstallablePackage, RegistryDataStream } from '../../../../types'; + +import { + _getLegacyComponentTemplatesForPackage, + _getIndexTemplatesToUsedByMap, + _filterComponentTemplatesInUse, +} from './remove_legacy'; + +const mockLogger: Logger = loggingSystemMock.create().get(); + +const pickRandom = (arr: any[]) => arr[Math.floor(Math.random() * arr.length)]; +const pickRandomType = pickRandom.bind(null, ['logs', 'metrics']); +const createMockDataStream = ({ + packageName, + type, + dataset, +}: { + packageName: string; + type?: string; + dataset?: string; +}) => { + return { + type: type || pickRandomType(), + dataset: dataset || uuid.v4(), + title: packageName, + package: packageName, + path: 'some_path', + release: 'ga', + } as RegistryDataStream; +}; +const createMockComponentTemplate = ({ + name = 'templateName', + packageName, +}: { + name?: string; + packageName: string; +}) => { + return { + name, + component_template: { + _meta: { + package: { name: packageName }, + }, + template: { + settings: {}, + }, + }, + } as ClusterComponentTemplate; +}; + +const createMockTemplate = ({ name, composedOf = [] }: { name: string; composedOf?: string[] }) => + ({ + name, + index_template: { + composed_of: composedOf, + }, + } as IndicesGetIndexTemplateIndexTemplateItem); + +const makeArrayOf = (arraySize: number, fn = (i: any) => i) => { + return [...Array(arraySize)].map(fn); +}; +describe('_getLegacyComponentTemplatesForPackage', () => { + it('should handle empty templates array', () => { + const templates = [] as ClusterComponentTemplate[]; + const pkg = { name: 'testPkg', data_streams: [] as RegistryDataStream[] } as InstallablePackage; + + const result = _getLegacyComponentTemplatesForPackage(templates, pkg); + expect(result).toEqual([]); + }); + it('should return empty array if no legacy templates', () => { + const packageName = 'testPkg'; + const templates = makeArrayOf(1000, () => createMockComponentTemplate({ packageName })); + const pkg = { + name: packageName, + data_streams: makeArrayOf(100, () => createMockDataStream({ packageName })), + } as InstallablePackage; + + const result = _getLegacyComponentTemplatesForPackage(templates, pkg); + expect(result).toEqual([]); + }); + + it('should find legacy templates', () => { + const packageName = 'testPkg'; + const legacyTemplates = [ + 'logs-testPkg.dataset@settings', + 'logs-testPkg.dataset@mappings', + 'metrics-testPkg.dataset2@mappings', + 'metrics-testPkg.dataset2@settings', + ]; + const templates = [ + ...makeArrayOf(100, () => createMockComponentTemplate({ packageName })), + ...legacyTemplates.map((name) => createMockComponentTemplate({ name, packageName })), + ]; + const pkg = { + name: packageName, + data_streams: [ + ...makeArrayOf(20, () => createMockDataStream({ packageName })), + createMockDataStream({ type: 'logs', packageName, dataset: 'testPkg.dataset' }), + createMockDataStream({ type: 'metrics', packageName, dataset: 'testPkg.dataset2' }), + ], + } as InstallablePackage; + + const result = _getLegacyComponentTemplatesForPackage(templates, pkg); + expect(result).toEqual(legacyTemplates); + }); + + it('should only return templates if package name matches as well', () => { + const packageName = 'testPkg'; + const legacyTemplates = [ + 'logs-testPkg.dataset@settings', + 'logs-testPkg.dataset@mappings', + 'metrics-testPkg.dataset2@mappings', + 'metrics-testPkg.dataset2@settings', + ]; + const templates = [ + ...makeArrayOf(20, () => createMockComponentTemplate({ packageName })), + ...legacyTemplates.map((name) => + createMockComponentTemplate({ name, packageName: 'someOtherPkg' }) + ), + ]; + const pkg = { + name: packageName, + data_streams: [ + ...makeArrayOf(20, () => createMockDataStream({ packageName })), + createMockDataStream({ type: 'logs', packageName, dataset: 'testPkg.dataset' }), + createMockDataStream({ type: 'metrics', packageName, dataset: 'testPkg.dataset2' }), + ], + } as InstallablePackage; + + const result = _getLegacyComponentTemplatesForPackage(templates, pkg); + expect(result).toEqual([]); + }); +}); + +describe('_getIndexTemplatesToUsedByMap', () => { + it('should return empty map if no index templates provided', () => { + const indexTemplates = [] as IndicesGetIndexTemplateIndexTemplateItem[]; + + const result = _getIndexTemplatesToUsedByMap(indexTemplates); + + expect(result.size).toEqual(0); + }); + + it('should return empty map if no index templates have no component templates', () => { + const indexTemplates = [createMockTemplate({ name: 'tmpl1' })]; + + const result = _getIndexTemplatesToUsedByMap(indexTemplates); + + expect(result.size).toEqual(0); + }); + + it('should return correct map if templates have composedOf', () => { + const indexTemplates = [ + createMockTemplate({ name: 'tmpl1' }), + createMockTemplate({ name: 'tmpl2', composedOf: ['ctmp1'] }), + createMockTemplate({ name: 'tmpl3', composedOf: ['ctmp1', 'ctmp2'] }), + createMockTemplate({ name: 'tmpl4', composedOf: ['ctmp3'] }), + ]; + + const expectedMap = { + ctmp1: ['tmpl2', 'tmpl3'], + ctmp2: ['tmpl3'], + ctmp3: ['tmpl4'], + }; + + const result = _getIndexTemplatesToUsedByMap(indexTemplates); + + expect(Object.fromEntries(result)).toEqual(expectedMap); + }); +}); + +describe('_filterComponentTemplatesInUse', () => { + it('should return empty array if provided with empty component templates', () => { + const componentTemplateNames = [] as string[]; + const indexTemplates = [] as IndicesGetIndexTemplateIndexTemplateItem[]; + + const result = _filterComponentTemplatesInUse({ + componentTemplateNames, + indexTemplates, + logger: mockLogger, + }); + + expect(result).toHaveLength(0); + }); + + it('should remove component template used by index template ', () => { + const componentTemplateNames = ['ctmp1', 'ctmp2'] as string[]; + const indexTemplates = [ + createMockTemplate({ name: 'tmpl1', composedOf: ['ctmp1'] }), + ] as IndicesGetIndexTemplateIndexTemplateItem[]; + + const result = _filterComponentTemplatesInUse({ + componentTemplateNames, + indexTemplates, + logger: mockLogger, + }); + + expect(result).toEqual(['ctmp2']); + }); + it('should remove component templates used by one index template ', () => { + const componentTemplateNames = ['ctmp1', 'ctmp2', 'ctmp3'] as string[]; + const indexTemplates = [ + createMockTemplate({ name: 'tmpl1', composedOf: ['ctmp1', 'ctmp2'] }), + ] as IndicesGetIndexTemplateIndexTemplateItem[]; + + const result = _filterComponentTemplatesInUse({ + componentTemplateNames, + indexTemplates, + logger: mockLogger, + }); + + expect(result).toEqual(['ctmp3']); + }); + it('should remove component templates used by different index templates ', () => { + const componentTemplateNames = ['ctmp1', 'ctmp2', 'ctmp3'] as string[]; + const indexTemplates = [ + createMockTemplate({ name: 'tmpl1', composedOf: ['ctmp1'] }), + createMockTemplate({ name: 'tmpl2', composedOf: ['ctmp2'] }), + ] as IndicesGetIndexTemplateIndexTemplateItem[]; + + const result = _filterComponentTemplatesInUse({ + componentTemplateNames, + indexTemplates, + logger: mockLogger, + }); + + expect(result).toEqual(['ctmp3']); + }); + it('should remove component templates used by multiple index templates ', () => { + const componentTemplateNames = ['ctmp1', 'ctmp2', 'ctmp3'] as string[]; + const indexTemplates = [ + createMockTemplate({ name: 'tmpl1', composedOf: ['ctmp1', 'ctmp2'] }), + createMockTemplate({ name: 'tmpl2', composedOf: ['ctmp2', 'ctmp1'] }), + ] as IndicesGetIndexTemplateIndexTemplateItem[]; + + const result = _filterComponentTemplatesInUse({ + componentTemplateNames, + indexTemplates, + logger: mockLogger, + }); + + expect(result).toEqual(['ctmp3']); + }); +}); diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/remove_legacy.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/remove_legacy.ts new file mode 100644 index 0000000000000..44b9756edc448 --- /dev/null +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/remove_legacy.ts @@ -0,0 +1,161 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { + ClusterComponentTemplate, + IndicesGetIndexTemplateIndexTemplateItem, +} from '@elastic/elasticsearch/lib/api/types'; +import type { ElasticsearchClient, Logger } from '@kbn/core/server'; + +import type { InstallablePackage, RegistryDataStream } from '../../../../types'; +import { getRegistryDataStreamAssetBaseName } from '..'; +const LEGACY_TEMPLATE_SUFFIXES = ['@mappings', '@settings']; + +const getComponentTemplateWithSuffix = (dataStream: RegistryDataStream, suffix: string) => { + const baseName = getRegistryDataStreamAssetBaseName(dataStream); + + return baseName + suffix; +}; + +export const _getLegacyComponentTemplatesForPackage = ( + componentTemplates: ClusterComponentTemplate[], + installablePackage: InstallablePackage +): string[] => { + const legacyNamesLookup: Set = new Set(); + + // fill a map with all possible @mappings and @settings component + // template names for fast lookup below. + installablePackage.data_streams?.forEach((ds) => { + LEGACY_TEMPLATE_SUFFIXES.forEach((suffix) => { + legacyNamesLookup.add(getComponentTemplateWithSuffix(ds, suffix)); + }); + }); + + return componentTemplates.reduce((legacyTemplates, componentTemplate) => { + if (!legacyNamesLookup.has(componentTemplate.name)) return legacyTemplates; + + if (componentTemplate.component_template._meta?.package?.name !== installablePackage.name) { + return legacyTemplates; + } + + return legacyTemplates.concat(componentTemplate.name); + }, []); +}; + +const _deleteComponentTemplates = async (params: { + templateNames: string[]; + esClient: ElasticsearchClient; + logger: Logger; +}): Promise => { + const { templateNames, esClient, logger } = params; + const deleteResults = await Promise.allSettled( + templateNames.map((name) => esClient.cluster.deleteComponentTemplate({ name })) + ); + + const errors = deleteResults.filter((r) => r.status === 'rejected') as PromiseRejectedResult[]; + + if (errors.length) { + const prettyErrors = errors.map((e) => `"${e.reason}"`).join(', '); + logger.debug( + `Encountered ${errors.length} errors deleting legacy component templates: ${prettyErrors}` + ); + } +}; + +export const _getIndexTemplatesToUsedByMap = ( + indexTemplates: IndicesGetIndexTemplateIndexTemplateItem[] +) => { + const lookupMap: Map = new Map(); + + indexTemplates.forEach(({ name: indexTemplateName, index_template: indexTemplate }) => { + const composedOf = indexTemplate?.composed_of; + + if (!composedOf) return; + + composedOf.forEach((componentTemplateName) => { + const existingEntry = lookupMap.get(componentTemplateName) || []; + + lookupMap.set(componentTemplateName, existingEntry.concat(indexTemplateName)); + }); + }); + return lookupMap; +}; + +const _getAllComponentTemplates = async (esClient: ElasticsearchClient) => { + const { component_templates: componentTemplates } = await esClient.cluster.getComponentTemplate(); + + return componentTemplates; +}; + +const _getAllIndexTemplatesWithComposedOf = async (esClient: ElasticsearchClient) => { + const { index_templates: indexTemplates } = await esClient.indices.getIndexTemplate(); + return indexTemplates.filter((tmpl) => tmpl.index_template.composed_of?.length); +}; + +export const _filterComponentTemplatesInUse = ({ + componentTemplateNames, + indexTemplates, + logger, +}: { + componentTemplateNames: string[]; + indexTemplates: IndicesGetIndexTemplateIndexTemplateItem[]; + logger: Logger; +}): string[] => { + const usedByLookup = _getIndexTemplatesToUsedByMap(indexTemplates); + + return componentTemplateNames.filter((componentTemplateName) => { + const indexTemplatesUsingComponentTemplate = usedByLookup.get(componentTemplateName); + + if (indexTemplatesUsingComponentTemplate?.length) { + const prettyTemplates = indexTemplatesUsingComponentTemplate.join(', '); + logger.debug( + `Not deleting legacy template ${componentTemplateName} as it is in use by index templates: ${prettyTemplates}` + ); + return false; + } + + return true; + }); +}; + +export const removeLegacyTemplates = async (params: { + packageInfo: InstallablePackage; + esClient: ElasticsearchClient; + logger: Logger; +}): Promise => { + const { packageInfo, esClient, logger } = params; + + const allComponentTemplates = await _getAllComponentTemplates(esClient); + + const legacyComponentTemplateNames = _getLegacyComponentTemplatesForPackage( + allComponentTemplates, + packageInfo + ); + + if (!legacyComponentTemplateNames.length) return; + + // all index templates that are composed of at least one component template + const allIndexTemplatesWithComposedOf = await _getAllIndexTemplatesWithComposedOf(esClient); + + let templatesToDelete = legacyComponentTemplateNames; + if (allIndexTemplatesWithComposedOf.length) { + // get the component templates not in use by any index templates + templatesToDelete = _filterComponentTemplatesInUse({ + componentTemplateNames: legacyComponentTemplateNames, + indexTemplates: allIndexTemplatesWithComposedOf, + logger, + }); + } + + if (!templatesToDelete.length) return; + + await _deleteComponentTemplates({ + templateNames: templatesToDelete, + esClient, + logger, + }); +}; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts b/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts index b4e673b8a9da4..796269eee38b1 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts @@ -23,6 +23,7 @@ import type { InstallablePackage, InstallSource, PackageAssetReference } from '. import { PACKAGES_SAVED_OBJECT_TYPE } from '../../../constants'; import type { AssetReference, Installation, InstallType } from '../../../types'; import { installTemplates } from '../elasticsearch/template/install'; +import { removeLegacyTemplates } from '../elasticsearch/template/remove_legacy'; import { installPipelines, isTopLevelPipeline, @@ -41,11 +42,11 @@ import { packagePolicyService } from '../..'; import { createInstallation, saveKibanaAssetsRefs, updateVersion } from './install'; import { deleteKibanaSavedObjectsAssets } from './remove'; +import { withPackageSpan } from './utils'; // this is only exported for testing // use a leading underscore to indicate it's not the supported path // only the more explicit `installPackage*` functions should be used - export async function _installPackage({ savedObjectsClient, savedObjectsImporter, @@ -105,71 +106,61 @@ export async function _installPackage({ }); } - const kibanaAssets = await getKibanaAssets(paths); - if (installedPkg) await deleteKibanaSavedObjectsAssets({ savedObjectsClient, installedPkg }); - // save new kibana refs before installing the assets - const installedKibanaAssetsRefs = await saveKibanaAssetsRefs( - savedObjectsClient, - pkgName, - kibanaAssets - ); + const installedKibanaAssetsRefs = await withPackageSpan('Install Kibana assets', async () => { + const kibanaAssets = await getKibanaAssets(paths); + if (installedPkg) await deleteKibanaSavedObjectsAssets({ savedObjectsClient, installedPkg }); + // save new kibana refs before installing the assets + const assetRefs = await saveKibanaAssetsRefs(savedObjectsClient, pkgName, kibanaAssets); + + await installKibanaAssets({ + logger, + savedObjectsImporter, + pkgName, + kibanaAssets, + }); - await installKibanaAssets({ - logger, - savedObjectsImporter, - pkgName, - kibanaAssets, + return assetRefs; }); // the rest of the installation must happen in sequential order // currently only the base package has an ILM policy // at some point ILM policies can be installed/modified // per data stream and we should then save them - await installILMPolicy(packageInfo, paths, esClient, logger); + await withPackageSpan('Install ILM policies', () => + installILMPolicy(packageInfo, paths, esClient, logger) + ); - const installedDataStreamIlm = await installIlmForDataStream( - packageInfo, - paths, - esClient, - savedObjectsClient, - logger + const installedDataStreamIlm = await withPackageSpan('Install Data Stream ILM policies', () => + installIlmForDataStream(packageInfo, paths, esClient, savedObjectsClient, logger) ); // installs ml models - const installedMlModel = await installMlModel( - packageInfo, - paths, - esClient, - savedObjectsClient, - logger + const installedMlModel = await withPackageSpan('Install ML models', () => + installMlModel(packageInfo, paths, esClient, savedObjectsClient, logger) ); // installs versionized pipelines without removing currently installed ones - const installedPipelines = await installPipelines( - packageInfo, - paths, - esClient, - savedObjectsClient, - logger + const installedPipelines = await withPackageSpan('Install ingest pipelines', () => + installPipelines(packageInfo, paths, esClient, savedObjectsClient, logger) ); // install or update the templates referencing the newly installed pipelines - const installedTemplates = await installTemplates( - packageInfo, - esClient, - logger, - paths, - savedObjectsClient + const installedTemplates = await withPackageSpan('Install index templates', () => + installTemplates(packageInfo, esClient, logger, paths, savedObjectsClient) ); + try { + await removeLegacyTemplates({ packageInfo, esClient, logger }); + } catch (e) { + logger.warn(`Error removing legacy templates: ${e.message}`); + } + // update current backing indices of each data stream - await updateCurrentWriteIndices(esClient, logger, installedTemplates); + await withPackageSpan('Update write indices', () => + updateCurrentWriteIndices(esClient, logger, installedTemplates) + ); - const installedTransforms = await installTransform( - packageInfo, - paths, - esClient, - savedObjectsClient, - logger + const installedTransforms = await withPackageSpan('Install transforms', () => + installTransform(packageInfo, paths, esClient, savedObjectsClient, logger) ); // If this is an update or retrying an update, delete the previous version's pipelines @@ -180,30 +171,36 @@ export async function _installPackage({ (installType === 'update' || installType === 'reupdate') && installedPkg ) { - await deletePreviousPipelines( - esClient, - savedObjectsClient, - pkgName, - installedPkg.attributes.version + await withPackageSpan('Delete previous ingest pipelines', () => + deletePreviousPipelines( + esClient, + savedObjectsClient, + pkgName, + installedPkg.attributes.version + ) ); } // pipelines from a different version may have installed during a failed update if (installType === 'rollback' && installedPkg) { - await deletePreviousPipelines( - esClient, - savedObjectsClient, - pkgName, - installedPkg.attributes.install_version + await await withPackageSpan('Delete previous ingest pipelines', () => + deletePreviousPipelines( + esClient, + savedObjectsClient, + pkgName, + installedPkg.attributes.install_version + ) ); } const installedTemplateRefs = getAllTemplateRefs(installedTemplates); - const packageAssetResults = await saveArchiveEntries({ - savedObjectsClient, - paths, - packageInfo, - installSource, - }); + const packageAssetResults = await withPackageSpan('Update archive entries', () => + saveArchiveEntries({ + savedObjectsClient, + paths, + packageInfo, + installSource, + }) + ); const packageAssetRefs: PackageAssetReference[] = packageAssetResults.saved_objects.map( (result) => ({ id: result.id, @@ -214,26 +211,26 @@ export async function _installPackage({ // update to newly installed version when all assets are successfully installed if (installedPkg) await updateVersion(savedObjectsClient, pkgName, pkgVersion); - const updatedPackage = await savedObjectsClient.update( - PACKAGES_SAVED_OBJECT_TYPE, - pkgName, - { + const updatedPackage = await withPackageSpan('Update install status', () => + savedObjectsClient.update(PACKAGES_SAVED_OBJECT_TYPE, pkgName, { install_version: pkgVersion, install_status: 'installed', package_assets: packageAssetRefs, - } + }) ); // If the package is flagged with the `keep_policies_up_to_date` flag, upgrade its // associated package policies after installation if (updatedPackage.attributes.keep_policies_up_to_date) { - const policyIdsToUpgrade = await packagePolicyService.listIds(savedObjectsClient, { - page: 1, - perPage: SO_SEARCH_LIMIT, - kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:${pkgName}`, - }); + await withPackageSpan('Upgrade package policies', async () => { + const policyIdsToUpgrade = await packagePolicyService.listIds(savedObjectsClient, { + page: 1, + perPage: SO_SEARCH_LIMIT, + kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:${pkgName}`, + }); - await packagePolicyService.upgrade(savedObjectsClient, esClient, policyIdsToUpgrade.items); + await packagePolicyService.upgrade(savedObjectsClient, esClient, policyIdsToUpgrade.items); + }); } return [ diff --git a/x-pack/plugins/fleet/server/services/epm/packages/get.test.ts b/x-pack/plugins/fleet/server/services/epm/packages/get.test.ts index 040bb79b9fc78..6c426c4efdf4f 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/get.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/get.test.ts @@ -187,6 +187,7 @@ describe('When using EPM `get` services', () => { beforeEach(() => { const mockContract = createAppContextStartContractMock(); appContextService.start(mockContract); + jest.clearAllMocks(); MockRegistry.fetchFindLatestPackageOrUndefined.mockResolvedValue({ name: 'my-package', version: '1.0.0', @@ -321,6 +322,56 @@ describe('When using EPM `get` services', () => { status: 'installed', }); }); + + it('sets the latestVersion to installed version when an installed package is newer than package in registry', async () => { + const soClient = savedObjectsClientMock.create(); + soClient.get.mockResolvedValue({ + id: 'my-package', + type: PACKAGES_SAVED_OBJECT_TYPE, + references: [], + attributes: { + version: '2.0.0', + install_status: 'installed', + }, + }); + + await expect( + getPackageInfo({ + savedObjectsClient: soClient, + pkgName: 'my-package', + pkgVersion: '1.0.0', + }) + ).resolves.toMatchObject({ + latestVersion: '1.0.0', + status: 'installed', + }); + }); + }); + + describe('skipArchive', () => { + it('avoids loading archive when skipArchive = true', async () => { + const soClient = savedObjectsClientMock.create(); + soClient.get.mockRejectedValue(SavedObjectsErrorHelpers.createGenericNotFoundError()); + MockRegistry.fetchInfo.mockResolvedValue({ + name: 'my-package', + version: '1.0.0', + assets: [], + } as unknown as RegistryPackage); + + await expect( + getPackageInfo({ + savedObjectsClient: soClient, + pkgName: 'my-package', + pkgVersion: '1.0.0', + skipArchive: true, + }) + ).resolves.toMatchObject({ + latestVersion: '1.0.0', + status: 'not_installed', + }); + + expect(MockRegistry.getRegistryPackage).not.toHaveBeenCalled(); + }); }); }); }); diff --git a/x-pack/plugins/fleet/server/services/epm/packages/get.ts b/x-pack/plugins/fleet/server/services/epm/packages/get.ts index de4ce6a1e84b5..27468e77c8e9f 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/get.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/get.ts @@ -6,6 +6,7 @@ */ import type { SavedObjectsClientContract, SavedObjectsFindOptions } from '@kbn/core/server'; +import semverGte from 'semver/functions/gte'; import { isPackageLimited, @@ -44,9 +45,10 @@ export async function getCategories(options: GetCategoriesRequest['query']) { export async function getPackages( options: { savedObjectsClient: SavedObjectsClientContract; + excludeInstallStatus?: boolean; } & Registry.SearchParams ) { - const { savedObjectsClient, experimental, category } = options; + const { savedObjectsClient, experimental, category, excludeInstallStatus = false } = options; const registryItems = await Registry.fetchList({ category, experimental }).then((items) => { return items.map((item) => Object.assign({}, item, { title: item.title || nameAsTitle(item.name) }, { id: item.name }) @@ -62,7 +64,23 @@ export async function getPackages( ) ) .sort(sortByName); - return packageList; + + if (!excludeInstallStatus) { + return packageList; + } + + // Exclude the `installStatus` value if the `excludeInstallStatus` query parameter is set to true + // to better facilitate response caching + const packageListWithoutStatus = packageList.map((pkg) => { + const newPkg = { + ...pkg, + status: undefined, + }; + + return newPkg; + }); + + return packageListWithoutStatus; } // Get package names for packages which cannot have more than one package policy on an agent policy @@ -70,7 +88,10 @@ export async function getLimitedPackages(options: { savedObjectsClient: SavedObjectsClientContract; }): Promise { const { savedObjectsClient } = options; - const allPackages = await getPackages({ savedObjectsClient, experimental: true }); + const allPackages = await getPackages({ + savedObjectsClient, + experimental: true, + }); const installedPackages = allPackages.filter( (pkg) => pkg.status === installationStatuses.Installed ); @@ -98,52 +119,18 @@ export async function getPackageSavedObjects( export const getInstallations = getPackageSavedObjects; -export async function getPackageInfoFromRegistry(options: { - savedObjectsClient: SavedObjectsClientContract; - pkgName: string; - pkgVersion: string; -}): Promise { - const { savedObjectsClient, pkgName, pkgVersion } = options; - const [savedObject, latestPackage] = await Promise.all([ - getInstallationObject({ savedObjectsClient, pkgName }), - Registry.fetchFindLatestPackageOrThrow(pkgName), - ]); - - // If no package version is provided, use the installed version in the response - let responsePkgVersion = pkgVersion || savedObject?.attributes.install_version; - // If no installed version of the given package exists, default to the latest version of the package - if (!responsePkgVersion) { - responsePkgVersion = latestPackage.version; - } - const packageInfo = await Registry.fetchInfo(pkgName, responsePkgVersion); - - // Fix the paths - const paths = - packageInfo?.assets?.map((path) => - path.replace(`/package/${pkgName}/${pkgVersion}`, `${pkgName}-${pkgVersion}`) - ) ?? []; - - // add properties that aren't (or aren't yet) on the package - const additions: EpmPackageAdditions = { - latestVersion: latestPackage.version, - title: packageInfo.title || nameAsTitle(packageInfo.name), - assets: Registry.groupPathsByService(paths || []), - removable: true, - notice: Registry.getNoticePath(paths || []), - keepPoliciesUpToDate: savedObject?.attributes.keep_policies_up_to_date ?? false, - }; - const updated = { ...packageInfo, ...additions }; - - return createInstallableFrom(updated, savedObject); -} - -export async function getPackageInfo(options: { +export async function getPackageInfo({ + savedObjectsClient, + pkgName, + pkgVersion, + skipArchive = false, +}: { savedObjectsClient: SavedObjectsClientContract; pkgName: string; pkgVersion: string; + /** Avoid loading the registry archive into the cache (only use for performance reasons). Defaults to `false` */ + skipArchive?: boolean; }): Promise { - const { savedObjectsClient, pkgName, pkgVersion } = options; - const [savedObject, latestPackage] = await Promise.all([ getInstallationObject({ savedObjectsClient, pkgName }), Registry.fetchFindLatestPackageOrUndefined(pkgName), @@ -154,20 +141,39 @@ export async function getPackageInfo(options: { } // If no package version is provided, use the installed version in the response, fallback to package from registry - const responsePkgVersion = - pkgVersion ?? savedObject?.attributes.install_version ?? latestPackage!.version; - - const getPackageRes = await getPackageFromSource({ - pkgName, - pkgVersion: responsePkgVersion, - savedObjectsClient, - installedPkg: savedObject?.attributes, - }); - const { paths, packageInfo } = getPackageRes; + const resolvedPkgVersion = + pkgVersion !== '' + ? pkgVersion + : savedObject?.attributes.install_version ?? latestPackage!.version; + + // If same version is available in registry and skipArchive is true, use the info from the registry (faster), + // otherwise build it from the archive + let paths: string[]; + let packageInfo: RegistryPackage | ArchivePackage | undefined = skipArchive + ? await Registry.fetchInfo(pkgName, pkgVersion).catch(() => undefined) + : undefined; + + if (packageInfo) { + // Fix the paths + paths = + packageInfo.assets?.map((path) => + path.replace(`/package/${pkgName}/${pkgVersion}`, `${pkgName}-${pkgVersion}`) + ) ?? []; + } else { + ({ paths, packageInfo } = await getPackageFromSource({ + pkgName, + pkgVersion: resolvedPkgVersion, + savedObjectsClient, + installedPkg: savedObject?.attributes, + })); + } // add properties that aren't (or aren't yet) on the package const additions: EpmPackageAdditions = { - latestVersion: latestPackage?.version ?? responsePkgVersion, + latestVersion: + latestPackage?.version && semverGte(latestPackage.version, resolvedPkgVersion) + ? latestPackage.version + : resolvedPkgVersion, title: packageInfo.title || nameAsTitle(packageInfo.name), assets: Registry.groupPathsByService(paths || []), removable: true, diff --git a/x-pack/plugins/fleet/server/services/epm/packages/index.ts b/x-pack/plugins/fleet/server/services/epm/packages/index.ts index 30d2b5ec3fd22..bfb09abcfaa28 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/index.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/index.ts @@ -20,7 +20,6 @@ export { getInstallation, getInstallations, getPackageInfo, - getPackageInfoFromRegistry, getPackages, getLimitedPackages, } from './get'; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/install.ts b/x-pack/plugins/fleet/server/services/epm/packages/install.ts index 3ecec951dde7e..9ae549982399c 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/install.ts @@ -5,6 +5,7 @@ * 2.0. */ +import apm from 'elastic-apm-node'; import { i18n } from '@kbn/i18n'; import semverLt from 'semver/functions/lt'; import type Boom from '@hapi/boom'; @@ -250,6 +251,10 @@ async function installPackageFromRegistry({ // TODO: change epm API to /packageName/version so we don't need to do this const { pkgName, pkgVersion } = Registry.splitPkgKey(pkgkey); + // Workaround apm issue with async spans: https://github.com/elastic/apm-agent-nodejs/issues/2611 + await Promise.resolve(); + const span = apm.startSpan(`Install package from registry ${pkgName}@${pkgVersion}`, 'package'); + // if an error happens during getInstallType, report that we don't know let installType: InstallType = 'unknown'; @@ -260,6 +265,12 @@ async function installPackageFromRegistry({ const installedPkg = await getInstallationObject({ savedObjectsClient, pkgName }); installType = getInstallType({ pkgVersion, installedPkg }); + span?.addLabels({ + packageName: pkgName, + packageVersion: pkgVersion, + installType, + }); + // get latest package version const latestPackage = await Registry.fetchFindLatestPackageOrThrow(pkgName, { ignoreConstraints, @@ -326,7 +337,7 @@ async function installPackageFromRegistry({ // try installing the package, if there was an error, call error handler and rethrow // @ts-expect-error status is string instead of InstallResult.status 'installed' | 'already_installed' - return _installPackage({ + return await _installPackage({ savedObjectsClient, savedObjectsImporter, esClient, @@ -377,6 +388,8 @@ async function installPackageFromRegistry({ installType, installSource: 'registry', }; + } finally { + span?.end(); } } @@ -395,6 +408,10 @@ async function installPackageByUpload({ contentType, spaceId, }: InstallUploadedArchiveParams): Promise { + // Workaround apm issue with async spans: https://github.com/elastic/apm-agent-nodejs/issues/2611 + await Promise.resolve(); + const span = apm.startSpan(`Install package from upload`, 'package'); + const logger = appContextService.getLogger(); // if an error happens during getInstallType, report that we don't know let installType: InstallType = 'unknown'; @@ -409,6 +426,12 @@ async function installPackageByUpload({ installType = getInstallType({ pkgVersion: packageInfo.version, installedPkg }); + span?.addLabels({ + packageName: packageInfo.name, + packageVersion: packageInfo.version, + installType, + }); + telemetryEvent.packageName = packageInfo.name; telemetryEvent.newVersion = packageInfo.version; telemetryEvent.installType = installType; @@ -434,7 +457,7 @@ async function installPackageByUpload({ .createImporter(savedObjectsClient); // @ts-expect-error status is string instead of InstallResult.status 'installed' | 'already_installed' - return _installPackage({ + return await _installPackage({ savedObjectsClient, savedObjectsImporter, esClient, @@ -466,6 +489,8 @@ async function installPackageByUpload({ errorMessage: e.message, }); return { error: e, installType, installSource: 'upload' }; + } finally { + span?.end(); } } diff --git a/x-pack/plugins/fleet/server/services/epm/packages/utils.ts b/x-pack/plugins/fleet/server/services/epm/packages/utils.ts new file mode 100644 index 0000000000000..0cb97ca007daf --- /dev/null +++ b/x-pack/plugins/fleet/server/services/epm/packages/utils.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { withSpan } from '@kbn/apm-utils'; + +export const withPackageSpan = (stepName: string, func: () => Promise) => + withSpan({ name: stepName, type: 'package' }, func); diff --git a/x-pack/plugins/fleet/server/services/epm/registry/index.ts b/x-pack/plugins/fleet/server/services/epm/registry/index.ts index 182f20297afd5..2ae531f63379d 100644 --- a/x-pack/plugins/fleet/server/services/epm/registry/index.ts +++ b/x-pack/plugins/fleet/server/services/epm/registry/index.ts @@ -37,6 +37,8 @@ import { PackageNotFoundError, PackageCacheError, RegistryResponseError } from ' import { getBundledPackageByName } from '../packages/bundled_packages'; +import { withPackageSpan } from '../packages/utils'; + import { fetchUrl, getResponse, getResponseStream } from './requests'; import { getRegistryUrl } from './registry_url'; @@ -75,42 +77,44 @@ async function _fetchFindLatestPackage( packageName: string, options?: FetchFindLatestPackageOptions ) { - const logger = appContextService.getLogger(); - const { ignoreConstraints = false } = options ?? {}; + return withPackageSpan(`Find latest package ${packageName}`, async () => { + const logger = appContextService.getLogger(); + const { ignoreConstraints = false } = options ?? {}; - const bundledPackage = await getBundledPackageByName(packageName); + const bundledPackage = await getBundledPackageByName(packageName); - const registryUrl = getRegistryUrl(); - const url = new URL(`${registryUrl}/search?package=${packageName}&experimental=true`); + const registryUrl = getRegistryUrl(); + const url = new URL(`${registryUrl}/search?package=${packageName}&experimental=true`); - if (!ignoreConstraints) { - setKibanaVersion(url); - } + if (!ignoreConstraints) { + setKibanaVersion(url); + } - try { - const res = await fetchUrl(url.toString(), 1); - const searchResults: RegistryPackage[] = JSON.parse(res); + try { + const res = await fetchUrl(url.toString(), 1); + const searchResults: RegistryPackage[] = JSON.parse(res); - const latestPackageFromRegistry = searchResults[0] ?? null; + const latestPackageFromRegistry = searchResults[0] ?? null; - if (bundledPackage && semverGte(bundledPackage.version, latestPackageFromRegistry.version)) { - return bundledPackage; - } + if (bundledPackage && semverGte(bundledPackage.version, latestPackageFromRegistry.version)) { + return bundledPackage; + } - return latestPackageFromRegistry; - } catch (error) { - logger.error( - `Failed to fetch latest version of ${packageName} from registry: ${error.message}` - ); + return latestPackageFromRegistry; + } catch (error) { + logger.error( + `Failed to fetch latest version of ${packageName} from registry: ${error.message}` + ); - // Fall back to the bundled version of the package if it exists - if (bundledPackage) { - return bundledPackage; - } + // Fall back to the bundled version of the package if it exists + if (bundledPackage) { + return bundledPackage; + } - // Otherwise, return null and allow callers to determine whether they'll consider this an error or not - return null; - } + // Otherwise, return null and allow callers to determine whether they'll consider this an error or not + return null; + } + }); } export async function fetchFindLatestPackageOrThrow( @@ -207,12 +211,14 @@ export async function fetchCategories( } export async function getInfo(name: string, version: string) { - let packageInfo = getPackageInfo({ name, version }); - if (!packageInfo) { - packageInfo = await fetchInfo(name, version); - setPackageInfo({ name, version, packageInfo }); - } - return packageInfo as RegistryPackage; + return withPackageSpan('Fetch package info', async () => { + let packageInfo = getPackageInfo({ name, version }); + if (!packageInfo) { + packageInfo = await fetchInfo(name, version); + setPackageInfo({ name, version, packageInfo }); + } + return packageInfo as RegistryPackage; + }); } export async function getRegistryPackage( @@ -222,14 +228,19 @@ export async function getRegistryPackage( const installSource = 'registry'; let paths = getArchiveFilelist({ name, version }); if (!paths || paths.length === 0) { - const { archiveBuffer, archivePath } = await fetchArchiveBuffer(name, version); - paths = await unpackBufferToCache({ - name, - version, - installSource, - archiveBuffer, - contentType: ensureContentType(archivePath), - }); + const { archiveBuffer, archivePath } = await withPackageSpan( + 'Fetch package archive from registry', + () => fetchArchiveBuffer(name, version) + ); + paths = await withPackageSpan('Unpack archive', () => + unpackBufferToCache({ + name, + version, + installSource, + archiveBuffer, + contentType: ensureContentType(archivePath), + }) + ); } const packageInfo = await getInfo(name, version); diff --git a/x-pack/plugins/fleet/server/services/package_policy.test.ts b/x-pack/plugins/fleet/server/services/package_policy.test.ts index 53218e7cda8f9..c84701bf5d5e9 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.test.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.test.ts @@ -9,6 +9,7 @@ import { elasticsearchServiceMock, savedObjectsClientMock, httpServerMock, + coreMock, } from '@kbn/core/server/mocks'; import { produce } from 'immer'; import type { @@ -1270,7 +1271,7 @@ describe('Package policy service', () => { await packagePolicyService.runExternalCallbacks( 'packagePolicyCreate', newPackagePolicy, - context, + coreMock.createCustomRequestHandlerContext(context), request ); expect(callbackCallingOrder).toEqual(['a', 'b']); @@ -1283,7 +1284,7 @@ describe('Package policy service', () => { await packagePolicyService.runExternalCallbacks( 'packagePolicyCreate', newPackagePolicy, - context, + coreMock.createCustomRequestHandlerContext(context), request ); @@ -1330,7 +1331,7 @@ describe('Package policy service', () => { await packagePolicyService.runExternalCallbacks( 'packagePolicyCreate', newPackagePolicy, - context, + coreMock.createCustomRequestHandlerContext(context), request ); } catch (e) { @@ -1349,7 +1350,7 @@ describe('Package policy service', () => { packagePolicyService.runExternalCallbacks( 'packagePolicyCreate', newPackagePolicy, - context, + coreMock.createCustomRequestHandlerContext(context), request ) ).rejects.toThrow('callbackThree threw error on purpose'); @@ -1438,15 +1439,16 @@ describe('Package policy service', () => { appContextService.addExternalCallback('packagePolicyPostCreate', callbackA); appContextService.addExternalCallback('packagePolicyPostCreate', callbackB); + const requestContext = coreMock.createCustomRequestHandlerContext(context); await packagePolicyService.runExternalCallbacks( 'packagePolicyPostCreate', packagePolicy, - context, + requestContext, request ); - expect(callbackA).toHaveBeenCalledWith(packagePolicy, context, request); - expect(callbackB).toHaveBeenCalledWith(packagePolicy, context, request); + expect(callbackA).toHaveBeenCalledWith(packagePolicy, requestContext, request); + expect(callbackB).toHaveBeenCalledWith(packagePolicy, requestContext, request); expect(callbackCallingOrder).toEqual(['a', 'b']); }); }); @@ -3326,6 +3328,7 @@ describe('Package policy service', () => { beforeEach(() => { savedObjectsClient = savedObjectsClientMock.create(); }); + function mockPackage(pkgName: string) { const mockPackagePolicy = createPackagePolicyMock(); @@ -3346,6 +3349,7 @@ describe('Package policy service', () => { attributes, }); } + it('should return success if package and policy versions match', async () => { mockPackage('apache'); diff --git a/x-pack/plugins/fleet/server/types/request_context.ts b/x-pack/plugins/fleet/server/types/request_context.ts index 0621319ba011c..f9972c6262348 100644 --- a/x-pack/plugins/fleet/server/types/request_context.ts +++ b/x-pack/plugins/fleet/server/types/request_context.ts @@ -8,7 +8,7 @@ import type { KibanaResponseFactory, RequestHandler, - RequestHandlerContext, + CustomRequestHandlerContext, RouteMethod, SavedObjectsClientContract, IRouter, @@ -18,7 +18,7 @@ import type { FleetAuthz } from '../../common/authz'; import type { AgentClient } from '../services'; /** @internal */ -export interface FleetRequestHandlerContext extends RequestHandlerContext { +export type FleetRequestHandlerContext = CustomRequestHandlerContext<{ fleet: { /** {@link FleetAuthz} */ authz: FleetAuthz; @@ -36,7 +36,7 @@ export interface FleetRequestHandlerContext extends RequestHandlerContext { }; spaceId: string; }; -} +}>; /** * Convenience type for request handlers in Fleet that includes the FleetRequestHandlerContext type diff --git a/x-pack/plugins/fleet/server/types/rest_spec/epm.ts b/x-pack/plugins/fleet/server/types/rest_spec/epm.ts index c51a0127c2e29..1385c110f2e4e 100644 --- a/x-pack/plugins/fleet/server/types/rest_spec/epm.ts +++ b/x-pack/plugins/fleet/server/types/rest_spec/epm.ts @@ -18,6 +18,7 @@ export const GetPackagesRequestSchema = { query: schema.object({ category: schema.maybe(schema.string()), experimental: schema.maybe(schema.boolean()), + excludeInstallStatus: schema.maybe(schema.boolean({ defaultValue: false })), }), }; diff --git a/x-pack/plugins/global_search/server/mocks.ts b/x-pack/plugins/global_search/server/mocks.ts index b27c9f7a9e6b8..948ea49b95fa9 100644 --- a/x-pack/plugins/global_search/server/mocks.ts +++ b/x-pack/plugins/global_search/server/mocks.ts @@ -52,7 +52,10 @@ const createRequestHandlerContextMock = (): jest.Mocked { async (ctx, req, res) => { const { params, options } = req.body; try { - const allResults = await ctx - .globalSearch!.find(params, { ...options, aborted$: req.events.aborted$ }) + const globalSearch = await ctx.globalSearch; + const allResults = await globalSearch + .find(params, { ...options, aborted$: req.events.aborted$ }) .pipe( map((batch) => batch.results), reduce((acc, results) => [...acc, ...results]) diff --git a/x-pack/plugins/global_search/server/routes/get_searchable_types.ts b/x-pack/plugins/global_search/server/routes/get_searchable_types.ts index 3db7a4ee75174..f456c0e665f19 100644 --- a/x-pack/plugins/global_search/server/routes/get_searchable_types.ts +++ b/x-pack/plugins/global_search/server/routes/get_searchable_types.ts @@ -14,7 +14,8 @@ export const registerInternalSearchableTypesRoute = (router: GlobalSearchRouter) validate: false, }, async (ctx, req, res) => { - const types = await ctx.globalSearch!.getSearchableTypes(); + const globalSearch = await ctx.globalSearch; + const types = await globalSearch.getSearchableTypes(); return res.ok({ body: { types, diff --git a/x-pack/plugins/global_search/server/types.ts b/x-pack/plugins/global_search/server/types.ts index 5f20f4f181db3..10a7bafe850dd 100644 --- a/x-pack/plugins/global_search/server/types.ts +++ b/x-pack/plugins/global_search/server/types.ts @@ -12,7 +12,7 @@ import type { SavedObjectsClientContract, Capabilities, IRouter, - RequestHandlerContext, + CustomRequestHandlerContext, } from '@kbn/core/server'; import { GlobalSearchBatchedResults, @@ -29,9 +29,9 @@ export type GlobalSearchPluginStart = Pick; /** * @internal diff --git a/x-pack/plugins/graph/public/components/search_bar.test.tsx b/x-pack/plugins/graph/public/components/search_bar.test.tsx index 3589c6c25b29a..c05da957599c9 100644 --- a/x-pack/plugins/graph/public/components/search_bar.test.tsx +++ b/x-pack/plugins/graph/public/components/search_bar.test.tsx @@ -19,7 +19,8 @@ import { import { act } from 'react-dom/test-utils'; import { QueryStringInput } from '@kbn/unified-search-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/public'; - +import { setAutocomplete } from '@kbn/unified-search-plugin/public/services'; +import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; import { I18nProvider, InjectedIntl } from '@kbn/i18n-react'; @@ -59,6 +60,8 @@ function getServiceMocks() { query: { savedQueries: {}, }, + }, + unifiedSearch: { autocomplete: { hasQuerySuggestions: () => false, }, @@ -101,6 +104,11 @@ describe('search_bar', () => { }, }; + beforeEach(() => { + const autocompleteStart = unifiedSearchPluginMock.createStartContract(); + setAutocomplete(autocompleteStart.autocomplete); + }); + beforeEach(() => { store = createMockGraphStore({ sagas: [submitSearchSaga], diff --git a/x-pack/plugins/graph/server/routes/explore.ts b/x-pack/plugins/graph/server/routes/explore.ts index b3dddfb21cb92..6a6072e17274c 100644 --- a/x-pack/plugins/graph/server/routes/explore.ts +++ b/x-pack/plugins/graph/server/routes/explore.ts @@ -34,50 +34,44 @@ export function registerExploreRoute({ }), }, }, - router.handleLegacyErrors( - async ( - { - core: { - elasticsearch: { client: esClient }, + router.handleLegacyErrors(async ({ core }, request, response) => { + verifyApiAccess(licenseState); + licenseState.notifyUsage('Graph'); + + const { + elasticsearch: { client: esClient }, + } = await core; + try { + return response.ok({ + body: { + resp: await esClient.asCurrentUser.transport.request({ + path: '/' + encodeURIComponent(request.body.index) + '/_graph/explore', + body: request.body.query, + method: 'POST', + }), }, - }, - request, - response - ) => { - verifyApiAccess(licenseState); - licenseState.notifyUsage('Graph'); - try { - return response.ok({ - body: { - resp: await esClient.asCurrentUser.transport.request({ - path: '/' + encodeURIComponent(request.body.index) + '/_graph/explore', - body: request.body.query, - method: 'POST', - }), - }, + }); + } catch (error) { + if (error instanceof errors.ResponseError) { + const errorBody: ErrorResponse = error.body; + const relevantCause = (errorBody.error?.root_cause ?? []).find((cause) => { + return ( + cause.reason.includes('Fielddata is disabled on text fields') || + cause.reason.includes('No support for examining floating point') || + cause.reason.includes('Sample diversifying key must be a single valued-field') || + cause.reason.includes('Failed to parse query') || + cause.reason.includes('Text fields are not optimised for operations') || + cause.type === 'parsing_exception' + ); }); - } catch (error) { - if (error instanceof errors.ResponseError) { - const errorBody: ErrorResponse = error.body; - const relevantCause = (errorBody.error?.root_cause ?? []).find((cause) => { - return ( - cause.reason.includes('Fielddata is disabled on text fields') || - cause.reason.includes('No support for examining floating point') || - cause.reason.includes('Sample diversifying key must be a single valued-field') || - cause.reason.includes('Failed to parse query') || - cause.reason.includes('Text fields are not optimised for operations') || - cause.type === 'parsing_exception' - ); - }); - if (relevantCause) { - throw Boom.badRequest(relevantCause.reason); - } + if (relevantCause) { + throw Boom.badRequest(relevantCause.reason); } - - throw error; } + + throw error; } - ) + }) ); } diff --git a/x-pack/plugins/graph/server/routes/search.ts b/x-pack/plugins/graph/server/routes/search.ts index 8d5827fe13316..2bdb956196ed4 100644 --- a/x-pack/plugins/graph/server/routes/search.ts +++ b/x-pack/plugins/graph/server/routes/search.ts @@ -27,40 +27,33 @@ export function registerSearchRoute({ }), }, }, - router.handleLegacyErrors( - async ( - { - core: { - uiSettings: { client: uiSettings }, - elasticsearch: { client: esClient }, + router.handleLegacyErrors(async ({ core }, request, response) => { + verifyApiAccess(licenseState); + licenseState.notifyUsage('Graph'); + const { + uiSettings: { client: uiSettings }, + elasticsearch: { client: esClient }, + } = await core; + const includeFrozen = await uiSettings.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); + try { + return response.ok({ + body: { + resp: await esClient.asCurrentUser.search({ + index: request.body.index, + body: request.body.body, + track_total_hits: true, + ...(includeFrozen ? { ignore_throttled: false } : {}), + }), }, - }, - request, - response - ) => { - verifyApiAccess(licenseState); - licenseState.notifyUsage('Graph'); - const includeFrozen = await uiSettings.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); - try { - return response.ok({ - body: { - resp: await esClient.asCurrentUser.search({ - index: request.body.index, - body: request.body.body, - track_total_hits: true, - ...(includeFrozen ? { ignore_throttled: false } : {}), - }), - }, - }); - } catch (error) { - return response.customError({ - statusCode: error.statusCode || 500, - body: { - message: error.message, - }, - }); - } + }); + } catch (error) { + return response.customError({ + statusCode: error.statusCode || 500, + body: { + message: error.message, + }, + }); } - ) + }) ); } diff --git a/x-pack/plugins/grokdebugger/server/routes/api/grokdebugger/register_grok_simulate_route.ts b/x-pack/plugins/grokdebugger/server/routes/api/grokdebugger/register_grok_simulate_route.ts index fb20812f3307e..3154a1880f4a9 100644 --- a/x-pack/plugins/grokdebugger/server/routes/api/grokdebugger/register_grok_simulate_route.ts +++ b/x-pack/plugins/grokdebugger/server/routes/api/grokdebugger/register_grok_simulate_route.ts @@ -34,11 +34,11 @@ export function registerGrokSimulateRoute(framework: KibanaFramework) { }, async (requestContext, request, response) => { try { + const esClient = (await requestContext.core).elasticsearch.client; const grokdebuggerRequest = GrokdebuggerRequest.fromDownstreamJSON(request.body); - const simulateResponseFromES = - await requestContext.core.elasticsearch.client.asCurrentUser.ingest.simulate({ - body: grokdebuggerRequest.upstreamJSON, - }); + const simulateResponseFromES = await esClient.asCurrentUser.ingest.simulate({ + body: grokdebuggerRequest.upstreamJSON, + }); const grokdebuggerResponse = GrokdebuggerResponse.fromUpstreamJSON(simulateResponseFromES); return response.ok({ body: grokdebuggerResponse, diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.ts new file mode 100644 index 0000000000000..df64fbce3fa1d --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.ts @@ -0,0 +1,66 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { act } from 'react-dom/test-utils'; +import { HttpSetup } from '@kbn/core/public'; +import { registerTestBed, TestBed, TestBedConfig } from '@kbn/test-jest-helpers'; +import { App } from '../../../public/application/app'; +import { WithAppDependencies } from '../helpers'; + +const getTestBedConfig = (initialEntries: string[]): TestBedConfig => ({ + memoryRouter: { + initialEntries, + }, + defaultProps: { + getUrlForApp: () => {}, + }, +}); + +export interface AppTestBed extends TestBed { + actions: { + clickPolicyNameLink: () => void; + clickCreatePolicyButton: () => void; + }; +} + +export const setup = async ( + httpSetup: HttpSetup, + initialEntries: string[] +): Promise => { + const initTestBed = registerTestBed( + WithAppDependencies(App, httpSetup), + getTestBedConfig(initialEntries) + ); + const testBed = await initTestBed(); + + const clickPolicyNameLink = async () => { + const { component, find } = testBed; + await act(async () => { + find('policyTablePolicyNameLink').simulate('click', { button: 0 }); + }); + component.update(); + }; + + const clickCreatePolicyButton = async () => { + const { component, find } = testBed; + await act(async () => { + find('createPolicyButton').simulate('click', { button: 0 }); + }); + component.update(); + }; + + return { + ...testBed, + actions: { clickPolicyNameLink, clickCreatePolicyButton }, + }; +}; + +export const getEncodedPolicyEditPath = (policyName: string): string => + `/policies/edit/${encodeURIComponent(policyName)}`; + +export const getDoubleEncodedPolicyEditPath = (policyName: string): string => + encodeURI(getEncodedPolicyEditPath(policyName)); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx deleted file mode 100644 index 9364d07d82382..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { act } from 'react-dom/test-utils'; -import { registerTestBed, TestBed, TestBedConfig } from '@kbn/test-jest-helpers'; -import { docLinksServiceMock, executionContextServiceMock } from '@kbn/core/public/mocks'; -import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; -import { licensingMock } from '@kbn/licensing-plugin/public/mocks'; -import { createBreadcrumbsMock } from '../../../public/application/services/breadcrumbs.mock'; -import { App } from '../../../public/application/app'; - -const breadcrumbService = createBreadcrumbsMock(); - -const AppWithContext = (props: any) => { - return ( - - - - ); -}; - -const getTestBedConfig = (initialEntries: string[]): TestBedConfig => ({ - memoryRouter: { - initialEntries, - }, - defaultProps: { - getUrlForApp: () => {}, - }, -}); - -const initTestBed = (initialEntries: string[]) => - registerTestBed(AppWithContext, getTestBedConfig(initialEntries))(); - -export interface AppTestBed extends TestBed { - actions: { - clickPolicyNameLink: () => void; - clickCreatePolicyButton: () => void; - }; -} - -export const setup = async (initialEntries: string[]): Promise => { - const testBed = await initTestBed(initialEntries); - - const clickPolicyNameLink = async () => { - const { component, find } = testBed; - await act(async () => { - find('policyTablePolicyNameLink').simulate('click', { button: 0 }); - }); - component.update(); - }; - - const clickCreatePolicyButton = async () => { - const { component, find } = testBed; - await act(async () => { - find('createPolicyButton').simulate('click', { button: 0 }); - }); - component.update(); - }; - - return { - ...testBed, - actions: { clickPolicyNameLink, clickCreatePolicyButton }, - }; -}; - -export const getEncodedPolicyEditPath = (policyName: string): string => - `/policies/edit/${encodeURIComponent(policyName)}`; - -export const getDoubleEncodedPolicyEditPath = (policyName: string): string => - encodeURI(getEncodedPolicyEditPath(policyName)); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts index e2c8a82af7d8f..1aaec089724b6 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts @@ -40,16 +40,13 @@ jest.mock('@elastic/eui', () => { describe('', () => { let testBed: AppTestBed; - const { server, httpRequestsMockHelpers } = setupEnvironment(); - afterAll(() => { - server.restore(); - }); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); describe('new policy creation', () => { test('when there are no policies', async () => { httpRequestsMockHelpers.setLoadPolicies([]); await act(async () => { - testBed = await setup(['/']); + testBed = await setup(httpSetup, ['/']); }); const { component, actions } = testBed; @@ -65,7 +62,7 @@ describe('', () => { test('when there are policies', async () => { httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy()]); await act(async () => { - testBed = await setup(['/']); + testBed = await setup(httpSetup, ['/']); }); const { component, actions } = testBed; @@ -86,7 +83,7 @@ describe('', () => { test('clicking policy name in the table works', async () => { await act(async () => { - testBed = await setup(['/']); + testBed = await setup(httpSetup, ['/']); }); const { component, actions } = testBed; @@ -100,7 +97,7 @@ describe('', () => { test('loading edit policy page url works', async () => { await act(async () => { - testBed = await setup([getEncodedPolicyEditPath(SPECIAL_CHARS_NAME)]); + testBed = await setup(httpSetup, [getEncodedPolicyEditPath(SPECIAL_CHARS_NAME)]); }); const { component } = testBed; @@ -113,7 +110,7 @@ describe('', () => { // when those links are open in a new tab, address bar contains double encoded url test('loading edit policy page url with double encoding works', async () => { await act(async () => { - testBed = await setup([getDoubleEncodedPolicyEditPath(SPECIAL_CHARS_NAME)]); + testBed = await setup(httpSetup, [getDoubleEncodedPolicyEditPath(SPECIAL_CHARS_NAME)]); }); const { component } = testBed; @@ -130,7 +127,7 @@ describe('', () => { test('loading edit policy page url works', async () => { await act(async () => { - testBed = await setup([getEncodedPolicyEditPath(PERCENT_SIGN_NAME)]); + testBed = await setup(httpSetup, [getEncodedPolicyEditPath(PERCENT_SIGN_NAME)]); }); const { component } = testBed; @@ -141,7 +138,7 @@ describe('', () => { test('loading edit policy page url with double encoding works', async () => { await act(async () => { - testBed = await setup([getDoubleEncodedPolicyEditPath(PERCENT_SIGN_NAME)]); + testBed = await setup(httpSetup, [getDoubleEncodedPolicyEditPath(PERCENT_SIGN_NAME)]); }); const { component } = testBed; @@ -160,7 +157,7 @@ describe('', () => { test('clicking policy name in the table works', async () => { await act(async () => { - testBed = await setup(['/']); + testBed = await setup(httpSetup, ['/']); }); const { component, actions } = testBed; @@ -176,7 +173,9 @@ describe('', () => { test("loading edit policy page url doesn't work", async () => { await act(async () => { - testBed = await setup([getEncodedPolicyEditPath(PERCENT_SIGN_WITH_OTHER_CHARS_NAME)]); + testBed = await setup(httpSetup, [ + getEncodedPolicyEditPath(PERCENT_SIGN_WITH_OTHER_CHARS_NAME), + ]); }); const { component } = testBed; @@ -192,7 +191,9 @@ describe('', () => { // when those links are open in a new tab, address bar contains double encoded url test('loading edit policy page url with double encoding works', async () => { await act(async () => { - testBed = await setup([getDoubleEncodedPolicyEditPath(PERCENT_SIGN_WITH_OTHER_CHARS_NAME)]); + testBed = await setup(httpSetup, [ + getDoubleEncodedPolicyEditPath(PERCENT_SIGN_WITH_OTHER_CHARS_NAME), + ]); }); const { component } = testBed; @@ -211,7 +212,7 @@ describe('', () => { test('clicking policy name in the table works correctly', async () => { await act(async () => { - testBed = await setup(['/']); + testBed = await setup(httpSetup, ['/']); }); const { component, actions } = testBed; @@ -227,7 +228,7 @@ describe('', () => { test("loading edit policy page url doesn't work", async () => { await act(async () => { - testBed = await setup([getEncodedPolicyEditPath(PERCENT_SIGN_25_SEQUENCE)]); + testBed = await setup(httpSetup, [getEncodedPolicyEditPath(PERCENT_SIGN_25_SEQUENCE)]); }); const { component } = testBed; @@ -243,7 +244,9 @@ describe('', () => { // when those links are open in a new tab, address bar contains double encoded url test('loading edit policy page url with double encoding works', async () => { await act(async () => { - testBed = await setup([getDoubleEncodedPolicyEditPath(PERCENT_SIGN_25_SEQUENCE)]); + testBed = await setup(httpSetup, [ + getDoubleEncodedPolicyEditPath(PERCENT_SIGN_25_SEQUENCE), + ]); }); const { component } = testBed; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/delete_phase.helpers.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/delete_phase.helpers.ts index 1914a056528e1..12237a05e7359 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/delete_phase.helpers.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/delete_phase.helpers.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { HttpSetup } from '@kbn/core/public'; import { createMinAgeActions, createSavePolicyAction, @@ -17,8 +18,8 @@ type SetupReturn = ReturnType; export type DeleteTestBed = SetupReturn extends Promise ? U : SetupReturn; -export const setupDeleteTestBed = async () => { - const testBed = await initTestBed(); +export const setupDeleteTestBed = async (httpSetup: HttpSetup) => { + const testBed = await initTestBed(httpSetup); const { exists } = testBed; return { diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/delete_phase.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/delete_phase.test.ts index f8c74ea91890e..d877f05d06ae1 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/delete_phase.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/delete_phase.test.ts @@ -18,11 +18,7 @@ import { DeleteTestBed, setupDeleteTestBed } from './delete_phase.helpers'; describe(' delete phase', () => { let testBed: DeleteTestBed; - const { server, httpRequestsMockHelpers } = setupEnvironment(); - - afterAll(() => { - server.restore(); - }); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeEach(async () => { httpRequestsMockHelpers.setLoadPolicies([DELETE_PHASE_POLICY]); @@ -32,7 +28,7 @@ describe(' delete phase', () => { ]); await act(async () => { - testBed = await setupDeleteTestBed(); + testBed = await setupDeleteTestBed(httpSetup); }); const { component } = testBed; @@ -43,7 +39,7 @@ describe(' delete phase', () => { httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy()]); await act(async () => { - testBed = await setupDeleteTestBed(); + testBed = await setupDeleteTestBed(httpSetup); }); const { component, actions } = testBed; @@ -72,7 +68,6 @@ describe(' delete phase', () => { await actions.savePolicy(); const expected = { - name: DELETE_PHASE_POLICY.name, phases: { ...DELETE_PHASE_POLICY.policy.phases, delete: { @@ -85,12 +80,13 @@ describe(' delete phase', () => { }, }, }, + name: DELETE_PHASE_POLICY.name, }; - const latestRequest = server.requests[server.requests.length - 1]; - expect(latestRequest.url).toBe(`${API_BASE_PATH}/policies`); - expect(latestRequest.method).toBe('POST'); - expect(JSON.parse(JSON.parse(latestRequest.requestBody).body)).toEqual(expected); + expect(httpSetup.post).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/policies`, + expect.objectContaining({ body: JSON.stringify(expected) }) + ); }); test('shows a callout when the input is not an existing policy', async () => { @@ -109,7 +105,6 @@ describe(' delete phase', () => { await actions.savePolicy(); const expected = { - name: DELETE_PHASE_POLICY.name, phases: { ...DELETE_PHASE_POLICY.policy.phases, delete: { @@ -119,19 +114,22 @@ describe(' delete phase', () => { }, }, }, + name: DELETE_PHASE_POLICY.name, }; delete expected.phases.delete.actions.wait_for_snapshot; - const latestRequest = server.requests[server.requests.length - 1]; - expect(JSON.parse(JSON.parse(latestRequest.requestBody).body)).toEqual(expected); + expect(httpSetup.post).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/policies`, + expect.objectContaining({ body: JSON.stringify(expected) }) + ); }); test('shows a callout when there are no snapshot policies', async () => { // need to call setup on testBed again for it to use a newly defined snapshot policies response httpRequestsMockHelpers.setLoadSnapshotPolicies([]); await act(async () => { - testBed = await setupDeleteTestBed(); + testBed = await setupDeleteTestBed(httpSetup); }); const { component, actions } = testBed; @@ -144,9 +142,10 @@ describe(' delete phase', () => { test('shows a callout when there is an error loading snapshot policies', async () => { // need to call setup on testBed again for it to use a newly defined snapshot policies response - httpRequestsMockHelpers.setLoadSnapshotPolicies([], { status: 500, body: 'error' }); + httpRequestsMockHelpers.setLoadSnapshotPolicies([], { statusCode: 500, message: 'error' }); + await act(async () => { - testBed = await setupDeleteTestBed(); + testBed = await setupDeleteTestBed(httpSetup); }); const { component, actions } = testBed; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/edit_warning.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/edit_warning.test.ts index 83b3a9fc53398..0cf57f4140aa4 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/edit_warning.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/edit_warning.test.ts @@ -13,7 +13,7 @@ import { getDefaultHotPhasePolicy, POLICY_NAME } from '../constants'; describe(' edit warning', () => { let testBed: TestBed; - const { server, httpRequestsMockHelpers } = setupEnvironment(); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { jest.useFakeTimers(); @@ -21,14 +21,13 @@ describe(' edit warning', () => { afterAll(() => { jest.useRealTimers(); - server.restore(); }); beforeEach(async () => { httpRequestsMockHelpers.setDefaultResponses(); await act(async () => { - testBed = await initTestBed(); + testBed = await initTestBed(httpSetup); }); const { component } = testBed; @@ -38,7 +37,7 @@ describe(' edit warning', () => { test('no edit warning for a new policy', async () => { httpRequestsMockHelpers.setLoadPolicies([]); await act(async () => { - testBed = await initTestBed(); + testBed = await initTestBed(httpSetup); }); const { exists, component } = testBed; component.update(); @@ -48,7 +47,7 @@ describe(' edit warning', () => { test('an edit warning is shown for an existing policy', async () => { httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy(POLICY_NAME)]); await act(async () => { - testBed = await initTestBed(); + testBed = await initTestBed(httpSetup); }); const { exists, component } = testBed; component.update(); @@ -60,7 +59,7 @@ describe(' edit warning', () => { { ...getDefaultHotPhasePolicy(POLICY_NAME), indices: [] }, ]); await act(async () => { - testBed = await initTestBed(); + testBed = await initTestBed(httpSetup); }); const { exists, component } = testBed; component.update(); @@ -72,7 +71,7 @@ describe(' edit warning', () => { { ...getDefaultHotPhasePolicy(POLICY_NAME), indexTemplates: [] }, ]); await act(async () => { - testBed = await initTestBed(); + testBed = await initTestBed(httpSetup); }); const { exists, component } = testBed; component.update(); @@ -87,7 +86,7 @@ describe(' edit warning', () => { }, ]); await act(async () => { - testBed = await initTestBed(); + testBed = await initTestBed(httpSetup); }); const { component, find } = testBed; component.update(); @@ -102,7 +101,7 @@ describe(' edit warning', () => { }, ]); await act(async () => { - testBed = await initTestBed(); + testBed = await initTestBed(httpSetup); }); const { component, find } = testBed; component.update(); @@ -117,7 +116,7 @@ describe(' edit warning', () => { }, ]); await act(async () => { - testBed = await initTestBed(); + testBed = await initTestBed(httpSetup); }); const { component, find, exists } = testBed; component.update(); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/frozen_phase.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/frozen_phase.test.ts index 05370558ae69d..ffe11133be7fd 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/frozen_phase.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/frozen_phase.test.ts @@ -14,7 +14,7 @@ import { initTestBed } from '../init_test_bed'; describe(' frozen phase', () => { let testBed: TestBed; - const { server, httpRequestsMockHelpers } = setupEnvironment(); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { jest.useFakeTimers(); @@ -22,14 +22,13 @@ describe(' frozen phase', () => { afterAll(() => { jest.useRealTimers(); - server.restore(); }); beforeEach(async () => { httpRequestsMockHelpers.setDefaultResponses(); await act(async () => { - testBed = await initTestBed(); + testBed = await initTestBed(httpSetup); }); const { component } = testBed; @@ -41,7 +40,7 @@ describe(' frozen phase', () => { httpRequestsMockHelpers.setDefaultResponses(); await act(async () => { - testBed = await initTestBed({ + testBed = await initTestBed(httpSetup, { appServicesContext: { license: licensingMock.createLicense({ license: { type: 'basic' } }), }, diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cloud_aware_behavior.helpers.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cloud_aware_behavior.helpers.ts index a0a1c80c90bbe..7092d52289de9 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cloud_aware_behavior.helpers.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cloud_aware_behavior.helpers.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { HttpSetup } from '@kbn/core/public'; import { TestBedConfig } from '@kbn/test-jest-helpers'; import { AppServicesContext } from '../../../../../public/types'; @@ -15,11 +16,14 @@ type SetupReturn = ReturnType; export type CloudNodeAllocationTestBed = SetupReturn extends Promise ? U : SetupReturn; -export const setupCloudNodeAllocation = async (arg?: { - appServicesContext?: Partial; - testBedConfig?: Partial; -}) => { - const testBed = await initTestBed(arg); +export const setupCloudNodeAllocation = async ( + httpSetup: HttpSetup, + arg?: { + appServicesContext?: Partial; + testBedConfig?: Partial; + } +) => { + const testBed = await initTestBed(httpSetup, arg); return { ...testBed, diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cloud_aware_behavior.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cloud_aware_behavior.test.ts index 136865329eb50..820f8a4f9100a 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cloud_aware_behavior.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cloud_aware_behavior.test.ts @@ -14,7 +14,7 @@ import { describe(' node allocation cloud-aware behavior', () => { let testBed: CloudNodeAllocationTestBed; - const { server, httpRequestsMockHelpers } = setupEnvironment(); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { jest.useFakeTimers(); @@ -22,23 +22,21 @@ describe(' node allocation cloud-aware behavior', () => { afterAll(() => { jest.useRealTimers(); - server.restore(); }); const setup = async (isOnCloud?: boolean) => { await act(async () => { if (Boolean(isOnCloud)) { - testBed = await setupCloudNodeAllocation({ + testBed = await setupCloudNodeAllocation(httpSetup, { appServicesContext: { cloud: { isCloudEnabled: true } }, }); } else { - testBed = await setupCloudNodeAllocation(); + testBed = await setupCloudNodeAllocation(httpSetup); } }); }; beforeEach(async () => { - server.respondImmediately = true; httpRequestsMockHelpers.setLoadPolicies([]); httpRequestsMockHelpers.setListNodes({ nodesByRoles: { data: ['node1'] }, diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cold_phase.helpers.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cold_phase.helpers.ts index 9848915f8feb9..16a545f882587 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cold_phase.helpers.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cold_phase.helpers.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { HttpSetup } from '@kbn/core/public'; import { createNodeAllocationActions, createTogglePhaseAction } from '../../../helpers'; import { initTestBed } from '../../init_test_bed'; @@ -12,8 +13,8 @@ type SetupReturn = ReturnType; export type NodeAllocationTestBed = SetupReturn extends Promise ? U : SetupReturn; -export const setupColdPhaseNodeAllocation = async () => { - const testBed = await initTestBed(); +export const setupColdPhaseNodeAllocation = async (httpSetup: HttpSetup) => { + const testBed = await initTestBed(httpSetup); return { ...testBed, diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cold_phase.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cold_phase.test.ts index e2093e04b7779..63382de45f414 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cold_phase.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cold_phase.test.ts @@ -11,7 +11,7 @@ import { NodeAllocationTestBed, setupColdPhaseNodeAllocation } from './cold_phas describe(' node allocation in the cold phase', () => { let testBed: NodeAllocationTestBed; - const { server, httpRequestsMockHelpers } = setupEnvironment(); + const { httpSetup, setDelayResponse, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { jest.useFakeTimers(); @@ -19,17 +19,15 @@ describe(' node allocation in the cold phase', () => { afterAll(() => { jest.useRealTimers(); - server.restore(); }); const setup = async () => { await act(async () => { - testBed = await setupColdPhaseNodeAllocation(); + testBed = await setupColdPhaseNodeAllocation(httpSetup); }); }; beforeEach(async () => { - server.respondImmediately = true; httpRequestsMockHelpers.setLoadPolicies([]); httpRequestsMockHelpers.setListNodes({ nodesByRoles: { data: ['node1'] }, @@ -64,7 +62,8 @@ describe(' node allocation in the cold phase', () => { describe('when using node attributes', () => { test('shows spinner for node attributes input when loading', async () => { - server.respondImmediately = false; + // We don't want the request to resolve immediately. + setDelayResponse(true); const { actions } = testBed; await actions.toggleColdPhase(); @@ -78,6 +77,9 @@ describe(' node allocation in the cold phase', () => { expect(actions.hasWillUseFallbackTierUsingNodeAttributesNotice()).toBeFalsy(); expect(actions.hasDefaultToDataNodesNotice()).toBeFalsy(); expect(actions.hasNoTiersAvailableUsingNodeAttributesNotice()).toBeFalsy(); + + // Reset delayed response status + setDelayResponse(false); }); describe('and some are defined', () => { diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/general_behavior.helpers.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/general_behavior.helpers.ts index 384478bcf4c66..ac7dbb61518c7 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/general_behavior.helpers.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/general_behavior.helpers.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { HttpSetup } from '@kbn/core/public'; import { createNodeAllocationActions, createReplicasAction, @@ -16,8 +17,8 @@ type SetupReturn = ReturnType; export type GeneralNodeAllocationTestBed = SetupReturn extends Promise ? U : SetupReturn; -export const setupGeneralNodeAllocation = async () => { - const testBed = await initTestBed(); +export const setupGeneralNodeAllocation = async (httpSetup: HttpSetup) => { + const testBed = await initTestBed(httpSetup); return { ...testBed, diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/general_behavior.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/general_behavior.test.ts index cac6c174b769e..1eecd5207664f 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/general_behavior.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/general_behavior.test.ts @@ -6,6 +6,7 @@ */ import { act } from 'react-dom/test-utils'; +import { HttpFetchOptionsWithPath } from '@kbn/core/public'; import { setupEnvironment } from '../../../helpers'; import { GeneralNodeAllocationTestBed, @@ -16,10 +17,11 @@ import { POLICY_WITH_NODE_ATTR_AND_OFF_ALLOCATION, POLICY_WITH_NODE_ROLE_ALLOCATION, } from '../../constants'; +import { API_BASE_PATH } from '../../../../../common/constants'; describe(' node allocation general behavior', () => { let testBed: GeneralNodeAllocationTestBed; - const { server, httpRequestsMockHelpers } = setupEnvironment(); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { jest.useFakeTimers(); @@ -27,12 +29,11 @@ describe(' node allocation general behavior', () => { afterAll(() => { jest.useRealTimers(); - server.restore(); }); const setup = async () => { await act(async () => { - testBed = await setupGeneralNodeAllocation(); + testBed = await setupGeneralNodeAllocation(httpSetup); }); }; @@ -53,10 +54,13 @@ describe(' node allocation general behavior', () => { await actions.setDataAllocation('node_attrs'); await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - const warmPhase = JSON.parse(JSON.parse(latestRequest.requestBody).body).phases.warm; - expect(warmPhase.actions.migrate).toEqual({ enabled: false }); + const lastReq: HttpFetchOptionsWithPath[] = httpSetup.post.mock.calls.pop() || []; + const [requestUrl, requestBody] = lastReq; + const parsedReqBody = JSON.parse((requestBody as Record).body); + + expect(requestUrl).toBe(`${API_BASE_PATH}/policies`); + expect(parsedReqBody.phases.warm.actions.migrate).toEqual({ enabled: false }); }); describe('node roles', () => { @@ -84,12 +88,16 @@ describe(' node allocation general behavior', () => { test('setting replicas serialization', async () => { const { actions } = testBed; + await actions.setReplicas('123'); await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - const warmPhaseActions = JSON.parse(JSON.parse(latestRequest.requestBody).body).phases.warm - .actions; - expect(warmPhaseActions).toMatchInlineSnapshot(` + + const lastReq: HttpFetchOptionsWithPath[] = httpSetup.post.mock.calls.pop() || []; + const [requestUrl, requestBody] = lastReq; + const parsedReqBody = JSON.parse((requestBody as Record).body); + + expect(requestUrl).toBe(`${API_BASE_PATH}/policies`); + expect(parsedReqBody.phases.warm.actions).toMatchInlineSnapshot(` Object { "allocate": Object { "number_of_replicas": 123, diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/warm_phase.helpers.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/warm_phase.helpers.ts index 5c576ebf74ccb..375b3a633297e 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/warm_phase.helpers.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/warm_phase.helpers.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { HttpSetup } from '@kbn/core/public'; import { createNodeAllocationActions, createTogglePhaseAction } from '../../../helpers'; import { initTestBed } from '../../init_test_bed'; @@ -12,8 +13,8 @@ type SetupReturn = ReturnType; export type NodeAllocationTestBed = SetupReturn extends Promise ? U : SetupReturn; -export const setupWarmPhaseNodeAllocation = async () => { - const testBed = await initTestBed(); +export const setupWarmPhaseNodeAllocation = async (httpSetup: HttpSetup) => { + const testBed = await initTestBed(httpSetup); return { ...testBed, diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/warm_phase.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/warm_phase.test.ts index 8d4d0afcf052d..6f96aaf07da1b 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/warm_phase.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/warm_phase.test.ts @@ -11,7 +11,7 @@ import { NodeAllocationTestBed, setupWarmPhaseNodeAllocation } from './warm_phas describe(' node allocation in the warm phase', () => { let testBed: NodeAllocationTestBed; - const { server, httpRequestsMockHelpers } = setupEnvironment(); + const { httpSetup, setDelayResponse, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { jest.useFakeTimers(); @@ -19,17 +19,15 @@ describe(' node allocation in the warm phase', () => { afterAll(() => { jest.useRealTimers(); - server.restore(); }); const setup = async () => { await act(async () => { - testBed = await setupWarmPhaseNodeAllocation(); + testBed = await setupWarmPhaseNodeAllocation(httpSetup); }); }; beforeEach(async () => { - server.respondImmediately = true; httpRequestsMockHelpers.setLoadPolicies([]); httpRequestsMockHelpers.setListNodes({ nodesByRoles: { data: ['node1'] }, @@ -64,7 +62,8 @@ describe(' node allocation in the warm phase', () => { describe('when using node attributes', () => { test('shows spinner for node attributes input when loading', async () => { - server.respondImmediately = false; + // We don't want the request to resolve immediately. + setDelayResponse(true); const { actions } = testBed; await actions.togglePhase(); @@ -78,6 +77,9 @@ describe(' node allocation in the warm phase', () => { expect(actions.hasWillUseFallbackTierUsingNodeAttributesNotice()).toBeFalsy(); expect(actions.hasDefaultToDataNodesNotice()).toBeFalsy(); expect(actions.hasNoTiersAvailableUsingNodeAttributesNotice()).toBeFalsy(); + + // Reset delayed response status + setDelayResponse(false); }); describe('and some are defined', () => { diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/request_flyout.helpers.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/request_flyout.helpers.ts index d74e2877c9fcd..540324d171971 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/request_flyout.helpers.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/request_flyout.helpers.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { HttpSetup } from '@kbn/core/public'; import { createFormSetValueAction, createMinAgeActions, @@ -18,10 +19,12 @@ type SetupReturn = ReturnType; export type RequestFlyoutTestBed = SetupReturn extends Promise ? U : SetupReturn; -export const setupRequestFlyoutTestBed = async (isNewPolicy?: boolean) => { +export const setupRequestFlyoutTestBed = async (httpSetup: HttpSetup, isNewPolicy?: boolean) => { const testBed = isNewPolicy - ? await initTestBed({ testBedConfig: { memoryRouter: { initialEntries: ['/policies/edit'] } } }) - : await initTestBed(); + ? await initTestBed(httpSetup, { + testBedConfig: { memoryRouter: { initialEntries: ['/policies/edit'] } }, + }) + : await initTestBed(httpSetup); return { ...testBed, diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/request_flyout.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/request_flyout.test.ts index e49a1c5c94f90..61dda6fa65efb 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/request_flyout.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/request_flyout.test.ts @@ -12,7 +12,7 @@ import { getDefaultHotPhasePolicy } from '../constants'; describe(' request flyout', () => { let testBed: RequestFlyoutTestBed; - const { server, httpRequestsMockHelpers } = setupEnvironment(); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { jest.useFakeTimers(); @@ -20,14 +20,13 @@ describe(' request flyout', () => { afterAll(() => { jest.useRealTimers(); - server.restore(); }); beforeEach(async () => { httpRequestsMockHelpers.setDefaultResponses(); await act(async () => { - testBed = await setupRequestFlyoutTestBed(); + testBed = await setupRequestFlyoutTestBed(httpSetup); }); const { component } = testBed; @@ -93,7 +92,7 @@ describe(' request flyout', () => { test('renders the correct json and name for a new policy', async () => { await act(async () => { - testBed = await setupRequestFlyoutTestBed(true); + testBed = await setupRequestFlyoutTestBed(httpSetup, true); }); const { component, actions } = testBed; @@ -154,7 +153,7 @@ describe(' request flyout', () => { httpRequestsMockHelpers.setLoadPolicies([policyWithMetaField]); await act(async () => { - testBed = await setupRequestFlyoutTestBed(); + testBed = await setupRequestFlyoutTestBed(httpSetup); }); const { component, actions } = testBed; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/rollover.helpers.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/rollover.helpers.ts index b15e956c84b4c..707240c459161 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/rollover.helpers.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/rollover.helpers.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { HttpSetup } from '@kbn/core/public'; import { createForceMergeActions, createMinAgeActions, @@ -20,8 +21,8 @@ type SetupReturn = ReturnType; export type RolloverTestBed = SetupReturn extends Promise ? U : SetupReturn; -export const setupRolloverTestBed = async () => { - const testBed = await initTestBed(); +export const setupRolloverTestBed = async (httpSetup: HttpSetup) => { + const testBed = await initTestBed(httpSetup); return { ...testBed, diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/rollover.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/rollover.test.ts index 432b07efca038..1544390229595 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/rollover.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/rollover.test.ts @@ -11,17 +11,13 @@ import { RolloverTestBed, setupRolloverTestBed } from './rollover.helpers'; describe(' rollover', () => { let testBed: RolloverTestBed; - const { server, httpRequestsMockHelpers } = setupEnvironment(); - - afterAll(() => { - server.restore(); - }); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeEach(async () => { httpRequestsMockHelpers.setDefaultResponses(); await act(async () => { - testBed = await setupRolloverTestBed(); + testBed = await setupRolloverTestBed(httpSetup); }); const { component } = testBed; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/searchable_snapshots.helpers.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/searchable_snapshots.helpers.ts index 23b64c3dade19..f4b41cedd70f1 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/searchable_snapshots.helpers.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/searchable_snapshots.helpers.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { HttpSetup } from '@kbn/core/public'; import { createForceMergeActions, createMinAgeActions, @@ -22,10 +23,13 @@ type SetupReturn = ReturnType; export type SearchableSnapshotsTestBed = SetupReturn extends Promise ? U : SetupReturn; -export const setupSearchableSnapshotsTestBed = async (args?: { - appServicesContext?: Partial; -}) => { - const testBed = await initTestBed(args); +export const setupSearchableSnapshotsTestBed = async ( + httpSetup: HttpSetup, + args?: { + appServicesContext?: Partial; + } +) => { + const testBed = await initTestBed(httpSetup, args); return { ...testBed, diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/searchable_snapshots.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/searchable_snapshots.test.ts index 571170b78b66b..09bb8b85082b6 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/searchable_snapshots.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/searchable_snapshots.test.ts @@ -7,8 +7,10 @@ import { act } from 'react-dom/test-utils'; import { licensingMock } from '@kbn/licensing-plugin/public/mocks'; +import { HttpFetchOptionsWithPath } from '@kbn/core/public'; import { setupEnvironment } from '../../helpers'; import { getDefaultHotPhasePolicy } from '../constants'; +import { API_BASE_PATH } from '../../../../common/constants'; import { SearchableSnapshotsTestBed, setupSearchableSnapshotsTestBed, @@ -16,17 +18,13 @@ import { describe(' searchable snapshots', () => { let testBed: SearchableSnapshotsTestBed; - const { server, httpRequestsMockHelpers } = setupEnvironment(); - - afterAll(() => { - server.restore(); - }); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeEach(async () => { httpRequestsMockHelpers.setDefaultResponses(); await act(async () => { - testBed = await setupSearchableSnapshotsTestBed(); + testBed = await setupSearchableSnapshotsTestBed(httpSetup); }); const { component } = testBed; @@ -78,14 +76,21 @@ describe(' searchable snapshots', () => { await actions.frozen.setMinAgeValue('15'); await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - expect(latestRequest.method).toBe('POST'); - expect(latestRequest.url).toBe('/api/index_lifecycle_management/policies'); - const reqBody = JSON.parse(JSON.parse(latestRequest.requestBody).body); - - expect(reqBody.phases.hot.actions.searchable_snapshot.snapshot_repository).toBe(repository); - expect(reqBody.phases.cold.actions.searchable_snapshot.snapshot_repository).toBe(repository); - expect(reqBody.phases.frozen.actions.searchable_snapshot.snapshot_repository).toBe(repository); + + const lastReq: HttpFetchOptionsWithPath[] = httpSetup.post.mock.calls.pop() || []; + const [requestUrl, requestBody] = lastReq; + const parsedReqBody = JSON.parse((requestBody as Record).body); + + expect(requestUrl).toBe(`${API_BASE_PATH}/policies`); + expect(parsedReqBody.phases.hot.actions.searchable_snapshot.snapshot_repository).toBe( + repository + ); + expect(parsedReqBody.phases.cold.actions.searchable_snapshot.snapshot_repository).toBe( + repository + ); + expect(parsedReqBody.phases.frozen.actions.searchable_snapshot.snapshot_repository).toBe( + repository + ); }); test('should update the repository in all searchable snapshot actions', async () => { @@ -101,13 +106,22 @@ describe(' searchable snapshots', () => { // We update the repository in one phase await actions.frozen.setSearchableSnapshot('changed'); await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - const reqBody = JSON.parse(JSON.parse(latestRequest.requestBody).body); + const lastReq: HttpFetchOptionsWithPath[] = httpSetup.post.mock.calls.pop() || []; + const [requestUrl, requestBody] = lastReq; + const parsedReqBody = JSON.parse((requestBody as Record).body); + + expect(requestUrl).toBe(`${API_BASE_PATH}/policies`); // And all phases should be updated - expect(reqBody.phases.hot.actions.searchable_snapshot.snapshot_repository).toBe('changed'); - expect(reqBody.phases.cold.actions.searchable_snapshot.snapshot_repository).toBe('changed'); - expect(reqBody.phases.frozen.actions.searchable_snapshot.snapshot_repository).toBe('changed'); + expect(parsedReqBody.phases.hot.actions.searchable_snapshot.snapshot_repository).toBe( + 'changed' + ); + expect(parsedReqBody.phases.cold.actions.searchable_snapshot.snapshot_repository).toBe( + 'changed' + ); + expect(parsedReqBody.phases.frozen.actions.searchable_snapshot.snapshot_repository).toBe( + 'changed' + ); }); describe('on cloud', () => { @@ -123,7 +137,7 @@ describe(' searchable snapshots', () => { httpRequestsMockHelpers.setListSnapshotRepos({ repositories: ['found-snapshots'] }); await act(async () => { - testBed = await setupSearchableSnapshotsTestBed({ + testBed = await setupSearchableSnapshotsTestBed(httpSetup, { appServicesContext: { cloud: { isCloudEnabled: true } }, }); }); @@ -152,7 +166,7 @@ describe(' searchable snapshots', () => { httpRequestsMockHelpers.setListSnapshotRepos({ repositories: ['found-snapshots'] }); await act(async () => { - testBed = await setupSearchableSnapshotsTestBed({ + testBed = await setupSearchableSnapshotsTestBed(httpSetup, { appServicesContext: { cloud: { isCloudEnabled: true } }, }); }); @@ -166,12 +180,15 @@ describe(' searchable snapshots', () => { await actions.togglePhase('cold'); await actions.cold.setMinAgeValue('10'); await actions.cold.toggleSearchableSnapshot(); + await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - expect(latestRequest.method).toBe('POST'); - expect(latestRequest.url).toBe('/api/index_lifecycle_management/policies'); - const reqBody = JSON.parse(JSON.parse(latestRequest.requestBody).body); - expect(reqBody.phases.cold.actions.searchable_snapshot.snapshot_repository).toEqual( + + const lastReq: HttpFetchOptionsWithPath[] = httpSetup.post.mock.calls.pop() || []; + const [requestUrl, requestBody] = lastReq; + const parsedReqBody = JSON.parse((requestBody as Record).body); + + expect(requestUrl).toBe(`${API_BASE_PATH}/policies`); + expect(parsedReqBody.phases.cold.actions.searchable_snapshot.snapshot_repository).toEqual( 'found-snapshots' ); }); @@ -189,7 +206,7 @@ describe(' searchable snapshots', () => { httpRequestsMockHelpers.setListSnapshotRepos({ repositories: ['my-repo'] }); await act(async () => { - testBed = await setupSearchableSnapshotsTestBed({ + testBed = await setupSearchableSnapshotsTestBed(httpSetup, { appServicesContext: { license: licensingMock.createLicense({ license: { type: 'basic' } }), }, diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timeline.helpers.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timeline.helpers.ts index 8303fdbac4837..496b27330c931 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timeline.helpers.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timeline.helpers.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { HttpSetup } from '@kbn/core/public'; import { createTogglePhaseAction } from '../../helpers'; import { initTestBed } from '../init_test_bed'; import { Phase } from '../../../../common/types'; @@ -13,8 +14,8 @@ type SetupReturn = ReturnType; export type TimelineTestBed = SetupReturn extends Promise ? U : SetupReturn; -export const setupTimelineTestBed = async () => { - const testBed = await initTestBed(); +export const setupTimelineTestBed = async (httpSetup: HttpSetup) => { + const testBed = await initTestBed(httpSetup); const { exists } = testBed; return { diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timeline.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timeline.test.ts index 33aeb80b38cae..760ede62606cb 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timeline.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timeline.test.ts @@ -11,17 +11,13 @@ import { setupTimelineTestBed, TimelineTestBed } from './timeline.helpers'; describe(' timeline', () => { let testBed: TimelineTestBed; - const { server, httpRequestsMockHelpers } = setupEnvironment(); - - afterAll(() => { - server.restore(); - }); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeEach(async () => { httpRequestsMockHelpers.setDefaultResponses(); await act(async () => { - testBed = await setupTimelineTestBed(); + testBed = await setupTimelineTestBed(httpSetup); }); const { component } = testBed; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timing.helpers.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timing.helpers.ts index 57d6f53a21c78..dc70d2dd5ef61 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timing.helpers.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timing.helpers.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { HttpSetup } from '@kbn/core/public'; import { createMinAgeActions, createTogglePhaseAction } from '../../helpers'; import { initTestBed } from '../init_test_bed'; @@ -12,8 +13,8 @@ type SetupReturn = ReturnType; export type TimingTestBed = SetupReturn extends Promise ? U : SetupReturn; -export const setupTimingTestBed = async () => { - const testBed = await initTestBed(); +export const setupTimingTestBed = async (httpSetup: HttpSetup) => { + const testBed = await initTestBed(httpSetup); return { ...testBed, diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timing.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timing.test.ts index 985ee807ed827..0aee8eb5f0be1 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timing.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timing.test.ts @@ -12,17 +12,13 @@ import { PhaseWithTiming } from '../../../../common/types'; describe(' timing', () => { let testBed: TimingTestBed; - const { server, httpRequestsMockHelpers } = setupEnvironment(); - - afterAll(() => { - server.restore(); - }); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeEach(async () => { httpRequestsMockHelpers.setDefaultResponses(); await act(async () => { - testBed = await setupTimingTestBed(); + testBed = await setupTimingTestBed(httpSetup); }); const { component } = testBed; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/cold_phase_validation.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/cold_phase_validation.test.ts index 4725631e6f894..98891ea72928f 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/cold_phase_validation.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/cold_phase_validation.test.ts @@ -12,7 +12,7 @@ import { setupValidationTestBed, ValidationTestBed } from './validation.helpers' describe(' cold phase validation', () => { let testBed: ValidationTestBed; - const { server, httpRequestsMockHelpers } = setupEnvironment(); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { jest.useFakeTimers(); @@ -20,7 +20,6 @@ describe(' cold phase validation', () => { afterAll(() => { jest.useRealTimers(); - server.restore(); }); beforeEach(async () => { @@ -35,7 +34,7 @@ describe(' cold phase validation', () => { ]); await act(async () => { - testBed = await setupValidationTestBed(); + testBed = await setupValidationTestBed(httpSetup); }); const { component, actions } = testBed; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/error_indicators.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/error_indicators.test.ts index 1464f683ef766..bd4a2caec0be5 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/error_indicators.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/error_indicators.test.ts @@ -11,7 +11,7 @@ import { setupValidationTestBed, ValidationTestBed } from './validation.helpers' describe(' error indicators', () => { let testBed: ValidationTestBed; - const { server, httpRequestsMockHelpers } = setupEnvironment(); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { jest.useFakeTimers(); @@ -19,14 +19,13 @@ describe(' error indicators', () => { afterAll(() => { jest.useRealTimers(); - server.restore(); }); beforeEach(async () => { httpRequestsMockHelpers.setDefaultResponses(); await act(async () => { - testBed = await setupValidationTestBed(); + testBed = await setupValidationTestBed(httpSetup); }); const { component } = testBed; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/hot_phase_validation.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/hot_phase_validation.test.ts index 6dca2b7b23fb7..b0f0857bd0501 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/hot_phase_validation.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/hot_phase_validation.test.ts @@ -13,7 +13,7 @@ import { setupValidationTestBed, ValidationTestBed } from './validation.helpers' describe(' hot phase validation', () => { let testBed: ValidationTestBed; let actions: ValidationTestBed['actions']; - const { server, httpRequestsMockHelpers } = setupEnvironment(); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { jest.useFakeTimers(); @@ -21,13 +21,12 @@ describe(' hot phase validation', () => { afterAll(() => { jest.useRealTimers(); - server.restore(); }); beforeEach(async () => { httpRequestsMockHelpers.setLoadPolicies([]); await act(async () => { - testBed = await setupValidationTestBed(); + testBed = await setupValidationTestBed(httpSetup); }); const { component } = testBed; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/policy_name_validation.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/policy_name_validation.test.ts index 799fbf89d47df..9c14584bb2fcf 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/policy_name_validation.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/policy_name_validation.test.ts @@ -14,7 +14,7 @@ import { setupValidationTestBed, ValidationTestBed } from './validation.helpers' describe(' policy name validation', () => { let testBed: ValidationTestBed; let actions: ValidationTestBed['actions']; - const { server, httpRequestsMockHelpers } = setupEnvironment(); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { jest.useFakeTimers(); @@ -22,14 +22,13 @@ describe(' policy name validation', () => { afterAll(() => { jest.useRealTimers(); - server.restore(); }); beforeEach(async () => { httpRequestsMockHelpers.setLoadPolicies(getGeneratedPolicies()); await act(async () => { - testBed = await setupValidationTestBed(); + testBed = await setupValidationTestBed(httpSetup); }); const { component } = testBed; @@ -56,7 +55,7 @@ describe(' policy name validation', () => { test(`doesn't allow to save as new policy but using the same name`, async () => { await act(async () => { - testBed = await setupValidationTestBed({ + testBed = await setupValidationTestBed(httpSetup, { testBedConfig: { memoryRouter: { initialEntries: [`/policies/edit/testy0`], diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/timing.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/timing.test.ts index be4f99103b319..3e29bc5d76580 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/timing.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/timing.test.ts @@ -15,7 +15,7 @@ import { setupValidationTestBed, ValidationTestBed } from './validation.helpers' describe(' timing validation', () => { let testBed: ValidationTestBed; let actions: ValidationTestBed['actions']; - const { server, httpRequestsMockHelpers } = setupEnvironment(); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { jest.useFakeTimers(); @@ -23,7 +23,6 @@ describe(' timing validation', () => { afterAll(() => { jest.useRealTimers(); - server.restore(); }); beforeEach(async () => { @@ -31,7 +30,7 @@ describe(' timing validation', () => { httpRequestsMockHelpers.setLoadPolicies([]); await act(async () => { - testBed = await setupValidationTestBed(); + testBed = await setupValidationTestBed(httpSetup); }); const { component } = testBed; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/validation.helpers.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/validation.helpers.ts index 5b5d3819c3463..592f081929b50 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/validation.helpers.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/validation.helpers.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { HttpSetup } from '@kbn/core/public'; import { TestBedConfig } from '@kbn/test-jest-helpers'; import { createColdPhaseActions, @@ -25,8 +26,11 @@ type SetupReturn = ReturnType; export type ValidationTestBed = SetupReturn extends Promise ? U : SetupReturn; -export const setupValidationTestBed = async (arg?: { testBedConfig?: Partial }) => { - const testBed = await initTestBed(arg); +export const setupValidationTestBed = async ( + httpSetup: HttpSetup, + arg?: { testBedConfig?: Partial } +) => { + const testBed = await initTestBed(httpSetup, arg); return { ...testBed, diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/warm_phase_validation.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/warm_phase_validation.test.ts index 741611f2d2c3b..9d326e9978519 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/warm_phase_validation.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/warm_phase_validation.test.ts @@ -12,7 +12,7 @@ import { setupValidationTestBed, ValidationTestBed } from './validation.helpers' describe(' warm phase validation', () => { let testBed: ValidationTestBed; - const { server, httpRequestsMockHelpers } = setupEnvironment(); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { jest.useFakeTimers(); @@ -20,7 +20,6 @@ describe(' warm phase validation', () => { afterAll(() => { jest.useRealTimers(); - server.restore(); }); beforeEach(async () => { @@ -28,7 +27,7 @@ describe(' warm phase validation', () => { httpRequestsMockHelpers.setLoadPolicies([]); await act(async () => { - testBed = await setupValidationTestBed(); + testBed = await setupValidationTestBed(httpSetup); }); const { component, actions } = testBed; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/init_test_bed.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/init_test_bed.ts new file mode 100644 index 0000000000000..875bf9db36264 --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/init_test_bed.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { registerTestBed, TestBedConfig } from '@kbn/test-jest-helpers'; + +import { HttpSetup } from '@kbn/core/public'; +import { WithAppDependencies } from '../helpers'; +import { EditPolicy } from '../../../public/application/sections/edit_policy'; +import { AppServicesContext } from '../../../public/types'; +import { POLICY_NAME } from './constants'; + +const getTestBedConfig = (testBedConfig?: Partial): TestBedConfig => { + return { + memoryRouter: { + initialEntries: [`/policies/edit/${POLICY_NAME}`], + componentRoutePath: `/policies/edit/:policyName`, + }, + ...testBedConfig, + }; +}; + +export const initTestBed = async ( + httpSetup: HttpSetup, + arg?: { + appServicesContext?: Partial; + testBedConfig?: Partial; + } +) => { + const { testBedConfig, appServicesContext } = arg || {}; + + const createTestBed = registerTestBed( + WithAppDependencies(EditPolicy, httpSetup, appServicesContext), + getTestBedConfig(testBedConfig) + ); + + return await createTestBed(); +}; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/init_test_bed.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/init_test_bed.tsx deleted file mode 100644 index 6e68032d9b0ea..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/init_test_bed.tsx +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { registerTestBed, TestBedConfig } from '@kbn/test-jest-helpers'; -import { docLinksServiceMock } from '@kbn/core/public/mocks'; - -import '../helpers/global_mocks'; - -import { licensingMock } from '@kbn/licensing-plugin/public/mocks'; -import { EditPolicy } from '../../../public/application/sections/edit_policy'; -import { KibanaContextProvider } from '../../../public/shared_imports'; -import { AppServicesContext } from '../../../public/types'; -import { createBreadcrumbsMock } from '../../../public/application/services/breadcrumbs.mock'; -import { POLICY_NAME } from './constants'; - -const getTestBedConfig = (testBedConfigArgs?: Partial): TestBedConfig => { - return { - memoryRouter: { - initialEntries: [`/policies/edit/${POLICY_NAME}`], - componentRoutePath: `/policies/edit/:policyName`, - }, - ...testBedConfigArgs, - }; -}; - -const breadcrumbService = createBreadcrumbsMock(); - -const EditPolicyContainer = ({ appServicesContext, ...rest }: any) => { - return ( - {}, - ...appServicesContext, - }} - > - - - ); -}; - -export const initTestBed = (arg?: { - appServicesContext?: Partial; - testBedConfig?: Partial; -}) => { - const { testBedConfig: testBedConfigArgs, ...rest } = arg || {}; - return registerTestBed(EditPolicyContainer, getTestBedConfig(testBedConfigArgs))(rest); -}; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/serialization/policy_serialization.helpers.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/serialization/policy_serialization.helpers.ts index 52d4debca9315..417f53c63a20c 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/serialization/policy_serialization.helpers.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/serialization/policy_serialization.helpers.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { HttpSetup } from '@kbn/core/public'; import { AppServicesContext } from '../../../../public/types'; import { createColdPhaseActions, @@ -23,10 +24,13 @@ type SetupReturn = ReturnType; export type SerializationTestBed = SetupReturn extends Promise ? U : SetupReturn; -export const setupSerializationTestBed = async (arg?: { - appServicesContext?: Partial; -}) => { - const testBed = await initTestBed(arg); +export const setupSerializationTestBed = async ( + httpSetup: HttpSetup, + arg?: { + appServicesContext?: Partial; + } +) => { + const testBed = await initTestBed(httpSetup, arg); return { ...testBed, diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/serialization/policy_serialization.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/serialization/policy_serialization.test.ts index 4e3d9fe737f4c..d539d7a6e48ce 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/serialization/policy_serialization.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/serialization/policy_serialization.test.ts @@ -7,7 +7,9 @@ import { act } from 'react-dom/test-utils'; import { licensingMock } from '@kbn/licensing-plugin/public/mocks'; +import { HttpFetchOptionsWithPath } from '@kbn/core/public'; import { setupEnvironment } from '../../helpers'; +import { API_BASE_PATH } from '../../../../common/constants'; import { getDefaultHotPhasePolicy, POLICY_WITH_INCLUDE_EXCLUDE, @@ -17,17 +19,13 @@ import { SerializationTestBed, setupSerializationTestBed } from './policy_serial describe(' serialization', () => { let testBed: SerializationTestBed; - const { server, httpRequestsMockHelpers } = setupEnvironment(); - - afterAll(() => { - server.restore(); - }); + const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeEach(async () => { httpRequestsMockHelpers.setDefaultResponses(); await act(async () => { - testBed = await setupSerializationTestBed(); + testBed = await setupSerializationTestBed(httpSetup); }); const { component } = testBed; @@ -35,6 +33,16 @@ describe(' serialization', () => { }); describe('top level form', () => { + afterAll(async () => { + await act(async () => { + testBed = await setupSerializationTestBed(httpSetup, { + appServicesContext: { + license: licensingMock.createLicense({ license: { type: 'enterprise' } }), + }, + }); + }); + }); + /** * We assume that policies that populate this form are loaded directly from ES and so * are valid according to ES. There may be settings in the policy created through the ILM @@ -44,7 +52,7 @@ describe(' serialization', () => { it('preserves policy settings it did not configure', async () => { httpRequestsMockHelpers.setLoadPolicies([POLICY_WITH_KNOWN_AND_UNKNOWN_FIELDS]); await act(async () => { - testBed = await setupSerializationTestBed(); + testBed = await setupSerializationTestBed(httpSetup); }); const { component, actions } = testBed; @@ -56,42 +64,44 @@ describe(' serialization', () => { await actions.togglePhase('delete'); await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - const entirePolicy = JSON.parse(JSON.parse(latestRequest.requestBody).body); - - expect(entirePolicy).toEqual({ - foo: 'bar', // Made up value - name: 'my_policy', - phases: { - hot: { - actions: { - rollover: { - max_docs: 1000, - max_size: '50gb', - unknown_setting: 123, // Made up setting that should stay preserved + expect(httpSetup.post).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/policies`, + expect.objectContaining({ + body: JSON.stringify({ + foo: 'bar', // Made up value + phases: { + hot: { + min_age: '0ms', + actions: { + rollover: { + unknown_setting: 123, // Made up setting that should stay preserved + max_size: '50gb', + max_docs: 1000, + }, + }, }, - }, - min_age: '0ms', - }, - warm: { - actions: { - my_unfollow_action: {}, // Made up action - set_priority: { - priority: 22, - unknown_setting: true, + warm: { + min_age: '10d', + actions: { + my_unfollow_action: {}, // Made up action + set_priority: { + priority: 22, + unknown_setting: true, + }, + }, }, }, - min_age: '10d', - }, - }, - }); + name: 'my_policy', + }), + }) + ); }); it('default policy (only policy name input) on enterprise license', async () => { httpRequestsMockHelpers.setLoadPolicies([]); await act(async () => { - testBed = await setupSerializationTestBed(); + testBed = await setupSerializationTestBed(httpSetup); }); const { component, actions } = testBed; @@ -99,33 +109,35 @@ describe(' serialization', () => { await actions.setPolicyName('test_policy'); await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - const entirePolicy = JSON.parse(JSON.parse(latestRequest.requestBody).body); - - expect(entirePolicy).toEqual({ - name: 'test_policy', - phases: { - hot: { - actions: { - rollover: { - max_age: '30d', - max_primary_shard_size: '50gb', - }, - set_priority: { - priority: 100, + expect(httpSetup.post).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/policies`, + expect.objectContaining({ + body: JSON.stringify({ + name: 'test_policy', + phases: { + hot: { + actions: { + rollover: { + max_age: '30d', + max_primary_shard_size: '50gb', + }, + set_priority: { + priority: 100, + }, + }, + min_age: '0ms', }, }, - min_age: '0ms', - }, - }, - }); + }), + }) + ); }); it('default policy (only policy name input) on basic license', async () => { httpRequestsMockHelpers.setLoadPolicies([]); await act(async () => { - testBed = await setupSerializationTestBed({ + testBed = await setupSerializationTestBed(httpSetup, { appServicesContext: { license: licensingMock.createLicense({ license: { type: 'basic' } }), }, @@ -137,30 +149,44 @@ describe(' serialization', () => { await actions.setPolicyName('test_policy'); await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - const entirePolicy = JSON.parse(JSON.parse(latestRequest.requestBody).body); - - expect(entirePolicy).toEqual({ - name: 'test_policy', - phases: { - hot: { - actions: { - rollover: { - max_age: '30d', - max_primary_shard_size: '50gb', - }, - set_priority: { - priority: 100, + expect(httpSetup.post).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/policies`, + expect.objectContaining({ + body: JSON.stringify({ + name: 'test_policy', + phases: { + hot: { + actions: { + rollover: { + max_age: '30d', + max_primary_shard_size: '50gb', + }, + set_priority: { + priority: 100, + }, + }, + min_age: '0ms', }, }, - min_age: '0ms', - }, - }, - }); + }), + }) + ); }); }); describe('hot phase', () => { + beforeEach(async () => { + httpRequestsMockHelpers.setDefaultResponses(); + + await act(async () => { + testBed = await setupSerializationTestBed(httpSetup); + }); + + const { component } = testBed; + + component.update(); + }); + test('setting all values', async () => { const { actions } = testBed; @@ -176,61 +202,72 @@ describe(' serialization', () => { await actions.hot.setIndexPriority('123'); await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - const entirePolicy = JSON.parse(JSON.parse(latestRequest.requestBody).body); - expect(entirePolicy).toMatchInlineSnapshot(` - Object { - "name": "my_policy", - "phases": Object { - "hot": Object { - "actions": Object { - "forcemerge": Object { - "index_codec": "best_compression", - "max_num_segments": 123, - }, - "readonly": Object {}, - "rollover": Object { - "max_age": "123h", - "max_docs": 123, - "max_primary_shard_size": "50gb", - "max_size": "123mb", - }, - "set_priority": Object { - "priority": 123, - }, - "shrink": Object { - "number_of_shards": 2, + + expect(httpSetup.post).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/policies`, + expect.objectContaining({ + body: JSON.stringify({ + name: 'my_policy', + phases: { + hot: { + min_age: '0ms', + actions: { + rollover: { + max_age: '123h', + max_primary_shard_size: '50gb', + max_docs: 123, + max_size: '123mb', + }, + forcemerge: { + max_num_segments: 123, + index_codec: 'best_compression', + }, + shrink: { + number_of_shards: 2, + }, + set_priority: { + priority: 123, + }, + readonly: {}, }, }, - "min_age": "0ms", }, - }, - } - `); + }), + }) + ); }); test('setting searchable snapshot', async () => { const { actions } = testBed; - await actions.hot.setSearchableSnapshot('my-repo'); + await actions.hot.setSearchableSnapshot('abc'); await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - const entirePolicy = JSON.parse(JSON.parse(latestRequest.requestBody).body); - expect(entirePolicy.phases.hot.actions.searchable_snapshot.snapshot_repository).toBe( - 'my-repo' - ); + + const lastReq: HttpFetchOptionsWithPath[] = httpSetup.post.mock.calls.pop() || []; + const [requestUrl, requestBody] = lastReq; + const parsedReqBody = JSON.parse((requestBody as Record).body); + + expect(requestUrl).toBe(`${API_BASE_PATH}/policies`); + expect(parsedReqBody.phases.hot.actions.searchable_snapshot.snapshot_repository).toBe('abc'); }); test('disabling rollover', async () => { const { actions } = testBed; + await actions.rollover.toggleDefault(); await actions.rollover.toggle(); + await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - const policy = JSON.parse(JSON.parse(latestRequest.requestBody).body); - const hotActions = policy.phases.hot.actions; + + const lastReq: HttpFetchOptionsWithPath[] = httpSetup.post.mock.calls.pop() || []; + const [requestUrl, requestBody] = lastReq; + const parsedReqBody = JSON.parse((requestBody as Record).body); + + const hotActions = parsedReqBody.phases.hot.actions; const rolloverAction = hotActions.rollover; + + expect(requestUrl).toBe(`${API_BASE_PATH}/policies`); expect(rolloverAction).toBe(undefined); expect(hotActions).toMatchInlineSnapshot(`Object {}`); }); @@ -241,7 +278,7 @@ describe(' serialization', () => { httpRequestsMockHelpers.setDefaultResponses(); await act(async () => { - testBed = await setupSerializationTestBed(); + testBed = await setupSerializationTestBed(httpSetup); }); const { component } = testBed; @@ -253,9 +290,13 @@ describe(' serialization', () => { await actions.togglePhase('warm'); await actions.warm.setMinAgeValue('11'); await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - const warmPhase = JSON.parse(JSON.parse(latestRequest.requestBody).body).phases.warm; - expect(warmPhase).toMatchInlineSnapshot(` + + const lastReq: HttpFetchOptionsWithPath[] = httpSetup.post.mock.calls.pop() || []; + const [requestUrl, requestBody] = lastReq; + const parsedReqBody = JSON.parse((requestBody as Record).body); + + expect(requestUrl).toBe(`${API_BASE_PATH}/policies`); + expect(parsedReqBody.phases.warm).toMatchInlineSnapshot(` Object { "actions": Object { "set_priority": Object { @@ -281,47 +322,48 @@ describe(' serialization', () => { await actions.warm.toggleReadonly(); await actions.warm.setIndexPriority('123'); await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - const entirePolicy = JSON.parse(JSON.parse(latestRequest.requestBody).body); - // Check shape of entire policy - expect(entirePolicy).toMatchInlineSnapshot(` - Object { - "name": "my_policy", - "phases": Object { - "hot": Object { - "actions": Object { - "rollover": Object { - "max_age": "30d", - "max_primary_shard_size": "50gb", + + expect(httpSetup.post).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/policies`, + expect.objectContaining({ + body: JSON.stringify({ + name: 'my_policy', + phases: { + hot: { + min_age: '0ms', + actions: { + rollover: { + max_age: '30d', + max_primary_shard_size: '50gb', + }, }, }, - "min_age": "0ms", - }, - "warm": Object { - "actions": Object { - "allocate": Object { - "number_of_replicas": 123, - "require": Object { - "test": "123", + warm: { + min_age: '11d', + actions: { + set_priority: { + priority: 123, }, - }, - "forcemerge": Object { - "index_codec": "best_compression", - "max_num_segments": 123, - }, - "readonly": Object {}, - "set_priority": Object { - "priority": 123, - }, - "shrink": Object { - "number_of_shards": 123, + shrink: { + number_of_shards: 123, + }, + forcemerge: { + max_num_segments: 123, + index_codec: 'best_compression', + }, + allocate: { + require: { + test: '123', + }, + number_of_replicas: 123, + }, + readonly: {}, }, }, - "min_age": "11d", }, - }, - } - `); + }), + }) + ); }); describe('policy with include and exclude', () => { @@ -335,7 +377,7 @@ describe(' serialization', () => { httpRequestsMockHelpers.setLoadSnapshotPolicies([]); await act(async () => { - testBed = await setupSerializationTestBed(); + testBed = await setupSerializationTestBed(httpSetup); }); const { component } = testBed; @@ -347,9 +389,14 @@ describe(' serialization', () => { await actions.warm.setDataAllocation('node_attrs'); await actions.warm.setSelectedNodeAttribute('test:123'); await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - const warmPhaseAllocate = JSON.parse(JSON.parse(latestRequest.requestBody).body).phases.warm - .actions.allocate; + + const lastReq: HttpFetchOptionsWithPath[] = httpSetup.post.mock.calls.pop() || []; + const [requestUrl, requestBody] = lastReq; + const parsedReqBody = JSON.parse((requestBody as Record).body); + + const warmPhaseAllocate = parsedReqBody.phases.warm.actions.allocate; + + expect(requestUrl).toBe(`${API_BASE_PATH}/policies`); expect(warmPhaseAllocate).toMatchInlineSnapshot(` Object { "exclude": Object { @@ -372,7 +419,7 @@ describe(' serialization', () => { httpRequestsMockHelpers.setDefaultResponses(); await act(async () => { - testBed = await setupSerializationTestBed(); + testBed = await setupSerializationTestBed(httpSetup); }); const { component } = testBed; @@ -385,9 +432,13 @@ describe(' serialization', () => { await actions.togglePhase('cold'); await actions.cold.setMinAgeValue('11'); await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - const entirePolicy = JSON.parse(JSON.parse(latestRequest.requestBody).body); - expect(entirePolicy.phases.cold).toMatchInlineSnapshot(` + + const lastReq: HttpFetchOptionsWithPath[] = httpSetup.post.mock.calls.pop() || []; + const [requestUrl, requestBody] = lastReq; + const parsedReqBody = JSON.parse((requestBody as Record).body); + + expect(requestUrl).toBe(`${API_BASE_PATH}/policies`); + expect(parsedReqBody.phases.cold).toMatchInlineSnapshot(` Object { "actions": Object { "set_priority": Object { @@ -412,40 +463,41 @@ describe(' serialization', () => { await actions.cold.setIndexPriority('123'); await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - const entirePolicy = JSON.parse(JSON.parse(latestRequest.requestBody).body); - - expect(entirePolicy).toMatchInlineSnapshot(` - Object { - "name": "my_policy", - "phases": Object { - "cold": Object { - "actions": Object { - "allocate": Object { - "number_of_replicas": 123, - "require": Object { - "test": "123", + + expect(httpSetup.post).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/policies`, + expect.objectContaining({ + body: JSON.stringify({ + name: 'my_policy', + phases: { + hot: { + min_age: '0ms', + actions: { + rollover: { + max_age: '30d', + max_primary_shard_size: '50gb', }, }, - "readonly": Object {}, - "set_priority": Object { - "priority": 123, - }, }, - "min_age": "123s", - }, - "hot": Object { - "actions": Object { - "rollover": Object { - "max_age": "30d", - "max_primary_shard_size": "50gb", + cold: { + min_age: '123s', + actions: { + set_priority: { + priority: 123, + }, + allocate: { + require: { + test: '123', + }, + number_of_replicas: 123, + }, + readonly: {}, }, }, - "min_age": "0ms", }, - }, - } - `); + }), + }) + ); }); // Setting searchable snapshot field disables setting replicas so we test this separately @@ -455,15 +507,30 @@ describe(' serialization', () => { await actions.cold.setMinAgeValue('10'); await actions.cold.setSearchableSnapshot('my-repo'); await actions.savePolicy(); - const latestRequest2 = server.requests[server.requests.length - 1]; - const entirePolicy2 = JSON.parse(JSON.parse(latestRequest2.requestBody).body); - expect(entirePolicy2.phases.cold.actions.searchable_snapshot.snapshot_repository).toEqual( + + const lastReq: HttpFetchOptionsWithPath[] = httpSetup.post.mock.calls.pop() || []; + const [requestUrl, requestBody] = lastReq; + const parsedReqBody = JSON.parse((requestBody as Record).body); + + expect(requestUrl).toBe(`${API_BASE_PATH}/policies`); + expect(parsedReqBody.phases.cold.actions.searchable_snapshot.snapshot_repository).toEqual( 'my-repo' ); }); }); describe('frozen phase', () => { + beforeEach(async () => { + httpRequestsMockHelpers.setDefaultResponses(); + + await act(async () => { + testBed = await setupSerializationTestBed(httpSetup); + }); + + const { component } = testBed; + component.update(); + }); + test('default value', async () => { const { actions } = testBed; await actions.togglePhase('frozen'); @@ -472,9 +539,12 @@ describe(' serialization', () => { await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - const entirePolicy = JSON.parse(JSON.parse(latestRequest.requestBody).body); - expect(entirePolicy.phases.frozen).toEqual({ + const lastReq: HttpFetchOptionsWithPath[] = httpSetup.post.mock.calls.pop() || []; + const [requestUrl, requestBody] = lastReq; + const parsedReqBody = JSON.parse((requestBody as Record).body); + + expect(requestUrl).toBe(`${API_BASE_PATH}/policies`); + expect(parsedReqBody.phases.frozen).toEqual({ min_age: '13d', actions: { searchable_snapshot: { snapshot_repository: 'myRepo' }, @@ -499,7 +569,7 @@ describe(' serialization', () => { }); await act(async () => { - testBed = await setupSerializationTestBed(); + testBed = await setupSerializationTestBed(httpSetup); }); const { component } = testBed; @@ -511,9 +581,12 @@ describe(' serialization', () => { await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - const entirePolicy = JSON.parse(JSON.parse(latestRequest.requestBody).body); - expect(entirePolicy.phases.frozen).toEqual({ + const lastReq: HttpFetchOptionsWithPath[] = httpSetup.post.mock.calls.pop() || []; + const [requestUrl, requestBody] = lastReq; + const parsedReqBody = JSON.parse((requestBody as Record).body); + + expect(requestUrl).toBe(`${API_BASE_PATH}/policies`); + expect(parsedReqBody.phases.frozen).toEqual({ min_age: '1234m', actions: { searchable_snapshot: { @@ -531,9 +604,13 @@ describe(' serialization', () => { await actions.togglePhase('delete'); await actions.delete.setSnapshotPolicy('test'); await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - const entirePolicy = JSON.parse(JSON.parse(latestRequest.requestBody).body); - expect(entirePolicy.phases.delete).toEqual({ + + const lastReq: HttpFetchOptionsWithPath[] = httpSetup.post.mock.calls.pop() || []; + const [requestUrl, requestBody] = lastReq; + const parsedReqBody = JSON.parse((requestBody as Record).body); + + expect(requestUrl).toBe(`${API_BASE_PATH}/policies`); + expect(parsedReqBody.phases.delete).toEqual({ min_age: '365d', actions: { delete: {}, @@ -555,38 +632,40 @@ describe(' serialization', () => { await actions.warm.setShrinkSize('100'); await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - const entirePolicy = JSON.parse(JSON.parse(latestRequest.requestBody).body); - expect(entirePolicy).toMatchInlineSnapshot(` - Object { - "name": "my_policy", - "phases": Object { - "hot": Object { - "actions": Object { - "rollover": Object { - "max_age": "30d", - "max_primary_shard_size": "50gb", - }, - "shrink": Object { - "max_primary_shard_size": "50gb", + + expect(httpSetup.post).toHaveBeenLastCalledWith( + `${API_BASE_PATH}/policies`, + expect.objectContaining({ + body: JSON.stringify({ + name: 'my_policy', + phases: { + hot: { + min_age: '0ms', + actions: { + rollover: { + max_age: '30d', + max_primary_shard_size: '50gb', + }, + shrink: { + max_primary_shard_size: '50gb', + }, }, }, - "min_age": "0ms", - }, - "warm": Object { - "actions": Object { - "set_priority": Object { - "priority": 50, - }, - "shrink": Object { - "max_primary_shard_size": "100gb", + warm: { + min_age: '11d', + actions: { + set_priority: { + priority: 50, + }, + shrink: { + max_primary_shard_size: '100gb', + }, }, }, - "min_age": "11d", }, - }, - } - `); + }), + }) + ); }); }); }); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/http_requests.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/http_requests.ts index 7f37d4c6ccbf0..7ddcd5358404f 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/http_requests.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/http_requests.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { fakeServer, SinonFakeServer } from 'sinon'; +import { httpServiceMock } from '@kbn/core/public/mocks'; import { API_BASE_PATH } from '../../../common/constants'; import { ListNodesRouteResponse, @@ -14,61 +14,92 @@ import { } from '../../../common/types'; import { getDefaultHotPhasePolicy } from '../edit_policy/constants'; +type HttpMethod = 'GET' | 'PUT' | 'DELETE' | 'POST'; +export interface ResponseError { + statusCode: number; + message: string | Error; +} + export const init = () => { - const server = fakeServer.create(); - server.respondImmediately = true; - server.respondWith([200, {}, 'DefaultServerResponse']); + let isResponseDelayed = false; + const getDelayResponse = () => isResponseDelayed; + const setDelayResponse = (shouldDelayResponse: boolean) => { + isResponseDelayed = shouldDelayResponse; + }; + + const httpSetup = httpServiceMock.createSetupContract(); + const httpRequestsMockHelpers = registerHttpRequestMockHelpers(httpSetup, getDelayResponse); return { - server, - httpRequestsMockHelpers: registerHttpRequestMockHelpers(server), + httpSetup, + setDelayResponse, + httpRequestsMockHelpers, }; }; -const registerHttpRequestMockHelpers = (server: SinonFakeServer) => { - const setLoadPolicies = (response: any = []) => { - server.respondWith('GET', `${API_BASE_PATH}/policies`, [ - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(response), - ]); - }; +const registerHttpRequestMockHelpers = ( + httpSetup: ReturnType, + shouldDelayResponse: () => boolean +) => { + const mockResponses = new Map>>( + ['GET', 'PUT', 'DELETE', 'POST'].map( + (method) => [method, new Map()] as [HttpMethod, Map>] + ) + ); - const setLoadSnapshotPolicies = (response: any = [], error?: { status: number; body: any }) => { - const status = error ? error.status : 200; - const body = error ? error.body : response; + const mockMethodImplementation = (method: HttpMethod, path: string) => { + const responsePromise = mockResponses.get(method)?.get(path) ?? Promise.resolve({}); + if (shouldDelayResponse()) { + return new Promise((resolve) => { + setTimeout(() => resolve(responsePromise), 1000); + }); + } - server.respondWith('GET', `${API_BASE_PATH}/snapshot_policies`, [ - status, - { 'Content-Type': 'application/json' }, - JSON.stringify(body), - ]); + return responsePromise; }; - const setListNodes = (body: ListNodesRouteResponse) => { - server.respondWith('GET', `${API_BASE_PATH}/nodes/list`, [ - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(body), - ]); - }; + httpSetup.get.mockImplementation((path) => + mockMethodImplementation('GET', path as unknown as string) + ); + httpSetup.delete.mockImplementation((path) => + mockMethodImplementation('DELETE', path as unknown as string) + ); + httpSetup.post.mockImplementation((path) => + mockMethodImplementation('POST', path as unknown as string) + ); + httpSetup.put.mockImplementation((path) => + mockMethodImplementation('PUT', path as unknown as string) + ); - const setNodesDetails = (nodeAttributes: string, body: NodesDetailsResponse) => { - server.respondWith('GET', `${API_BASE_PATH}/nodes/${nodeAttributes}/details`, [ - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(body), - ]); - }; + const mockResponse = (method: HttpMethod, path: string, response?: unknown, error?: unknown) => { + const defuse = (promise: Promise) => { + promise.catch(() => {}); + return promise; + }; - const setListSnapshotRepos = (body: ListSnapshotReposResponse) => { - server.respondWith('GET', `${API_BASE_PATH}/snapshot_repositories`, [ - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(body), - ]); + return mockResponses + .get(method)! + .set(path, error ? defuse(Promise.reject({ body: error })) : Promise.resolve(response)); }; + const setLoadPolicies = (response: any = [], error?: ResponseError) => + mockResponse('GET', `${API_BASE_PATH}/policies`, response, error); + + const setLoadSnapshotPolicies = (response: any = [], error?: ResponseError) => + mockResponse('GET', `${API_BASE_PATH}/snapshot_policies`, response, error); + + const setListNodes = (response: ListNodesRouteResponse, error?: ResponseError) => + mockResponse('GET', `${API_BASE_PATH}/nodes/list`, response, error); + + const setNodesDetails = ( + nodeAttributes: string, + response: NodesDetailsResponse, + error?: ResponseError + ) => mockResponse('GET', `${API_BASE_PATH}/nodes/${nodeAttributes}/details`, response, error); + + const setListSnapshotRepos = (response: ListSnapshotReposResponse, error?: ResponseError) => + mockResponse('GET', `${API_BASE_PATH}/snapshot_repositories`, response, error); + const setDefaultResponses = () => { setLoadPolicies([getDefaultHotPhasePolicy()]); setLoadSnapshotPolicies([]); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/index.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/index.ts index f9cd1f27b72be..6794509f6c84f 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/index.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/index.ts @@ -7,4 +7,4 @@ export * from './actions'; -export { setupEnvironment } from './setup_environment'; +export { setupEnvironment, WithAppDependencies } from './setup_environment'; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/setup_environment.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/setup_environment.ts deleted file mode 100644 index eb212787fa62f..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/setup_environment.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import axios from 'axios'; -import axiosXhrAdapter from 'axios/lib/adapters/xhr'; - -import { usageCollectionPluginMock } from '@kbn/usage-collection-plugin/public/mocks'; -import { notificationServiceMock, fatalErrorsServiceMock } from '@kbn/core/public/mocks'; -import { init as initHttp } from '../../../public/application/services/http'; -import { init as initHttpRequests } from './http_requests'; -import { init as initUiMetric } from '../../../public/application/services/ui_metric'; -import { init as initNotification } from '../../../public/application/services/notification'; - -const mockHttpClient = axios.create({ adapter: axiosXhrAdapter }); - -export const setupEnvironment = () => { - initUiMetric(usageCollectionPluginMock.createSetupContract()); - initNotification( - notificationServiceMock.createSetupContract().toasts, - fatalErrorsServiceMock.createSetupContract() - ); - - mockHttpClient.interceptors.response.use(({ data }) => data); - // This expects HttpSetup but we're giving it AxiosInstance. - // @ts-ignore - initHttp(mockHttpClient); - const { server, httpRequestsMockHelpers } = initHttpRequests(); - - return { - server, - httpRequestsMockHelpers, - }; -}; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/setup_environment.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/setup_environment.tsx new file mode 100644 index 0000000000000..dde9368f81294 --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/setup_environment.tsx @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { merge } from 'lodash'; + +import './global_mocks'; + +import { HttpSetup } from '@kbn/core/public'; +import { usageCollectionPluginMock } from '@kbn/usage-collection-plugin/public/mocks'; +import { notificationServiceMock, fatalErrorsServiceMock } from '@kbn/core/public/mocks'; +import { executionContextServiceMock } from '@kbn/core/public/execution_context/execution_context_service.mock'; +import { docLinksServiceMock } from '@kbn/core/public/mocks'; +import { licensingMock } from '@kbn/licensing-plugin/public/mocks'; +import { init as initHttp } from '../../../public/application/services/http'; +import { init as initHttpRequests } from './http_requests'; +import { init as initUiMetric } from '../../../public/application/services/ui_metric'; +import { init as initNotification } from '../../../public/application/services/notification'; +import { KibanaContextProvider } from '../../../public/shared_imports'; +import { createBreadcrumbsMock } from '../../../public/application/services/breadcrumbs.mock'; + +const breadcrumbService = createBreadcrumbsMock(); +const appContextMock = { + breadcrumbService, + license: licensingMock.createLicense({ license: { type: 'enterprise' } }), + docLinks: docLinksServiceMock.createStartContract(), + getUrlForApp: () => {}, + executionContext: executionContextServiceMock.createSetupContract(), +}; + +export const WithAppDependencies = + (Comp: any, httpSetup: HttpSetup, overrides: Record = {}) => + (props: Record) => { + initHttp(httpSetup); + breadcrumbService.setup(() => ''); + + return ( + + + + ); + }; + +export const setupEnvironment = () => { + initUiMetric(usageCollectionPluginMock.createSetupContract()); + initNotification( + notificationServiceMock.createSetupContract().toasts, + fatalErrorsServiceMock.createSetupContract() + ); + + return initHttpRequests(); +}; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/extend_index_management.test.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/extend_index_management.test.tsx index a769a310fff5d..07ae90e8bc861 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/extend_index_management.test.tsx +++ b/x-pack/plugins/index_lifecycle_management/__jest__/extend_index_management.test.tsx @@ -6,9 +6,8 @@ */ import moment from 'moment-timezone'; -import axios from 'axios'; -import axiosXhrAdapter from 'axios/lib/adapters/xhr'; +import { init } from './client_integration/helpers/http_requests'; import { mountWithIntl } from '@kbn/test-jest-helpers'; import { usageCollectionPluginMock } from '@kbn/usage-collection-plugin/public/mocks'; import { Index } from '../common/types'; @@ -23,12 +22,9 @@ import { import { init as initHttp } from '../public/application/services/http'; import { init as initUiMetric } from '../public/application/services/ui_metric'; -// We need to init the http with a mock for any tests that depend upon the http service. -// For example, add_lifecycle_confirm_modal makes an API request in its componentDidMount -// lifecycle method. If we don't mock this, CI will fail with "Call retries were exceeded". -// This expects HttpSetup but we're giving it AxiosInstance. -// @ts-ignore -initHttp(axios.create({ adapter: axiosXhrAdapter })); +const { httpSetup } = init(); + +initHttp(httpSetup); initUiMetric(usageCollectionPluginMock.createSetupContract()); jest.mock('@kbn/index-management-plugin/public', async () => { diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_add_policy_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_add_policy_route.ts index da4668ab3ead3..1d4821e10211c 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_add_policy_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_add_policy_route.ts @@ -45,12 +45,8 @@ export function registerAddPolicyRoute({ const { indexName, policyName, alias = '' } = body; try { - await addLifecyclePolicy( - context.core.elasticsearch.client.asCurrentUser, - indexName, - policyName, - alias - ); + const esClient = (await context.core).elasticsearch.client; + await addLifecyclePolicy(esClient.asCurrentUser, indexName, policyName, alias); return response.ok(); } catch (error) { return handleEsError({ error, response }); diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_remove_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_remove_route.ts index 08ea60cb806ae..cec5da7aad90c 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_remove_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_remove_route.ts @@ -39,7 +39,8 @@ export function registerRemoveRoute({ const { indexNames } = body; try { - await removeLifecycle(context.core.elasticsearch.client.asCurrentUser, indexNames); + const esClient = (await context.core).elasticsearch.client; + await removeLifecycle(esClient.asCurrentUser, indexNames); return response.ok(); } catch (error) { return handleEsError({ error, response }); diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_retry_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_retry_route.ts index d229e82504c9d..42bcffcbd8122 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_retry_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_retry_route.ts @@ -36,7 +36,8 @@ export function registerRetryRoute({ router, license, lib: { handleEsError } }: const { indexNames } = body; try { - await retryLifecycle(context.core.elasticsearch.client.asCurrentUser, indexNames); + const esClient = (await context.core).elasticsearch.client; + await retryLifecycle(esClient.asCurrentUser, indexNames); return response.ok(); } catch (error) { return handleEsError({ error, response }); diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/nodes/register_details_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/nodes/register_details_route.ts index 3cf26ca96595a..13393182d0528 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/nodes/register_details_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/nodes/register_details_route.ts @@ -42,7 +42,8 @@ export function registerDetailsRoute({ const { nodeAttrs } = params; try { - const statsResponse = await context.core.elasticsearch.client.asCurrentUser.nodes.stats(); + const esClient = (await context.core).elasticsearch.client; + const statsResponse = await esClient.asCurrentUser.nodes.stats(); const okResponse = { body: findMatchingNodes(statsResponse, nodeAttrs) }; return response.ok(okResponse); } catch (error) { diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/nodes/register_list_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/nodes/register_list_route.ts index cf892ddff67bf..a9b17c25110b0 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/nodes/register_list_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/nodes/register_list_route.ts @@ -88,14 +88,14 @@ export function registerListRoute({ { path: addBasePath('/nodes/list'), validate: false }, license.guardApiRoute(async (context, request, response) => { try { - const settingsResponse = - await context.core.elasticsearch.client.asCurrentUser.transport.request({ - method: 'GET', - path: '/_nodes/settings', - querystring: { - format: 'json', - }, - }); + const esClient = (await context.core).elasticsearch.client; + const settingsResponse = await esClient.asCurrentUser.transport.request({ + method: 'GET', + path: '/_nodes/settings', + querystring: { + format: 'json', + }, + }); const body: ListNodesRouteResponse = convertSettingsIntoLists( settingsResponse as Settings, disallowedNodeAttributes diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_create_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_create_route.ts index 909f6ca7bf5a8..65c37120e552f 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_create_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_create_route.ts @@ -55,7 +55,8 @@ export function registerCreateRoute({ const { name, ...rest } = body; try { - await createPolicy(context.core.elasticsearch.client.asCurrentUser, name, rest); + const esClient = (await context.core).elasticsearch.client; + await createPolicy(esClient.asCurrentUser, name, rest); return response.ok(); } catch (error) { return handleEsError({ error, response }); diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_delete_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_delete_route.ts index 9927f093aef25..d113e646f0b38 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_delete_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_delete_route.ts @@ -36,7 +36,8 @@ export function registerDeleteRoute({ const { policyNames } = params; try { - await deletePolicies(context.core.elasticsearch.client.asCurrentUser, policyNames); + const esClient = (await context.core).elasticsearch.client; + await deletePolicies(esClient.asCurrentUser, policyNames); return response.ok(); } catch (error) { return handleEsError({ error, response }); diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_fetch_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_fetch_route.ts index 09f28679d58b2..9526aca51d33f 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_fetch_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_fetch_route.ts @@ -62,7 +62,7 @@ export function registerFetchRoute({ router, license, lib: { handleEsError } }: router.get( { path: addBasePath('/policies'), validate: false }, license.guardApiRoute(async (context, request, response) => { - const { asCurrentUser } = context.core.elasticsearch.client; + const { asCurrentUser } = (await context.core).elasticsearch.client; try { const policiesResponse = await fetchPolicies(asCurrentUser); diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/snapshot_policies/register_fetch_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/snapshot_policies/register_fetch_route.ts index ebe8a2388a025..5a01908287896 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/snapshot_policies/register_fetch_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/snapshot_policies/register_fetch_route.ts @@ -13,8 +13,8 @@ export function registerFetchRoute({ router, license, lib: { handleEsError } }: { path: addBasePath('/snapshot_policies'), validate: false }, license.guardApiRoute(async (context, request, response) => { try { - const policiesByName = - await context.core.elasticsearch.client.asCurrentUser.slm.getLifecycle(); + const esClient = (await context.core).elasticsearch.client; + const policiesByName = await esClient.asCurrentUser.slm.getLifecycle(); return response.ok({ body: Object.keys(policiesByName) }); } catch (error) { return handleEsError({ error, response }); diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/snapshot_repositories/register_fetch_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/snapshot_repositories/register_fetch_route.ts index a4bdbd5fc7afc..45a55cfce5da1 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/snapshot_repositories/register_fetch_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/snapshot_repositories/register_fetch_route.ts @@ -28,7 +28,8 @@ export const registerFetchRoute = ({ router, license }: RouteDependencies) => { } try { - const esResult = await ctx.core.elasticsearch.client.asCurrentUser.snapshot.getRepository({ + const esClient = (await ctx.core).elasticsearch.client; + const esResult = await esClient.asCurrentUser.snapshot.getRepository({ name: '*', }); const repos: ListSnapshotReposResponse = { diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_add_policy_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_add_policy_route.ts index 8b8b50834c69a..3f6b4ce843e89 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_add_policy_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_add_policy_route.ts @@ -106,8 +106,9 @@ export function registerAddPolicyRoute({ const { templateName, policyName, aliasName } = body; const isLegacy = (request.query as TypeOf).legacy === 'true'; try { + const esClient = (await context.core).elasticsearch.client; const updatedTemplate = await updateIndexTemplate( - context.core.elasticsearch.client.asCurrentUser, + esClient.asCurrentUser, isLegacy, templateName, policyName, diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_fetch_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_fetch_route.ts index dfa3f0c6b64c9..e70f2ed2bdac0 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_fetch_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_fetch_route.ts @@ -88,10 +88,8 @@ export function registerFetchRoute({ router, license, lib: { handleEsError } }: license.guardApiRoute(async (context, request, response) => { const isLegacy = (request.query as TypeOf).legacy === 'true'; try { - const templates = await fetchTemplates( - context.core.elasticsearch.client.asCurrentUser, - isLegacy - ); + const esClient = (await context.core).elasticsearch.client; + const templates = await fetchTemplates(esClient.asCurrentUser, isLegacy); const okResponse = { body: filterTemplates(templates, isLegacy) }; return response.ok(okResponse); } catch (error) { diff --git a/x-pack/plugins/index_management/server/routes/api/component_templates/register_create_route.ts b/x-pack/plugins/index_management/server/routes/api/component_templates/register_create_route.ts index cc98035f37c5c..adfa0d61859f1 100644 --- a/x-pack/plugins/index_management/server/routes/api/component_templates/register_create_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/component_templates/register_create_route.ts @@ -24,7 +24,7 @@ export const registerCreateRoute = ({ }, }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const serializedComponentTemplate = serializeComponentTemplate(request.body); diff --git a/x-pack/plugins/index_management/server/routes/api/component_templates/register_delete_route.ts b/x-pack/plugins/index_management/server/routes/api/component_templates/register_delete_route.ts index 34a644d607162..c06f90821b337 100644 --- a/x-pack/plugins/index_management/server/routes/api/component_templates/register_delete_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/component_templates/register_delete_route.ts @@ -26,7 +26,7 @@ export const registerDeleteRoute = ({ }, }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { names } = request.params; const componentNames = names.split(','); diff --git a/x-pack/plugins/index_management/server/routes/api/component_templates/register_get_route.ts b/x-pack/plugins/index_management/server/routes/api/component_templates/register_get_route.ts index caca3c8ce853f..73224c0356ad5 100644 --- a/x-pack/plugins/index_management/server/routes/api/component_templates/register_get_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/component_templates/register_get_route.ts @@ -24,7 +24,7 @@ export function registerGetAllRoute({ router, lib: { handleEsError } }: RouteDep router.get( { path: addBasePath('/component_templates'), validate: false }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; try { const { component_templates: componentTemplates } = @@ -58,7 +58,7 @@ export function registerGetAllRoute({ router, lib: { handleEsError } }: RouteDep }, }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { name } = request.params; try { diff --git a/x-pack/plugins/index_management/server/routes/api/component_templates/register_privileges_route.ts b/x-pack/plugins/index_management/server/routes/api/component_templates/register_privileges_route.ts index d2fe85d219ef1..a8b488fb54c9a 100644 --- a/x-pack/plugins/index_management/server/routes/api/component_templates/register_privileges_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/component_templates/register_privileges_route.ts @@ -41,7 +41,7 @@ export const registerPrivilegesRoute = ({ return response.ok({ body: privilegesResult }); } - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; try { const { has_all_requested: hasAllPrivileges, cluster } = diff --git a/x-pack/plugins/index_management/server/routes/api/component_templates/register_update_route.ts b/x-pack/plugins/index_management/server/routes/api/component_templates/register_update_route.ts index 016e379165d49..1a9e642cd9342 100644 --- a/x-pack/plugins/index_management/server/routes/api/component_templates/register_update_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/component_templates/register_update_route.ts @@ -29,7 +29,7 @@ export const registerUpdateRoute = ({ }, }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { name } = request.params; const { template, version, _meta } = request.body; diff --git a/x-pack/plugins/index_management/server/routes/api/data_streams/register_delete_route.ts b/x-pack/plugins/index_management/server/routes/api/data_streams/register_delete_route.ts index 0602aaaaafc6c..dcdb4056cb681 100644 --- a/x-pack/plugins/index_management/server/routes/api/data_streams/register_delete_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/data_streams/register_delete_route.ts @@ -21,7 +21,7 @@ export function registerDeleteRoute({ router, lib: { handleEsError } }: RouteDep validate: { body: bodySchema }, }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { dataStreams } = request.body as TypeOf; const responseBody: { dataStreamsDeleted: string[]; errors: any[] } = { diff --git a/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts b/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts index a698be6f913d3..a562cc5f4cc52 100644 --- a/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts @@ -103,7 +103,7 @@ export function registerGetAllRoute({ router, lib: { handleEsError }, config }: router.get( { path: addBasePath('/data_streams'), validate: { query: querySchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const includeStats = (request.query as TypeOf).includeStats === 'true'; @@ -152,7 +152,7 @@ export function registerGetOneRoute({ router, lib: { handleEsError }, config }: }, async (context, request, response) => { const { name } = request.params as TypeOf; - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; try { const [{ data_streams: dataStreams }, { data_streams: dataStreamsStats }] = await Promise.all([getDataStreams(client, name), getDataStreamsStats(client, name)]); diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_clear_cache_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_clear_cache_route.ts index 9e7c4a82bca59..a46a23b8fe479 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_clear_cache_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_clear_cache_route.ts @@ -18,7 +18,7 @@ export function registerClearCacheRoute({ router, lib: { handleEsError } }: Rout router.post( { path: addBasePath('/indices/clear_cache'), validate: { body: bodySchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indices = [] } = request.body as typeof bodySchema.type; const params = { diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_close_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_close_route.ts index 7d549dadd010c..69d33b7fc7999 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_close_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_close_route.ts @@ -18,7 +18,7 @@ export function registerCloseRoute({ router, lib: { handleEsError } }: RouteDepe router.post( { path: addBasePath('/indices/close'), validate: { body: bodySchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indices = [] } = request.body as typeof bodySchema.type; const params = { diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_delete_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_delete_route.ts index 8f97711858059..b72a2059beb1d 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_delete_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_delete_route.ts @@ -18,7 +18,7 @@ export function registerDeleteRoute({ router, lib: { handleEsError } }: RouteDep router.post( { path: addBasePath('/indices/delete'), validate: { body: bodySchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indices = [] } = request.body as typeof bodySchema.type; const params = { diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_flush_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_flush_route.ts index d8215849d2de5..cc07b92e70907 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_flush_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_flush_route.ts @@ -18,7 +18,7 @@ export function registerFlushRoute({ router, lib: { handleEsError } }: RouteDepe router.post( { path: addBasePath('/indices/flush'), validate: { body: bodySchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indices = [] } = request.body as typeof bodySchema.type; const params = { diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_forcemerge_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_forcemerge_route.ts index d9bdd572b63f3..af07a7371cf65 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_forcemerge_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_forcemerge_route.ts @@ -24,7 +24,7 @@ export function registerForcemergeRoute({ router, lib: { handleEsError } }: Rout }, }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { maxNumSegments, indices = [] } = request.body as typeof bodySchema.type; const params = { expand_wildcards: 'none' as const, diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_list_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_list_route.ts index cbdfee665cfec..48c1800aba95e 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_list_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_list_route.ts @@ -17,7 +17,7 @@ export function registerListRoute({ router.get( { path: addBasePath('/indices'), validate: false }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; try { const indices = await fetchIndices(client, indexDataEnricher); return response.ok({ body: indices }); diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_open_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_open_route.ts index b7aa023c27433..dde9e72af39d7 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_open_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_open_route.ts @@ -18,7 +18,7 @@ export function registerOpenRoute({ router, lib: { handleEsError } }: RouteDepen router.post( { path: addBasePath('/indices/open'), validate: { body: bodySchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indices = [] } = request.body as typeof bodySchema.type; const params = { diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_refresh_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_refresh_route.ts index ba7d3f19dbb23..2483cd534b80e 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_refresh_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_refresh_route.ts @@ -18,7 +18,7 @@ export function registerRefreshRoute({ router, lib: { handleEsError } }: RouteDe router.post( { path: addBasePath('/indices/refresh'), validate: { body: bodySchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indices = [] } = request.body as typeof bodySchema.type; const params = { diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_reload_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_reload_route.ts index 05951629bcb2d..42b78fe246ba8 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_reload_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_reload_route.ts @@ -25,7 +25,7 @@ export function registerReloadRoute({ router.post( { path: addBasePath('/indices/reload'), validate: { body: bodySchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indexNames = [] } = (request.body as typeof bodySchema.type) ?? {}; try { diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_unfreeze_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_unfreeze_route.ts index e0447efe1090f..3636a0707df8c 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_unfreeze_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_unfreeze_route.ts @@ -18,7 +18,7 @@ export function registerUnfreezeRoute({ router, lib: { handleEsError } }: RouteD router.post( { path: addBasePath('/indices/unfreeze'), validate: { body: bodySchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indices = [] } = request.body as typeof bodySchema.type; try { diff --git a/x-pack/plugins/index_management/server/routes/api/mapping/register_mapping_route.ts b/x-pack/plugins/index_management/server/routes/api/mapping/register_mapping_route.ts index c2dbcc92144b2..641ad26417f67 100644 --- a/x-pack/plugins/index_management/server/routes/api/mapping/register_mapping_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/mapping/register_mapping_route.ts @@ -25,7 +25,7 @@ export function registerMappingRoute({ router, lib: { handleEsError } }: RouteDe router.get( { path: addBasePath('/mapping/{indexName}'), validate: { params: paramsSchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indexName } = request.params as typeof paramsSchema.type; const params = { expand_wildcards: 'none' as const, diff --git a/x-pack/plugins/index_management/server/routes/api/nodes/register_nodes_route.ts b/x-pack/plugins/index_management/server/routes/api/nodes/register_nodes_route.ts index 8702a6bdd2037..08a0684f69c97 100644 --- a/x-pack/plugins/index_management/server/routes/api/nodes/register_nodes_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/nodes/register_nodes_route.ts @@ -13,7 +13,7 @@ export function registerNodesRoute({ router, lib: { handleEsError } }: RouteDepe router.get( { path: addBasePath('/nodes/plugins'), validate: {} }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; try { const body = await client.asCurrentUser.nodes.info(); diff --git a/x-pack/plugins/index_management/server/routes/api/settings/register_load_route.ts b/x-pack/plugins/index_management/server/routes/api/settings/register_load_route.ts index fc8600182dd13..bcdf29af65856 100644 --- a/x-pack/plugins/index_management/server/routes/api/settings/register_load_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/settings/register_load_route.ts @@ -25,7 +25,7 @@ export function registerLoadRoute({ router, lib: { handleEsError } }: RouteDepen router.get( { path: addBasePath('/settings/{indexName}'), validate: { params: paramsSchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indexName } = request.params as typeof paramsSchema.type; const params = { expand_wildcards: 'none' as const, diff --git a/x-pack/plugins/index_management/server/routes/api/settings/register_update_route.ts b/x-pack/plugins/index_management/server/routes/api/settings/register_update_route.ts index 31f04a20c5dbe..cfb0be50e0484 100644 --- a/x-pack/plugins/index_management/server/routes/api/settings/register_update_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/settings/register_update_route.ts @@ -23,7 +23,7 @@ export function registerUpdateRoute({ router, lib: { handleEsError } }: RouteDep validate: { body: bodySchema, params: paramsSchema }, }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indexName } = request.params as typeof paramsSchema.type; const params = { ignore_unavailable: true, diff --git a/x-pack/plugins/index_management/server/routes/api/stats/register_stats_route.ts b/x-pack/plugins/index_management/server/routes/api/stats/register_stats_route.ts index a81aba00901eb..8e361d8488ba3 100644 --- a/x-pack/plugins/index_management/server/routes/api/stats/register_stats_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/stats/register_stats_route.ts @@ -33,7 +33,7 @@ export function registerStatsRoute({ router, lib: { handleEsError } }: RouteDepe router.get( { path: addBasePath('/stats/{indexName}'), validate: { params: paramsSchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indexName } = request.params as typeof paramsSchema.type; const params = { expand_wildcards: 'none' as const, diff --git a/x-pack/plugins/index_management/server/routes/api/templates/register_create_route.ts b/x-pack/plugins/index_management/server/routes/api/templates/register_create_route.ts index 7463f41cb18ac..0b903d4356ec4 100644 --- a/x-pack/plugins/index_management/server/routes/api/templates/register_create_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/templates/register_create_route.ts @@ -19,7 +19,7 @@ export function registerCreateRoute({ router, lib: { handleEsError } }: RouteDep router.post( { path: addBasePath('/index_templates'), validate: { body: bodySchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const template = request.body as TemplateDeserialized; try { diff --git a/x-pack/plugins/index_management/server/routes/api/templates/register_delete_route.ts b/x-pack/plugins/index_management/server/routes/api/templates/register_delete_route.ts index 585408bbfe233..b6c289f3a72a8 100644 --- a/x-pack/plugins/index_management/server/routes/api/templates/register_delete_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/templates/register_delete_route.ts @@ -28,7 +28,7 @@ export function registerDeleteRoute({ router, lib: { handleEsError } }: RouteDep validate: { body: bodySchema }, }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { templates } = request.body as TypeOf; const responseBody: { templatesDeleted: Array; diff --git a/x-pack/plugins/index_management/server/routes/api/templates/register_get_routes.ts b/x-pack/plugins/index_management/server/routes/api/templates/register_get_routes.ts index f8966b1355ffe..32661bb308876 100644 --- a/x-pack/plugins/index_management/server/routes/api/templates/register_get_routes.ts +++ b/x-pack/plugins/index_management/server/routes/api/templates/register_get_routes.ts @@ -21,7 +21,7 @@ export function registerGetAllRoute({ router, lib: { handleEsError } }: RouteDep router.get( { path: addBasePath('/index_templates'), validate: false }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; try { const cloudManagedTemplatePrefix = await getCloudManagedTemplatePrefix(client); @@ -66,7 +66,7 @@ export function registerGetOneRoute({ router, lib: { handleEsError } }: RouteDep validate: { params: paramsSchema, query: querySchema }, }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { name } = request.params as TypeOf; const isLegacy = (request.query as TypeOf).legacy === 'true'; diff --git a/x-pack/plugins/index_management/server/routes/api/templates/register_simulate_route.ts b/x-pack/plugins/index_management/server/routes/api/templates/register_simulate_route.ts index 13833cb889362..3dc6201f0831c 100644 --- a/x-pack/plugins/index_management/server/routes/api/templates/register_simulate_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/templates/register_simulate_route.ts @@ -19,7 +19,7 @@ export function registerSimulateRoute({ router, lib: { handleEsError } }: RouteD validate: { body: bodySchema }, }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const template = request.body as TypeOf; try { diff --git a/x-pack/plugins/index_management/server/routes/api/templates/register_update_route.ts b/x-pack/plugins/index_management/server/routes/api/templates/register_update_route.ts index 7d89d0ff8af09..30b93f2e59ec0 100644 --- a/x-pack/plugins/index_management/server/routes/api/templates/register_update_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/templates/register_update_route.ts @@ -25,7 +25,7 @@ export function registerUpdateRoute({ router, lib: { handleEsError } }: RouteDep validate: { body: bodySchema, params: paramsSchema }, }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { name } = request.params as typeof paramsSchema.type; const template = request.body as TemplateDeserialized; diff --git a/x-pack/plugins/infra/kibana.json b/x-pack/plugins/infra/kibana.json index 2eec94187900f..d9d432fc702e4 100644 --- a/x-pack/plugins/infra/kibana.json +++ b/x-pack/plugins/infra/kibana.json @@ -9,7 +9,6 @@ "spaces", "embeddable", "data", - "dataEnhanced", "dataViews", "visTypeTimeseries", "alerting", diff --git a/x-pack/plugins/infra/public/components/autocomplete_field/autocomplete_field.tsx b/x-pack/plugins/infra/public/components/autocomplete_field/autocomplete_field.tsx index 82f5516f0831e..d54b12511a05c 100644 --- a/x-pack/plugins/infra/public/components/autocomplete_field/autocomplete_field.tsx +++ b/x-pack/plugins/infra/public/components/autocomplete_field/autocomplete_field.tsx @@ -7,7 +7,7 @@ import { EuiFieldSearch, EuiOutsideClickDetector, EuiPanel } from '@elastic/eui'; import React from 'react'; -import { QuerySuggestion } from '@kbn/data-plugin/public'; +import { QuerySuggestion } from '@kbn/unified-search-plugin/public'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; import { composeStateUpdaters } from '../../utils/typed_react'; import { SuggestionItem } from './suggestion_item'; diff --git a/x-pack/plugins/infra/public/components/autocomplete_field/suggestion_item.tsx b/x-pack/plugins/infra/public/components/autocomplete_field/suggestion_item.tsx index 47a5114f79173..a317ad3ecff5e 100644 --- a/x-pack/plugins/infra/public/components/autocomplete_field/suggestion_item.tsx +++ b/x-pack/plugins/infra/public/components/autocomplete_field/suggestion_item.tsx @@ -5,11 +5,11 @@ * 2.0. */ -import { EuiIcon } from '@elastic/eui'; -import { transparentize } from 'polished'; import React from 'react'; +import { EuiIcon } from '@elastic/eui'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; -import { QuerySuggestion, QuerySuggestionTypes } from '@kbn/data-plugin/public'; +import { QuerySuggestion, QuerySuggestionTypes } from '@kbn/unified-search-plugin/public'; +import { transparentize } from 'polished'; interface Props { isSelected?: boolean; diff --git a/x-pack/plugins/infra/public/containers/with_kuery_autocompletion.tsx b/x-pack/plugins/infra/public/containers/with_kuery_autocompletion.tsx index 5da13a4fed711..96410973f8c0e 100644 --- a/x-pack/plugins/infra/public/containers/with_kuery_autocompletion.tsx +++ b/x-pack/plugins/infra/public/containers/with_kuery_autocompletion.tsx @@ -7,16 +7,18 @@ import React from 'react'; import { DataViewBase } from '@kbn/es-query'; -import { QuerySuggestion, DataPublicPluginStart } from '@kbn/data-plugin/public'; import { withKibana, KibanaReactContextValue, KibanaServices, } from '@kbn/kibana-react-plugin/public'; +import { QuerySuggestion, UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import { RendererFunction } from '../utils/typed_react'; interface WithKueryAutocompletionLifecycleProps { - kibana: KibanaReactContextValue<{ data: DataPublicPluginStart } & KibanaServices>; + kibana: KibanaReactContextValue< + { unifiedSearch: UnifiedSearchPublicPluginStart } & KibanaServices + >; children: RendererFunction<{ isLoadingSuggestions: boolean; loadSuggestions: (expression: string, cursorPosition: number, maxSuggestions?: number) => void; @@ -63,7 +65,7 @@ class WithKueryAutocompletionComponent extends React.Component< const { indexPattern } = this.props; const language = 'kuery'; const hasQuerySuggestions = - this.props.kibana.services.data?.autocomplete.hasQuerySuggestions(language); + this.props.kibana.services.unifiedSearch?.autocomplete.hasQuerySuggestions(language); if (!hasQuerySuggestions) { return; @@ -78,7 +80,7 @@ class WithKueryAutocompletionComponent extends React.Component< }); const suggestions = - (await this.props.kibana.services.data.autocomplete.getQuerySuggestions({ + (await this.props.kibana.services.unifiedSearch.autocomplete.getQuerySuggestions({ language, query: expression, selectionStart: cursorPosition, diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/osquery/index.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/osquery/index.tsx index 1bd6cfd353140..ce023064edee1 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/osquery/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/osquery/index.tsx @@ -48,7 +48,7 @@ const TabComponent = (props: TabProps) => { return ( - + ); }, [OsqueryAction, loading, metadata]); diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/kuery_bar.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/kuery_bar.tsx index ff3cbdceefb3f..0e7d4e6d41e1b 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/kuery_bar.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/kuery_bar.tsx @@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n'; import { fromKueryExpression } from '@kbn/es-query'; import React, { useEffect, useState } from 'react'; import { DataViewBase } from '@kbn/es-query'; -import { QuerySuggestion } from '@kbn/data-plugin/public'; +import { QuerySuggestion } from '@kbn/unified-search-plugin/public'; import { WithKueryAutocompletion } from '../../../../containers/with_kuery_autocompletion'; import { AutocompleteField } from '../../../../components/autocomplete_field'; diff --git a/x-pack/plugins/infra/public/types.ts b/x-pack/plugins/infra/public/types.ts index ab7df75592712..b5147f343ea5b 100644 --- a/x-pack/plugins/infra/public/types.ts +++ b/x-pack/plugins/infra/public/types.ts @@ -20,7 +20,6 @@ import type { TriggersAndActionsUIPublicPluginSetup, TriggersAndActionsUIPublicPluginStart, } from '@kbn/triggers-actions-ui-plugin/public'; -import type { DataEnhancedSetup, DataEnhancedStart } from '@kbn/data-enhanced-plugin/public'; import { MlPluginSetup, MlPluginStart } from '@kbn/ml-plugin/public'; import type { ObservabilityPublicSetup, @@ -52,7 +51,6 @@ export interface InfraClientStartExports { } export interface InfraClientSetupDeps { - dataEnhanced: DataEnhancedSetup; home?: HomePublicPluginSetup; observability: ObservabilityPublicSetup; triggersActionsUi: TriggersAndActionsUIPublicPluginSetup; @@ -64,7 +62,6 @@ export interface InfraClientSetupDeps { export interface InfraClientStartDeps { data: DataPublicPluginStart; - dataEnhanced: DataEnhancedStart; dataViews: DataViewsPublicPluginStart; observability: ObservabilityPublicStart; spaces: SpacesPluginStart; diff --git a/x-pack/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts index 28592e430c163..7aa4b433c477c 100644 --- a/x-pack/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts +++ b/x-pack/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts @@ -124,7 +124,7 @@ export class KibanaFramework { endpoint: string, params: CallWithRequestParams ) { - const { elasticsearch, uiSettings } = requestContext.core; + const { elasticsearch, uiSettings } = await requestContext.core; const includeFrozen = await uiSettings.client.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); if (endpoint === 'msearch') { @@ -200,9 +200,10 @@ export class KibanaFramework { public async getIndexPatternsServiceWithRequestContext( requestContext: InfraPluginRequestHandlerContext ) { + const { savedObjects, elasticsearch } = await requestContext.core; return await this.createIndexPatternsService( - requestContext.core.savedObjects.client, - requestContext.core.elasticsearch.client.asCurrentUser + savedObjects.client, + elasticsearch.client.asCurrentUser ); } diff --git a/x-pack/plugins/infra/server/lib/domains/fields_domain.ts b/x-pack/plugins/infra/server/lib/domains/fields_domain.ts index 0997d9517fa8d..b80fa9d796021 100644 --- a/x-pack/plugins/infra/server/lib/domains/fields_domain.ts +++ b/x-pack/plugins/infra/server/lib/domains/fields_domain.ts @@ -20,10 +20,8 @@ export class InfraFieldsDomain { sourceId: string, indexType: 'METRICS' ): Promise { - const { configuration } = await this.libs.sources.getSourceConfiguration( - requestContext.core.savedObjects.client, - sourceId - ); + const soClient = (await requestContext.core).savedObjects.client; + const { configuration } = await this.libs.sources.getSourceConfiguration(soClient, sourceId); const fields = await this.adapter.getIndexFields(requestContext, configuration.metricAlias); diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts index ef6b7122aa4de..1e0daad376a1a 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts @@ -42,6 +42,7 @@ export interface LogEntriesParams { cursor?: { before: LogEntryCursor | 'last' } | { after: LogEntryCursor | 'first' }; highlightTerm?: string; } + export interface LogEntriesAroundParams { startTimestamp: number; endTimestamp: number; @@ -130,11 +131,9 @@ export class InfraLogEntriesDomain { columnOverrides?: LogViewColumnConfiguration[] ): Promise<{ entries: LogEntry[]; hasMoreBefore?: boolean; hasMoreAfter?: boolean }> { const [, , { logViews }] = await this.libs.getStartServices(); + const { savedObjects, elasticsearch } = await requestContext.core; const resolvedLogView = await logViews - .getClient( - requestContext.core.savedObjects.client, - requestContext.core.elasticsearch.client.asCurrentUser - ) + .getClient(savedObjects.client, elasticsearch.client.asCurrentUser) .getResolvedLogView(sourceId); const columnDefinitions = columnOverrides ?? resolvedLogView.columns; @@ -192,11 +191,9 @@ export class InfraLogEntriesDomain { filterQuery?: LogEntryQuery ): Promise { const [, , { logViews }] = await this.libs.getStartServices(); + const { savedObjects, elasticsearch } = await requestContext.core; const resolvedLogView = await logViews - .getClient( - requestContext.core.savedObjects.client, - requestContext.core.elasticsearch.client.asCurrentUser - ) + .getClient(savedObjects.client, elasticsearch.client.asCurrentUser) .getResolvedLogView(sourceId); const dateRangeBuckets = await this.adapter.getContainedLogSummaryBuckets( requestContext, @@ -219,11 +216,9 @@ export class InfraLogEntriesDomain { filterQuery?: LogEntryQuery ): Promise { const [, , { logViews }] = await this.libs.getStartServices(); + const { savedObjects, elasticsearch } = await requestContext.core; const resolvedLogView = await logViews - .getClient( - requestContext.core.savedObjects.client, - requestContext.core.elasticsearch.client.asCurrentUser - ) + .getClient(savedObjects.client, elasticsearch.client.asCurrentUser) .getResolvedLogView(sourceId); const messageFormattingRules = compileFormattingRules( getBuiltinRules(resolvedLogView.messageField) diff --git a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts index feb0f6b5b9998..22bf5466ee3b4 100644 --- a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts +++ b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts @@ -96,7 +96,9 @@ async function getCompatibleAnomaliesJobIds( } export async function getLogEntryAnomalies( - context: InfraPluginRequestHandlerContext & { infra: Required }, + context: InfraPluginRequestHandlerContext & { + infra: Promise>; + }, sourceId: string, startTime: number, endTime: number, @@ -106,13 +108,14 @@ export async function getLogEntryAnomalies( ) { const finalizeLogEntryAnomaliesSpan = startTracingSpan('get log entry anomalies'); + const infraContext = await context.infra; const { jobIds, timing: { spans: jobSpans }, } = await getCompatibleAnomaliesJobIds( - context.infra.spaceId, + infraContext.spaceId, sourceId, - context.infra.mlAnomalyDetectors + infraContext.mlAnomalyDetectors ); if (jobIds.length === 0) { @@ -127,7 +130,7 @@ export async function getLogEntryAnomalies( hasMoreEntries, timing: { spans: fetchLogEntryAnomaliesSpans }, } = await fetchLogEntryAnomalies( - context.infra.mlSystem, + infraContext.mlSystem, jobIds, startTime, endTime, @@ -151,13 +154,13 @@ export async function getLogEntryAnomalies( }, []); const logEntryCategoriesCountJobId = getJobId( - context.infra.spaceId, + infraContext.spaceId, sourceId, logEntryCategoriesJobTypes[0] ); const { logEntryCategoriesById } = await fetchLogEntryCategories( - context, + { infra: infraContext }, logEntryCategoriesCountJobId, categoryIds ); @@ -325,7 +328,9 @@ async function fetchLogEntryAnomalies( } export async function getLogEntryExamples( - context: InfraPluginRequestHandlerContext & { infra: Required }, + context: InfraPluginRequestHandlerContext & { + infra: Promise>; + }, sourceId: string, startTime: number, endTime: number, @@ -336,9 +341,10 @@ export async function getLogEntryExamples( categoryId?: string ) { const finalizeLogEntryExamplesSpan = startTracingSpan('get log entry rate example log entries'); + const infraContext = await context.infra; const jobId = getJobId( - context.infra.spaceId, + infraContext.spaceId, sourceId, categoryId != null ? logEntryCategoriesJobTypes[0] : logEntryRateJobTypes[0] ); @@ -346,7 +352,7 @@ export async function getLogEntryExamples( const { mlJob, timing: { spans: fetchMlJobSpans }, - } = await fetchMlJob(context.infra.mlAnomalyDetectors, jobId); + } = await fetchMlJob(infraContext.mlAnomalyDetectors, jobId); const customSettings = decodeOrThrow(jobCustomSettingsRT)(mlJob.custom_settings); const indices = customSettings?.logs_source_config?.indexPattern; @@ -388,7 +394,9 @@ export async function getLogEntryExamples( } export async function fetchLogEntryExamples( - context: InfraPluginRequestHandlerContext & { infra: Required }, + context: InfraPluginRequestHandlerContext & { + infra: Promise>; + }, sourceId: string, indices: string, runtimeMappings: estypes.MappingRuntimeFields, @@ -403,6 +411,7 @@ export async function fetchLogEntryExamples( ) { const finalizeEsSearchSpan = startTracingSpan('Fetch log rate examples from ES'); + const infraContext = await context.infra; let categoryQuery: string | undefined; // Examples should be further scoped to a specific ML category @@ -410,13 +419,13 @@ export async function fetchLogEntryExamples( const parsedCategoryId = parseInt(categoryId, 10); const logEntryCategoriesCountJobId = getJobId( - context.infra.spaceId, + infraContext.spaceId, sourceId, logEntryCategoriesJobTypes[0] ); const { logEntryCategoriesById } = await fetchLogEntryCategories( - context, + { infra: infraContext }, logEntryCategoriesCountJobId, [parsedCategoryId] ); diff --git a/x-pack/plugins/infra/server/lib/metrics/make_get_metric_indices.test.ts b/x-pack/plugins/infra/server/lib/metrics/make_get_metric_indices.test.ts new file mode 100644 index 0000000000000..9dedf9b5afaa0 --- /dev/null +++ b/x-pack/plugins/infra/server/lib/metrics/make_get_metric_indices.test.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { savedObjectsClientMock } from '@kbn/core/server/mocks'; +import { defaultSourceConfiguration, InfraSource } from '../sources'; +import { createInfraSourcesMock } from '../sources/mocks'; +import { makeGetMetricIndices } from './make_get_metric_indices'; + +describe('getMetricIndices', () => { + it('should return the indices from a resolved configuration', async () => { + const sourceConfiguration: InfraSource = { + id: 'default', + origin: 'stored', + configuration: defaultSourceConfiguration, + }; + const infraSourcesMock = createInfraSourcesMock(); + infraSourcesMock.getSourceConfiguration.mockResolvedValueOnce(sourceConfiguration); + + const getMetricIndices = makeGetMetricIndices(infraSourcesMock); + + const savedObjectsClient = savedObjectsClientMock.create(); + const metricIndices = await getMetricIndices(savedObjectsClient); + + expect(metricIndices).toEqual(defaultSourceConfiguration.metricAlias); + }); +}); diff --git a/x-pack/plugins/infra/server/lib/metrics/make_get_metric_indices.ts b/x-pack/plugins/infra/server/lib/metrics/make_get_metric_indices.ts new file mode 100644 index 0000000000000..a6ff7e96a55a0 --- /dev/null +++ b/x-pack/plugins/infra/server/lib/metrics/make_get_metric_indices.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { SavedObjectsClientContract } from '@kbn/core/server'; +import type { IInfraSources } from '../sources'; + +export function makeGetMetricIndices(metricSources: IInfraSources) { + return async (savedObjectsClient: SavedObjectsClientContract, sourceId: string = 'default') => { + const source = await metricSources.getSourceConfiguration(savedObjectsClient, sourceId); + return source.configuration.metricAlias; + }; +} diff --git a/x-pack/plugins/infra/server/lib/source_status.ts b/x-pack/plugins/infra/server/lib/source_status.ts index 8c6d7d1ad451f..9e492e448ab92 100644 --- a/x-pack/plugins/infra/server/lib/source_status.ts +++ b/x-pack/plugins/infra/server/lib/source_status.ts @@ -18,38 +18,34 @@ export class InfraSourceStatus { requestContext: InfraPluginRequestHandlerContext, sourceId: string ): Promise { - const sourceConfiguration = await this.libs.sources.getSourceConfiguration( - requestContext.core.savedObjects.client, - sourceId - ); + const soClient = (await requestContext.core).savedObjects.client; + const sourceConfiguration = await this.libs.sources.getSourceConfiguration(soClient, sourceId); const indexNames = await this.adapter.getIndexNames( requestContext, sourceConfiguration.configuration.metricAlias ); return indexNames; } + public async hasMetricAlias( requestContext: InfraPluginRequestHandlerContext, sourceId: string ): Promise { - const sourceConfiguration = await this.libs.sources.getSourceConfiguration( - requestContext.core.savedObjects.client, - sourceId - ); + const soClient = (await requestContext.core).savedObjects.client; + const sourceConfiguration = await this.libs.sources.getSourceConfiguration(soClient, sourceId); const hasAlias = await this.adapter.hasAlias( requestContext, sourceConfiguration.configuration.metricAlias ); return hasAlias; } + public async hasMetricIndices( requestContext: InfraPluginRequestHandlerContext, sourceId: string ): Promise { - const sourceConfiguration = await this.libs.sources.getSourceConfiguration( - requestContext.core.savedObjects.client, - sourceId - ); + const soClient = (await requestContext.core).savedObjects.client; + const sourceConfiguration = await this.libs.sources.getSourceConfiguration(soClient, sourceId); const indexStatus = await this.adapter.getIndexStatus( requestContext, sourceConfiguration.configuration.metricAlias @@ -65,7 +61,9 @@ export interface InfraSourceStatusAdapter { requestContext: InfraPluginRequestHandlerContext, aliasName: string ): Promise; + hasAlias(requestContext: InfraPluginRequestHandlerContext, aliasName: string): Promise; + getIndexStatus( requestContext: InfraPluginRequestHandlerContext, indexNames: string diff --git a/x-pack/plugins/infra/server/plugin.ts b/x-pack/plugins/infra/server/plugin.ts index a0d0b617f3f41..bfd7113ec4dc0 100644 --- a/x-pack/plugins/infra/server/plugin.ts +++ b/x-pack/plugins/infra/server/plugin.ts @@ -7,8 +7,6 @@ import { Server } from '@hapi/hapi'; import { schema } from '@kbn/config-schema'; -import { i18n } from '@kbn/i18n'; -import { Logger } from '@kbn/logging'; import { CoreStart, Plugin, @@ -16,6 +14,8 @@ import { PluginInitializerContext, } from '@kbn/core/server'; import { handleEsError } from '@kbn/es-ui-shared-plugin/server'; +import { i18n } from '@kbn/i18n'; +import { Logger } from '@kbn/logging'; import { LOGS_FEATURE_ID, METRICS_FEATURE_ID } from '../common/constants'; import { defaultLogViewsStaticConfig } from '../common/log_views'; import { publicConfigKeys } from '../common/plugin_config_types'; @@ -35,6 +35,7 @@ import { InfraFieldsDomain } from './lib/domains/fields_domain'; import { InfraLogEntriesDomain } from './lib/domains/log_entries_domain'; import { InfraMetricsDomain } from './lib/domains/metrics_domain'; import { InfraBackendLibs, InfraDomainLibs } from './lib/infra_types'; +import { makeGetMetricIndices } from './lib/metrics/make_get_metric_indices'; import { infraSourceConfigurationSavedObjectType, InfraSources } from './lib/sources'; import { InfraSourceStatus } from './lib/source_status'; import { logViewSavedObjectType } from './saved_objects'; @@ -190,12 +191,10 @@ export class InfraServerPlugin core.http.registerRouteHandlerContext( 'infra', - (context, request) => { - const mlSystem = plugins.ml?.mlSystemProvider(request, context.core.savedObjects.client); - const mlAnomalyDetectors = plugins.ml?.anomalyDetectorsProvider( - request, - context.core.savedObjects.client - ); + async (context, request) => { + const soClient = (await context.core).savedObjects.client; + const mlSystem = plugins.ml?.mlSystemProvider(request, soClient); + const mlAnomalyDetectors = plugins.ml?.anomalyDetectorsProvider(request, soClient); const spaceId = plugins.spaces?.spacesService.getSpaceId(request) || 'default'; return { @@ -238,7 +237,9 @@ export class InfraServerPlugin return { logViews, + getMetricIndices: makeGetMetricIndices(this.libs.sources), }; } + stop() {} } diff --git a/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_hosts_anomalies.ts b/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_hosts_anomalies.ts index 1b5ed62a006be..a83854817866f 100644 --- a/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_hosts_anomalies.ts +++ b/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_hosts_anomalies.ts @@ -47,7 +47,7 @@ export const initGetHostsAnomaliesRoute = ({ framework }: InfraBackendLibs) => { const { sort, pagination } = getSortAndPagination(sortParam, paginationParam); try { - assertHasInfraMlPlugins(requestContext); + const infraMlContext = await assertHasInfraMlPlugins(requestContext); const { data: anomalies, @@ -55,7 +55,7 @@ export const initGetHostsAnomaliesRoute = ({ framework }: InfraBackendLibs) => { hasMoreEntries, timing, } = await getMetricsHostsAnomalies({ - context: requestContext.infra, + context: await infraMlContext.infra, sourceId, anomalyThreshold, startTime, diff --git a/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_k8s_anomalies.ts b/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_k8s_anomalies.ts index 667760d1d409e..55cc6c4098325 100644 --- a/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_k8s_anomalies.ts +++ b/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_k8s_anomalies.ts @@ -45,7 +45,7 @@ export const initGetK8sAnomaliesRoute = ({ framework }: InfraBackendLibs) => { const { sort, pagination } = getSortAndPagination(sortParam, paginationParam); try { - assertHasInfraMlPlugins(requestContext); + const infraMlContext = await assertHasInfraMlPlugins(requestContext); const { data: anomalies, @@ -53,7 +53,7 @@ export const initGetK8sAnomaliesRoute = ({ framework }: InfraBackendLibs) => { hasMoreEntries, timing, } = await getMetricK8sAnomalies({ - context: requestContext.infra, + context: await infraMlContext.infra, sourceId, anomalyThreshold, startTime, diff --git a/x-pack/plugins/infra/server/routes/inventory_metadata/index.ts b/x-pack/plugins/infra/server/routes/inventory_metadata/index.ts index 70d29773f76c5..c6ed81ccd8256 100644 --- a/x-pack/plugins/infra/server/routes/inventory_metadata/index.ts +++ b/x-pack/plugins/infra/server/routes/inventory_metadata/index.ts @@ -38,10 +38,8 @@ export const initInventoryMetaRoute = (libs: InfraBackendLibs) => { fold(throwErrors(Boom.badRequest), identity) ); - const { configuration } = await libs.sources.getSourceConfiguration( - requestContext.core.savedObjects.client, - sourceId - ); + const soClient = (await requestContext.core).savedObjects.client; + const { configuration } = await libs.sources.getSourceConfiguration(soClient, sourceId); const awsMetadata = await getCloudMetadata( framework, diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies.ts index d0a18727b6813..dd6254cf560e2 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies.ts @@ -42,7 +42,7 @@ export const initGetLogEntryAnomaliesRoute = ({ framework }: InfraBackendLibs) = const { sort, pagination } = getSortAndPagination(sortParam, paginationParam); try { - assertHasInfraMlPlugins(requestContext); + const infraMlContext = await assertHasInfraMlPlugins(requestContext); const { data: logEntryAnomalies, @@ -50,7 +50,7 @@ export const initGetLogEntryAnomaliesRoute = ({ framework }: InfraBackendLibs) = hasMoreEntries, timing, } = await getLogEntryAnomalies( - requestContext, + infraMlContext, sourceId, startTime, endTime, diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies_datasets.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies_datasets.ts index 9d3b9f22a839e..1d1f620063b2e 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies_datasets.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies_datasets.ts @@ -35,10 +35,10 @@ export const initGetLogEntryAnomaliesDatasetsRoute = ({ framework }: InfraBacken } = request.body; try { - assertHasInfraMlPlugins(requestContext); + const infraMlContext = await assertHasInfraMlPlugins(requestContext); const { datasets, timing } = await getLogEntryAnomaliesDatasets( - requestContext, + { infra: await infraMlContext.infra }, sourceId, startTime, endTime diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_categories.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_categories.ts index d3660aa16c1f8..6e2e8e8a6c2ad 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_categories.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_categories.ts @@ -39,10 +39,10 @@ export const initGetLogEntryCategoriesRoute = ({ framework }: InfraBackendLibs) } = request.body; try { - assertHasInfraMlPlugins(requestContext); + const infraMlContext = await assertHasInfraMlPlugins(requestContext); const { data: topLogEntryCategories, timing } = await getTopLogEntryCategories( - requestContext, + { infra: await infraMlContext.infra }, sourceId, startTime, endTime, diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_datasets.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_datasets.ts index 76103c936dd6d..de5ac9dac4b07 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_datasets.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_datasets.ts @@ -35,10 +35,10 @@ export const initGetLogEntryCategoryDatasetsRoute = ({ framework }: InfraBackend } = request.body; try { - assertHasInfraMlPlugins(requestContext); + const infraMlContext = await assertHasInfraMlPlugins(requestContext); const { data: logEntryCategoryDatasets, timing } = await getLogEntryCategoryDatasets( - requestContext, + { infra: await infraMlContext.infra }, sourceId, startTime, endTime diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_datasets_stats.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_datasets_stats.ts index 01a98ce43833b..5844405ec062d 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_datasets_stats.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_datasets_stats.ts @@ -36,10 +36,10 @@ export const initGetLogEntryCategoryDatasetsStatsRoute = ({ framework }: InfraBa } = request.body; try { - assertHasInfraMlPlugins(requestContext); + const infraMlContext = await assertHasInfraMlPlugins(requestContext); const { data: datasetStats, timing } = await getLatestLogEntriesCategoriesDatasetsStats( - requestContext, + { infra: await infraMlContext.infra }, jobIds, startTime, endTime, diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_examples.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_examples.ts index 14787406319db..b51aed45b7e11 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_examples.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_examples.ts @@ -43,10 +43,10 @@ export const initGetLogEntryCategoryExamplesRoute = ({ const resolvedLogView = await logViews.getScopedClient(request).getResolvedLogView(sourceId); try { - assertHasInfraMlPlugins(requestContext); + const infraMlContext = await assertHasInfraMlPlugins(requestContext); const { data: logEntryCategoryExamples, timing } = await getLogEntryCategoryExamples( - requestContext, + { infra: await infraMlContext.infra, core: await infraMlContext.core }, sourceId, startTime, endTime, diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_examples.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_examples.ts index f11e9e46bf4c6..fb82a2cd90df5 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_examples.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_examples.ts @@ -44,10 +44,10 @@ export const initGetLogEntryExamplesRoute = ({ const resolvedLogView = await logViews.getScopedClient(request).getResolvedLogView(sourceId); try { - assertHasInfraMlPlugins(requestContext); + const infraMlContext = await assertHasInfraMlPlugins(requestContext); const { data: logEntryExamples, timing } = await getLogEntryExamples( - requestContext, + infraMlContext, sourceId, startTime, endTime, diff --git a/x-pack/plugins/infra/server/routes/metadata/index.ts b/x-pack/plugins/infra/server/routes/metadata/index.ts index 39021ba51c9d9..18ee48ed5ad09 100644 --- a/x-pack/plugins/infra/server/routes/metadata/index.ts +++ b/x-pack/plugins/infra/server/routes/metadata/index.ts @@ -42,10 +42,8 @@ export const initMetadataRoute = (libs: InfraBackendLibs) => { fold(throwErrors(Boom.badRequest), identity) ); - const { configuration } = await libs.sources.getSourceConfiguration( - requestContext.core.savedObjects.client, - sourceId - ); + const soClient = (await requestContext.core).savedObjects.client; + const { configuration } = await libs.sources.getSourceConfiguration(soClient, sourceId); const metricsMetadata = await getMetricMetadata( framework, requestContext, diff --git a/x-pack/plugins/infra/server/routes/metrics_sources/index.ts b/x-pack/plugins/infra/server/routes/metrics_sources/index.ts index cba520e6d53c0..a0cd0afbca50c 100644 --- a/x-pack/plugins/infra/server/routes/metrics_sources/index.ts +++ b/x-pack/plugins/infra/server/routes/metrics_sources/index.ts @@ -33,9 +33,10 @@ export const initMetricsSourceConfigurationRoutes = (libs: InfraBackendLibs) => }, async (requestContext, request, response) => { const { sourceId } = request.params; + const soClient = (await requestContext.core).savedObjects.client; const [source, metricIndicesExist, indexFields] = await Promise.all([ - libs.sources.getSourceConfiguration(requestContext.core.savedObjects.client, sourceId), + libs.sources.getSourceConfiguration(soClient, sourceId), libs.sourceStatus.hasMetricIndices(requestContext, sourceId), libs.fields.getFields(requestContext, sourceId, 'METRICS'), ]); @@ -72,10 +73,8 @@ export const initMetricsSourceConfigurationRoutes = (libs: InfraBackendLibs) => const patchedSourceConfigurationProperties = request.body; try { - const sourceConfiguration = await sources.getSourceConfiguration( - requestContext.core.savedObjects.client, - sourceId - ); + const soClient = (await requestContext.core).savedObjects.client; + const sourceConfiguration = await sources.getSourceConfiguration(soClient, sourceId); if (sourceConfiguration.origin === 'internal') { response.conflict({ @@ -86,13 +85,13 @@ export const initMetricsSourceConfigurationRoutes = (libs: InfraBackendLibs) => const sourceConfigurationExists = sourceConfiguration.origin === 'stored'; const patchedSourceConfiguration = await (sourceConfigurationExists ? sources.updateSourceConfiguration( - requestContext.core.savedObjects.client, + soClient, sourceId, // @ts-ignore patchedSourceConfigurationProperties ) : sources.createSourceConfiguration( - requestContext.core.savedObjects.client, + soClient, sourceId, // @ts-ignore patchedSourceConfigurationProperties @@ -151,10 +150,8 @@ export const initMetricsSourceConfigurationRoutes = (libs: InfraBackendLibs) => const { sourceId } = request.params; const client = createSearchClient(requestContext, framework); - const source = await libs.sources.getSourceConfiguration( - requestContext.core.savedObjects.client, - sourceId - ); + const soClient = (await requestContext.core).savedObjects.client; + const source = await libs.sources.getSourceConfiguration(soClient, sourceId); const results = await hasData(source.configuration.metricAlias, client); diff --git a/x-pack/plugins/infra/server/routes/node_details/index.ts b/x-pack/plugins/infra/server/routes/node_details/index.ts index 8e305226112bd..cd92c902a110e 100644 --- a/x-pack/plugins/infra/server/routes/node_details/index.ts +++ b/x-pack/plugins/infra/server/routes/node_details/index.ts @@ -38,10 +38,8 @@ export const initNodeDetailsRoute = (libs: InfraBackendLibs) => { NodeDetailsRequestRT.decode(request.body), fold(throwErrors(Boom.badRequest), identity) ); - const source = await libs.sources.getSourceConfiguration( - requestContext.core.savedObjects.client, - sourceId - ); + const soClient = (await requestContext.core).savedObjects.client; + const source = await libs.sources.getSourceConfiguration(soClient, sourceId); UsageCollector.countNode(nodeType); diff --git a/x-pack/plugins/infra/server/routes/overview/index.ts b/x-pack/plugins/infra/server/routes/overview/index.ts index fa0e0f4d09aff..9736fd0d7c22e 100644 --- a/x-pack/plugins/infra/server/routes/overview/index.ts +++ b/x-pack/plugins/infra/server/routes/overview/index.ts @@ -24,10 +24,8 @@ export const initOverviewRoute = (libs: InfraBackendLibs) => { async (requestContext, request, response) => { const options = request.body; const client = createSearchClient(requestContext, framework); - const source = await libs.sources.getSourceConfiguration( - requestContext.core.savedObjects.client, - options.sourceId - ); + const soClient = (await requestContext.core).savedObjects.client; + const source = await libs.sources.getSourceConfiguration(soClient, options.sourceId); const topNResponse = await queryTopNodes(options, client, source); diff --git a/x-pack/plugins/infra/server/routes/snapshot/index.ts b/x-pack/plugins/infra/server/routes/snapshot/index.ts index 06b2104e0e17e..99cde598b19e4 100644 --- a/x-pack/plugins/infra/server/routes/snapshot/index.ts +++ b/x-pack/plugins/infra/server/routes/snapshot/index.ts @@ -37,10 +37,8 @@ export const initSnapshotRoute = (libs: InfraBackendLibs) => { fold(throwErrors(Boom.badRequest), identity) ); - const source = await libs.sources.getSourceConfiguration( - requestContext.core.savedObjects.client, - snapshotRequest.sourceId - ); + const soClient = (await requestContext.core).savedObjects.client; + const source = await libs.sources.getSourceConfiguration(soClient, snapshotRequest.sourceId); const compositeSize = libs.configuration.inventory.compositeSize; const [, , { logViews }] = await libs.getStartServices(); const logQueryFields: LogQueryFields | undefined = await logViews diff --git a/x-pack/plugins/infra/server/types.ts b/x-pack/plugins/infra/server/types.ts index a791c15d9e6b9..108575c0f8324 100644 --- a/x-pack/plugins/infra/server/types.ts +++ b/x-pack/plugins/infra/server/types.ts @@ -5,7 +5,11 @@ * 2.0. */ -import type { CoreSetup, RequestHandlerContext } from '@kbn/core/server'; +import type { + CoreSetup, + CustomRequestHandlerContext, + SavedObjectsClientContract, +} from '@kbn/core/server'; import type { SearchRequestHandlerContext } from '@kbn/data-plugin/server'; import type { MlPluginSetup } from '@kbn/ml-plugin/server'; import type { InfraStaticSourceConfiguration } from '../common/source_configuration/source_configuration'; @@ -27,6 +31,10 @@ export interface InfraPluginSetup { export interface InfraPluginStart { logViews: LogViewsServiceStart; + getMetricIndices: ( + savedObjectsClient: SavedObjectsClientContract, + sourceId?: string + ) => Promise; } export type MlSystem = ReturnType; @@ -47,7 +55,7 @@ export type InfraRequestHandlerContext = InfraMlRequestHandlerContext & /** * @internal */ -export interface InfraPluginRequestHandlerContext extends RequestHandlerContext { +export type InfraPluginRequestHandlerContext = CustomRequestHandlerContext<{ infra: InfraRequestHandlerContext; search: SearchRequestHandlerContext; -} +}>; diff --git a/x-pack/plugins/infra/server/utils/request_context.ts b/x-pack/plugins/infra/server/utils/request_context.ts index 8924a03549adc..f0546c8843990 100644 --- a/x-pack/plugins/infra/server/utils/request_context.ts +++ b/x-pack/plugins/infra/server/utils/request_context.ts @@ -7,7 +7,7 @@ /* eslint-disable max-classes-per-file */ -import { InfraMlRequestHandlerContext, InfraRequestHandlerContext } from '../types'; +import { InfraRequestHandlerContext } from '../types'; export class MissingContextValuesError extends Error { constructor(message?: string) { @@ -23,22 +23,31 @@ export class NoMlPluginError extends Error { } } -export function assertHasInfraPlugins( - context: Context -): asserts context is Context & { infra: Context['infra'] } { +export function assertHasInfraPlugins< + Context extends { infra?: Promise } +>(context: Context): asserts context is Context & { infra: Context['infra'] } { if (context.infra == null) { throw new MissingContextValuesError('Failed to access "infra" context values.'); } } -export function assertHasInfraMlPlugins( +export async function assertHasInfraMlPlugins< + Context extends { infra?: Promise } +>( context: Context -): asserts context is Context & { - infra: Context['infra'] & Required; -} { +): Promise< + Context & { + infra: Promise>; + } +> { assertHasInfraPlugins(context); - if (context.infra?.mlAnomalyDetectors == null || context.infra?.mlSystem == null) { + const infraContext = await context.infra; + if (infraContext?.mlAnomalyDetectors == null || infraContext?.mlSystem == null) { throw new NoMlPluginError('Failed to access ML plugin.'); } + + return context as Context & { + infra: Promise>; + }; } diff --git a/x-pack/plugins/infra/tsconfig.json b/x-pack/plugins/infra/tsconfig.json index b508b8fb6da80..370644367b441 100644 --- a/x-pack/plugins/infra/tsconfig.json +++ b/x-pack/plugins/infra/tsconfig.json @@ -24,7 +24,6 @@ { "path": "../../../src/plugins/kibana_react/tsconfig.json" }, { "path": "../../../src/plugins/usage_collection/tsconfig.json" }, { "path": "../../../src/plugins/vis_types/timeseries/tsconfig.json" }, - { "path": "../data_enhanced/tsconfig.json" }, { "path": "../alerting/tsconfig.json" }, { "path": "../features/tsconfig.json" }, { "path": "../license_management/tsconfig.json" }, diff --git a/x-pack/plugins/ingest_pipelines/server/routes/api/create.ts b/x-pack/plugins/ingest_pipelines/server/routes/api/create.ts index 90893b2841cc0..1e59151f73885 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/create.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/create.ts @@ -30,7 +30,7 @@ export const registerCreateRoute = ({ }, }, async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const pipeline = req.body as Pipeline; // eslint-disable-next-line @typescript-eslint/naming-convention diff --git a/x-pack/plugins/ingest_pipelines/server/routes/api/delete.ts b/x-pack/plugins/ingest_pipelines/server/routes/api/delete.ts index 1ffa5adabd83b..1b2fdd1444400 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/delete.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/delete.ts @@ -23,7 +23,7 @@ export const registerDeleteRoute = ({ router }: RouteDependencies): void => { }, }, async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { names } = req.params; const pipelineNames = names.split(','); diff --git a/x-pack/plugins/ingest_pipelines/server/routes/api/documents.ts b/x-pack/plugins/ingest_pipelines/server/routes/api/documents.ts index d9f27ed84f899..b5aff114e44d2 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/documents.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/documents.ts @@ -27,7 +27,7 @@ export const registerDocumentsRoute = ({ }, }, async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { index, id } = req.params; try { diff --git a/x-pack/plugins/ingest_pipelines/server/routes/api/get.ts b/x-pack/plugins/ingest_pipelines/server/routes/api/get.ts index 7da2cf3e6a13a..c053c80e65713 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/get.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/get.ts @@ -18,7 +18,7 @@ const paramsSchema = schema.object({ export const registerGetRoutes = ({ router, lib: { handleEsError } }: RouteDependencies): void => { // Get all pipelines router.get({ path: API_BASE_PATH, validate: false }, async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; try { const pipelines = await clusterClient.asCurrentUser.ingest.getPipeline(); @@ -44,7 +44,7 @@ export const registerGetRoutes = ({ router, lib: { handleEsError } }: RouteDepen }, }, async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = req.params; try { diff --git a/x-pack/plugins/ingest_pipelines/server/routes/api/privileges.ts b/x-pack/plugins/ingest_pipelines/server/routes/api/privileges.ts index 114a5b8840336..175ef4eb37179 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/privileges.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/privileges.ts @@ -36,7 +36,7 @@ export const registerPrivilegesRoute = ({ router, config }: RouteDependencies) = return res.ok({ body: privilegesResult }); } - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { has_all_requested: hasAllPrivileges, cluster } = await clusterClient.asCurrentUser.security.hasPrivileges({ diff --git a/x-pack/plugins/ingest_pipelines/server/routes/api/simulate.ts b/x-pack/plugins/ingest_pipelines/server/routes/api/simulate.ts index 9e4e894e2c7cb..a313afbc2a2c5 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/simulate.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/simulate.ts @@ -29,7 +29,7 @@ export const registerSimulateRoute = ({ }, }, async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { pipeline, documents, verbose } = req.body; diff --git a/x-pack/plugins/ingest_pipelines/server/routes/api/update.ts b/x-pack/plugins/ingest_pipelines/server/routes/api/update.ts index 51983f12e6a60..5b1b032c8aedb 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/update.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/update.ts @@ -30,7 +30,7 @@ export const registerUpdateRoute = ({ }, }, async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = req.params; // eslint-disable-next-line @typescript-eslint/naming-convention const { description, processors, version, on_failure } = req.body; diff --git a/x-pack/plugins/lens/common/embeddable_factory/index.ts b/x-pack/plugins/lens/common/embeddable_factory/index.ts index c4b03ae280778..8ddddf654b017 100644 --- a/x-pack/plugins/lens/common/embeddable_factory/index.ts +++ b/x-pack/plugins/lens/common/embeddable_factory/index.ts @@ -7,9 +7,10 @@ import { SerializableRecord, Serializable } from '@kbn/utility-types'; import { SavedObjectReference } from '@kbn/core/types'; -import { EmbeddableStateWithType } from '@kbn/embeddable-plugin/common'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { EmbeddableRegistryDefinition } from '@kbn/embeddable-plugin/server'; +import type { + EmbeddableStateWithType, + EmbeddableRegistryDefinition, +} from '@kbn/embeddable-plugin/common'; export type LensEmbeddablePersistableState = EmbeddableStateWithType & { attributes: SerializableRecord; diff --git a/x-pack/plugins/lens/common/expressions/counter_rate/counter_rate.test.ts b/x-pack/plugins/lens/common/expressions/counter_rate/counter_rate.test.ts index 32a37e0cf949e..9f19b5d052c68 100644 --- a/x-pack/plugins/lens/common/expressions/counter_rate/counter_rate.test.ts +++ b/x-pack/plugins/lens/common/expressions/counter_rate/counter_rate.test.ts @@ -7,8 +7,7 @@ import { counterRate, CounterRateArgs } from '.'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { Datatable } from '@kbn/expressions-plugin/public'; +import { Datatable } from '@kbn/expressions-plugin/common'; import { functionWrapper } from '@kbn/expressions-plugin/common/expression_functions/specs/tests/utils'; describe('lens_counter_rate', () => { diff --git a/x-pack/plugins/lens/common/expressions/format_column/format_column.test.ts b/x-pack/plugins/lens/common/expressions/format_column/format_column.test.ts index 63e32ffbf1df6..d0db49f4afaae 100644 --- a/x-pack/plugins/lens/common/expressions/format_column/format_column.test.ts +++ b/x-pack/plugins/lens/common/expressions/format_column/format_column.test.ts @@ -5,8 +5,7 @@ * 2.0. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { Datatable, DatatableColumn } from '@kbn/expressions-plugin/public'; +import type { Datatable, DatatableColumn } from '@kbn/expressions-plugin/common'; import { functionWrapper } from '@kbn/expressions-plugin/common/expression_functions/specs/tests/utils'; import { formatColumn } from '.'; diff --git a/x-pack/plugins/lens/common/expressions/merge_tables/merge_tables.test.ts b/x-pack/plugins/lens/common/expressions/merge_tables/merge_tables.test.ts index 4c8a3bf9aa310..4558bdfe68661 100644 --- a/x-pack/plugins/lens/common/expressions/merge_tables/merge_tables.test.ts +++ b/x-pack/plugins/lens/common/expressions/merge_tables/merge_tables.test.ts @@ -7,8 +7,7 @@ import moment from 'moment'; import { mergeTables } from '.'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ExpressionValueSearchContext } from '@kbn/data-plugin/public'; +import type { ExpressionValueSearchContext } from '@kbn/data-plugin/common'; import { Datatable, ExecutionContext, diff --git a/x-pack/plugins/lens/common/expressions/time_scale/time_scale.test.ts b/x-pack/plugins/lens/common/expressions/time_scale/time_scale.test.ts index dd3e18c720c0a..e7fdd720d075c 100644 --- a/x-pack/plugins/lens/common/expressions/time_scale/time_scale.test.ts +++ b/x-pack/plugins/lens/common/expressions/time_scale/time_scale.test.ts @@ -6,10 +6,8 @@ */ import moment from 'moment'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import type { Datatable } from '@kbn/expressions-plugin/public'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import type { TimeRange } from '@kbn/data-plugin/public'; +import type { Datatable } from '@kbn/expressions-plugin/common'; +import type { TimeRange } from '@kbn/data-plugin/common'; import { functionWrapper } from '@kbn/expressions-plugin/common/expression_functions/specs/tests/utils'; // mock the specific inner variable: diff --git a/x-pack/plugins/lens/kibana.json b/x-pack/plugins/lens/kibana.json index 237a25ce78a9a..8ed33fb304525 100644 --- a/x-pack/plugins/lens/kibana.json +++ b/x-pack/plugins/lens/kibana.json @@ -22,7 +22,8 @@ "dataViewFieldEditor", "expressionGauge", "expressionHeatmap", - "eventAnnotation" + "eventAnnotation", + "unifiedSearch" ], "optionalPlugins": [ "expressionXY", diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/frame_layout.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/frame_layout.scss index b49c77bb8b419..cab1a78294a86 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/frame_layout.scss +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/frame_layout.scss @@ -96,7 +96,7 @@ a tilemap in an iframe: https://github.com/elastic/kibana/issues/16457 */ .lnsFrameLayout__sidebar--right { flex-basis: 25%; background-color: lightOrDarkTheme($euiColorLightestShade, $euiColorInk); - min-width: $lnsPanelMinWidth + $euiSizeXL; + min-width: $lnsPanelMinWidth + 70; max-width: $euiFormMaxWidth + $euiSizeXXL; max-height: 100%; diff --git a/x-pack/plugins/lens/public/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/embeddable/embeddable.tsx index 79b2bf31fb9f0..56a24458bbdc0 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable.tsx +++ b/x-pack/plugins/lens/public/embeddable/embeddable.tsx @@ -531,6 +531,7 @@ export class Embeddable interactive={!input.disableTriggers} renderMode={input.renderMode} syncColors={input.syncColors} + syncTooltips={input.syncTooltips} hasCompatibleActions={this.hasCompatibleActions} className={input.className} style={input.style} diff --git a/x-pack/plugins/lens/public/embeddable/expression_wrapper.tsx b/x-pack/plugins/lens/public/embeddable/expression_wrapper.tsx index c2b9d1d2dbb31..27094d154efd2 100644 --- a/x-pack/plugins/lens/public/embeddable/expression_wrapper.tsx +++ b/x-pack/plugins/lens/public/embeddable/expression_wrapper.tsx @@ -38,6 +38,7 @@ export interface ExpressionWrapperProps { onRender$: () => void; renderMode?: RenderMode; syncColors?: boolean; + syncTooltips?: boolean; hasCompatibleActions?: ReactExpressionRendererProps['hasCompatibleActions']; style?: React.CSSProperties; className?: string; @@ -110,6 +111,7 @@ export function ExpressionWrapper({ onRender$, renderMode, syncColors, + syncTooltips, hasCompatibleActions, style, className, @@ -138,6 +140,7 @@ export function ExpressionWrapper({ inspectorAdapters={lensInspector.adapters} renderMode={renderMode} syncColors={syncColors} + syncTooltips={syncTooltips} executionContext={executionContext} renderError={(errorMessage, error) => { onRuntimeError(); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.scss b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.scss index d4c91f80317fd..99286ad34b380 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.scss +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.scss @@ -37,13 +37,7 @@ .lnsIndexPatternDimensionEditor__columns { column-count: 2; - column-gap: $euiSizeXL; -} - -// overrides the .euiListGroupItem display flex. -// The parent container has a column-count property that only works properly with block elements. -.lnsIndexPatternDimensionEditor__operation { - display: block; + column-gap: $euiSizeM; } .lnsIndexPatternDimensionEditor__operation .euiListGroupItem__label { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx index a9e37e2d53d70..790873fdc74b2 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx @@ -6,7 +6,7 @@ */ import './dimension_editor.scss'; -import React, { useState, useMemo, useCallback } from 'react'; +import React, { useState, useMemo, useCallback, useRef, useEffect } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiListGroup, @@ -16,6 +16,7 @@ import { EuiToolTip, EuiText, } from '@elastic/eui'; +import ReactDOM from 'react-dom'; import type { IndexPatternDimensionEditorProps } from './dimension_panel'; import type { OperationSupportMatrix } from './operation_support'; import type { GenericIndexPatternColumn } from '../indexpattern'; @@ -58,6 +59,7 @@ import type { TemporaryState } from './dimensions_editor_helpers'; import { FieldInput } from './field_input'; import { NameInput } from '../../shared_components'; import { ParamEditorProps } from '../operations/definitions'; +import { WrappingHelpPopover } from '../help_popover'; const operationPanels = getOperationDisplay(); @@ -93,6 +95,7 @@ export function DimensionEditor(props: DimensionEditorProps) { savedObjectsClient: props.savedObjectsClient, http: props.http, storage: props.storage, + unifiedSearch: props.unifiedSearch, }; const { fieldByOperation, operationWithoutField } = operationSupportMatrix; @@ -227,6 +230,15 @@ export function DimensionEditor(props: DimensionEditorProps) { const [filterByOpenInitially, setFilterByOpenInitally] = useState(false); const [timeShiftedFocused, setTimeShiftFocused] = useState(false); + const helpPopoverContainer = useRef(null); + useEffect(() => { + return () => { + if (helpPopoverContainer.current) { + ReactDOM.unmountComponentAtNode(helpPopoverContainer.current); + document.body.removeChild(helpPopoverContainer.current); + } + }; + }, []); // Operations are compatible if they match inputs. They are always compatible in // the empty state. Field-based operations are not compatible with field-less operations. @@ -308,6 +320,45 @@ export function DimensionEditor(props: DimensionEditorProps) { compatibleWithCurrentField ? '' : ' incompatible' }`, [`aria-pressed`]: isActive, + extraAction: operationDefinitionMap[operationType].helpComponent + ? { + color: 'primary', + onClick: (e) => { + if (!helpPopoverContainer.current) { + const container = document.createElement('div'); + helpPopoverContainer.current = container; + document.body.appendChild(container); + const HelpComponent = operationDefinitionMap[operationType].helpComponent!; + const element = ( + { + if (helpPopoverContainer.current) { + ReactDOM.unmountComponentAtNode(helpPopoverContainer.current); + document.body.removeChild(helpPopoverContainer.current); + helpPopoverContainer.current = null; + } + }} + > + + + ); + ReactDOM.render(element, helpPopoverContainer.current); + } else { + ReactDOM.unmountComponentAtNode(helpPopoverContainer.current); + document.body.removeChild(helpPopoverContainer.current); + helpPopoverContainer.current = null; + } + }, + iconType: 'documentation', + iconSize: 's', + 'aria-label': i18n.translate('xpack.lens.indexPattern.helpLabel', { + defaultMessage: 'Function help', + }), + } + : undefined, onClick() { if ( ['none', 'fullReference', 'managedReference'].includes( diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx index f4d27a16f19f0..7f21cf21000b1 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx @@ -16,6 +16,7 @@ import { EuiSelect, EuiButtonIcon, } from '@elastic/eui'; +import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; import { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { IndexPatternDimensionEditorComponent, @@ -208,6 +209,7 @@ describe('IndexPatternDimensionEditorPanel', () => { uiSettings: {} as IUiSettingsClient, savedObjectsClient: {} as SavedObjectsClientContract, http: {} as HttpSetup, + unifiedSearch: unifiedSearchPluginMock.createStartContract(), data: { fieldFormats: { getType: jest.fn().mockReturnValue({ @@ -633,7 +635,7 @@ describe('IndexPatternDimensionEditorPanel', () => { act(() => { wrapper - .find('input[data-test-subj="indexPattern-label-edit"]') + .find('input[data-test-subj="column-label-edit"]') .simulate('change', { target: { value: 'New Label' } }); }); @@ -737,7 +739,7 @@ describe('IndexPatternDimensionEditorPanel', () => { act(() => { wrapper - .find('input[data-test-subj="indexPattern-label-edit"]') + .find('input[data-test-subj="column-label-edit"]') .simulate('change', { target: { value: 'Sum of bytes' } }); }); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.tsx index cdccdb65e70db..4f20db3004e8b 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.tsx @@ -9,6 +9,7 @@ import React, { memo, useMemo } from 'react'; import { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from '@kbn/core/public'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import { DatasourceDimensionTriggerProps, DatasourceDimensionEditorProps } from '../../types'; import { GenericIndexPatternColumn } from '../indexpattern'; import { isColumnInvalid } from '../utils'; @@ -31,6 +32,7 @@ export type IndexPatternDimensionEditorProps = layerId: string; http: HttpSetup; data: DataPublicPluginStart; + unifiedSearch: UnifiedSearchPublicPluginStart; uniqueLabel: string; dateRange: DateRange; }; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/droppable.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/droppable.test.ts index c5da32f3a7baa..412f8211844b2 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/droppable.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/droppable.test.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { IndexPatternDimensionEditorProps } from '../dimension_panel'; import { onDrop } from './on_drop_handler'; @@ -322,6 +323,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }), } as unknown as DataPublicPluginStart['fieldFormats'], } as unknown as DataPublicPluginStart, + unifiedSearch: {} as UnifiedSearchPublicPluginStart, core: {} as CoreSetup, dimensionGroups: [], isFullscreen: false, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/reference_editor.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/reference_editor.test.tsx index 1cfea4b6c32e0..804cbde3d170f 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/reference_editor.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/reference_editor.test.tsx @@ -10,6 +10,7 @@ import { ReactWrapper, ShallowWrapper } from 'enzyme'; import { act } from 'react-dom/test-utils'; import { EuiComboBox } from '@elastic/eui'; import { mountWithIntl as mount } from '@kbn/test-jest-helpers'; +import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import type { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from '@kbn/core/public'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; @@ -54,6 +55,7 @@ describe('reference editor', () => { savedObjectsClient: {} as SavedObjectsClientContract, http: {} as HttpSetup, data: {} as DataPublicPluginStart, + unifiedSearch: {} as UnifiedSearchPublicPluginStart, dimensionGroups: [], isFullscreen: false, toggleFullscreen: jest.fn(), diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/reference_editor.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/reference_editor.tsx index 4e373859d6258..3c16d271401ad 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/reference_editor.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/reference_editor.tsx @@ -15,6 +15,7 @@ import { EuiComboBox, EuiComboBoxOptionOption, } from '@elastic/eui'; +import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import type { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from '@kbn/core/public'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; @@ -65,6 +66,7 @@ export interface ReferenceEditorProps { savedObjectsClient: SavedObjectsClientContract; http: HttpSetup; data: DataPublicPluginStart; + unifiedSearch: UnifiedSearchPublicPluginStart; paramEditorCustomProps?: ParamEditorCustomProps; } diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/help_popover.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/help_popover.tsx index 88fb96b58cd21..a1bbc7ccd55f1 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/help_popover.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/help_popover.tsx @@ -12,6 +12,8 @@ import { EuiLinkButtonProps, EuiPopover, EuiPopoverProps, + EuiWrappingPopover, + EuiWrappingPopoverProps, EuiPopoverTitle, EuiText, } from '@elastic/eui'; @@ -75,3 +77,43 @@ export const HelpPopover = ({ ); }; + +export const WrappingHelpPopover = ({ + anchorPosition, + button, + children, + closePopover, + isOpen, + title, +}: { + anchorPosition?: EuiWrappingPopoverProps['anchorPosition']; + button: EuiWrappingPopoverProps['button']; + children: ReactNode; + closePopover: EuiWrappingPopoverProps['closePopover']; + isOpen: EuiWrappingPopoverProps['isOpen']; + title?: string; +}) => { + useEffect(() => { + if (isOpen) { + trackUiEvent('open_help_popover'); + } + }, [isOpen]); + return ( + + {title && {title}} + + + {children} + + + ); +}; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/index.ts b/x-pack/plugins/lens/public/indexpattern_datasource/index.ts index d5ac84568ff1d..41f2a4df9bcda 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/index.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/index.ts @@ -7,11 +7,12 @@ import type { CoreSetup } from '@kbn/core/public'; import { createStartServicesGetter, Storage } from '@kbn/kibana-utils-plugin/public'; +import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; +import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import type { ExpressionsSetup } from '@kbn/expressions-plugin/public'; import type { ChartsPluginSetup } from '@kbn/charts-plugin/public'; import type { IndexPatternFieldEditorStart } from '@kbn/data-view-field-editor-plugin/public'; import type { DataPublicPluginSetup, DataPublicPluginStart } from '@kbn/data-plugin/public'; -import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import type { UiActionsStart } from '@kbn/ui-actions-plugin/public'; import type { FieldFormatsStart, FieldFormatsSetup } from '@kbn/field-formats-plugin/public'; import type { EditorFrameSetup } from '../types'; @@ -28,6 +29,7 @@ export interface IndexPatternDatasourceSetupPlugins { export interface IndexPatternDatasourceStartPlugins { data: DataPublicPluginStart; + unifiedSearch: UnifiedSearchPublicPluginStart; fieldFormats: FieldFormatsStart; dataViewFieldEditor: IndexPatternFieldEditorStart; dataViews: DataViewsPublicPluginStart; @@ -58,14 +60,17 @@ export class IndexPatternDatasource { fieldFormatsSetup.register([suffixFormatter]); } - const [coreStart, { dataViewFieldEditor, uiActions, data, fieldFormats, dataViews }] = - await core.getStartServices(); + const [ + coreStart, + { dataViewFieldEditor, uiActions, data, fieldFormats, dataViews, unifiedSearch }, + ] = await core.getStartServices(); return getIndexPatternDatasource({ core: coreStart, fieldFormats, storage: new Storage(localStorage), data, + unifiedSearch, dataViews, charts, dataViewFieldEditor, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts index 6ae1f0b6f7f4a..db10c420b90de 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts @@ -6,16 +6,22 @@ */ import React, { ReactElement } from 'react'; +import { SavedObjectReference } from '@kbn/core/public'; import { isFragment } from 'react-is'; -import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; -import { getIndexPatternDatasource, GenericIndexPatternColumn } from './indexpattern'; -import { DatasourcePublicAPI, Datasource, FramePublicAPI, OperationDescriptor } from '../types'; import { coreMock } from '@kbn/core/public/mocks'; +import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { IndexPatternPersistedState, IndexPatternPrivateState } from './types'; +import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; import { Ast } from '@kbn/interpreter'; import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; +import { indexPatternFieldEditorPluginMock } from '@kbn/data-view-field-editor-plugin/public/mocks'; +import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks'; +import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks'; +import { TinymathAST } from '@kbn/tinymath'; +import { getIndexPatternDatasource, GenericIndexPatternColumn } from './indexpattern'; +import { DatasourcePublicAPI, Datasource, FramePublicAPI, OperationDescriptor } from '../types'; import { getFieldByNameFactory } from './pure_helpers'; import { operationDefinitionMap, @@ -29,11 +35,6 @@ import { FiltersIndexPatternColumn, } from './operations'; import { createMockedFullReference } from './operations/mocks'; -import { indexPatternFieldEditorPluginMock } from '@kbn/data-view-field-editor-plugin/public/mocks'; -import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks'; -import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks'; -import { TinymathAST } from '@kbn/tinymath'; -import { SavedObjectReference } from '@kbn/core/public'; import { cloneDeep } from 'lodash'; import { DatatableColumn } from '@kbn/expressions-plugin'; @@ -186,6 +187,7 @@ describe('IndexPattern Data Source', () => { beforeEach(() => { indexPatternDatasource = getIndexPatternDatasource({ + unifiedSearch: unifiedSearchPluginMock.createStartContract(), storage: {} as IStorageWrapper, core: coreMock.createStart(), data: dataPluginMock.createStartContract(), diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx index 8ff9ffd6c0460..bfa28b1d1c1ae 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx @@ -20,6 +20,7 @@ import { DataPublicPluginStart, ES_FIELD_TYPES } from '@kbn/data-plugin/public'; import { VisualizeFieldContext } from '@kbn/ui-actions-plugin/public'; import { ChartsPluginSetup } from '@kbn/charts-plugin/public'; import { UiActionsStart } from '@kbn/ui-actions-plugin/public'; +import { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import type { DatasourceDimensionEditorProps, DatasourceDimensionTriggerProps, @@ -115,6 +116,7 @@ export function getIndexPatternDatasource({ core, storage, data, + unifiedSearch, dataViews, fieldFormats, charts, @@ -124,6 +126,7 @@ export function getIndexPatternDatasource({ core: CoreStart; storage: IStorageWrapper; data: DataPublicPluginStart; + unifiedSearch: UnifiedSearchPublicPluginStart; dataViews: DataViewsPublicPluginStart; fieldFormats: FieldFormatsStart; charts: ChartsPluginSetup; @@ -371,6 +374,7 @@ export function getIndexPatternDatasource({ savedObjectsClient={core.savedObjects.client} http={core.http} data={data} + unifiedSearch={unifiedSearch} uniqueLabel={columnLabelMap[props.columnId]} {...props} /> diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/moving_average.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/moving_average.tsx index aa68c8409ad80..cf96bcd11b788 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/moving_average.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/moving_average.tsx @@ -28,7 +28,6 @@ import { combineErrorMessages, } from '../helpers'; import { adjustTimeScaleOnOtherColumnChange } from '../../time_scale_utils'; -import { HelpPopover, HelpPopoverButton } from '../../../help_popover'; import type { OperationDefinition, ParamEditorProps } from '..'; import { getDisallowedPreviousShiftMessage } from '../../../time_shift_utils'; @@ -129,7 +128,10 @@ export const movingAverageOperation: OperationDefinition< getDisallowedPreviousShiftMessage(layer, columnId), ]); }, - getHelpMessage: () => , + helpComponent: () => , + helpComponentTitle: i18n.translate('xpack.lens.indexPattern.movingAverage.titleHelp', { + defaultMessage: 'How moving average works', + }), getDisabledStatus(indexPattern, layer, layerType) { const opName = i18n.translate('xpack.lens.indexPattern.movingAverage', { defaultMessage: 'Moving average', @@ -217,27 +219,8 @@ function MovingAverageParamEditor({ } const MovingAveragePopup = () => { - const [isPopoverOpen, setIsPopoverOpen] = useState(false); return ( - { - setIsPopoverOpen(!isPopoverOpen); - }} - > - {i18n.translate('xpack.lens.indexPattern.movingAverage.helpText', { - defaultMessage: 'How it works', - })} - - } - closePopover={() => setIsPopoverOpen(false)} - isOpen={isPopoverOpen} - title={i18n.translate('xpack.lens.indexPattern.movingAverage.titleHelp', { - defaultMessage: 'How moving average works', - })} - > + <>

{ defaultMessage="The first moving average value starts at the second item." />

-
+ ); }; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.test.tsx index cc1303a2a4f62..e1e5f39a8cc48 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.test.tsx @@ -8,8 +8,9 @@ import React from 'react'; import type { DateHistogramIndexPatternColumn } from './date_histogram'; import { dateHistogramOperation } from '.'; -import { shallow } from 'enzyme'; +import { mount, shallow } from 'enzyme'; import { EuiSwitch } from '@elastic/eui'; +import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; import type { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from '@kbn/core/public'; import type { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { UI_SETTINGS } from '@kbn/data-plugin/public'; @@ -17,8 +18,10 @@ import { dataPluginMock, getCalculateAutoTimeExpression } from '@kbn/data-plugin import { createMockedIndexPattern } from '../../mocks'; import type { IndexPatternLayer, IndexPattern } from '../../types'; import { getFieldByNameFactory } from '../../pure_helpers'; +import { act } from 'react-dom/test-utils'; const dataStart = dataPluginMock.createStartContract(); +const unifiedSearchStart = unifiedSearchPluginMock.createStartContract(); dataStart.search.aggs.calculateAutoTimeExpression = getCalculateAutoTimeExpression( (path: string) => { if (path === UI_SETTINGS.HISTOGRAM_MAX_BARS) { @@ -93,6 +96,7 @@ const defaultOptions = { toDate: 'now', }, data: dataStart, + unifiedSearch: unifiedSearchStart, http: {} as HttpSetup, indexPattern: indexPattern1, operationDefinitionMap: {}, @@ -309,8 +313,9 @@ describe('date_histogram', () => { /> ); - expect(instance.find('[data-test-subj="lensDateHistogramValue"]').prop('value')).toEqual(42); - expect(instance.find('[data-test-subj="lensDateHistogramUnit"]').prop('value')).toEqual('w'); + expect( + instance.find('[data-test-subj="lensDateHistogramInterval"]').prop('selectedOptions') + ).toEqual([expect.objectContaining({ label: '42w' })]); }); it('should render current value for other index pattern', () => { @@ -345,11 +350,12 @@ describe('date_histogram', () => { /> ); - expect(instance.find('[data-test-subj="lensDateHistogramValue"]').prop('value')).toEqual(''); - expect(instance.find('[data-test-subj="lensDateHistogramUnit"]').prop('value')).toEqual('d'); + expect( + instance.find('[data-test-subj="lensDateHistogramInterval"]').prop('selectedOptions') + ).toEqual([expect.objectContaining({ key: 'd' })]); }); - it('should render disabled switch and no time interval control for auto interval', () => { + it('should render time interval control set to auto for auto interval', () => { const thirdLayer: IndexPatternLayer = { indexPatternId: '1', columnOrder: ['col1'], @@ -379,9 +385,9 @@ describe('date_histogram', () => { indexPattern={indexPattern1} /> ); - expect(instance.find('[data-test-subj="lensDateHistogramValue"]').exists()).toBeFalsy(); - expect(instance.find('[data-test-subj="lensDateHistogramUnit"]').exists()).toBeFalsy(); - expect(instance.find(EuiSwitch).at(1).prop('checked')).toBe(false); + expect( + instance.find('[data-test-subj="lensDateHistogramInterval"]').prop('selectedOptions') + ).toEqual([expect.objectContaining({ key: 'auto' })]); }); it('should allow switching to manual interval', () => { @@ -458,7 +464,7 @@ describe('date_histogram', () => { ); instance .find(EuiSwitch) - .at(2) + .at(1) .simulate('change', { target: { checked: false }, }); @@ -499,16 +505,14 @@ describe('date_histogram', () => { indexPattern={{ ...indexPattern1, timeFieldName: undefined }} /> ); - instance - .find(EuiSwitch) - .at(1) - .simulate('change', { - target: { checked: false }, - }); + ( + instance + .find('[data-test-subj="lensDateHistogramInterval"]') + .prop('onChange') as unknown as (v: Array<{ key: string }>) => void + )([{ key: 'auto' }]); expect(updateLayerSpy).toHaveBeenCalled(); const newLayer = updateLayerSpy.mock.calls[0][0]; expect(newLayer).toHaveProperty('columns.col1.params.ignoreTimeRange', false); - expect(newLayer).toHaveProperty('columns.col1.params.interval', 'auto'); }); it('turns off drop partial bucket on tuning off time range ignore', () => { @@ -557,12 +561,14 @@ describe('date_histogram', () => { currentColumn={layer.columns.col1 as DateHistogramIndexPatternColumn} /> ); - instance.find('[data-test-subj="lensDateHistogramValue"]').simulate('change', { - target: { - value: '2', - }, - }); - expect(updateLayerSpy).toHaveBeenCalledWith(layerWithInterval('1w')); + ( + instance.find('[data-test-subj="lensDateHistogramInterval"]').prop('onCreateOption') as ( + s: string + ) => void + )('2w'); + expect( + instance.find('[data-test-subj="lensDateHistogramInterval"]').prop('isInvalid') + ).toBeTruthy(); }); it('should display error if an invalid interval is specified', () => { @@ -577,7 +583,9 @@ describe('date_histogram', () => { currentColumn={testLayer.columns.col1 as DateHistogramIndexPatternColumn} /> ); - expect(instance.find('[data-test-subj="lensDateHistogramError"]').exists()).toBeTruthy(); + expect( + instance.find('[data-test-subj="lensDateHistogramInterval"]').prop('isInvalid') + ).toBeTruthy(); }); it('should not display error if interval value is blank', () => { @@ -592,7 +600,9 @@ describe('date_histogram', () => { currentColumn={testLayer.columns.col1 as DateHistogramIndexPatternColumn} /> ); - expect(instance.find('[data-test-subj="lensDateHistogramError"]').exists()).toBeFalsy(); + expect( + instance.find('[data-test-subj="lensDateHistogramInterval"]').prop('isInvalid') + ).toBeFalsy(); }); it('should display error if interval value is 0', () => { @@ -607,12 +617,14 @@ describe('date_histogram', () => { currentColumn={testLayer.columns.col1 as DateHistogramIndexPatternColumn} /> ); - expect(instance.find('[data-test-subj="lensDateHistogramError"]').exists()).toBeTruthy(); + expect( + instance.find('[data-test-subj="lensDateHistogramInterval"]').prop('isInvalid') + ).toBeTruthy(); }); - it('should update the unit', () => { + it('should update the unit', async () => { const updateLayerSpy = jest.fn(); - const instance = shallow( + const instance = mount( { currentColumn={layer.columns.col1 as DateHistogramIndexPatternColumn} /> ); - instance.find('[data-test-subj="lensDateHistogramUnit"]').simulate('change', { - target: { - value: 'd', - }, + act(() => { + ( + instance + .find('[data-test-subj="lensDateHistogramInterval"]') + .at(0) + .prop('onCreateOption') as (s: string) => void + )('42d'); }); - expect(updateLayerSpy).toHaveBeenCalledWith(layerWithInterval('42d')); + expect(updateLayerSpy.mock.calls[0][0](layer)).toEqual(layerWithInterval('42d')); }); it('should update the value', () => { const updateLayerSpy = jest.fn(); const testLayer = layerWithInterval('42d'); - const instance = shallow( + const instance = mount( { currentColumn={testLayer.columns.col1 as DateHistogramIndexPatternColumn} /> ); - instance.find('[data-test-subj="lensDateHistogramValue"]').simulate('change', { - target: { - value: '9', - }, - }); - expect(updateLayerSpy).toHaveBeenCalledWith(layerWithInterval('9d')); + act(() => + ( + instance + .find('[data-test-subj="lensDateHistogramInterval"]') + .at(0) + .prop('onCreateOption') as (s: string) => void + )('9d') + ); + expect(updateLayerSpy.mock.calls[0][0](layer)).toEqual(layerWithInterval('9d')); }); it('should not render options if they are restricted', () => { @@ -692,7 +710,7 @@ describe('date_histogram', () => { /> ); - expect(instance.find('[data-test-subj="lensDateHistogramValue"]').exists()).toBeFalsy(); + expect(instance.find('[data-test-subj="lensDateHistogramInterval"]').exists()).toBeFalsy(); }); it('should allow the drop of partial buckets', () => { @@ -732,7 +750,7 @@ describe('date_histogram', () => { target: { checked: true }, }); expect(updateLayerSpy).toHaveBeenCalled(); - const newLayer = updateLayerSpy.mock.calls[0][0]; + const newLayer = updateLayerSpy.mock.calls[0][0](layer); expect(newLayer).toHaveProperty('columns.col1.params.dropPartials', true); }); }); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx index f96e584326340..3b6d75879640d 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx @@ -5,38 +5,32 @@ * 2.0. */ -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiBasicTable, EuiCode, - EuiFieldNumber, - EuiFlexGroup, - EuiFlexItem, + EuiComboBox, EuiFormRow, EuiIconTip, - EuiSelect, - EuiSpacer, EuiSwitch, EuiSwitchEvent, - EuiTextColor, } from '@elastic/eui'; import { AggFunctionsMapping, - DataPublicPluginStart, + AggParamOption, IndexPatternAggRestrictions, search, UI_SETTINGS, } from '@kbn/data-plugin/public'; -import { extendedBoundsToAst } from '@kbn/data-plugin/common'; +import { extendedBoundsToAst, intervalOptions } from '@kbn/data-plugin/common'; import { buildExpressionFunction } from '@kbn/expressions-plugin/public'; import { updateColumnParam } from '../layer_helpers'; import { OperationDefinition, ParamEditorProps } from '.'; import { FieldBasedIndexPatternColumn } from './column_types'; import { getInvalidFieldMessage, getSafeName } from './helpers'; -import { HelpPopover, HelpPopoverButton } from '../../help_popover'; import { IndexPatternLayer } from '../../types'; import { TooltipWrapper } from '../../../shared_components'; @@ -96,7 +90,6 @@ export const dateHistogramOperation: OperationDefinition< ) || []), getMultipleDateHistogramsErrorMessage(layer, columnId) || '', ].filter(Boolean), - getHelpMessage: (props) => , getPossibleOperationForField: ({ aggregationRestrictions, aggregatable, type }) => { if ( (type === 'date' || type === 'date_range') && @@ -187,54 +180,81 @@ export const dateHistogramOperation: OperationDefinition< const intervalIsRestricted = field!.aggregationRestrictions && field!.aggregationRestrictions.date_histogram; - const interval = parseInterval(currentColumn.params.interval); + const [intervalInput, setIntervalInput] = useState(currentColumn.params.interval); + const interval = intervalInput === autoInterval ? autoInterval : parseInterval(intervalInput); // We force the interval value to 1 if it's empty, since that is the ES behavior, // and the isValidInterval function doesn't handle the empty case properly. Fixing // isValidInterval involves breaking changes in other areas. - const isValid = isValidInterval( - `${interval.value === '' ? '1' : interval.value}${interval.unit}`, - restrictedInterval(field!.aggregationRestrictions) - ); + const isValid = + (!currentColumn.params.ignoreTimeRange && intervalInput === autoInterval) || + (interval !== autoInterval && + intervalInput !== '' && + isValidInterval( + `${interval.value === '' ? '1' : interval.value}${interval.unit}`, + restrictedInterval(field!.aggregationRestrictions) + )); - const onChangeAutoInterval = useCallback( + const onChangeDropPartialBuckets = useCallback( (ev: EuiSwitchEvent) => { - const { fromDate, toDate } = dateRange; - const value = ev.target.checked - ? data.search.aggs.calculateAutoTimeExpression({ from: fromDate, to: toDate }) || '1h' - : autoInterval; - updateLayer( + updateLayer((newLayer) => updateColumnParam({ - layer: updateColumnParam({ layer, columnId, paramName: 'interval', value }), + layer: newLayer, columnId, - paramName: 'ignoreTimeRange', - value: false, + paramName: 'dropPartials', + value: ev.target.checked, }) ); }, - [dateRange, data.search.aggs, updateLayer, layer, columnId] + [columnId, updateLayer] ); - const onChangeDropPartialBuckets = useCallback( - (ev: EuiSwitchEvent) => { - updateLayer( - updateColumnParam({ - layer, - columnId, - paramName: 'dropPartials', - value: ev.target.checked, - }) + const setInterval = useCallback( + (newInterval: typeof interval) => { + const isCalendarInterval = + newInterval !== autoInterval && calendarOnlyIntervals.has(newInterval.unit); + const value = + newInterval === autoInterval + ? autoInterval + : `${isCalendarInterval ? '1' : newInterval.value}${newInterval.unit || 'd'}`; + + updateLayer((newLayer) => + updateColumnParam({ layer: newLayer, columnId, paramName: 'interval', value }) ); }, - [columnId, layer, updateLayer] + [columnId, updateLayer] ); - const setInterval = (newInterval: typeof interval) => { - const isCalendarInterval = calendarOnlyIntervals.has(newInterval.unit); - const value = `${isCalendarInterval ? '1' : newInterval.value}${newInterval.unit || 'd'}`; + const options = (intervalOptions || []) + .filter((option) => option.val !== autoInterval) + .map((option: AggParamOption) => { + return { label: option.display, key: option.val }; + }, []); - updateLayer(updateColumnParam({ layer, columnId, paramName: 'interval', value })); - }; + options.unshift({ + label: i18n.translate('xpack.lens.indexPattern.autoIntervalLabel', { + defaultMessage: 'Auto ({interval})', + values: { + interval: + data.search.aggs.calculateAutoTimeExpression({ + from: dateRange.fromDate, + to: dateRange.toDate, + }) || '1h', + }, + }), + key: autoInterval, + }); + + const definedOption = options.find((o) => o.key === intervalInput); + const selectedOptions = definedOption + ? [definedOption] + : [{ label: intervalInput, key: intervalInput }]; + + useEffect(() => { + if (isValid && intervalInput !== currentColumn.params.interval) { + setInterval(parseInterval(intervalInput)); + } + }, [intervalInput, isValid, currentColumn.params.interval, setInterval]); const bindToGlobalTimePickerValue = indexPattern.timeFieldName === field?.name || !currentColumn.params.ignoreTimeRange; @@ -263,187 +283,122 @@ export const dateHistogramOperation: OperationDefinition< /> - {!intervalIsRestricted && ( - - + {intervalIsRestricted ? ( + - - )} - {currentColumn.params.interval !== autoInterval && ( - <> - - {intervalIsRestricted ? ( - - ) : ( - <> - - - { - const newInterval = { - ...interval, - value: e.target.value, - }; - setInterval(newInterval); - }} - step={1} - /> - - - { - const newInterval = { - ...interval, - unit: e.target.value, - }; - setInterval(newInterval); - }} - isInvalid={!isValid} - options={[ - { - value: 'ms', - text: i18n.translate( - 'xpack.lens.indexPattern.dateHistogram.milliseconds', - { - defaultMessage: 'milliseconds', - } - ), - }, - { - value: 's', - text: i18n.translate('xpack.lens.indexPattern.dateHistogram.seconds', { - defaultMessage: 'seconds', - }), - }, - { - value: 'm', - text: i18n.translate('xpack.lens.indexPattern.dateHistogram.minutes', { - defaultMessage: 'minutes', - }), - }, - { - value: 'h', - text: i18n.translate('xpack.lens.indexPattern.dateHistogram.hours', { - defaultMessage: 'hours', - }), - }, - { - value: 'd', - text: i18n.translate('xpack.lens.indexPattern.dateHistogram.days', { - defaultMessage: 'days', - }), - }, - { - value: 'w', - text: i18n.translate('xpack.lens.indexPattern.dateHistogram.week', { - defaultMessage: 'week', - }), - }, - { - value: 'M', - text: i18n.translate('xpack.lens.indexPattern.dateHistogram.month', { - defaultMessage: 'month', - }), - }, - // Quarterly intervals appear to be unsupported by esaggs - { - value: 'y', - text: i18n.translate('xpack.lens.indexPattern.dateHistogram.year', { - defaultMessage: 'year', - }), - }, - ]} - /> - - - {!isValid && ( - <> - - - {i18n.translate('xpack.lens.indexPattern.invalidInterval', { - defaultMessage: 'Invalid interval value', - })} - - - )} - - )} - - - - {i18n.translate( - 'xpack.lens.indexPattern.dateHistogram.bindToGlobalTimePicker', - { - defaultMessage: 'Bind to global time picker', - } - )}{' '} - - - } - disabled={indexPattern.timeFieldName === field?.name} - checked={bindToGlobalTimePickerValue} - onChange={() => { + ) : ( + { + const newValue = opts.length ? opts[0].key! : ''; + setIntervalInput(newValue); + if (newValue === autoInterval && currentColumn.params.ignoreTimeRange) { updateLayer( updateColumnParam({ layer, columnId, paramName: 'ignoreTimeRange', - value: !currentColumn.params.ignoreTimeRange, + value: false, }) ); - }} - compressed - /> - - - )} + } + }} + onCreateOption={(customValue: string) => setIntervalInput(customValue.trim())} + options={options} + selectedOptions={selectedOptions} + singleSelection={{ asPlainText: true }} + placeholder={i18n.translate( + 'xpack.lens.indexPattern.dateHistogram.selectIntervalPlaceholder', + { + defaultMessage: 'Select an interval', + } + )} + /> + )} + + + + {i18n.translate('xpack.lens.indexPattern.dateHistogram.bindToGlobalTimePicker', { + defaultMessage: 'Bind to global time picker', + })}{' '} + + + } + disabled={indexPattern.timeFieldName === field?.name} + checked={bindToGlobalTimePickerValue} + onChange={() => { + let newLayer = updateColumnParam({ + layer, + columnId, + paramName: 'ignoreTimeRange', + value: !currentColumn.params.ignoreTimeRange, + }); + if ( + !currentColumn.params.ignoreTimeRange && + currentColumn.params.interval === autoInterval + ) { + const newFixedInterval = + data.search.aggs.calculateAutoTimeExpression({ + from: dateRange.fromDate, + to: dateRange.toDate, + }) || '1h'; + newLayer = updateColumnParam({ + layer: newLayer, + columnId, + paramName: 'interval', + value: newFixedInterval, + }); + setIntervalInput(newFixedInterval); + } + updateLayer(newLayer); + }} + compressed + /> + ); }, + helpComponentTitle: i18n.translate('xpack.lens.indexPattern.dateHistogram.titleHelp', { + defaultMessage: 'How auto date histogram works', + }), + helpComponent() { + const infiniteBound = i18n.translate('xpack.lens.indexPattern.dateHistogram.moreThanYear', { + defaultMessage: 'More than a year', + }); + const upToLabel = i18n.translate('xpack.lens.indexPattern.dateHistogram.upTo', { + defaultMessage: 'Up to', + }); + + return ( + <> +

+ {i18n.translate('xpack.lens.indexPattern.dateHistogram.autoBasicExplanation', { + defaultMessage: 'The auto date histogram splits a data field into buckets by interval.', + })} +

+ +

+ {UI_SETTINGS.HISTOGRAM_MAX_BARS}, + targetBarSetting: {UI_SETTINGS.HISTOGRAM_BAR_TARGET}, + }} + /> +

+ +

+ {i18n.translate('xpack.lens.indexPattern.dateHistogram.autoAdvancedExplanation', { + defaultMessage: 'The interval follows this logic:', + })} +

+ + ({ + bound: typeof bound === 'number' ? infiniteBound : `${upToLabel} ${boundLabel}`, + interval: intervalLabel, + }))} + columns={[ + { + field: 'bound', + name: i18n.translate('xpack.lens.indexPattern.dateHistogram.autoBoundHeader', { + defaultMessage: 'Target interval measured', + }), + }, + { + field: 'interval', + name: i18n.translate('xpack.lens.indexPattern.dateHistogram.autoIntervalHeader', { + defaultMessage: 'Interval used', + }), + }, + ]} + /> + + ); + }, }; function parseInterval(currentInterval: string) { @@ -491,79 +505,3 @@ function restrictedInterval(aggregationRestrictions?: Partial { - const [isPopoverOpen, setIsPopoverOpen] = useState(false); - const infiniteBound = i18n.translate('xpack.lens.indexPattern.dateHistogram.moreThanYear', { - defaultMessage: 'More than a year', - }); - const upToLabel = i18n.translate('xpack.lens.indexPattern.dateHistogram.upTo', { - defaultMessage: 'Up to', - }); - - return ( - { - setIsPopoverOpen(!isPopoverOpen); - }} - > - {i18n.translate('xpack.lens.indexPattern.dateHistogram.autoHelpText', { - defaultMessage: 'How it works', - })} - - } - closePopover={() => setIsPopoverOpen(false)} - isOpen={isPopoverOpen} - title={i18n.translate('xpack.lens.indexPattern.dateHistogram.titleHelp', { - defaultMessage: 'How auto date histogram works', - })} - > -

- {i18n.translate('xpack.lens.indexPattern.dateHistogram.autoBasicExplanation', { - defaultMessage: 'The auto date histogram splits a data field into buckets by interval.', - })} -

- -

- {UI_SETTINGS.HISTOGRAM_MAX_BARS}, - targetBarSetting: {UI_SETTINGS.HISTOGRAM_BAR_TARGET}, - }} - /> -

- -

- {i18n.translate('xpack.lens.indexPattern.dateHistogram.autoAdvancedExplanation', { - defaultMessage: 'The interval follows this logic:', - })} -

- - ({ - bound: typeof bound === 'number' ? infiniteBound : `${upToLabel} ${boundLabel}`, - interval: intervalLabel, - }))} - columns={[ - { - field: 'bound', - name: i18n.translate('xpack.lens.indexPattern.dateHistogram.autoBoundHeader', { - defaultMessage: 'Target interval measured', - }), - }, - { - field: 'interval', - name: i18n.translate('xpack.lens.indexPattern.dateHistogram.autoIntervalHeader', { - defaultMessage: 'Interval used', - }), - }, - ]} - /> -
- ); -}; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filters.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filters.test.tsx index 0e35a7e96cd7d..7208965ec080c 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filters.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filters.test.tsx @@ -8,6 +8,7 @@ import React from 'react'; import { mount } from 'enzyme'; import { act } from 'react-dom/test-utils'; +import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; import type { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from '@kbn/core/public'; import type { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; @@ -25,6 +26,7 @@ const defaultProps = { savedObjectsClient: {} as SavedObjectsClientContract, dateRange: { fromDate: 'now-1d', toDate: 'now' }, data: dataPluginMock.createStartContract(), + unifiedSearch: unifiedSearchPluginMock.createStartContract(), http: {} as HttpSetup, indexPattern: createMockedIndexPattern(), operationDefinitionMap: {}, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula_editor.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula_editor.tsx index fe579e2e5a5f5..ecc46babcfe71 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula_editor.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula_editor.tsx @@ -89,7 +89,7 @@ export function FormulaEditor({ columnId, indexPattern, operationDefinitionMap, - data, + unifiedSearch, toggleFullscreen, isFullscreen, setIsCloseable, @@ -416,7 +416,7 @@ export function FormulaEditor({ context, indexPattern, operationDefinitionMap: visibleOperationsMap, - data, + unifiedSearch, dateHistogramInterval: baseIntervalRef.current, }); } @@ -427,7 +427,7 @@ export function FormulaEditor({ context, indexPattern, operationDefinitionMap: visibleOperationsMap, - data, + unifiedSearch, dateHistogramInterval: baseIntervalRef.current, }); } @@ -444,7 +444,7 @@ export function FormulaEditor({ ), }; }, - [indexPattern, visibleOperationsMap, data, baseIntervalRef] + [indexPattern, visibleOperationsMap, unifiedSearch, baseIntervalRef] ); const provideSignatureHelp = useCallback( diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/math_completion.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/math_completion.test.ts index 92014b340e412..0039f486933b9 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/math_completion.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/math_completion.test.ts @@ -7,11 +7,11 @@ import { parse } from '@kbn/tinymath'; import { monaco } from '@kbn/monaco'; +import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; import { createMockedIndexPattern } from '../../../../mocks'; import { GenericOperationDefinition } from '../..'; import type { IndexPatternField } from '../../../../types'; import type { OperationMetadata } from '../../../../../types'; -import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { tinymathFunctions } from '../util'; import { getSignatureHelp, @@ -217,7 +217,7 @@ describe('math completion', () => { }, indexPattern: createMockedIndexPattern(), operationDefinitionMap, - data: dataPluginMock.createStartContract(), + unifiedSearch: unifiedSearchPluginMock.createStartContract(), }); expect(results.list).toHaveLength(4 + Object.keys(tinymathFunctions).length); ['sum', 'moving_average', 'cumulative_sum', 'last_value'].forEach((key) => { @@ -238,7 +238,7 @@ describe('math completion', () => { }, indexPattern: createMockedIndexPattern(), operationDefinitionMap, - data: dataPluginMock.createStartContract(), + unifiedSearch: unifiedSearchPluginMock.createStartContract(), }); expect(results.list).toHaveLength(2); ['sum', 'last_value'].forEach((key) => { @@ -256,7 +256,7 @@ describe('math completion', () => { }, indexPattern: createMockedIndexPattern(), operationDefinitionMap, - data: dataPluginMock.createStartContract(), + unifiedSearch: unifiedSearchPluginMock.createStartContract(), }); expect(results.list).toEqual(['window']); }); @@ -271,7 +271,7 @@ describe('math completion', () => { }, indexPattern: createMockedIndexPattern(), operationDefinitionMap, - data: dataPluginMock.createStartContract(), + unifiedSearch: unifiedSearchPluginMock.createStartContract(), }); expect(results.list).toEqual([]); }); @@ -286,7 +286,7 @@ describe('math completion', () => { }, indexPattern: createMockedIndexPattern(), operationDefinitionMap, - data: dataPluginMock.createStartContract(), + unifiedSearch: unifiedSearchPluginMock.createStartContract(), }); expect(results.list).toHaveLength(4 + Object.keys(tinymathFunctions).length); ['sum', 'moving_average', 'cumulative_sum', 'last_value'].forEach((key) => { @@ -307,7 +307,7 @@ describe('math completion', () => { }, indexPattern: createMockedIndexPattern(), operationDefinitionMap, - data: dataPluginMock.createStartContract(), + unifiedSearch: unifiedSearchPluginMock.createStartContract(), }); expect(results.list).toHaveLength(4 + Object.keys(tinymathFunctions).length); ['sum', 'moving_average', 'cumulative_sum', 'last_value'].forEach((key) => { @@ -328,7 +328,7 @@ describe('math completion', () => { }, indexPattern: createMockedIndexPattern(), operationDefinitionMap, - data: dataPluginMock.createStartContract(), + unifiedSearch: unifiedSearchPluginMock.createStartContract(), }); expect(results.list).toHaveLength(0); }); @@ -343,7 +343,7 @@ describe('math completion', () => { }, indexPattern: createMockedIndexPattern(), operationDefinitionMap, - data: dataPluginMock.createStartContract(), + unifiedSearch: unifiedSearchPluginMock.createStartContract(), }); expect(results.list).toEqual(['bytes', 'memory']); }); @@ -358,7 +358,7 @@ describe('math completion', () => { }, indexPattern: createMockedIndexPattern(), operationDefinitionMap, - data: dataPluginMock.createStartContract(), + unifiedSearch: unifiedSearchPluginMock.createStartContract(), }); expect(results.list).toEqual(['bytes', 'memory']); }); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/math_completion.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/math_completion.ts index 33dc7a343be4d..a1b629be9c134 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/math_completion.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/math_completion.ts @@ -16,7 +16,10 @@ import { TinymathVariable, TinymathNamedArgument, } from '@kbn/tinymath'; -import type { DataPublicPluginStart, QuerySuggestion } from '@kbn/data-plugin/public'; +import type { + UnifiedSearchPublicPluginStart, + QuerySuggestion, +} from '@kbn/unified-search-plugin/public'; import { parseTimeShift } from '@kbn/data-plugin/common'; import { IndexPattern } from '../../../../types'; import { memoizedGetAvailableOperationsByMetadata } from '../../../operations'; @@ -117,7 +120,7 @@ export async function suggest({ context, indexPattern, operationDefinitionMap, - data, + unifiedSearch, dateHistogramInterval, }: { expression: string; @@ -125,7 +128,7 @@ export async function suggest({ context: monaco.languages.CompletionContext; indexPattern: IndexPattern; operationDefinitionMap: Record; - data: DataPublicPluginStart; + unifiedSearch: UnifiedSearchPublicPluginStart; dateHistogramInterval?: number; }): Promise { const text = @@ -145,7 +148,7 @@ export async function suggest({ if (tokenInfo?.parent && (context.triggerCharacter === '=' || isNamedArgument)) { return await getNamedArgumentSuggestions({ ast: tokenAst as TinymathNamedArgument, - data, + unifiedSearch, indexPattern, dateHistogramInterval, }); @@ -328,13 +331,13 @@ function getArgumentSuggestions( export async function getNamedArgumentSuggestions({ ast, - data, + unifiedSearch, indexPattern, dateHistogramInterval, }: { ast: TinymathNamedArgument; indexPattern: IndexPattern; - data: DataPublicPluginStart; + unifiedSearch: UnifiedSearchPublicPluginStart; dateHistogramInterval?: number; }) { if (ast.name === 'shift') { @@ -356,14 +359,14 @@ export async function getNamedArgumentSuggestions({ if (ast.name !== 'kql' && ast.name !== 'lucene') { return { list: [], type: SUGGESTION_TYPE.KQL }; } - if (!data.autocomplete.hasQuerySuggestions(ast.name === 'kql' ? 'kuery' : 'lucene')) { + if (!unifiedSearch.autocomplete.hasQuerySuggestions(ast.name === 'kql' ? 'kuery' : 'lucene')) { return { list: [], type: SUGGESTION_TYPE.KQL }; } const query = ast.value.split(MARKER)[0]; const position = ast.value.indexOf(MARKER) + 1; - const suggestions = await data.autocomplete.getQuerySuggestions({ + const suggestions = await unifiedSearch.autocomplete.getQuerySuggestions({ language: ast.name === 'kql' ? 'kuery' : 'lucene', query, selectionStart: position, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/index.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/index.ts index 9ac5d683b74ad..36039a058908b 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/index.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/index.ts @@ -14,6 +14,7 @@ import { import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { ExpressionAstFunction } from '@kbn/expressions-plugin/public'; import { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import { termsOperation } from './terms'; import { filtersOperation } from './filters'; import { cardinalityOperation } from './cardinality'; @@ -163,6 +164,7 @@ export interface ParamEditorProps { http: HttpSetup; dateRange: DateRange; data: DataPublicPluginStart; + unifiedSearch: UnifiedSearchPublicPluginStart; activeData?: IndexPatternDimensionEditorProps['activeData']; operationDefinitionMap: Record; paramEditorCustomProps?: ParamEditorCustomProps; @@ -362,6 +364,14 @@ interface BaseOperationDefinitionProps * are not pass the transferable checks */ getNonTransferableFields?: (column: C, indexPattern: IndexPattern) => string[]; + /** + * Component rendered as inline help + */ + helpComponent?: React.ComponentType<{}>; + /** + * Title for the help component + */ + helpComponentTitle?: string; } interface BaseBuildColumnArgs { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.test.tsx index 556c91d3fa46d..5e3f1f0043664 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.test.tsx @@ -8,6 +8,7 @@ import React from 'react'; import { shallow, ShallowWrapper } from 'enzyme'; import { EuiComboBox, EuiFormRow } from '@elastic/eui'; +import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; import { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from '@kbn/core/public'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; @@ -25,6 +26,7 @@ const defaultProps = { uiSettings: uiSettingsMock, savedObjectsClient: {} as SavedObjectsClientContract, dateRange: { fromDate: 'now-1d', toDate: 'now' }, + unifiedSearch: unifiedSearchPluginMock.createStartContract(), data: dataPluginMock.createStartContract(), http: {} as HttpSetup, indexPattern: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.test.tsx index a900e4cc29ae7..831bb03c89abd 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.test.tsx @@ -6,17 +6,18 @@ */ import React, { ChangeEvent } from 'react'; -import { shallow, mount } from 'enzyme'; +import { act } from 'react-dom/test-utils'; +import { EuiRange } from '@elastic/eui'; import { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from '@kbn/core/public'; +import { EuiFormRow } from '@elastic/eui'; +import { shallow, mount } from 'enzyme'; +import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { createMockedIndexPattern } from '../../mocks'; import { percentileOperation } from '.'; import { IndexPattern, IndexPatternLayer } from '../../types'; import { PercentileIndexPatternColumn } from './percentile'; -import { EuiRange } from '@elastic/eui'; -import { act } from 'react-dom/test-utils'; -import { EuiFormRow } from '@elastic/eui'; import { TermsIndexPatternColumn } from './terms'; jest.mock('lodash', () => { @@ -36,6 +37,7 @@ const defaultProps = { savedObjectsClient: {} as SavedObjectsClientContract, dateRange: { fromDate: 'now-1d', toDate: 'now' }, data: dataPluginMock.createStartContract(), + unifiedSearch: unifiedSearchPluginMock.createStartContract(), http: {} as HttpSetup, indexPattern: { ...createMockedIndexPattern(), diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.test.tsx index 534fcdbaf2d02..5f882a3ec2112 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.test.tsx @@ -11,8 +11,9 @@ import { act } from 'react-dom/test-utils'; import { EuiFieldNumber, EuiRange, EuiButtonEmpty, EuiLink, EuiText } from '@elastic/eui'; import { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from '@kbn/core/public'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; -import type { IndexPatternLayer, IndexPattern } from '../../../types'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; +import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; +import type { IndexPatternLayer, IndexPattern } from '../../../types'; import { rangeOperation } from '..'; import { RangeIndexPatternColumn } from './ranges'; import { @@ -51,6 +52,7 @@ jest.mock('lodash', () => { }); const dataPluginMockValue = dataPluginMock.createStartContract(); +const unifiedSearchPluginMockValue = unifiedSearchPluginMock.createStartContract(); // need to overwrite the formatter field first dataPluginMockValue.fieldFormats.deserialize = jest.fn().mockImplementation(({ id, params }) => { return { @@ -84,6 +86,7 @@ const defaultOptions = { toDate: 'now', }, data: dataPluginMockValue, + unifiedSearch: unifiedSearchPluginMockValue, http: {} as HttpSetup, indexPattern: { id: '1', diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/static_value.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/static_value.test.tsx index 546e25308346a..60a871efd85cf 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/static_value.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/static_value.test.tsx @@ -6,16 +6,17 @@ */ import React from 'react'; -import { shallow, mount } from 'enzyme'; +import { act } from 'react-dom/test-utils'; +import { EuiFieldNumber } from '@elastic/eui'; import { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from '@kbn/core/public'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; +import { shallow, mount } from 'enzyme'; +import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { createMockedIndexPattern } from '../../mocks'; import { staticValueOperation } from '.'; import { IndexPattern, IndexPatternLayer } from '../../types'; import { StaticValueIndexPatternColumn } from './static_value'; -import { EuiFieldNumber } from '@elastic/eui'; -import { act } from 'react-dom/test-utils'; import { TermsIndexPatternColumn } from './terms'; jest.mock('lodash', () => { @@ -35,6 +36,7 @@ const defaultProps = { savedObjectsClient: {} as SavedObjectsClientContract, dateRange: { fromDate: 'now-1d', toDate: 'now' }, data: dataPluginMock.createStartContract(), + unifiedSearch: unifiedSearchPluginMock.createStartContract(), http: {} as HttpSetup, indexPattern: { ...createMockedIndexPattern(), diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/terms.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/terms.test.tsx index e028d81ad4549..8cfeb1b68e5b9 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/terms.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/terms.test.tsx @@ -15,6 +15,7 @@ import type { HttpSetup, CoreStart, } from '@kbn/core/public'; +import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; import type { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { createMockedIndexPattern } from '../../../mocks'; @@ -58,6 +59,7 @@ const defaultProps = { savedObjectsClient: {} as SavedObjectsClientContract, dateRange: { fromDate: 'now-1d', toDate: 'now' }, data: dataPluginMock.createStartContract(), + unifiedSearch: unifiedSearchPluginMock.createStartContract(), http: {} as HttpSetup, indexPattern: createMockedIndexPattern(), // need to provide the terms operation as some helpers use operation specific features diff --git a/x-pack/plugins/lens/public/mocks/index.ts b/x-pack/plugins/lens/public/mocks/index.ts index ab6f2066e8804..58ef8ce05c613 100644 --- a/x-pack/plugins/lens/public/mocks/index.ts +++ b/x-pack/plugins/lens/public/mocks/index.ts @@ -31,14 +31,14 @@ export type FrameMock = jest.Mocked; export const createMockFramePublicAPI = (): FrameMock => ({ datasourceLayers: {}, - dateRange: { fromDate: 'now-7d', toDate: 'now' }, + dateRange: { fromDate: '2022-03-17T08:25:00.000Z', toDate: '2022-04-17T08:25:00.000Z' }, }); export type FrameDatasourceMock = jest.Mocked; export const createMockFrameDatasourceAPI = (): FrameDatasourceMock => ({ datasourceLayers: {}, - dateRange: { fromDate: 'now-7d', toDate: 'now' }, + dateRange: { fromDate: '2022-03-17T08:25:00.000Z', toDate: '2022-04-17T08:25:00.000Z' }, query: { query: '', language: 'lucene' }, filters: [], }); diff --git a/x-pack/plugins/lens/public/plugin.ts b/x-pack/plugins/lens/public/plugin.ts index f2d82e96b98cd..b39c14cd82454 100644 --- a/x-pack/plugins/lens/public/plugin.ts +++ b/x-pack/plugins/lens/public/plugin.ts @@ -13,11 +13,8 @@ import type { UsageCollectionStart, } from '@kbn/usage-collection-plugin/public'; import type { DataPublicPluginSetup, DataPublicPluginStart } from '@kbn/data-plugin/public'; -import { - CONTEXT_MENU_TRIGGER, - EmbeddableSetup, - EmbeddableStart, -} from '@kbn/embeddable-plugin/public'; +import type { EmbeddableSetup, EmbeddableStart } from '@kbn/embeddable-plugin/public'; +import { CONTEXT_MENU_TRIGGER } from '@kbn/embeddable-plugin/public'; import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import type { DashboardStart } from '@kbn/dashboard-plugin/public'; import type { SpacesPluginStart } from '@kbn/spaces-plugin/public'; @@ -45,6 +42,7 @@ import { import { VISUALIZE_EDITOR_TRIGGER } from '@kbn/visualizations-plugin/public'; import { createStartServicesGetter } from '@kbn/kibana-utils-plugin/public'; import type { DiscoverSetup, DiscoverStart } from '@kbn/discover-plugin/public'; +import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import type { EditorFrameService as EditorFrameServiceType } from './editor_frame_service'; import type { IndexPatternDatasource as IndexPatternDatasourceType, @@ -111,6 +109,7 @@ export interface LensPluginSetupDependencies { export interface LensPluginStartDependencies { data: DataPublicPluginStart; + unifiedSearch: UnifiedSearchPublicPluginStart; dataViews: DataViewsPublicPluginStart; fieldFormats: FieldFormatsStart; expressions: ExpressionsStart; diff --git a/x-pack/plugins/lens/public/shared_components/legend_location_settings.tsx b/x-pack/plugins/lens/public/shared_components/legend_location_settings.tsx index 7372b727268bd..5e4ef239b4295 100644 --- a/x-pack/plugins/lens/public/shared_components/legend_location_settings.tsx +++ b/x-pack/plugins/lens/public/shared_components/legend_location_settings.tsx @@ -30,11 +30,11 @@ export interface LegendLocationSettingsProps { /** * Sets the vertical alignment for legend inside chart */ - verticalAlignment?: VerticalAlignment; + verticalAlignment?: typeof VerticalAlignment.Top | typeof VerticalAlignment.Bottom; /** * Sets the vertical alignment for legend inside chart */ - horizontalAlignment?: HorizontalAlignment; + horizontalAlignment?: typeof HorizontalAlignment.Left | typeof HorizontalAlignment.Right; /** * Callback on horizontal alignment option change */ diff --git a/x-pack/plugins/lens/public/shared_components/legend_settings_popover.tsx b/x-pack/plugins/lens/public/shared_components/legend_settings_popover.tsx index 37ccb794a9145..944c55fb56091 100644 --- a/x-pack/plugins/lens/public/shared_components/legend_settings_popover.tsx +++ b/x-pack/plugins/lens/public/shared_components/legend_settings_popover.tsx @@ -58,11 +58,11 @@ export interface LegendSettingsPopoverProps { /** * Sets the vertical alignment for legend inside chart */ - verticalAlignment?: VerticalAlignment; + verticalAlignment?: typeof VerticalAlignment.Top | typeof VerticalAlignment.Bottom; /** * Sets the vertical alignment for legend inside chart */ - horizontalAlignment?: HorizontalAlignment; + horizontalAlignment?: typeof HorizontalAlignment.Left | typeof HorizontalAlignment.Right; /** * Callback on horizontal alignment option change */ diff --git a/x-pack/plugins/lens/public/shared_components/name_input.tsx b/x-pack/plugins/lens/public/shared_components/name_input.tsx index 0b65b26021628..9502c7df93d55 100644 --- a/x-pack/plugins/lens/public/shared_components/name_input.tsx +++ b/x-pack/plugins/lens/public/shared_components/name_input.tsx @@ -35,8 +35,9 @@ export const NameInput = ({ fullWidth > { handleInputChange(e.target.value); diff --git a/x-pack/plugins/lens/public/types.ts b/x-pack/plugins/lens/public/types.ts index 0d60db866a2c1..8c6c6d9af22dc 100644 --- a/x-pack/plugins/lens/public/types.ts +++ b/x-pack/plugins/lens/public/types.ts @@ -525,7 +525,7 @@ export interface OperationDescriptor extends Operation { export interface VisualizationConfigProps { layerId: string; - frame: Pick; + frame: FramePublicAPI; state: T; } diff --git a/x-pack/plugins/lens/public/xy_visualization/annotations/helpers.tsx b/x-pack/plugins/lens/public/xy_visualization/annotations/helpers.tsx index 9492c980beacb..f9f4b9da5342a 100644 --- a/x-pack/plugins/lens/public/xy_visualization/annotations/helpers.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/annotations/helpers.tsx @@ -7,7 +7,11 @@ import { i18n } from '@kbn/i18n'; import moment from 'moment'; -import { defaultAnnotationColor } from '@kbn/event-annotation-plugin/public'; +import { + defaultAnnotationColor, + defaultAnnotationRangeColor, + isRangeAnnotation, +} from '@kbn/event-annotation-plugin/public'; import { layerTypes } from '../../../common'; import type { FramePublicAPI, Visualization } from '../../types'; import { isHorizontalChart } from '../state_helpers'; @@ -29,6 +33,13 @@ export const defaultAnnotationLabel = i18n.translate('xpack.lens.xyChart.default defaultMessage: 'Event', }); +export const defaultRangeAnnotationLabel = i18n.translate( + 'xpack.lens.xyChart.defaultRangeAnnotationLabel', + { + defaultMessage: 'Event range', + } +); + export function getStaticDate(dataLayers: XYDataLayerConfig[], frame: FramePublicAPI) { const dataLayersId = dataLayers.map(({ layerId }) => layerId); const { activeData, dateRange } = frame; @@ -162,7 +173,9 @@ export const getAnnotationsAccessorColorConfig = (layer: XYAnnotationLayerConfig return { columnId: annotation.id, triggerIcon: annotation.isHidden ? ('invisible' as const) : ('color' as const), - color: annotation?.color || defaultAnnotationColor, + color: + annotation?.color || + (isRangeAnnotation(annotation) ? defaultAnnotationRangeColor : defaultAnnotationColor), }; }); }; diff --git a/x-pack/plugins/lens/public/xy_visualization/to_expression.ts b/x-pack/plugins/lens/public/xy_visualization/to_expression.ts index 4b4546ae839ec..1c73c455dfe9e 100644 --- a/x-pack/plugins/lens/public/xy_visualization/to_expression.ts +++ b/x-pack/plugins/lens/public/xy_visualization/to_expression.ts @@ -10,7 +10,7 @@ import { ScaleType } from '@elastic/charts'; import type { PaletteRegistry } from '@kbn/coloring'; import { EventAnnotationServiceType } from '@kbn/event-annotation-plugin/public'; -import type { ExtendedYConfig, YConfig } from '@kbn/expression-xy-plugin/common'; +import type { AxisExtentConfig, ExtendedYConfig, YConfig } from '@kbn/expression-xy-plugin/common'; import type { ExpressionAstExpression } from '@kbn/expressions-plugin/common'; import { State, @@ -30,7 +30,7 @@ import { getReferenceLayers, getAnnotationsLayers, } from './visualization_helpers'; -import { getUniqueLabels, defaultAnnotationLabel } from './annotations/helpers'; +import { getUniqueLabels } from './annotations/helpers'; import { layerTypes } from '../../common'; export const getSortedAccessors = ( @@ -86,7 +86,7 @@ const simplifiedLayerExpression = { [layerTypes.REFERENCELINE]: (layer: XYReferenceLineLayerConfig) => ({ ...layer, hide: true, - yConfig: layer.yConfig?.map(({ lineWidth, ...rest }) => ({ + yConfig: layer.yConfig?.map(({ ...rest }) => ({ ...rest, lineWidth: 1, icon: undefined, @@ -96,12 +96,6 @@ const simplifiedLayerExpression = { [layerTypes.ANNOTATIONS]: (layer: XYAnnotationLayerConfig) => ({ ...layer, hide: true, - annotations: layer.annotations?.map(({ lineWidth, ...rest }) => ({ - ...rest, - lineWidth: 1, - icon: undefined, - textVisibility: false, - })), }), }; @@ -234,9 +228,10 @@ export const buildExpression = ( : [], // ensure that even if the user types more than 5 columns // we will only show 5 - floatingColumns: state.legend.floatingColumns - ? [Math.min(5, state.legend.floatingColumns)] - : [], + floatingColumns: + state.legend.floatingColumns && state.legend.isInside + ? [Math.min(5, state.legend.floatingColumns)] + : [], maxLines: state.legend.maxLines ? [state.legend.maxLines] : [], shouldTruncate: [ state.legend.shouldTruncate ?? @@ -252,50 +247,8 @@ export const buildExpression = ( emphasizeFitting: [state.emphasizeFitting || false], curveType: [state.curveType || 'LINEAR'], fillOpacity: [state.fillOpacity || 0.3], - yLeftExtent: [ - { - type: 'expression', - chain: [ - { - type: 'function', - function: 'axisExtentConfig', - arguments: { - mode: [state?.yLeftExtent?.mode || 'full'], - lowerBound: - state?.yLeftExtent?.lowerBound !== undefined - ? [state?.yLeftExtent?.lowerBound] - : [], - upperBound: - state?.yLeftExtent?.upperBound !== undefined - ? [state?.yLeftExtent?.upperBound] - : [], - }, - }, - ], - }, - ], - yRightExtent: [ - { - type: 'expression', - chain: [ - { - type: 'function', - function: 'axisExtentConfig', - arguments: { - mode: [state?.yRightExtent?.mode || 'full'], - lowerBound: - state?.yRightExtent?.lowerBound !== undefined - ? [state?.yRightExtent?.lowerBound] - : [], - upperBound: - state?.yRightExtent?.upperBound !== undefined - ? [state?.yRightExtent?.upperBound] - : [], - }, - }, - ], - }, - ], + yLeftExtent: [axisExtentConfigToExpression(state.yLeftExtent, validDataLayers)], + yRightExtent: [axisExtentConfigToExpression(state.yRightExtent, validDataLayers)], axisTitlesVisibilitySettings: [ { type: 'expression', @@ -436,19 +389,7 @@ const annotationLayerToExpression = ( hide: [Boolean(layer.hide)], layerId: [layer.layerId], annotations: layer.annotations - ? layer.annotations.map( - (ann): Ast => - eventAnnotationService.toExpression({ - time: ann.key.timestamp, - label: ann.label || defaultAnnotationLabel, - textVisibility: ann.textVisibility, - icon: ann.icon, - lineStyle: ann.lineStyle, - lineWidth: ann.lineWidth, - color: ann.color, - isHidden: Boolean(ann.isHidden), - }) - ) + ? layer.annotations.map((ann): Ast => eventAnnotationService.toExpression(ann)) : [], }, }, @@ -570,3 +511,21 @@ const extendedYConfigToExpression = (yConfig: ExtendedYConfig, defaultColor?: st ], }; }; + +const axisExtentConfigToExpression = ( + extent: AxisExtentConfig | undefined, + layers: ValidXYDataLayerConfig[] +): Ast => ({ + type: 'expression', + chain: [ + { + type: 'function', + function: 'axisExtentConfig', + arguments: { + mode: [extent?.mode ?? 'full'], + lowerBound: extent?.lowerBound !== undefined ? [extent?.lowerBound] : [], + upperBound: extent?.upperBound !== undefined ? [extent?.upperBound] : [], + }, + }, + ], +}); diff --git a/x-pack/plugins/lens/public/xy_visualization/types.ts b/x-pack/plugins/lens/public/xy_visualization/types.ts index cd770cedce3f9..b96ddf1aaee2d 100644 --- a/x-pack/plugins/lens/public/xy_visualization/types.ts +++ b/x-pack/plugins/lens/public/xy_visualization/types.ts @@ -56,7 +56,6 @@ export interface XYReferenceLineLayerConfig { layerId: string; accessors: string[]; yConfig?: ExtendedYConfig[]; - palette?: PaletteOutput; layerType: 'referenceLine'; } diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/annotations_config_panel/annotations_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/annotations_config_panel/annotations_panel.tsx index 6435f4c7ba2b8..02a1858e5444b 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/annotations_config_panel/annotations_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/annotations_config_panel/annotations_panel.tsx @@ -5,23 +5,115 @@ * 2.0. */ +import './index.scss'; import React, { useCallback } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiDatePicker, EuiFormRow, EuiSwitch, EuiSwitchEvent } from '@elastic/eui'; +import { + EuiDatePicker, + EuiFormRow, + EuiSwitch, + EuiSwitchEvent, + EuiButtonGroup, + EuiFormLabel, + EuiFormControlLayout, + EuiText, + transparentize, +} from '@elastic/eui'; import type { PaletteRegistry } from '@kbn/coloring'; import moment from 'moment'; -import { EventAnnotationConfig } from '@kbn/event-annotation-plugin/common/types'; -import type { VisualizationDimensionEditorProps } from '../../../types'; -import { State, XYState, XYAnnotationLayerConfig } from '../../types'; +import { + EventAnnotationConfig, + PointInTimeEventAnnotationConfig, + RangeEventAnnotationConfig, +} from '@kbn/event-annotation-plugin/common/types'; +import { pick } from 'lodash'; +import { search } from '@kbn/data-plugin/public'; +import { + defaultAnnotationColor, + defaultAnnotationRangeColor, + isRangeAnnotation, +} from '@kbn/event-annotation-plugin/public'; +import Color from 'color'; +import { getDataLayers } from '../../visualization_helpers'; import { FormatFactory } from '../../../../common'; import { DimensionEditorSection, NameInput, useDebouncedValue } from '../../../shared_components'; import { isHorizontalChart } from '../../state_helpers'; -import { defaultAnnotationLabel } from '../../annotations/helpers'; +import { defaultAnnotationLabel, defaultRangeAnnotationLabel } from '../../annotations/helpers'; import { ColorPicker } from '../color_picker'; import { IconSelectSetting, TextDecorationSetting } from '../shared/marker_decoration_settings'; import { LineStyleSettings } from '../shared/line_style_settings'; import { updateLayer } from '..'; import { annotationsIconSet } from './icon_set'; +import type { FramePublicAPI, VisualizationDimensionEditorProps } from '../../../types'; +import { State, XYState, XYAnnotationLayerConfig, XYDataLayerConfig } from '../../types'; + +export const toRangeAnnotationColor = (color = defaultAnnotationColor) => { + return new Color(transparentize(color, 0.1)).hexa(); +}; + +export const toLineAnnotationColor = (color = defaultAnnotationRangeColor) => { + return new Color(transparentize(color, 1)).hex(); +}; + +export const getEndTimestamp = ( + startTime: string, + { activeData, dateRange }: FramePublicAPI, + dataLayers: XYDataLayerConfig[] +) => { + const startTimeNumber = moment(startTime).valueOf(); + const dateRangeFraction = + (moment(dateRange.toDate).valueOf() - moment(dateRange.fromDate).valueOf()) * 0.1; + const fallbackValue = moment(startTimeNumber + dateRangeFraction).toISOString(); + const dataLayersId = dataLayers.map(({ layerId }) => layerId); + if ( + !dataLayersId.length || + !activeData || + Object.entries(activeData) + .filter(([key]) => dataLayersId.includes(key)) + .every(([, { rows }]) => !rows || !rows.length) + ) { + return fallbackValue; + } + const xColumn = activeData?.[dataLayersId[0]].columns.find( + (column) => column.id === dataLayers[0].xAccessor + ); + if (!xColumn) { + return fallbackValue; + } + + const dateInterval = search.aggs.getDateHistogramMetaDataByDatatableColumn(xColumn)?.interval; + if (!dateInterval) return fallbackValue; + const intervalDuration = search.aggs.parseInterval(dateInterval); + if (!intervalDuration) return fallbackValue; + return moment(startTimeNumber + 3 * intervalDuration.as('milliseconds')).toISOString(); +}; + +const sanitizeProperties = (annotation: EventAnnotationConfig) => { + if (isRangeAnnotation(annotation)) { + const rangeAnnotation: RangeEventAnnotationConfig = pick(annotation, [ + 'label', + 'key', + 'id', + 'isHidden', + 'color', + 'outside', + ]); + return rangeAnnotation; + } else { + const lineAnnotation: PointInTimeEventAnnotationConfig = pick(annotation, [ + 'id', + 'label', + 'key', + 'isHidden', + 'lineStyle', + 'lineWidth', + 'color', + 'icon', + 'textVisibility', + ]); + return lineAnnotation; + } +}; export const AnnotationsPanel = ( props: VisualizationDimensionEditorProps & { @@ -29,7 +121,7 @@ export const AnnotationsPanel = ( paletteService: PaletteRegistry; } ) => { - const { state, setState, layerId, accessor } = props; + const { state, setState, layerId, accessor, frame } = props; const isHorizontal = isHorizontalChart(state.layers); const { inputValue: localState, handleInputChange: setLocalState } = useDebouncedValue({ @@ -42,19 +134,26 @@ export const AnnotationsPanel = ( (l) => l.layerId === layerId ) as XYAnnotationLayerConfig; - const currentAnnotations = localLayer.annotations?.find((c) => c.id === accessor); + const currentAnnotation = localLayer.annotations?.find((c) => c.id === accessor); + + const isRange = isRangeAnnotation(currentAnnotation); const setAnnotations = useCallback( - (annotations: Partial | undefined) => { - if (annotations == null) { + (annotation) => { + if (annotation == null) { return; } const newConfigs = [...(localLayer.annotations || [])]; const existingIndex = newConfigs.findIndex((c) => c.id === accessor); if (existingIndex !== -1) { - newConfigs[existingIndex] = { ...newConfigs[existingIndex], ...annotations }; + newConfigs[existingIndex] = sanitizeProperties({ + ...newConfigs[existingIndex], + ...annotation, + }); } else { - return; // that should never happen because annotations are created before annotations panel is opened + throw new Error( + 'should never happen because annotation is created before config panel is opened' + ); } setLocalState(updateLayer(localState, { ...localLayer, annotations: newConfigs }, index)); }, @@ -68,21 +167,97 @@ export const AnnotationsPanel = ( defaultMessage: 'Placement', })} > - { - if (date) { - setAnnotations({ - key: { - ...(currentAnnotations?.key || { type: 'point_in_time' }), - timestamp: date.toISOString(), - }, - }); - } - }} - label={i18n.translate('xpack.lens.xyChart.annotationDate', { - defaultMessage: 'Annotation date', - })} + {isRange ? ( + <> + { + if (date) { + const currentEndTime = moment(currentAnnotation?.key.endTimestamp).valueOf(); + if (currentEndTime < date.valueOf()) { + const currentStartTime = moment(currentAnnotation?.key.timestamp).valueOf(); + const dif = currentEndTime - currentStartTime; + setAnnotations({ + key: { + ...(currentAnnotation?.key || { type: 'range' }), + timestamp: date.toISOString(), + endTimestamp: moment(date.valueOf() + dif).toISOString(), + }, + }); + } else { + setAnnotations({ + key: { + ...(currentAnnotation?.key || { type: 'range' }), + timestamp: date.toISOString(), + }, + }); + } + } + }} + label={i18n.translate('xpack.lens.xyChart.annotationDate', { + defaultMessage: 'Annotation date', + })} + /> + { + if (date) { + const currentStartTime = moment(currentAnnotation?.key.timestamp).valueOf(); + if (currentStartTime > date.valueOf()) { + const currentEndTime = moment(currentAnnotation?.key.endTimestamp).valueOf(); + const dif = currentEndTime - currentStartTime; + setAnnotations({ + key: { + ...(currentAnnotation?.key || { type: 'range' }), + endTimestamp: date.toISOString(), + timestamp: moment(date.valueOf() - dif).toISOString(), + }, + }); + } else { + setAnnotations({ + key: { + ...(currentAnnotation?.key || { type: 'range' }), + endTimestamp: date.toISOString(), + }, + }); + } + } + }} + /> + + ) : ( + { + if (date) { + setAnnotations({ + key: { + ...(currentAnnotation?.key || { type: 'point_in_time' }), + timestamp: date.toISOString(), + }, + }); + } + }} + /> + )} + + { setAnnotations({ label: value }); }} /> - - - + {!isRange && ( + + )} + {!isRange && ( + + )} + {!isRange && ( + + )} + + {isRange && ( + + { + setAnnotations({ + outside: id === `lens_xyChart_fillStyle_outside`, + }); + }} + isFullWidth + /> + + )} + setAnnotations({ isHidden: ev.target.checked })} /> @@ -134,25 +363,114 @@ export const AnnotationsPanel = ( ); }; -const ConfigPanelDatePicker = ({ +const ConfigPanelApplyAsRangeSwitch = ({ + annotation, + onChange, + frame, + state, +}: { + annotation?: EventAnnotationConfig; + onChange: (annotations: Partial | undefined) => void; + frame: FramePublicAPI; + state: XYState; +}) => { + const isRange = isRangeAnnotation(annotation); + return ( + + + {i18n.translate('xpack.lens.xyChart.applyAsRange', { + defaultMessage: 'Apply as range', + })} + + } + checked={isRange} + onChange={() => { + if (isRange) { + const newPointAnnotation: PointInTimeEventAnnotationConfig = { + key: { + type: 'point_in_time', + timestamp: annotation.key.timestamp, + }, + id: annotation.id, + label: + annotation.label === defaultRangeAnnotationLabel + ? defaultAnnotationLabel + : annotation.label, + color: toLineAnnotationColor(annotation.color), + isHidden: annotation.isHidden, + }; + onChange(newPointAnnotation); + } else if (annotation) { + const fromTimestamp = moment(annotation?.key.timestamp); + const dataLayers = getDataLayers(state.layers); + const newRangeAnnotation: RangeEventAnnotationConfig = { + key: { + type: 'range', + timestamp: annotation.key.timestamp, + endTimestamp: getEndTimestamp(fromTimestamp.toISOString(), frame, dataLayers), + }, + id: annotation.id, + label: + annotation.label === defaultAnnotationLabel + ? defaultRangeAnnotationLabel + : annotation.label, + color: toRangeAnnotationColor(annotation.color), + isHidden: annotation.isHidden, + }; + onChange(newRangeAnnotation); + } + }} + compressed + /> + + ); +}; + +const ConfigPanelRangeDatePicker = ({ value, label, + prependLabel, onChange, + dataTestSubj = 'lnsXY_annotation_date_picker', }: { value: moment.Moment; - label: string; + prependLabel?: string; + label?: string; onChange: (val: moment.Moment | null) => void; + dataTestSubj?: string; }) => { return ( - - + + {prependLabel ? ( + {prependLabel} + } + > + + + ) : ( + + )} ); }; diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/annotations_config_panel/index.scss b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/annotations_config_panel/index.scss new file mode 100644 index 0000000000000..3a0f4b944aa6c --- /dev/null +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/annotations_config_panel/index.scss @@ -0,0 +1,12 @@ +.lnsRowCompressedMargin+.lnsRowCompressedMargin { + margin-top: $euiSizeS; +} + +.lnsConfigPanelNoPadding { + padding: 0; +} + +.lnsConfigPanelDate__label { + min-width: 56px; // makes both labels ("from" and "to") the same width + text-align: center; +} \ No newline at end of file diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/annotations_config_panel/index.test.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/annotations_config_panel/index.test.tsx new file mode 100644 index 0000000000000..f97b4009e3e3e --- /dev/null +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/annotations_config_panel/index.test.tsx @@ -0,0 +1,222 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { mountWithIntl as mount } from '@kbn/test-jest-helpers'; +import { AnnotationsPanel } from '.'; +import { FramePublicAPI } from '../../../types'; +import { layerTypes } from '../../..'; +import { createMockFramePublicAPI } from '../../../mocks'; +import { State } from '../../types'; +import { Position } from '@elastic/charts'; +import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; +import moment from 'moment'; + +jest.mock('lodash', () => { + const original = jest.requireActual('lodash'); + + return { + ...original, + debounce: (fn: unknown) => fn, + }; +}); + +const customLineStaticAnnotation = { + id: 'ann1', + key: { type: 'point_in_time' as const, timestamp: '2022-03-18T08:25:00.000Z' }, + label: 'Event', + icon: 'triangle' as const, + color: 'red', + lineStyle: 'dashed' as const, + lineWidth: 3, +}; + +describe('AnnotationsPanel', () => { + let frame: FramePublicAPI; + + function testState(): State { + return { + legend: { isVisible: true, position: Position.Right }, + valueLabels: 'hide', + preferredSeriesType: 'bar', + layers: [ + { + layerType: layerTypes.ANNOTATIONS, + layerId: 'annotation', + annotations: [customLineStaticAnnotation], + }, + ], + }; + } + + beforeEach(() => { + frame = createMockFramePublicAPI(); + frame.datasourceLayers = {}; + }); + describe('Dimension Editor', () => { + test('shows correct options for line annotations', () => { + const state = testState(); + const component = mount( + + ); + + expect( + component.find('EuiDatePicker[data-test-subj="lns-xyAnnotation-time"]').prop('selected') + ).toEqual(moment('2022-03-18T08:25:00.000Z')); + expect( + component.find('EuiDatePicker[data-test-subj="lns-xyAnnotation-fromTime"]').exists() + ).toBeFalsy(); + expect( + component.find('EuiDatePicker[data-test-subj="lns-xyAnnotation-toTime"]').exists() + ).toBeFalsy(); + expect( + component.find('EuiSwitch[data-test-subj="lns-xyAnnotation-rangeSwitch"]').prop('checked') + ).toEqual(false); + expect( + component.find('EuiFieldText[data-test-subj="column-label-edit"]').prop('value') + ).toEqual('Event'); + expect( + component.find('EuiComboBox[data-test-subj="lns-icon-select"]').prop('selectedOptions') + ).toEqual([{ label: 'Triangle', value: 'triangle' }]); + expect(component.find('TextDecorationSetting').exists()).toBeTruthy(); + expect(component.find('LineStyleSettings').exists()).toBeTruthy(); + expect( + component.find('EuiButtonGroup[data-test-subj="lns-xyAnnotation-fillStyle"]').exists() + ).toBeFalsy(); + }); + test('shows correct options for range annotations', () => { + const state = testState(); + state.layers[0] = { + annotations: [ + { + color: 'red', + icon: 'triangle', + id: 'ann1', + isHidden: undefined, + key: { + endTimestamp: '2022-03-21T10:49:00.000Z', + timestamp: '2022-03-18T08:25:00.000Z', + type: 'range', + }, + label: 'Event range', + lineStyle: 'dashed', + lineWidth: 3, + }, + ], + layerId: 'annotation', + layerType: 'annotations', + }; + const component = mount( + + ); + + expect( + component.find('EuiDatePicker[data-test-subj="lns-xyAnnotation-fromTime"]').prop('selected') + ).toEqual(moment('2022-03-18T08:25:00.000Z')); + expect( + component.find('EuiDatePicker[data-test-subj="lns-xyAnnotation-toTime"]').prop('selected') + ).toEqual(moment('2022-03-21T10:49:00.000Z')); + expect( + component.find('EuiDatePicker[data-test-subj="lns-xyAnnotation-time"]').exists() + ).toBeFalsy(); + expect( + component.find('EuiSwitch[data-test-subj="lns-xyAnnotation-rangeSwitch"]').prop('checked') + ).toEqual(true); + expect( + component.find('EuiFieldText[data-test-subj="column-label-edit"]').prop('value') + ).toEqual('Event range'); + expect(component.find('EuiComboBox[data-test-subj="lns-icon-select"]').exists()).toBeFalsy(); + expect(component.find('TextDecorationSetting').exists()).toBeFalsy(); + expect(component.find('LineStyleSettings').exists()).toBeFalsy(); + expect(component.find('[data-test-subj="lns-xyAnnotation-fillStyle"]').exists()).toBeTruthy(); + }); + + test('calculates correct endTimstamp and transparent color when switching for range annotation and back', () => { + const state = testState(); + const setState = jest.fn(); + const component = mount( + + ); + component.find('button[data-test-subj="lns-xyAnnotation-rangeSwitch"]').simulate('click'); + + expect(setState).toBeCalledWith({ + ...state, + layers: [ + { + annotations: [ + { + color: '#FF00001A', + id: 'ann1', + isHidden: undefined, + label: 'Event range', + key: { + endTimestamp: '2022-03-21T10:49:00.000Z', + timestamp: '2022-03-18T08:25:00.000Z', + type: 'range', + }, + }, + ], + layerId: 'annotation', + layerType: 'annotations', + }, + ], + }); + component.find('button[data-test-subj="lns-xyAnnotation-rangeSwitch"]').simulate('click'); + expect(setState).toBeCalledWith({ + ...state, + layers: [ + { + annotations: [ + { + color: '#FF0000', + id: 'ann1', + isHidden: undefined, + key: { + timestamp: '2022-03-18T08:25:00.000Z', + type: 'point_in_time', + }, + label: 'Event', + }, + ], + layerId: 'annotation', + layerType: 'annotations', + }, + ], + }); + }); + }); +}); diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/color_picker.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/color_picker.tsx index 9024b0f4f593e..00f03f261ef7b 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/color_picker.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/color_picker.tsx @@ -5,23 +5,26 @@ * 2.0. */ -import React, { useMemo, useState } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; +import chroma from 'chroma-js'; import { i18n } from '@kbn/i18n'; -import { EuiFormRow, EuiColorPicker, EuiColorPickerProps, EuiToolTip, EuiIcon } from '@elastic/eui'; +import { + EuiFormRow, + EuiColorPicker, + EuiColorPickerProps, + EuiToolTip, + EuiIcon, + euiPaletteColorBlind, +} from '@elastic/eui'; import type { PaletteRegistry } from '@kbn/coloring'; -import { defaultAnnotationColor } from '@kbn/event-annotation-plugin/public'; import type { VisualizationDimensionEditorProps } from '../../types'; -import { State, XYDataLayerConfig } from '../types'; +import { State } from '../types'; import { FormatFactory } from '../../../common'; import { getSeriesColor } from '../state_helpers'; -import { - defaultReferenceLineColor, - getAccessorColorConfig, - getColorAssignments, -} from '../color_assignment'; +import { getAccessorColorConfig, getColorAssignments } from '../color_assignment'; import { getSortedAccessors } from '../to_expression'; import { TooltipWrapper } from '../../shared_components'; -import { isReferenceLayer, isAnnotationsLayer, getDataLayers } from '../visualization_helpers'; +import { getDataLayers, isDataLayer } from '../visualization_helpers'; const tooltipContent = { auto: i18n.translate('xpack.lens.configPanel.color.tooltip.auto', { @@ -47,6 +50,8 @@ export const ColorPicker = ({ disableHelpTooltip, disabled, setConfig, + showAlpha, + defaultColor, }: VisualizationDimensionEditorProps & { formatFactory: FormatFactory; paletteService: PaletteRegistry; @@ -54,6 +59,8 @@ export const ColorPicker = ({ disableHelpTooltip?: boolean; disabled?: boolean; setConfig: (config: { color?: string }) => void; + showAlpha?: boolean; + defaultColor?: string; }) => { const index = state.layers.findIndex((l) => l.layerId === layerId); const layer = state.layers[index]; @@ -61,38 +68,47 @@ export const ColorPicker = ({ const overwriteColor = getSeriesColor(layer, accessor); const currentColor = useMemo(() => { if (overwriteColor || !frame.activeData) return overwriteColor; - if (isReferenceLayer(layer)) { - return defaultReferenceLineColor; - } else if (isAnnotationsLayer(layer)) { - return defaultAnnotationColor; + if (defaultColor) { + return defaultColor; } - - const dataLayer: XYDataLayerConfig = layer; - const sortedAccessors: string[] = getSortedAccessors( - frame.datasourceLayers[layer.layerId] ?? layer.accessors, - layer - ); - - const colorAssignments = getColorAssignments( - getDataLayers(state.layers), - { tables: frame.activeData ?? {} }, - formatFactory - ); - const mappedAccessors = getAccessorColorConfig( - colorAssignments, - frame, - { - ...dataLayer, - accessors: sortedAccessors.filter((sorted) => dataLayer.accessors.includes(sorted)), - }, - paletteService - ); - - return mappedAccessors.find((a) => a.columnId === accessor)?.color || null; - }, [overwriteColor, frame, layer, state.layers, formatFactory, paletteService, accessor]); + if (isDataLayer(layer)) { + const sortedAccessors: string[] = getSortedAccessors( + frame.datasourceLayers[layer.layerId] ?? layer.accessors, + layer + ); + const colorAssignments = getColorAssignments( + getDataLayers(state.layers), + { tables: frame.activeData ?? {} }, + formatFactory + ); + const mappedAccessors = getAccessorColorConfig( + colorAssignments, + frame, + { + ...layer, + accessors: sortedAccessors.filter((sorted) => layer.accessors.includes(sorted)), + }, + paletteService + ); + return mappedAccessors.find((a) => a.columnId === accessor)?.color || null; + } + }, [ + overwriteColor, + frame, + paletteService, + state.layers, + accessor, + formatFactory, + layer, + defaultColor, + ]); const [color, setColor] = useState(currentColor); + useEffect(() => { + setColor(currentColor); + }, [currentColor]); + const handleColor: EuiColorPickerProps['onChange'] = (text, output) => { setColor(text); if (output.isValid || text === '') { @@ -107,8 +123,11 @@ export const ColorPicker = ({ defaultMessage: 'Series color', }); + const currentColorAlpha = color ? chroma(color).alpha() : 1; + const colorPicker = ( chroma(c).alpha(currentColorAlpha).hex()) + } /> ); diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/index.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/index.tsx index b61f4694f8a91..00c4e9c8eaeb2 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/index.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/index.tsx @@ -7,7 +7,7 @@ import React, { memo, useCallback } from 'react'; import { i18n } from '@kbn/i18n'; -import { Position, ScaleType, VerticalAlignment, HorizontalAlignment } from '@elastic/charts'; +import { Position, ScaleType } from '@elastic/charts'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { AxesSettingsConfig, AxisExtentConfig } from '@kbn/expression-xy-plugin/common'; import type { VisualizationToolbarProps, FramePublicAPI } from '../../types'; @@ -21,6 +21,7 @@ import { getScaleType } from '../to_expression'; import { TooltipWrapper } from '../../shared_components'; import { getDefaultVisualValuesForLayer } from '../../shared_components/datasource_default_values'; import { getDataLayers } from '../visualization_helpers'; +import { LegendSettingsPopoverProps } from '../../shared_components/legend_settings_popover'; type UnwrapArray = T extends Array ? P : T; type AxesSettingsConfigKeys = keyof AxesSettingsConfig; @@ -380,8 +381,10 @@ export const XyToolbar = memo(function XyToolbar( }} onAlignmentChange={(value) => { const [vertical, horizontal] = value.split('_'); - const verticalAlignment = vertical as VerticalAlignment; - const horizontalAlignment = horizontal as HorizontalAlignment; + const verticalAlignment = vertical as LegendSettingsPopoverProps['verticalAlignment']; + const horizontalAlignment = + horizontal as LegendSettingsPopoverProps['horizontalAlignment']; + setState({ ...state, legend: { ...state.legend, verticalAlignment, horizontalAlignment }, diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/reference_line_config_panel/reference_line_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/reference_line_config_panel/reference_line_panel.tsx index e44fd053c7c8b..e25c191d2bec1 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/reference_line_config_panel/reference_line_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/reference_line_config_panel/reference_line_panel.tsx @@ -26,6 +26,7 @@ import { } from '../shared/marker_decoration_settings'; import { LineStyleSettings } from '../shared/line_style_settings'; import { referenceLineIconsSet } from './icon_set'; +import { defaultReferenceLineColor } from '../../color_assignment'; export const ReferenceLinePanel = ( props: VisualizationDimensionEditorProps & { @@ -93,6 +94,7 @@ export const ReferenceLinePanel = ( ({ value, onChange, customIconSet, + defaultIcon = 'empty', }: { value?: Icon; onChange: (newIcon: Icon) => void; customIconSet: IconSet; + defaultIcon?: string; }) { const selectedIcon = customIconSet.find((option) => value === option.value) || - customIconSet.find((option) => option.value === 'empty')!; + customIconSet.find((option) => option.value === defaultIcon)!; return ( { onChange(selection[0].value!); }} diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/shared/marker_decoration_settings.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/shared/marker_decoration_settings.tsx index a5f740ce9a999..64b00ef246161 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/shared/marker_decoration_settings.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/shared/marker_decoration_settings.tsx @@ -132,10 +132,12 @@ export function IconSelectSetting({ currentConfig, setConfig, customIconSet, + defaultIcon = 'empty', }: { currentConfig?: MarkerDecorationConfig; setConfig: (config: MarkerDecorationConfig) => void; customIconSet: IconSet; + defaultIcon?: string; }) { return ( ({ })} > { diff --git a/x-pack/plugins/lens/server/embeddable/make_lens_embeddable_factory.ts b/x-pack/plugins/lens/server/embeddable/make_lens_embeddable_factory.ts index f6d6a6e49e450..215f080d3dbdf 100644 --- a/x-pack/plugins/lens/server/embeddable/make_lens_embeddable_factory.ts +++ b/x-pack/plugins/lens/server/embeddable/make_lens_embeddable_factory.ts @@ -115,11 +115,9 @@ export const makeLensEmbeddableFactory = '8.3.0': (state) => { const lensState = state as unknown as { attributes: LensDocShape810 }; let migratedLensState = commonLockOldMetricVisSettings(lensState.attributes); - if (migratedLensState.visualizationType !== 'lnsXY') { - migratedLensState = commonFixValueLabelsInXY( - migratedLensState as LensDocShape810 - ); - } + migratedLensState = commonFixValueLabelsInXY( + migratedLensState as LensDocShape810 + ); return { ...lensState, attributes: migratedLensState, diff --git a/x-pack/plugins/lens/server/migrations/common_migrations.ts b/x-pack/plugins/lens/server/migrations/common_migrations.ts index d276b8d832914..7cafa41f569d4 100644 --- a/x-pack/plugins/lens/server/migrations/common_migrations.ts +++ b/x-pack/plugins/lens/server/migrations/common_migrations.ts @@ -348,6 +348,10 @@ export const fixLensTopValuesCustomFormatting = (attributes: LensDocShape810): L export const commonFixValueLabelsInXY = ( attributes: LensDocShape830 ): LensDocShape830 => { + if (attributes.visualizationType !== 'lnsXY') { + return attributes as LensDocShape830; + } + const newAttributes: LensDocShape830 = cloneDeep(attributes); const { visualization } = newAttributes.state; const { valueLabels } = visualization; diff --git a/x-pack/plugins/lens/server/migrations/saved_object_migrations.ts b/x-pack/plugins/lens/server/migrations/saved_object_migrations.ts index a9bac4f6edddf..00ec6c29154e3 100644 --- a/x-pack/plugins/lens/server/migrations/saved_object_migrations.ts +++ b/x-pack/plugins/lens/server/migrations/saved_object_migrations.ts @@ -13,9 +13,7 @@ import { SavedObjectReference, SavedObjectUnsanitizedDoc, } from '@kbn/core/server'; -import { Filter } from '@kbn/es-query'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { Query } from '@kbn/data-plugin/public'; +import type { Query, Filter } from '@kbn/es-query'; import { mergeSavedObjectMigrationMaps } from '@kbn/core/server'; import { MigrateFunctionsObject } from '@kbn/kibana-utils-plugin/common'; import { PersistableFilter } from '../../common'; @@ -499,10 +497,6 @@ const fixValueLabelsInXY: SavedObjectMigrationFn< LensDocShape830, LensDocShape830 > = (doc) => { - if (doc.attributes.visualizationType !== 'lnsXY') { - return doc; - } - const newDoc = cloneDeep(doc); return { ...newDoc, attributes: commonFixValueLabelsInXY(newDoc.attributes) }; }; diff --git a/x-pack/plugins/lens/server/migrations/types.ts b/x-pack/plugins/lens/server/migrations/types.ts index 53804a6bbcfe0..6b38bb4b4f631 100644 --- a/x-pack/plugins/lens/server/migrations/types.ts +++ b/x-pack/plugins/lens/server/migrations/types.ts @@ -6,9 +6,7 @@ */ import type { PaletteOutput, CustomPaletteParams } from '@kbn/coloring'; -import { Filter } from '@kbn/es-query'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { Query } from '@kbn/data-plugin/public'; +import type { Query, Filter } from '@kbn/es-query'; import type { MigrateFunctionsObject } from '@kbn/kibana-utils-plugin/common'; import type { LayerType, PersistableFilter, ValueLabelConfig } from '../../common'; diff --git a/x-pack/plugins/lens/server/routes/existing_fields.ts b/x-pack/plugins/lens/server/routes/existing_fields.ts index 542cdb33df8ab..61df3bb458912 100644 --- a/x-pack/plugins/lens/server/routes/existing_fields.ts +++ b/x-pack/plugins/lens/server/routes/existing_fields.ts @@ -136,7 +136,8 @@ async function fetchFieldExistence({ }); } - const metaFields: string[] = await context.core.uiSettings.client.get(UI_SETTINGS.META_FIELDS); + const uiSettingsClient = (await context.core).uiSettings.client; + const metaFields: string[] = await uiSettingsClient.get(UI_SETTINGS.META_FIELDS); const dataView = await dataViewsService.get(indexPatternId); const allFields = buildFieldList(dataView, metaFields); const existingFieldList = await dataViewsService.getFieldsForIndexPattern(dataView, { @@ -169,7 +170,8 @@ async function legacyFetchFieldExistenceSampling({ timeFieldName?: string; includeFrozen: boolean; }) { - const metaFields: string[] = await context.core.uiSettings.client.get(UI_SETTINGS.META_FIELDS); + const coreContext = await context.core; + const metaFields: string[] = await coreContext.uiSettings.client.get(UI_SETTINGS.META_FIELDS); const indexPattern = await dataViewsService.get(indexPatternId); const fields = buildFieldList(indexPattern, metaFields); @@ -179,7 +181,7 @@ async function legacyFetchFieldExistenceSampling({ fromDate, toDate, dslQuery, - client: context.core.elasticsearch.client.asCurrentUser, + client: coreContext.elasticsearch.client.asCurrentUser, index: indexPattern.title, timeFieldName: timeFieldName || indexPattern.timeFieldName, fields, diff --git a/x-pack/plugins/lens/server/routes/field_stats.ts b/x-pack/plugins/lens/server/routes/field_stats.ts index 1da732ab60ab2..35a15ea44be67 100644 --- a/x-pack/plugins/lens/server/routes/field_stats.ts +++ b/x-pack/plugins/lens/server/routes/field_stats.ts @@ -39,7 +39,7 @@ export async function initFieldsRoute(setup: CoreSetup) { }, }, async (context, req, res) => { - const requestClient = context.core.elasticsearch.client.asCurrentUser; + const requestClient = (await context.core).elasticsearch.client.asCurrentUser; const { fromDate, toDate, fieldName, dslQuery, size } = req.body; const [{ savedObjects, elasticsearch }, { dataViews }] = await setup.getStartServices(); diff --git a/x-pack/plugins/lens/server/routes/telemetry.ts b/x-pack/plugins/lens/server/routes/telemetry.ts index 8ef45a5029e93..01c843cf5489d 100644 --- a/x-pack/plugins/lens/server/routes/telemetry.ts +++ b/x-pack/plugins/lens/server/routes/telemetry.ts @@ -33,7 +33,7 @@ export async function initLensUsageRoute(setup: CoreSetup) const { events, suggestionEvents } = req.body; try { - const client = context.core.savedObjects.client; + const client = (await context.core).savedObjects.client; const allEvents: Array<{ type: 'lens-ui-telemetry'; diff --git a/x-pack/plugins/license_management/server/routes/api/license/register_license_route.ts b/x-pack/plugins/license_management/server/routes/api/license/register_license_route.ts index 03e57b1a12cd9..0a9bbacaff4d5 100644 --- a/x-pack/plugins/license_management/server/routes/api/license/register_license_route.ts +++ b/x-pack/plugins/license_management/server/routes/api/license/register_license_route.ts @@ -26,7 +26,7 @@ export function registerLicenseRoute({ }, }, async (ctx, req, res) => { - const { client } = ctx.core.elasticsearch; + const { client } = (await ctx.core).elasticsearch; try { return res.ok({ body: await putLicense({ diff --git a/x-pack/plugins/license_management/server/routes/api/license/register_permissions_route.ts b/x-pack/plugins/license_management/server/routes/api/license/register_permissions_route.ts index 01aae5cd6d441..8372273726911 100644 --- a/x-pack/plugins/license_management/server/routes/api/license/register_permissions_route.ts +++ b/x-pack/plugins/license_management/server/routes/api/license/register_permissions_route.ts @@ -15,7 +15,7 @@ export function registerPermissionsRoute({ config: { isSecurityEnabled }, }: RouteDependencies) { router.post({ path: addBasePath('/permissions'), validate: false }, async (ctx, req, res) => { - const { client } = ctx.core.elasticsearch; + const { client } = (await ctx.core).elasticsearch; try { return res.ok({ diff --git a/x-pack/plugins/license_management/server/routes/api/license/register_start_basic_route.ts b/x-pack/plugins/license_management/server/routes/api/license/register_start_basic_route.ts index 60e72d297b2ed..fa9f13ade07a1 100644 --- a/x-pack/plugins/license_management/server/routes/api/license/register_start_basic_route.ts +++ b/x-pack/plugins/license_management/server/routes/api/license/register_start_basic_route.ts @@ -21,7 +21,7 @@ export function registerStartBasicRoute({ validate: { query: schema.object({ acknowledge: schema.string() }) }, }, async (ctx, req, res) => { - const { client } = ctx.core.elasticsearch; + const { client } = (await ctx.core).elasticsearch; try { return res.ok({ body: await startBasic({ diff --git a/x-pack/plugins/license_management/server/routes/api/license/register_start_trial_routes.ts b/x-pack/plugins/license_management/server/routes/api/license/register_start_trial_routes.ts index 43ab7c5eafdb5..5ff25f4d21308 100644 --- a/x-pack/plugins/license_management/server/routes/api/license/register_start_trial_routes.ts +++ b/x-pack/plugins/license_management/server/routes/api/license/register_start_trial_routes.ts @@ -15,7 +15,7 @@ export function registerStartTrialRoutes({ plugins: { licensing }, }: RouteDependencies) { router.get({ path: addBasePath('/start_trial'), validate: false }, async (ctx, req, res) => { - const { client } = ctx.core.elasticsearch; + const { client } = (await ctx.core).elasticsearch; try { return res.ok({ body: await canStartTrial(client) }); } catch (error) { @@ -24,7 +24,7 @@ export function registerStartTrialRoutes({ }); router.post({ path: addBasePath('/start_trial'), validate: false }, async (ctx, req, res) => { - const { client } = ctx.core.elasticsearch; + const { client } = (await ctx.core).elasticsearch; try { return res.ok({ body: await startTrial({ client, licensing }), diff --git a/x-pack/plugins/licensing/server/routes/info.ts b/x-pack/plugins/licensing/server/routes/info.ts index 9db7a1c8ca1ba..1cbc7b6398966 100644 --- a/x-pack/plugins/licensing/server/routes/info.ts +++ b/x-pack/plugins/licensing/server/routes/info.ts @@ -8,9 +8,12 @@ import { LicensingRouter } from '../types'; export function registerInfoRoute(router: LicensingRouter) { - router.get({ path: '/api/licensing/info', validate: false }, (context, request, response) => { - return response.ok({ - body: context.licensing.license, - }); - }); + router.get( + { path: '/api/licensing/info', validate: false }, + async (context, request, response) => { + return response.ok({ + body: (await context.licensing).license, + }); + } + ); } diff --git a/x-pack/plugins/licensing/server/routes/internal/notify_feature_usage.ts b/x-pack/plugins/licensing/server/routes/internal/notify_feature_usage.ts index 2cc4a64b63a3f..a33cf4284245d 100644 --- a/x-pack/plugins/licensing/server/routes/internal/notify_feature_usage.ts +++ b/x-pack/plugins/licensing/server/routes/internal/notify_feature_usage.ts @@ -22,7 +22,7 @@ export function registerNotifyFeatureUsageRoute(router: LicensingRouter) { async (context, request, response) => { const { featureName, lastUsed } = request.body; - context.licensing.featureUsage.notifyUsage(featureName, lastUsed); + (await context.licensing).featureUsage.notifyUsage(featureName, lastUsed); return response.ok({ body: { diff --git a/x-pack/plugins/licensing/server/types.ts b/x-pack/plugins/licensing/server/types.ts index 59bb2dd5b1045..83b39cb663715 100644 --- a/x-pack/plugins/licensing/server/types.ts +++ b/x-pack/plugins/licensing/server/types.ts @@ -6,7 +6,7 @@ */ import { Observable } from 'rxjs'; -import type { IClusterClient, IRouter, RequestHandlerContext } from '@kbn/core/server'; +import type { IClusterClient, IRouter, CustomRequestHandlerContext } from '@kbn/core/server'; import { ILicense } from '../common/types'; import { FeatureUsageServiceSetup, FeatureUsageServiceStart } from './services'; @@ -35,9 +35,9 @@ export interface LicensingApiRequestHandlerContext { /** * @internal */ -export interface LicensingRequestHandlerContext extends RequestHandlerContext { +export type LicensingRequestHandlerContext = CustomRequestHandlerContext<{ licensing: LicensingApiRequestHandlerContext; -} +}>; /** * @internal diff --git a/x-pack/plugins/licensing/server/wrap_route_with_license_check.ts b/x-pack/plugins/licensing/server/wrap_route_with_license_check.ts index 2358e24b6793a..0adcf3f3b6120 100644 --- a/x-pack/plugins/licensing/server/wrap_route_with_license_check.ts +++ b/x-pack/plugins/licensing/server/wrap_route_with_license_check.ts @@ -28,7 +28,8 @@ export function wrapRouteWithLicenseCheck, response: KibanaResponseFactory ) => { - const licenseCheckResult = checkLicense(context.licensing.license); + const { license } = await context.licensing; + const licenseCheckResult = checkLicense(license); if (licenseCheckResult.valid) { return handler(context, request, response); diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/builder.stories.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/builder.stories.tsx index ff2efccee90a6..bb345f481112a 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/builder.stories.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/builder.stories.tsx @@ -8,7 +8,7 @@ import { Story, addDecorator } from '@storybook/react'; import React from 'react'; import { HttpStart } from '@kbn/core/public'; -import type { AutocompleteStart } from '@kbn/data-plugin/public'; +import type { AutocompleteStart } from '@kbn/unified-search-plugin/public'; import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; import { fields, getField } from '@kbn/data-plugin/common/mocks'; diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.stories.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.stories.tsx index 6388a9e5b7053..2fbc89e719eb1 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.stories.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.stories.tsx @@ -13,7 +13,7 @@ import { ListOperatorEnum as OperatorEnum, ListOperatorTypeEnum as OperatorTypeEnum, } from '@kbn/securitysolution-io-ts-list-types'; -import type { AutocompleteStart } from '@kbn/data-plugin/public'; +import type { AutocompleteStart } from '@kbn/unified-search-plugin/public'; import { fields } from '@kbn/data-plugin/common/mocks'; import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.test.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.test.tsx index 4409bd0448ec8..d0d931387f0e4 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.test.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.test.tsx @@ -5,10 +5,9 @@ * 2.0. */ -import { ReactWrapper, mount } from 'enzyme'; import React from 'react'; import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; -import { waitFor } from '@testing-library/dom'; +import { coreMock } from '@kbn/core/public/mocks'; import { doesNotExistOperator, existsOperator, @@ -24,8 +23,9 @@ import { validateFilePathInput } from '@kbn/securitysolution-utils'; import { useFindLists } from '@kbn/securitysolution-list-hooks'; import type { FieldSpec } from '@kbn/data-plugin/common'; import { fields, getField } from '@kbn/data-plugin/common/mocks'; -import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; -import { coreMock } from '@kbn/core/public/mocks'; +import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; +import { waitFor } from '@testing-library/dom'; +import { ReactWrapper, mount } from 'enzyme'; import { getFoundListSchemaMock } from '../../../../common/schemas/response/found_list_schema.mock'; @@ -35,7 +35,7 @@ jest.mock('@kbn/securitysolution-list-hooks'); jest.mock('@kbn/securitysolution-utils'); const mockKibanaHttpService = coreMock.createStart().http; -const { autocomplete: autocompleteStartMock } = dataPluginMock.createStartContract(); +const { autocomplete: autocompleteStartMock } = unifiedSearchPluginMock.createStartContract(); describe('BuilderEntryItem', () => { let wrapper: ReactWrapper; diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx index 3b65042866c55..a28686595053b 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx @@ -44,7 +44,7 @@ import { validateFilePathInput, } from '@kbn/securitysolution-utils'; import { DataViewBase, DataViewFieldBase } from '@kbn/es-query'; -import type { AutocompleteStart } from '@kbn/data-plugin/public'; +import type { AutocompleteStart } from '@kbn/unified-search-plugin/public'; import { HttpStart } from '@kbn/core/public'; import { getEmptyValue } from '../../../common/empty_value'; diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/exception_item_renderer.test.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/exception_item_renderer.test.tsx index 65c1e38215984..4041c8516ee27 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/exception_item_renderer.test.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/exception_item_renderer.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { mount } from 'enzyme'; -import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; +import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; import { fields } from '@kbn/data-plugin/common/mocks'; import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; import { coreMock } from '@kbn/core/public/mocks'; @@ -19,7 +19,7 @@ import { getEntryMatchAnyMock } from '../../../../common/schemas/types/entry_mat import { BuilderExceptionListItemComponent } from './exception_item_renderer'; const mockKibanaHttpService = coreMock.createStart().http; -const { autocomplete: autocompleteStartMock } = dataPluginMock.createStartContract(); +const { autocomplete: autocompleteStartMock } = unifiedSearchPluginMock.createStartContract(); describe('BuilderExceptionListItemComponent', () => { const getValueSuggestionsMock = jest.fn().mockResolvedValue(['value 1', 'value 2']); diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/exception_item_renderer.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/exception_item_renderer.tsx index a8b6850239757..d55289d016883 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/exception_item_renderer.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/exception_item_renderer.tsx @@ -8,8 +8,8 @@ import React, { useCallback, useMemo } from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import styled from 'styled-components'; +import type { AutocompleteStart } from '@kbn/unified-search-plugin/public'; import { HttpStart } from '@kbn/core/public'; -import type { AutocompleteStart } from '@kbn/data-plugin/public'; import { ExceptionListType, OsTypeArray } from '@kbn/securitysolution-io-ts-list-types'; import { BuilderEntry, diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.test.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.test.tsx index 5e86979432f60..e30c5e5cd5519 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.test.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.test.tsx @@ -8,8 +8,8 @@ import React from 'react'; import { ReactWrapper, mount } from 'enzyme'; import { waitFor } from '@testing-library/react'; +import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; import { coreMock } from '@kbn/core/public/mocks'; -import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; import { fields, getField } from '@kbn/data-plugin/common/mocks'; @@ -20,7 +20,7 @@ import { getEmptyValue } from '../../../common/empty_value'; import { ExceptionBuilderComponent } from './exception_items_renderer'; const mockKibanaHttpService = coreMock.createStart().http; -const { autocomplete: autocompleteStartMock } = dataPluginMock.createStartContract(); +const { autocomplete: autocompleteStartMock } = unifiedSearchPluginMock.createStartContract(); describe('ExceptionBuilderComponent', () => { let wrapper: ReactWrapper; diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.tsx index 8a04ebed888dd..69467d7ecea8b 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.tsx @@ -32,7 +32,7 @@ import { getNewExceptionItem, } from '@kbn/securitysolution-list-utils'; import { DataViewBase } from '@kbn/es-query'; -import type { AutocompleteStart } from '@kbn/data-plugin/public'; +import type { AutocompleteStart } from '@kbn/unified-search-plugin/public'; import { AndOrBadge } from '../and_or_badge'; diff --git a/x-pack/plugins/lists/server/plugin.ts b/x-pack/plugins/lists/server/plugin.ts index c5cef49e48735..688469ea063bd 100644 --- a/x-pack/plugins/lists/server/plugin.ts +++ b/x-pack/plugins/lists/server/plugin.ts @@ -103,13 +103,11 @@ export class ListPlugin implements Plugin { const { spaces, config, security, extensionPoints } = this; const { - core: { - savedObjects: { client: savedObjectsClient }, - elasticsearch: { - client: { asCurrentUser: esClient }, - }, + savedObjects: { client: savedObjectsClient }, + elasticsearch: { + client: { asCurrentUser: esClient }, }, - } = context; + } = await context.core; if (config == null) { throw new TypeError('Configuration is required for this plugin to operate'); } else { diff --git a/x-pack/plugins/lists/server/routes/create_endpoint_list_item_route.ts b/x-pack/plugins/lists/server/routes/create_endpoint_list_item_route.ts index 46c139d1f3732..d6272626618ec 100644 --- a/x-pack/plugins/lists/server/routes/create_endpoint_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/create_endpoint_list_item_route.ts @@ -47,7 +47,7 @@ export const createEndpointListItemRoute = (router: ListsPluginRouter): void => os_types: osTypes, type, } = request.body; - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const exceptionListItem = await exceptionLists.getEndpointListItem({ id: undefined, itemId, diff --git a/x-pack/plugins/lists/server/routes/create_endpoint_list_route.ts b/x-pack/plugins/lists/server/routes/create_endpoint_list_route.ts index 134682d3a4283..1868a47952a6d 100644 --- a/x-pack/plugins/lists/server/routes/create_endpoint_list_route.ts +++ b/x-pack/plugins/lists/server/routes/create_endpoint_list_route.ts @@ -36,7 +36,7 @@ export const createEndpointListRoute = (router: ListsPluginRouter): void => { async (context, _, response) => { const siemResponse = buildSiemResponse(response); try { - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const createdList = await exceptionLists.createEndpointList(); // We always return ok on a create endpoint list route but with an empty body as // an additional fetch of the full list would be slower and the UI has everything hard coded diff --git a/x-pack/plugins/lists/server/routes/create_exception_list_item_route.ts b/x-pack/plugins/lists/server/routes/create_exception_list_item_route.ts index 968f341b9decf..1659fc2645f16 100644 --- a/x-pack/plugins/lists/server/routes/create_exception_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/create_exception_list_item_route.ts @@ -51,7 +51,7 @@ export const createExceptionListItemRoute = (router: ListsPluginRouter): void => os_types: osTypes, type, } = request.body; - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const exceptionList = await exceptionLists.getExceptionList({ id: undefined, listId, diff --git a/x-pack/plugins/lists/server/routes/create_exception_list_route.ts b/x-pack/plugins/lists/server/routes/create_exception_list_route.ts index 22be6432a70c1..8d59d8492c822 100644 --- a/x-pack/plugins/lists/server/routes/create_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/create_exception_list_route.ts @@ -46,7 +46,7 @@ export const createExceptionListRoute = (router: ListsPluginRouter): void => { type, version, } = request.body; - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const exceptionList = await exceptionLists.getExceptionList({ id: undefined, listId, diff --git a/x-pack/plugins/lists/server/routes/create_list_index_route.ts b/x-pack/plugins/lists/server/routes/create_list_index_route.ts index cebd6140c36aa..ee6a3003a0f0f 100644 --- a/x-pack/plugins/lists/server/routes/create_list_index_route.ts +++ b/x-pack/plugins/lists/server/routes/create_list_index_route.ts @@ -29,7 +29,7 @@ export const createListIndexRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { - const lists = getListClient(context); + const lists = await getListClient(context); const listIndexExists = await lists.getListIndexExists(); const listItemIndexExists = await lists.getListItemIndexExists(); diff --git a/x-pack/plugins/lists/server/routes/create_list_item_route.ts b/x-pack/plugins/lists/server/routes/create_list_item_route.ts index bbdc507ebdb69..de798aea97fd6 100644 --- a/x-pack/plugins/lists/server/routes/create_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/create_list_item_route.ts @@ -31,7 +31,7 @@ export const createListItemRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { id, list_id: listId, value, meta } = request.body; - const lists = getListClient(context); + const lists = await getListClient(context); const list = await lists.getList({ id: listId }); if (list == null) { return siemResponse.error({ diff --git a/x-pack/plugins/lists/server/routes/create_list_route.ts b/x-pack/plugins/lists/server/routes/create_list_route.ts index b259fe31b931d..5e2ddea4aa4b2 100644 --- a/x-pack/plugins/lists/server/routes/create_list_route.ts +++ b/x-pack/plugins/lists/server/routes/create_list_route.ts @@ -38,7 +38,7 @@ export const createListRoute = (router: ListsPluginRouter): void => { try { const { name, description, deserializer, id, serializer, type, meta, version } = request.body; - const lists = getListClient(context); + const lists = await getListClient(context); const listExists = await lists.getListIndexExists(); if (!listExists) { return siemResponse.error({ diff --git a/x-pack/plugins/lists/server/routes/delete_endpoint_list_item_route.ts b/x-pack/plugins/lists/server/routes/delete_endpoint_list_item_route.ts index 650d2d11b0d1f..94456cea0c328 100644 --- a/x-pack/plugins/lists/server/routes/delete_endpoint_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/delete_endpoint_list_item_route.ts @@ -40,7 +40,7 @@ export const deleteEndpointListItemRoute = (router: ListsPluginRouter): void => async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const { item_id: itemId, id } = request.query; if (itemId == null && id == null) { return siemResponse.error({ diff --git a/x-pack/plugins/lists/server/routes/delete_exception_list_item_route.ts b/x-pack/plugins/lists/server/routes/delete_exception_list_item_route.ts index 7ec220bfb3a60..5aea87e5e9efb 100644 --- a/x-pack/plugins/lists/server/routes/delete_exception_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/delete_exception_list_item_route.ts @@ -40,7 +40,7 @@ export const deleteExceptionListItemRoute = (router: ListsPluginRouter): void => async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const { item_id: itemId, id, namespace_type: namespaceType } = request.query; if (itemId == null && id == null) { return siemResponse.error({ diff --git a/x-pack/plugins/lists/server/routes/delete_exception_list_route.ts b/x-pack/plugins/lists/server/routes/delete_exception_list_route.ts index b4928d0262528..26c45c8055a96 100644 --- a/x-pack/plugins/lists/server/routes/delete_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/delete_exception_list_route.ts @@ -40,7 +40,7 @@ export const deleteExceptionListRoute = (router: ListsPluginRouter): void => { async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const { list_id: listId, id, namespace_type: namespaceType } = request.query; if (listId == null && id == null) { return siemResponse.error({ diff --git a/x-pack/plugins/lists/server/routes/delete_list_index_route.ts b/x-pack/plugins/lists/server/routes/delete_list_index_route.ts index 448c6c7692164..85c6cf96c85ab 100644 --- a/x-pack/plugins/lists/server/routes/delete_list_index_route.ts +++ b/x-pack/plugins/lists/server/routes/delete_list_index_route.ts @@ -45,7 +45,7 @@ export const deleteListIndexRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { - const lists = getListClient(context); + const lists = await getListClient(context); const listIndexExists = await lists.getListIndexExists(); const listItemIndexExists = await lists.getListItemIndexExists(); diff --git a/x-pack/plugins/lists/server/routes/delete_list_item_route.ts b/x-pack/plugins/lists/server/routes/delete_list_item_route.ts index cd6c0ee038b4d..bf03f083bd742 100644 --- a/x-pack/plugins/lists/server/routes/delete_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/delete_list_item_route.ts @@ -35,7 +35,7 @@ export const deleteListItemRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { id, list_id: listId, value } = request.query; - const lists = getListClient(context); + const lists = await getListClient(context); if (id != null) { const deleted = await lists.deleteListItem({ id }); if (deleted == null) { diff --git a/x-pack/plugins/lists/server/routes/delete_list_route.ts b/x-pack/plugins/lists/server/routes/delete_list_route.ts index 6ddcce94d82e8..57923699c25eb 100644 --- a/x-pack/plugins/lists/server/routes/delete_list_route.ts +++ b/x-pack/plugins/lists/server/routes/delete_list_route.ts @@ -42,8 +42,8 @@ export const deleteListRoute = (router: ListsPluginRouter): void => { async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const lists = getListClient(context); - const exceptionLists = getExceptionListClient(context); + const lists = await getListClient(context); + const exceptionLists = await getExceptionListClient(context); const { id, deleteReferences, ignoreReferences } = request.query; let deleteExceptionItemResponses; diff --git a/x-pack/plugins/lists/server/routes/export_exception_list_route.ts b/x-pack/plugins/lists/server/routes/export_exception_list_route.ts index f13e84c6e58dd..03c7b416ab54f 100644 --- a/x-pack/plugins/lists/server/routes/export_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/export_exception_list_route.ts @@ -29,7 +29,7 @@ export const exportExceptionsRoute = (router: ListsPluginRouter): void => { try { const { id, list_id: listId, namespace_type: namespaceType } = request.query; - const exceptionListsClient = getExceptionListClient(context); + const exceptionListsClient = await getExceptionListClient(context); const exportContent = await exceptionListsClient.exportExceptionListAndItems({ id, diff --git a/x-pack/plugins/lists/server/routes/export_list_item_route.ts b/x-pack/plugins/lists/server/routes/export_list_item_route.ts index 413c911560e10..f542909327f1c 100644 --- a/x-pack/plugins/lists/server/routes/export_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/export_list_item_route.ts @@ -32,7 +32,7 @@ export const exportListItemRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { list_id: listId } = request.query; - const lists = getListClient(context); + const lists = await getListClient(context); const list = await lists.getList({ id: listId }); if (list == null) { return siemResponse.error({ diff --git a/x-pack/plugins/lists/server/routes/find_endpoint_list_item_route.ts b/x-pack/plugins/lists/server/routes/find_endpoint_list_item_route.ts index 6516e88877384..c91a7d882355b 100644 --- a/x-pack/plugins/lists/server/routes/find_endpoint_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/find_endpoint_list_item_route.ts @@ -35,7 +35,7 @@ export const findEndpointListItemRoute = (router: ListsPluginRouter): void => { async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const { filter, page, diff --git a/x-pack/plugins/lists/server/routes/find_exception_list_item_route.ts b/x-pack/plugins/lists/server/routes/find_exception_list_item_route.ts index 67450ca02bb20..b28ebf26b012c 100644 --- a/x-pack/plugins/lists/server/routes/find_exception_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/find_exception_list_item_route.ts @@ -35,7 +35,7 @@ export const findExceptionListItemRoute = (router: ListsPluginRouter): void => { async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const { filter, list_id: listId, diff --git a/x-pack/plugins/lists/server/routes/find_exception_list_route.ts b/x-pack/plugins/lists/server/routes/find_exception_list_route.ts index e49b9c39d2f04..9365c07e876a2 100644 --- a/x-pack/plugins/lists/server/routes/find_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/find_exception_list_route.ts @@ -34,7 +34,7 @@ export const findExceptionListRoute = (router: ListsPluginRouter): void => { async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const { filter, page, diff --git a/x-pack/plugins/lists/server/routes/find_list_item_route.ts b/x-pack/plugins/lists/server/routes/find_list_item_route.ts index b0a4a386e21e8..37e3ede6582be 100644 --- a/x-pack/plugins/lists/server/routes/find_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/find_list_item_route.ts @@ -35,7 +35,7 @@ export const findListItemRoute = (router: ListsPluginRouter): void => { async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const lists = getListClient(context); + const lists = await getListClient(context); const { cursor, filter: filterOrUndefined, diff --git a/x-pack/plugins/lists/server/routes/find_list_route.ts b/x-pack/plugins/lists/server/routes/find_list_route.ts index 98697cc79030c..89ed27941d8ad 100644 --- a/x-pack/plugins/lists/server/routes/find_list_route.ts +++ b/x-pack/plugins/lists/server/routes/find_list_route.ts @@ -29,7 +29,7 @@ export const findListRoute = (router: ListsPluginRouter): void => { async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const lists = getListClient(context); + const lists = await getListClient(context); const { cursor, filter: filterOrUndefined, diff --git a/x-pack/plugins/lists/server/routes/import_exceptions_route.ts b/x-pack/plugins/lists/server/routes/import_exceptions_route.ts index 9db8c27c5397d..78e0d571b2dc2 100644 --- a/x-pack/plugins/lists/server/routes/import_exceptions_route.ts +++ b/x-pack/plugins/lists/server/routes/import_exceptions_route.ts @@ -43,7 +43,7 @@ export const importExceptionsRoute = (router: ListsPluginRouter, config: ConfigT }, }, async (context, request, response) => { - const exceptionListsClient = getExceptionListClient(context); + const exceptionListsClient = await getExceptionListClient(context); const siemResponse = buildSiemResponse(response); try { diff --git a/x-pack/plugins/lists/server/routes/import_list_item_route.ts b/x-pack/plugins/lists/server/routes/import_list_item_route.ts index a911a6bc26eb0..0af6035e40b5d 100644 --- a/x-pack/plugins/lists/server/routes/import_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/import_list_item_route.ts @@ -44,7 +44,7 @@ export const importListItemRoute = (router: ListsPluginRouter, config: ConfigTyp try { const stream = createStreamFromBuffer(request.body); const { deserializer, list_id: listId, serializer, type } = request.query; - const lists = getListClient(context); + const lists = await getListClient(context); const listExists = await lists.getListIndexExists(); if (!listExists) { return siemResponse.error({ diff --git a/x-pack/plugins/lists/server/routes/patch_list_item_route.ts b/x-pack/plugins/lists/server/routes/patch_list_item_route.ts index 7bbcab1b1dd62..45d02f5c9d3ac 100644 --- a/x-pack/plugins/lists/server/routes/patch_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/patch_list_item_route.ts @@ -31,7 +31,7 @@ export const patchListItemRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { value, id, meta, _version } = request.body; - const lists = getListClient(context); + const lists = await getListClient(context); const listItem = await lists.updateListItem({ _version, id, diff --git a/x-pack/plugins/lists/server/routes/patch_list_route.ts b/x-pack/plugins/lists/server/routes/patch_list_route.ts index da2ea0b65e413..6b23fb1da8978 100644 --- a/x-pack/plugins/lists/server/routes/patch_list_route.ts +++ b/x-pack/plugins/lists/server/routes/patch_list_route.ts @@ -31,7 +31,7 @@ export const patchListRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { name, description, id, meta, _version, version } = request.body; - const lists = getListClient(context); + const lists = await getListClient(context); const list = await lists.updateList({ _version, description, id, meta, name, version }); if (list == null) { return siemResponse.error({ diff --git a/x-pack/plugins/lists/server/routes/read_endpoint_list_item_route.ts b/x-pack/plugins/lists/server/routes/read_endpoint_list_item_route.ts index aed51fbb4a5d0..053e74dee48c8 100644 --- a/x-pack/plugins/lists/server/routes/read_endpoint_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/read_endpoint_list_item_route.ts @@ -41,7 +41,7 @@ export const readEndpointListItemRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { id, item_id: itemId } = request.query; - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); if (id != null || itemId != null) { const exceptionListItem = await exceptionLists.getEndpointListItem({ id, diff --git a/x-pack/plugins/lists/server/routes/read_exception_list_item_route.ts b/x-pack/plugins/lists/server/routes/read_exception_list_item_route.ts index d1afb35d41a30..7ea8c02be96db 100644 --- a/x-pack/plugins/lists/server/routes/read_exception_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/read_exception_list_item_route.ts @@ -41,7 +41,7 @@ export const readExceptionListItemRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { id, item_id: itemId, namespace_type: namespaceType } = request.query; - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); if (id != null || itemId != null) { const exceptionListItem = await exceptionLists.getExceptionListItem({ id, diff --git a/x-pack/plugins/lists/server/routes/read_exception_list_route.ts b/x-pack/plugins/lists/server/routes/read_exception_list_route.ts index 3b652db6fab63..22ef6e636720f 100644 --- a/x-pack/plugins/lists/server/routes/read_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/read_exception_list_route.ts @@ -40,7 +40,7 @@ export const readExceptionListRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { id, list_id: listId, namespace_type: namespaceType } = request.query; - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); if (id != null || listId != null) { const exceptionList = await exceptionLists.getExceptionList({ id, diff --git a/x-pack/plugins/lists/server/routes/read_list_index_route.ts b/x-pack/plugins/lists/server/routes/read_list_index_route.ts index 6fd15e628edb0..061c8486db358 100644 --- a/x-pack/plugins/lists/server/routes/read_list_index_route.ts +++ b/x-pack/plugins/lists/server/routes/read_list_index_route.ts @@ -29,7 +29,7 @@ export const readListIndexRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { - const lists = getListClient(context); + const lists = await getListClient(context); const listIndexExists = await lists.getListIndexExists(); const listItemIndexExists = await lists.getListItemIndexExists(); diff --git a/x-pack/plugins/lists/server/routes/read_list_item_route.ts b/x-pack/plugins/lists/server/routes/read_list_item_route.ts index 2cb2c4e042884..a663cfe9b8d08 100644 --- a/x-pack/plugins/lists/server/routes/read_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/read_list_item_route.ts @@ -35,7 +35,7 @@ export const readListItemRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { id, list_id: listId, value } = request.query; - const lists = getListClient(context); + const lists = await getListClient(context); if (id != null) { const listItem = await lists.getListItem({ id }); if (listItem == null) { diff --git a/x-pack/plugins/lists/server/routes/read_list_route.ts b/x-pack/plugins/lists/server/routes/read_list_route.ts index e4806f274d511..86761b5c98835 100644 --- a/x-pack/plugins/lists/server/routes/read_list_route.ts +++ b/x-pack/plugins/lists/server/routes/read_list_route.ts @@ -31,7 +31,7 @@ export const readListRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { id } = request.query; - const lists = getListClient(context); + const lists = await getListClient(context); const list = await lists.getList({ id }); if (list == null) { return siemResponse.error({ diff --git a/x-pack/plugins/lists/server/routes/read_privileges_route.ts b/x-pack/plugins/lists/server/routes/read_privileges_route.ts index 0fc72e6cc4341..51ffaa9713b62 100644 --- a/x-pack/plugins/lists/server/routes/read_privileges_route.ts +++ b/x-pack/plugins/lists/server/routes/read_privileges_route.ts @@ -25,8 +25,8 @@ export const readPrivilegesRoute = (router: ListsPluginRouter): void => { async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const esClient = context.core.elasticsearch.client.asCurrentUser; - const lists = getListClient(context); + const esClient = (await context.core).elasticsearch.client.asCurrentUser; + const lists = await getListClient(context); const clusterPrivilegesLists = await readPrivileges(esClient, lists.getListIndex()); const clusterPrivilegesListItems = await readPrivileges(esClient, lists.getListItemIndex()); const privileges = merge( diff --git a/x-pack/plugins/lists/server/routes/summary_exception_list_route.ts b/x-pack/plugins/lists/server/routes/summary_exception_list_route.ts index 932681eb30d2f..f44161a25d372 100644 --- a/x-pack/plugins/lists/server/routes/summary_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/summary_exception_list_route.ts @@ -41,7 +41,7 @@ export const summaryExceptionListRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { id, list_id: listId, namespace_type: namespaceType, filter } = request.query; - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); if (id != null || listId != null) { const exceptionListSummary = await exceptionLists.getExceptionListSummary({ filter, diff --git a/x-pack/plugins/lists/server/routes/update_endpoint_list_item_route.ts b/x-pack/plugins/lists/server/routes/update_endpoint_list_item_route.ts index 2c960736460dd..e1e117f6c5604 100644 --- a/x-pack/plugins/lists/server/routes/update_endpoint_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/update_endpoint_list_item_route.ts @@ -50,7 +50,7 @@ export const updateEndpointListItemRoute = (router: ListsPluginRouter): void => item_id: itemId, tags, } = request.body; - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const exceptionListItem = await exceptionLists.updateEndpointListItem({ _version, comments, diff --git a/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts b/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts index 910d78e68061e..a997ac132e7cf 100644 --- a/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts @@ -63,7 +63,7 @@ export const updateExceptionListItemRoute = (router: ListsPluginRouter): void => statusCode: 404, }); } else { - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const exceptionListItem = await exceptionLists.updateExceptionListItem({ _version, comments, diff --git a/x-pack/plugins/lists/server/routes/update_exception_list_route.ts b/x-pack/plugins/lists/server/routes/update_exception_list_route.ts index 43279e1f1045d..b41a43a0f7c6d 100644 --- a/x-pack/plugins/lists/server/routes/update_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/update_exception_list_route.ts @@ -53,7 +53,7 @@ export const updateExceptionListRoute = (router: ListsPluginRouter): void => { type, version, } = request.body; - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); if (id == null && listId == null) { return siemResponse.error({ body: 'either id or list_id need to be defined', diff --git a/x-pack/plugins/lists/server/routes/update_list_item_route.ts b/x-pack/plugins/lists/server/routes/update_list_item_route.ts index 07ba8539ae624..37c9848f9ddcd 100644 --- a/x-pack/plugins/lists/server/routes/update_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/update_list_item_route.ts @@ -31,7 +31,7 @@ export const updateListItemRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { value, id, meta, _version } = request.body; - const lists = getListClient(context); + const lists = await getListClient(context); const listItem = await lists.updateListItem({ _version, id, diff --git a/x-pack/plugins/lists/server/routes/update_list_route.ts b/x-pack/plugins/lists/server/routes/update_list_route.ts index 47ab77b444196..bbf49df7e689a 100644 --- a/x-pack/plugins/lists/server/routes/update_list_route.ts +++ b/x-pack/plugins/lists/server/routes/update_list_route.ts @@ -31,7 +31,7 @@ export const updateListRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { name, description, id, meta, _version, version } = request.body; - const lists = getListClient(context); + const lists = await getListClient(context); const list = await lists.updateList({ _version, description, id, meta, name, version }); if (list == null) { return siemResponse.error({ diff --git a/x-pack/plugins/lists/server/routes/utils/get_exception_list_client.ts b/x-pack/plugins/lists/server/routes/utils/get_exception_list_client.ts index 46a02180d7319..e4c948a11ddae 100644 --- a/x-pack/plugins/lists/server/routes/utils/get_exception_list_client.ts +++ b/x-pack/plugins/lists/server/routes/utils/get_exception_list_client.ts @@ -9,10 +9,10 @@ import type { ListsRequestHandlerContext } from '../../types'; import { ErrorWithStatusCode } from '../../error_with_status_code'; import { ExceptionListClient } from '../../services/exception_lists/exception_list_client'; -export const getExceptionListClient = ( +export const getExceptionListClient = async ( context: ListsRequestHandlerContext -): ExceptionListClient => { - const exceptionLists = context.lists?.getExceptionListClient(); +): Promise => { + const exceptionLists = (await context.lists)?.getExceptionListClient(); if (exceptionLists == null) { throw new ErrorWithStatusCode('Exception lists is not found as a plugin', 404); } else { diff --git a/x-pack/plugins/lists/server/routes/utils/get_list_client.ts b/x-pack/plugins/lists/server/routes/utils/get_list_client.ts index 1c6e995f3fac6..9880148681809 100644 --- a/x-pack/plugins/lists/server/routes/utils/get_list_client.ts +++ b/x-pack/plugins/lists/server/routes/utils/get_list_client.ts @@ -9,8 +9,8 @@ import { ListClient } from '../../services/lists/list_client'; import { ErrorWithStatusCode } from '../../error_with_status_code'; import type { ListsRequestHandlerContext } from '../../types'; -export const getListClient = (context: ListsRequestHandlerContext): ListClient => { - const lists = context.lists?.getListClient(); +export const getListClient = async (context: ListsRequestHandlerContext): Promise => { + const lists = (await context.lists)?.getListClient(); if (lists == null) { throw new ErrorWithStatusCode('Lists is not found as a plugin', 404); } else { diff --git a/x-pack/plugins/lists/server/types.ts b/x-pack/plugins/lists/server/types.ts index 15bbe0d47b6c0..78fdd0e8534a6 100644 --- a/x-pack/plugins/lists/server/types.ts +++ b/x-pack/plugins/lists/server/types.ts @@ -6,10 +6,10 @@ */ import { + CustomRequestHandlerContext, ElasticsearchClient, IContextProvider, IRouter, - RequestHandlerContext, SavedObjectsClientContract, } from '@kbn/core/server'; import type { SecurityPluginStart } from '@kbn/security-plugin/server'; @@ -24,6 +24,7 @@ import type { export type ContextProvider = IContextProvider; export type ListsPluginStart = void; + export interface PluginsStart { security: SecurityPluginStart | undefined | null; spaces: SpacesPluginStart | undefined | null; @@ -60,9 +61,9 @@ export interface ListsApiRequestHandlerContext { /** * @internal */ -export interface ListsRequestHandlerContext extends RequestHandlerContext { +export type ListsRequestHandlerContext = CustomRequestHandlerContext<{ lists?: ListsApiRequestHandlerContext; -} +}>; /** * @internal diff --git a/x-pack/plugins/lists/tsconfig.json b/x-pack/plugins/lists/tsconfig.json index 691c5243d9db8..6cfffbbaa7421 100644 --- a/x-pack/plugins/lists/tsconfig.json +++ b/x-pack/plugins/lists/tsconfig.json @@ -18,5 +18,6 @@ { "path": "../../../src/core/tsconfig.json" }, { "path": "../spaces/tsconfig.json" }, { "path": "../security/tsconfig.json"}, + { "path": "../../../src/plugins/unified_search/tsconfig.json" } ] } diff --git a/x-pack/plugins/logstash/server/routes/cluster/load.ts b/x-pack/plugins/logstash/server/routes/cluster/load.ts index e3937071cb98c..d0967ee123763 100644 --- a/x-pack/plugins/logstash/server/routes/cluster/load.ts +++ b/x-pack/plugins/logstash/server/routes/cluster/load.ts @@ -18,7 +18,7 @@ export function registerClusterLoadRoute(router: LogstashPluginRouter) { }, wrapRouteWithLicenseCheck(checkLicense, async (context, request, response) => { try { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const info = await client.asCurrentUser.info(); return response.ok({ body: { diff --git a/x-pack/plugins/logstash/server/routes/pipeline/delete.ts b/x-pack/plugins/logstash/server/routes/pipeline/delete.ts index 1fb21c0e87013..ba9ea73850cc4 100644 --- a/x-pack/plugins/logstash/server/routes/pipeline/delete.ts +++ b/x-pack/plugins/logstash/server/routes/pipeline/delete.ts @@ -24,7 +24,7 @@ export function registerPipelineDeleteRoute(router: LogstashPluginRouter) { checkLicense, router.handleLegacyErrors(async (context, request, response) => { const { id } = request.params; - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; try { await client.asCurrentUser.logstash.deletePipeline({ id }); diff --git a/x-pack/plugins/logstash/server/routes/pipeline/load.ts b/x-pack/plugins/logstash/server/routes/pipeline/load.ts index 44811aba0b208..8a657207414d9 100644 --- a/x-pack/plugins/logstash/server/routes/pipeline/load.ts +++ b/x-pack/plugins/logstash/server/routes/pipeline/load.ts @@ -26,7 +26,7 @@ export function registerPipelineLoadRoute(router: LogstashPluginRouter) { checkLicense, router.handleLegacyErrors(async (context, request, response) => { const { id } = request.params; - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const result = await client.asCurrentUser.logstash.getPipeline({ id }, { ignore: [404] }); diff --git a/x-pack/plugins/logstash/server/routes/pipeline/save.ts b/x-pack/plugins/logstash/server/routes/pipeline/save.ts index 703edb95a43ff..5c50dac7e050c 100644 --- a/x-pack/plugins/logstash/server/routes/pipeline/save.ts +++ b/x-pack/plugins/logstash/server/routes/pipeline/save.ts @@ -42,7 +42,7 @@ export function registerPipelineSaveRoute( username = user?.username; } - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const pipeline = Pipeline.fromDownstreamJSON(request.body, request.params.id, username); await client.asCurrentUser.logstash.putPipeline({ diff --git a/x-pack/plugins/logstash/server/routes/pipelines/delete.ts b/x-pack/plugins/logstash/server/routes/pipelines/delete.ts index 4aac23a2921fd..777b86ea65284 100644 --- a/x-pack/plugins/logstash/server/routes/pipelines/delete.ts +++ b/x-pack/plugins/logstash/server/routes/pipelines/delete.ts @@ -45,7 +45,7 @@ export function registerPipelinesDeleteRoute(router: LogstashPluginRouter) { wrapRouteWithLicenseCheck( checkLicense, router.handleLegacyErrors(async (context, request, response) => { - const client = context.core.elasticsearch.client.asCurrentUser; + const client = (await context.core).elasticsearch.client.asCurrentUser; const results = await deletePipelines(client, request.body.pipelineIds); return response.ok({ body: { results } }); diff --git a/x-pack/plugins/logstash/server/routes/pipelines/list.ts b/x-pack/plugins/logstash/server/routes/pipelines/list.ts index 884b923eaf87e..cb1a14cbbd423 100644 --- a/x-pack/plugins/logstash/server/routes/pipelines/list.ts +++ b/x-pack/plugins/logstash/server/routes/pipelines/list.ts @@ -33,7 +33,7 @@ export function registerPipelinesListRoute(router: LogstashPluginRouter) { checkLicense, router.handleLegacyErrors(async (context, request, response) => { try { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const pipelinesRecord = (await fetchPipelines(client.asCurrentUser)) as Record< string, any diff --git a/x-pack/plugins/logstash/server/types.ts b/x-pack/plugins/logstash/server/types.ts index 69db9753f1e38..d9a9f90101f40 100644 --- a/x-pack/plugins/logstash/server/types.ts +++ b/x-pack/plugins/logstash/server/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { IRouter, RequestHandlerContext } from '@kbn/core/server'; +import type { IRouter, CustomRequestHandlerContext } from '@kbn/core/server'; import type { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server'; export interface PipelineListItemOptions { @@ -18,9 +18,9 @@ export interface PipelineListItemOptions { /** * @internal */ -export interface LogstashRequestHandlerContext extends RequestHandlerContext { +export type LogstashRequestHandlerContext = CustomRequestHandlerContext<{ licensing: LicensingApiRequestHandlerContext; -} +}>; /** * @internal diff --git a/x-pack/plugins/maps/common/descriptor_types/data_request_descriptor_types.ts b/x-pack/plugins/maps/common/descriptor_types/data_request_descriptor_types.ts index f3132d145c7a2..a560114d71b4f 100644 --- a/x-pack/plugins/maps/common/descriptor_types/data_request_descriptor_types.ts +++ b/x-pack/plugins/maps/common/descriptor_types/data_request_descriptor_types.ts @@ -41,6 +41,7 @@ export type VectorSourceRequestMeta = DataFilters & { sourceQuery?: Query; sourceMeta: object | null; isForceRefresh: boolean; + isFeatureEditorOpenForLayer: boolean; }; export type VectorJoinSourceRequestMeta = Omit; diff --git a/x-pack/plugins/maps/common/descriptor_types/layer_descriptor_types.ts b/x-pack/plugins/maps/common/descriptor_types/layer_descriptor_types.ts index 1cd8b254f9e14..996e3d7303b82 100644 --- a/x-pack/plugins/maps/common/descriptor_types/layer_descriptor_types.ts +++ b/x-pack/plugins/maps/common/descriptor_types/layer_descriptor_types.ts @@ -35,11 +35,17 @@ export type TileMetaFeature = Feature & { 'hits.total.value': number; // For _mvt requests with "aggs" property in request: aggregation statistics returned in the pattern outined below + // aggregations._count.avg + // aggregations._count.count // aggregations._count.min // aggregations._count.max + // aggregations._count.sum + // aggregations..avg + // aggregations..count // aggregations..min // aggregations..max - [key: string]: number | string; + // aggregations..sum + [key: string]: number | string | boolean; }; }; diff --git a/x-pack/plugins/maps/common/embeddable/extract.ts b/x-pack/plugins/maps/common/embeddable/extract.ts index e73b1566c0289..d329aefe7cff6 100644 --- a/x-pack/plugins/maps/common/embeddable/extract.ts +++ b/x-pack/plugins/maps/common/embeddable/extract.ts @@ -5,8 +5,7 @@ * 2.0. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { EmbeddableRegistryDefinition } from '@kbn/embeddable-plugin/server'; +import { EmbeddableRegistryDefinition } from '@kbn/embeddable-plugin/common'; import { MapEmbeddablePersistableState } from './types'; import { MapSavedObjectAttributes } from '../map_saved_object_type'; import { extractReferences } from '../migrations/references'; diff --git a/x-pack/plugins/maps/common/embeddable/inject.ts b/x-pack/plugins/maps/common/embeddable/inject.ts index 2e1892b95a0f1..4bb26dd00d28d 100644 --- a/x-pack/plugins/maps/common/embeddable/inject.ts +++ b/x-pack/plugins/maps/common/embeddable/inject.ts @@ -5,10 +5,9 @@ * 2.0. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { EmbeddableRegistryDefinition } from '@kbn/embeddable-plugin/server'; -import { MapEmbeddablePersistableState } from './types'; -import { MapSavedObjectAttributes } from '../map_saved_object_type'; +import type { EmbeddableRegistryDefinition } from '@kbn/embeddable-plugin/common'; +import type { MapEmbeddablePersistableState } from './types'; +import type { MapSavedObjectAttributes } from '../map_saved_object_type'; import { extractReferences, injectReferences } from '../migrations/references'; export const inject: EmbeddableRegistryDefinition['inject'] = (state, references) => { diff --git a/x-pack/plugins/maps/public/_mapbox_hacks.scss b/x-pack/plugins/maps/public/_mapbox_hacks.scss index 480232007995d..118e0b1862066 100644 --- a/x-pack/plugins/maps/public/_mapbox_hacks.scss +++ b/x-pack/plugins/maps/public/_mapbox_hacks.scss @@ -3,12 +3,12 @@ .mapContainer { flex-grow: 1; - .mapboxgl-ctrl-top-left .mapboxgl-ctrl { + .maplibregl-ctrl-top-left .maplibregl-ctrl { margin-left: $euiSizeM; margin-top: $euiSizeM; } - .mapboxgl-ctrl-group:not(:empty) { + .maplibregl-ctrl-group:not(:empty) { @include euiBottomShadowLarge; @include mapToolbarButtonGroupBorderRadius; background-color: $euiColorEmptyShade; @@ -27,7 +27,7 @@ } } - .mapboxgl-ctrl button:not(:disabled) { + .maplibregl-ctrl button:not(:disabled) { transition: background $euiAnimSpeedNormal ease-in-out; &:hover { @@ -35,14 +35,14 @@ } } - .mapboxgl-ctrl-group button:focus:focus-visible { + .maplibregl-ctrl-group button:focus:focus-visible { box-shadow: none; } } // Custom SVG as background for zoom controls based off of EUI glyphs plusInCircleFilled and minusInCircleFilled // Also fixes dark mode -.mapboxgl-ctrl-zoom-in .mapboxgl-ctrl-icon { +.maplibregl-ctrl-zoom-in .maplibregl-ctrl-icon { // sass-lint:disable-block no-important background-repeat: no-repeat !important; // sass-lint:disable-block quotes @@ -50,7 +50,7 @@ background-position: center !important; } -.mapboxgl-ctrl-zoom-out .mapboxgl-ctrl-icon { +.maplibregl-ctrl-zoom-out .maplibregl-ctrl-icon { // sass-lint:disable-block no-important background-repeat: no-repeat !important; // sass-lint:disable-block quotes diff --git a/x-pack/plugins/maps/public/actions/data_request_actions.ts b/x-pack/plugins/maps/public/actions/data_request_actions.ts index 5788c9360fdf2..d2cb416dcbe20 100644 --- a/x-pack/plugins/maps/public/actions/data_request_actions.ts +++ b/x-pack/plugins/maps/public/actions/data_request_actions.ts @@ -24,6 +24,7 @@ import { getDataRequestDescriptor, getLayerById, getLayerList, + getEditState, } from '../selectors/map_selectors'; import { cancelRequest, @@ -67,6 +68,7 @@ export type DataRequestContext = { dataFilters: DataFilters; forceRefreshDueToDrawing: boolean; // Boolean signaling data request triggered by a user updating layer features via drawing tools. When true, layer will re-load regardless of "source.applyForceRefresh" flag. isForceRefresh: boolean; // Boolean signaling data request triggered by auto-refresh timer or user clicking refresh button. When true, layer will re-load only when "source.applyForceRefresh" flag is set to true. + isFeatureEditorOpenForLayer: boolean; // Boolean signaling that feature editor menu is open for a layer. When true, layer will ignore all global and layer filtering so drawn features are displayed and not filtered out. }; export function clearDataRequests(layer: ILayer) { @@ -145,6 +147,7 @@ function getDataRequestContext( dispatch(registerCancelCallback(requestToken, callback)), forceRefreshDueToDrawing, isForceRefresh, + isFeatureEditorOpenForLayer: getEditState(getState())?.layerId === layerId, }; } diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index 8a16d036393ad..e8585560238fd 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -58,6 +58,7 @@ import { autoFitToBounds, syncDataForAllLayers, syncDataForLayerDueToDrawing, + syncDataForLayerId, } from './data_request_actions'; import { addLayer, addLayerWithoutDataSync } from './layer_actions'; import { MapSettings } from '../reducers/map'; @@ -394,7 +395,7 @@ export function setEditLayerToSelectedLayer() { } export function updateEditLayer(layerId: string | null) { - return (dispatch: Dispatch) => { + return (dispatch: ThunkDispatch) => { if (layerId !== null) { dispatch({ type: SET_OPEN_TOOLTIPS, openTooltips: [] }); } @@ -406,6 +407,7 @@ export function updateEditLayer(layerId: string | null) { type: UPDATE_EDIT_STATE, editState: layerId ? { layerId } : undefined, }); + dispatch(syncDataForLayerId(layerId, false)); }; } diff --git a/x-pack/plugins/maps/public/classes/fields/agg/agg_field.ts b/x-pack/plugins/maps/public/classes/fields/agg/agg_field.ts index 13b40962c5461..9202e09bab67d 100644 --- a/x-pack/plugins/maps/public/classes/fields/agg/agg_field.ts +++ b/x-pack/plugins/maps/public/classes/fields/agg/agg_field.ts @@ -13,6 +13,7 @@ import { isMetricCountable } from '../../util/is_metric_countable'; import { CountAggFieldParams } from './agg_field_types'; import { addFieldToDSL, getField } from '../../../../common/elasticsearch_util'; import { IField } from '../field'; +import { getAggRange } from '../../util/tile_meta_feature_utils'; const TERMS_AGG_SHARD_SIZE = 5; @@ -111,15 +112,6 @@ export class AggField extends CountAggField { } pluckRangeFromTileMetaFeature(metaFeature: TileMetaFeature) { - const minField = `aggregations.${this.getName()}.min`; - const maxField = `aggregations.${this.getName()}.max`; - return metaFeature.properties && - typeof metaFeature.properties[minField] === 'number' && - typeof metaFeature.properties[maxField] === 'number' - ? { - min: metaFeature.properties[minField] as number, - max: metaFeature.properties[maxField] as number, - } - : null; + return getAggRange(metaFeature, this.getName()); } } diff --git a/x-pack/plugins/maps/public/classes/fields/agg/count_agg_field.ts b/x-pack/plugins/maps/public/classes/fields/agg/count_agg_field.ts index 03c0d3f0791a5..4b136ab950ffa 100644 --- a/x-pack/plugins/maps/public/classes/fields/agg/count_agg_field.ts +++ b/x-pack/plugins/maps/public/classes/fields/agg/count_agg_field.ts @@ -13,6 +13,7 @@ import { TileMetaFeature } from '../../../../common/descriptor_types'; import { ITooltipProperty, TooltipProperty } from '../../tooltips/tooltip_property'; import { ESAggTooltipProperty } from '../../tooltips/es_agg_tooltip_property'; import { IESAggField, CountAggFieldParams } from './agg_field_types'; +import { getAggRange } from '../../util/tile_meta_feature_utils'; // Agg without field. Essentially a count-aggregation. export class CountAggField implements IESAggField { @@ -116,15 +117,6 @@ export class CountAggField implements IESAggField { } pluckRangeFromTileMetaFeature(metaFeature: TileMetaFeature) { - const minField = `aggregations._count.min`; - const maxField = `aggregations._count.max`; - return metaFeature.properties && - typeof metaFeature.properties[minField] === 'number' && - typeof metaFeature.properties[maxField] === 'number' - ? { - min: metaFeature.properties[minField] as number, - max: metaFeature.properties[maxField] as number, - } - : null; + return getAggRange(metaFeature, '_count'); } } diff --git a/x-pack/plugins/maps/public/classes/layers/__fixtures__/mock_sync_context.ts b/x-pack/plugins/maps/public/classes/layers/__fixtures__/mock_sync_context.ts index b81ba6c854629..4d1f23599f48d 100644 --- a/x-pack/plugins/maps/public/classes/layers/__fixtures__/mock_sync_context.ts +++ b/x-pack/plugins/maps/public/classes/layers/__fixtures__/mock_sync_context.ts @@ -20,6 +20,7 @@ export class MockSyncContext implements DataRequestContext { updateSourceData: (newData: unknown) => void; forceRefreshDueToDrawing: boolean; isForceRefresh: boolean; + isFeatureEditorOpenForLayer: boolean; constructor({ dataFilters }: { dataFilters: Partial }) { const mapFilters: DataFilters = { @@ -44,5 +45,6 @@ export class MockSyncContext implements DataRequestContext { this.updateSourceData = sinon.spy(); this.forceRefreshDueToDrawing = false; this.isForceRefresh = false; + this.isFeatureEditorOpenForLayer = false; } } diff --git a/x-pack/plugins/maps/public/classes/layers/build_vector_request_meta.ts b/x-pack/plugins/maps/public/classes/layers/build_vector_request_meta.ts index 52dd93033020d..e8d74003c6790 100644 --- a/x-pack/plugins/maps/public/classes/layers/build_vector_request_meta.ts +++ b/x-pack/plugins/maps/public/classes/layers/build_vector_request_meta.ts @@ -16,7 +16,8 @@ export function buildVectorRequestMeta( fieldNames: string[], dataFilters: DataFilters, sourceQuery: Query | null | undefined, - isForceRefresh: boolean + isForceRefresh: boolean, + isFeatureEditorOpenForLayer: boolean ): VectorSourceRequestMeta { return { ...dataFilters, @@ -28,5 +29,6 @@ export function buildVectorRequestMeta( sourceMeta: source.getSyncMeta(), applyForceRefresh: source.isESSource() ? source.getApplyForceRefresh() : false, isForceRefresh, + isFeatureEditorOpenForLayer, }; } diff --git a/x-pack/plugins/maps/public/classes/layers/ems_vector_tile_layer/ems_vector_tile_layer.test.ts b/x-pack/plugins/maps/public/classes/layers/ems_vector_tile_layer/ems_vector_tile_layer.test.ts index 8b27bacff8ecb..21c9c1f79d970 100644 --- a/x-pack/plugins/maps/public/classes/layers/ems_vector_tile_layer/ems_vector_tile_layer.test.ts +++ b/x-pack/plugins/maps/public/classes/layers/ems_vector_tile_layer/ems_vector_tile_layer.test.ts @@ -6,14 +6,18 @@ */ import { SOURCE_TYPES } from '../../../../common/constants'; -import { DataFilters, XYZTMSSourceDescriptor } from '../../../../common/descriptor_types'; +import { + DataFilters, + LayerDescriptor, + XYZTMSSourceDescriptor, +} from '../../../../common/descriptor_types'; import { ILayer } from '../layer'; import { EmsVectorTileLayer } from './ems_vector_tile_layer'; import { DataRequestContext } from '../../../actions'; import { EMSTMSSource } from '../../sources/ems_tms_source'; describe('EmsVectorTileLayer', () => { - it('should correctly inject tileLayerId in meta', async () => { + test('should correctly inject tileLayerId in meta', async () => { const layer: ILayer = new EmsVectorTileLayer({ source: { getTileLayerId: () => { @@ -50,4 +54,34 @@ describe('EmsVectorTileLayer', () => { expect(actualMeta).toStrictEqual({ tileLayerId: 'myTileLayerId' }); expect(actualErrorMessage).toStrictEqual('network error'); }); + + describe('isInitialDataLoadComplete', () => { + test('should return false when tile loading has not started', () => { + const layer = new EmsVectorTileLayer({ + source: {} as unknown as EMSTMSSource, + layerDescriptor: {} as unknown as LayerDescriptor, + }); + expect(layer.isInitialDataLoadComplete()).toBe(false); + }); + + test('should return false when tiles are loading', () => { + const layer = new EmsVectorTileLayer({ + source: {} as unknown as EMSTMSSource, + layerDescriptor: { + __areTilesLoaded: false, + } as unknown as LayerDescriptor, + }); + expect(layer.isInitialDataLoadComplete()).toBe(false); + }); + + test('should return true when tiles are loaded', () => { + const layer = new EmsVectorTileLayer({ + source: {} as unknown as EMSTMSSource, + layerDescriptor: { + __areTilesLoaded: true, + } as unknown as LayerDescriptor, + }); + expect(layer.isInitialDataLoadComplete()).toBe(true); + }); + }); }); diff --git a/x-pack/plugins/maps/public/classes/layers/ems_vector_tile_layer/ems_vector_tile_layer.tsx b/x-pack/plugins/maps/public/classes/layers/ems_vector_tile_layer/ems_vector_tile_layer.tsx index c6d594617c448..646ccb3c09acd 100644 --- a/x-pack/plugins/maps/public/classes/layers/ems_vector_tile_layer/ems_vector_tile_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/ems_vector_tile_layer/ems_vector_tile_layer.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { Map as MbMap, Layer as MbLayer, Style as MbStyle } from '@kbn/mapbox-gl'; +import type { Map as MbMap, LayerSpecification, StyleSpecification } from '@kbn/mapbox-gl'; import _ from 'lodash'; // @ts-expect-error import { RGBAImage } from './image_utils'; @@ -38,7 +38,7 @@ export interface EmsSpriteSheet { interface SourceRequestData { spriteSheetImageData?: ImageData; - vectorStyleSheet?: MbStyle; + vectorStyleSheet?: StyleSpecification; spriteMeta?: { png: string; json: EmsSpriteSheet; @@ -67,6 +67,10 @@ export class EmsVectorTileLayer extends AbstractLayer { this._style = new TileStyle(); } + isInitialDataLoadComplete(): boolean { + return !!this._descriptor.__areTilesLoaded; + } + getSource(): EMSTMSSource { return super.getSource() as EMSTMSSource; } @@ -141,7 +145,7 @@ export class EmsVectorTileLayer extends AbstractLayer { return `${this._generateMbSourceIdPrefix()}${name}`; } - _getVectorStyle() { + _getVectorStyle(): StyleSpecification | null | undefined { const sourceDataRequest = this.getSourceDataRequest(); if (!sourceDataRequest) { return null; @@ -317,8 +321,8 @@ export class EmsVectorTileLayer extends AbstractLayer { const newLayerObject = { ...layer, source: this._generateMbSourceId( - typeof (layer as MbLayer).source === 'string' - ? ((layer as MbLayer).source as string) + 'source' in layer && typeof layer.source === 'string' + ? (layer.source as string) : undefined ), id: mbLayerId, @@ -375,7 +379,7 @@ export class EmsVectorTileLayer extends AbstractLayer { return []; } - _setOpacityForType(mbMap: MbMap, mbLayer: MbLayer, mbLayerId: string) { + _setOpacityForType(mbMap: MbMap, mbLayer: LayerSpecification, mbLayerId: string) { this._getOpacityProps(mbLayer.type).forEach((opacityProp) => { const mbPaint = mbLayer.paint as { [key: string]: unknown } | undefined; if (mbPaint && typeof mbPaint[opacityProp] === 'number') { @@ -387,7 +391,7 @@ export class EmsVectorTileLayer extends AbstractLayer { }); } - _setLayerZoomRange(mbMap: MbMap, mbLayer: MbLayer, mbLayerId: string) { + _setLayerZoomRange(mbMap: MbMap, mbLayer: LayerSpecification, mbLayerId: string) { let minZoom = this.getMinZoom(); if (typeof mbLayer.minzoom === 'number') { minZoom = Math.max(minZoom, mbLayer.minzoom); diff --git a/x-pack/plugins/maps/public/classes/layers/heatmap_layer/heatmap_layer.ts b/x-pack/plugins/maps/public/classes/layers/heatmap_layer/heatmap_layer.ts index a977ed10fdade..d1247590af2e9 100644 --- a/x-pack/plugins/maps/public/classes/layers/heatmap_layer/heatmap_layer.ts +++ b/x-pack/plugins/maps/public/classes/layers/heatmap_layer/heatmap_layer.ts @@ -5,16 +5,22 @@ * 2.0. */ -import type { Map as MbMap, VectorSource as MbVectorSource } from '@kbn/mapbox-gl'; +import type { Map as MbMap, VectorTileSource } from '@kbn/mapbox-gl'; import { AbstractLayer } from '../layer'; import { HeatmapStyle } from '../../styles/heatmap/heatmap_style'; import { LAYER_TYPE } from '../../../../common/constants'; import { HeatmapLayerDescriptor } from '../../../../common/descriptor_types'; import { ESGeoGridSource } from '../../sources/es_geo_grid_source'; -import { syncBoundsData, MvtSourceData, syncMvtSourceData } from '../vector_layer'; +import { + NO_RESULTS_ICON_AND_TOOLTIPCONTENT, + syncBoundsData, + MvtSourceData, + syncMvtSourceData, +} from '../vector_layer'; import { DataRequestContext } from '../../../actions'; import { buildVectorRequestMeta } from '../build_vector_request_meta'; import { IMvtVectorSource } from '../../sources/vector_source'; +import { getAggsMeta } from '../../util/tile_meta_feature_utils'; export class HeatmapLayer extends AbstractLayer { private readonly _style: HeatmapStyle; @@ -48,6 +54,11 @@ export class HeatmapLayer extends AbstractLayer { } } + getLayerIcon(isTocIcon: boolean) { + const { docCount } = getAggsMeta(this._getMetaFromTiles()); + return docCount === 0 ? NO_RESULTS_ICON_AND_TOOLTIPCONTENT : super.getLayerIcon(isTocIcon); + } + getSource(): ESGeoGridSource { return super.getSource() as ESGeoGridSource; } @@ -89,7 +100,8 @@ export class HeatmapLayer extends AbstractLayer { this.getSource().getFieldNames(), syncContext.dataFilters, this.getQuery(), - syncContext.isForceRefresh + syncContext.isForceRefresh, + syncContext.isFeatureEditorOpenForLayer ), source: this.getSource() as IMvtVectorSource, syncContext, @@ -97,7 +109,7 @@ export class HeatmapLayer extends AbstractLayer { } _requiresPrevSourceCleanup(mbMap: MbMap): boolean { - const mbSource = mbMap.getSource(this.getMbSourceId()) as MbVectorSource; + const mbSource = mbMap.getSource(this.getMbSourceId()) as VectorTileSource; if (!mbSource) { return false; } diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/blended_vector_layer/blended_vector_layer.ts b/x-pack/plugins/maps/public/classes/layers/vector_layer/blended_vector_layer/blended_vector_layer.ts index e46c670b677ba..b1fddcca5d5f2 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/blended_vector_layer/blended_vector_layer.ts +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/blended_vector_layer/blended_vector_layer.ts @@ -298,7 +298,8 @@ export class BlendedVectorLayer extends GeoJsonVectorLayer implements IVectorLay syncContext.isForceRefresh, syncContext.dataFilters, this.getSource(), - this.getCurrentStyle() + this.getCurrentStyle(), + syncContext.isFeatureEditorOpenForLayer ); const source = this.getSource(); diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/bounds_data.ts b/x-pack/plugins/maps/public/classes/layers/vector_layer/bounds_data.ts index 29ecf1635d626..7136c9d0c2235 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/bounds_data.ts +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/bounds_data.ts @@ -22,7 +22,13 @@ export async function syncBoundsData({ source: IVectorSource; sourceQuery: Query | null; }): Promise { - const { startLoading, stopLoading, registerCancelCallback, dataFilters } = syncContext; + const { + startLoading, + stopLoading, + registerCancelCallback, + dataFilters, + isFeatureEditorOpenForLayer, + } = syncContext; const requestToken = Symbol(`${SOURCE_BOUNDS_DATA_REQUEST_ID}-${layerId}`); @@ -37,6 +43,7 @@ export async function syncBoundsData({ joinKeyFilter: dataFilters.joinKeyFilter, applyGlobalQuery: source.getApplyGlobalQuery(), applyGlobalTime: source.getApplyGlobalTime(), + isFeatureEditorOpenForLayer, }; let bounds = null; diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/geojson_vector_layer/geojson_vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/geojson_vector_layer/geojson_vector_layer.tsx index 18972e89607e4..bc7ba78c84d98 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/geojson_vector_layer/geojson_vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/geojson_vector_layer/geojson_vector_layer.tsx @@ -10,7 +10,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiIcon } from '@elastic/eui'; import { Feature, FeatureCollection } from 'geojson'; -import type { Map as MbMap, GeoJSONSource as MbGeoJSONSource } from '@kbn/mapbox-gl'; +import type { FilterSpecification, Map as MbMap, GeoJSONSource } from '@kbn/mapbox-gl'; import { EMPTY_FEATURE_COLLECTION, FEATURE_VISIBLE_PROPERTY_NAME, @@ -160,7 +160,7 @@ export class GeoJsonVectorLayer extends AbstractVectorLayer { this._setMbLinePolygonProperties(mbMap, undefined, timesliceMaskConfig); } - _getJoinFilterExpression(): unknown | undefined { + _getJoinFilterExpression(): FilterSpecification | undefined { return this.hasJoins() ? // Remove unjoined source features by filtering out features without GeoJSON feature.property[FEATURE_VISIBLE_PROPERTY_NAME] is true ['==', ['get', FEATURE_VISIBLE_PROPERTY_NAME], true] @@ -168,7 +168,7 @@ export class GeoJsonVectorLayer extends AbstractVectorLayer { } _syncFeatureCollectionWithMb(mbMap: MbMap) { - const mbGeoJSONSource = mbMap.getSource(this.getId()) as MbGeoJSONSource; + const mbGeoJSONSource = mbMap.getSource(this.getId()) as GeoJSONSource; const featureCollection = this._getSourceFeatureCollection(); const featureCollectionOnMap = AbstractLayer.getBoundDataForSource(mbMap, this.getId()); @@ -237,7 +237,8 @@ export class GeoJsonVectorLayer extends AbstractVectorLayer { syncContext.isForceRefresh, syncContext.dataFilters, source, - style + style, + syncContext.isFeatureEditorOpenForLayer ), syncContext, source, diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/mvt_vector_layer/mvt_source_data.test.ts b/x-pack/plugins/maps/public/classes/layers/vector_layer/mvt_vector_layer/mvt_source_data.test.ts index 4b45adc8848bd..ccc73f94aac57 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/mvt_vector_layer/mvt_source_data.test.ts +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/mvt_vector_layer/mvt_source_data.test.ts @@ -59,6 +59,7 @@ describe('syncMvtSourceData', () => { fieldNames: [], sourceMeta: {}, isForceRefresh: false, + isFeatureEditorOpenForLayer: false, }, source: mockSource, syncContext, @@ -90,6 +91,7 @@ describe('syncMvtSourceData', () => { fieldNames: [], sourceMeta: {}, isForceRefresh: false, + isFeatureEditorOpenForLayer: false, }; await syncMvtSourceData({ @@ -131,6 +133,7 @@ describe('syncMvtSourceData', () => { fieldNames: [], sourceMeta: {}, isForceRefresh: false, + isFeatureEditorOpenForLayer: false, }; await syncMvtSourceData({ @@ -169,6 +172,7 @@ describe('syncMvtSourceData', () => { fieldNames: [], sourceMeta: {}, isForceRefresh: false, + isFeatureEditorOpenForLayer: false, }; await syncMvtSourceData({ @@ -215,6 +219,7 @@ describe('syncMvtSourceData', () => { fieldNames: [], sourceMeta: {}, isForceRefresh: false, + isFeatureEditorOpenForLayer: false, }; await syncMvtSourceData({ @@ -253,6 +258,7 @@ describe('syncMvtSourceData', () => { fieldNames: [], sourceMeta: {}, isForceRefresh: false, + isFeatureEditorOpenForLayer: false, }; await syncMvtSourceData({ @@ -291,6 +297,7 @@ describe('syncMvtSourceData', () => { fieldNames: [], sourceMeta: {}, isForceRefresh: false, + isFeatureEditorOpenForLayer: false, }; await syncMvtSourceData({ diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/mvt_vector_layer/mvt_vector_layer.test.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/mvt_vector_layer/mvt_vector_layer.test.tsx index 27d377851152e..d9ee5207b29f3 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/mvt_vector_layer/mvt_vector_layer.test.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/mvt_vector_layer/mvt_vector_layer.test.tsx @@ -17,6 +17,8 @@ import { shallow } from 'enzyme'; import { Feature } from 'geojson'; import { MVTSingleLayerVectorSource } from '../../../sources/mvt_single_layer_vector_source'; +import { IVectorSource } from '../../../sources/vector_source'; +import { InnerJoin } from '../../../joins/inner_join'; import { TiledSingleLayerVectorSourceDescriptor, VectorLayerDescriptor, @@ -93,3 +95,107 @@ describe('getFeatureById', () => { expect(feature).toEqual(null); }); }); + +describe('isInitialDataLoadComplete', () => { + const sourceDataRequestDescriptor = { + data: {}, + dataId: 'source', + dataRequestMeta: {}, + dataRequestMetaAtStart: undefined, + dataRequestToken: undefined, + }; + test('should return false when tile loading has not started', () => { + const layer = new MvtVectorLayer({ + customIcons: [], + layerDescriptor: { + __dataRequests: [sourceDataRequestDescriptor], + } as unknown as VectorLayerDescriptor, + source: {} as unknown as IVectorSource, + }); + expect(layer.isInitialDataLoadComplete()).toBe(false); + }); + + test('should return false when tiles are loading', () => { + const layer = new MvtVectorLayer({ + customIcons: [], + layerDescriptor: { + __areTilesLoaded: false, + __dataRequests: [sourceDataRequestDescriptor], + } as unknown as VectorLayerDescriptor, + source: {} as unknown as IVectorSource, + }); + expect(layer.isInitialDataLoadComplete()).toBe(false); + }); + + test('should return true when tiles are loaded', () => { + const layer = new MvtVectorLayer({ + customIcons: [], + layerDescriptor: { + __areTilesLoaded: true, + __dataRequests: [sourceDataRequestDescriptor], + } as unknown as VectorLayerDescriptor, + source: {} as unknown as IVectorSource, + }); + expect(layer.isInitialDataLoadComplete()).toBe(true); + }); + + test('should return false when tiles are loaded but join is loading', () => { + const layer = new MvtVectorLayer({ + customIcons: [], + joins: [ + { + hasCompleteConfig: () => { + return true; + }, + getSourceDataRequestId: () => { + return 'join_source_a0b0da65-5e1a-4967-9dbe-74f24391afe2'; + }, + } as unknown as InnerJoin, + ], + layerDescriptor: { + __areTilesLoaded: true, + __dataRequests: [ + sourceDataRequestDescriptor, + { + dataId: 'join_source_a0b0da65-5e1a-4967-9dbe-74f24391afe2', + dataRequestMetaAtStart: {}, + dataRequestToken: Symbol('join request'), + }, + ], + } as unknown as VectorLayerDescriptor, + source: {} as unknown as IVectorSource, + }); + expect(layer.isInitialDataLoadComplete()).toBe(false); + }); + + test('should return true when tiles are loaded and joins are loaded', () => { + const layer = new MvtVectorLayer({ + customIcons: [], + joins: [ + { + hasCompleteConfig: () => { + return true; + }, + getSourceDataRequestId: () => { + return 'join_source_a0b0da65-5e1a-4967-9dbe-74f24391afe2'; + }, + } as unknown as InnerJoin, + ], + layerDescriptor: { + __areTilesLoaded: true, + __dataRequests: [ + sourceDataRequestDescriptor, + { + data: {}, + dataId: 'join_source_a0b0da65-5e1a-4967-9dbe-74f24391afe2', + dataRequestMeta: {}, + dataRequestMetaAtStart: undefined, + dataRequestToken: undefined, + }, + ], + } as unknown as VectorLayerDescriptor, + source: {} as unknown as IVectorSource, + }); + expect(layer.isInitialDataLoadComplete()).toBe(true); + }); +}); diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/mvt_vector_layer/mvt_vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/mvt_vector_layer/mvt_vector_layer.tsx index 4d15cddcf44db..adb211f8f9420 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/mvt_vector_layer/mvt_vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/mvt_vector_layer/mvt_vector_layer.tsx @@ -8,10 +8,10 @@ import _ from 'lodash'; import type { FeatureIdentifier, + FilterSpecification, Map as MbMap, - AnyLayer as MbLayer, - GeoJSONSource as MbGeoJSONSource, - VectorSource as MbVectorSource, + LayerSpecification, + VectorTileSource, } from '@kbn/mapbox-gl'; import { Feature } from 'geojson'; import { i18n } from '@kbn/i18n'; @@ -29,7 +29,6 @@ import { DataRequestContext } from '../../../../actions'; import { DataRequestMeta, StyleMetaDescriptor, - TileMetaFeature, VectorLayerDescriptor, } from '../../../../../common/descriptor_types'; import { ESSearchSource } from '../../../sources/es_search_source'; @@ -39,10 +38,14 @@ import { LayerIcon } from '../../layer'; import { MvtSourceData, syncMvtSourceData } from './mvt_source_data'; import { PropertiesMap } from '../../../../../common/elasticsearch_util'; import { pluckStyleMeta } from './pluck_style_meta'; +import { + ES_MVT_HITS_TOTAL_RELATION, + ES_MVT_HITS_TOTAL_VALUE, + ES_MVT_META_LAYER_NAME, + getAggsMeta, + getHitsMeta, +} from '../../../util/tile_meta_feature_utils'; -export const ES_MVT_META_LAYER_NAME = 'meta'; -const ES_MVT_HITS_TOTAL_RELATION = 'hits.total.relation'; -const ES_MVT_HITS_TOTAL_VALUE = 'hits.total.value'; const MAX_RESULT_WINDOW_DATA_REQUEST_ID = 'maxResultWindow'; export class MvtVectorLayer extends AbstractVectorLayer { @@ -68,6 +71,12 @@ export class MvtVectorLayer extends AbstractVectorLayer { this._source = args.source as IMvtVectorSource; } + isInitialDataLoadComplete(): boolean { + return this._descriptor.__areTilesLoaded === undefined || !this._descriptor.__areTilesLoaded + ? false + : super.isInitialDataLoadComplete(); + } + async getBounds(syncContext: DataRequestContext) { // Add filter to narrow bounds to features with matching join keys let joinKeyFilter; @@ -116,19 +125,15 @@ export class MvtVectorLayer extends AbstractVectorLayer { // // TODO ES MVT specific - move to es_tiled_vector_layer implementation // - - const tileMetaFeatures = this._getMetaFromTiles(); - if (!tileMetaFeatures.length) { - return NO_RESULTS_ICON_AND_TOOLTIPCONTENT; - } - - if (this.getSource().getType() !== SOURCE_TYPES.ES_SEARCH) { - // aggregation ES sources are never trimmed - return { - icon: this.getCurrentStyle().getIcon(false), - tooltipContent: null, - areResultsTrimmed: false, - }; + if (this.getSource().getType() === SOURCE_TYPES.ES_GEO_GRID) { + const { docCount } = getAggsMeta(this._getMetaFromTiles()); + return docCount === 0 + ? NO_RESULTS_ICON_AND_TOOLTIPCONTENT + : { + icon: this.getCurrentStyle().getIcon(false), + tooltipContent: null, + areResultsTrimmed: false, + }; } const maxResultWindow = this._getMaxResultWindow(); @@ -140,28 +145,16 @@ export class MvtVectorLayer extends AbstractVectorLayer { }; } - let totalFeaturesCount = 0; - let tilesWithFeatures = 0; - tileMetaFeatures.forEach((tileMeta: Feature) => { - const count = - tileMeta && tileMeta.properties ? tileMeta.properties[ES_MVT_HITS_TOTAL_VALUE] : 0; - if (count > 0) { - totalFeaturesCount += count; - tilesWithFeatures++; - } - }); + const { totalFeaturesCount, tilesWithFeatures, tilesWithTrimmedResults } = getHitsMeta( + this._getMetaFromTiles(), + maxResultWindow + ); if (totalFeaturesCount === 0) { return NO_RESULTS_ICON_AND_TOOLTIPCONTENT; } - const areResultsTrimmed: boolean = tileMetaFeatures.some((tileMeta: TileMetaFeature) => { - if (tileMeta?.properties?.[ES_MVT_HITS_TOTAL_RELATION] === 'gte') { - return tileMeta?.properties?.[ES_MVT_HITS_TOTAL_VALUE] >= maxResultWindow + 1; - } else { - return false; - } - }); + const areResultsTrimmed = tilesWithTrimmedResults > 0; // Documents may be counted multiple times if geometry crosses tile boundaries. const canMultiCountShapes = @@ -232,7 +225,8 @@ export class MvtVectorLayer extends AbstractVectorLayer { syncContext.isForceRefresh, syncContext.dataFilters, this.getSource(), - this.getCurrentStyle() + this.getCurrentStyle(), + syncContext.isFeatureEditorOpenForLayer ), source: this.getSource() as IMvtVectorSource, syncContext, @@ -302,7 +296,7 @@ export class MvtVectorLayer extends AbstractVectorLayer { return this.makeMbLayerId('toomanyfeatures'); } - _getJoinFilterExpression(): unknown | undefined { + _getJoinFilterExpression(): FilterSpecification | undefined { const { join, joinPropertiesMap } = this._getJoinResults(); if (!join) { return undefined; @@ -321,13 +315,13 @@ export class MvtVectorLayer extends AbstractVectorLayer { return joinKeys.length ? // Unable to check FEATURE_VISIBLE_PROPERTY_NAME flag since filter expressions do not support feature-state // Instead, remove unjoined source features by filtering out features without matching join keys - [ + ([ 'match', ['get', join.getLeftField().getName()], joinKeys, true, // match value false, // fallback - value with no match - ] + ] as FilterSpecification) : hideAllFilter; } @@ -408,7 +402,7 @@ export class MvtVectorLayer extends AbstractVectorLayer { const tooManyFeaturesLayerId = this._getMbTooManyFeaturesLayerId(); if (!mbMap.getLayer(tooManyFeaturesLayerId)) { - const mbTooManyFeaturesLayer: MbLayer = { + const mbTooManyFeaturesLayer: LayerSpecification = { id: tooManyFeaturesLayerId, type: 'line', source: this.getId(), @@ -448,7 +442,7 @@ export class MvtVectorLayer extends AbstractVectorLayer { // Must remove/add vector source to update source attributes. // _requiresPrevSourceCleanup returns true when vector source needs to be removed so it can be re-added with updated attributes _requiresPrevSourceCleanup(mbMap: MbMap): boolean { - const mbSource = mbMap.getSource(this.getMbSourceId()) as MbVectorSource | MbGeoJSONSource; + const mbSource = mbMap.getSource(this.getMbSourceId()); if (!mbSource) { return false; } @@ -456,7 +450,7 @@ export class MvtVectorLayer extends AbstractVectorLayer { // Expected source is not compatible, so remove. return true; } - const mbTileSource = mbSource as MbVectorSource; + const mbTileSource = mbSource as VectorTileSource; const sourceDataRequest = this.getSourceDataRequest(); if (!sourceDataRequest) { @@ -484,9 +478,7 @@ export class MvtVectorLayer extends AbstractVectorLayer { // but the programmable JS-object uses camelcase `sourceLayer` if ( mbLayer && - // @ts-expect-error mbLayer.sourceLayer !== sourceData.tileSourceLayer && - // @ts-expect-error mbLayer.sourceLayer !== ES_MVT_META_LAYER_NAME ) { // If the source-pointer of one of the layers is stale, they will all be stale. diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx index 23c76924e911e..aee4312713b7d 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx @@ -7,7 +7,7 @@ import React from 'react'; import uuid from 'uuid/v4'; -import type { Map as MbMap, AnyLayer as MbLayer } from '@kbn/mapbox-gl'; +import type { FilterSpecification, Map as MbMap, LayerSpecification } from '@kbn/mapbox-gl'; import type { Query } from '@kbn/data-plugin/common'; import { Feature, GeoJsonProperties, Geometry, Position } from 'geojson'; import _ from 'lodash'; @@ -366,7 +366,8 @@ export class AbstractVectorLayer extends AbstractLayer implements IVectorLayer { isForceRefresh: boolean, dataFilters: DataFilters, source: IVectorSource, - style: IVectorStyle + style: IVectorStyle, + isFeatureEditorOpenForLayer: boolean ): Promise { const fieldNames = [ ...source.getFieldNames(), @@ -378,7 +379,14 @@ export class AbstractVectorLayer extends AbstractLayer implements IVectorLayer { if (timesliceMaskFieldName) { fieldNames.push(timesliceMaskFieldName); } - return buildVectorRequestMeta(source, fieldNames, dataFilters, this.getQuery(), isForceRefresh); + return buildVectorRequestMeta( + source, + fieldNames, + dataFilters, + this.getQuery(), + isForceRefresh, + isFeatureEditorOpenForLayer + ); } async _syncSourceStyleMeta( @@ -542,6 +550,7 @@ export class AbstractVectorLayer extends AbstractLayer implements IVectorLayer { registerCancelCallback, dataFilters, isForceRefresh, + isFeatureEditorOpenForLayer, }: { join: InnerJoin } & DataRequestContext): Promise { const joinSource = join.getRightJoinSource(); const sourceDataId = join.getSourceDataRequestId(); @@ -552,7 +561,8 @@ export class AbstractVectorLayer extends AbstractLayer implements IVectorLayer { joinSource.getFieldNames(), dataFilters, joinSource.getWhereQuery(), - isForceRefresh + isForceRefresh, + isFeatureEditorOpenForLayer ) as VectorJoinSourceRequestMeta; const prevDataRequest = this.getDataRequest(sourceDataId); @@ -673,7 +683,7 @@ export class AbstractVectorLayer extends AbstractLayer implements IVectorLayer { } } - _getJoinFilterExpression(): unknown | undefined { + _getJoinFilterExpression(): FilterSpecification | undefined { return undefined; } @@ -698,7 +708,7 @@ export class AbstractVectorLayer extends AbstractLayer implements IVectorLayer { if (this.getCurrentStyle().arePointsSymbolizedAsCircles()) { markerLayerId = pointLayerId; if (!pointLayer) { - const mbLayer: MbLayer = { + const mbLayer: LayerSpecification = { id: pointLayerId, type: 'circle', source: sourceId, @@ -716,7 +726,7 @@ export class AbstractVectorLayer extends AbstractLayer implements IVectorLayer { } else { markerLayerId = symbolLayerId; if (!symbolLayer) { - const mbLayer: MbLayer = { + const mbLayer: LayerSpecification = { id: symbolLayerId, type: 'symbol', source: sourceId, @@ -768,7 +778,7 @@ export class AbstractVectorLayer extends AbstractLayer implements IVectorLayer { const lineLayerId = this._getMbLineLayerId(); if (!mbMap.getLayer(fillLayerId)) { - const mbLayer: MbLayer = { + const mbLayer: LayerSpecification = { id: fillLayerId, type: 'fill', source: sourceId, @@ -780,7 +790,7 @@ export class AbstractVectorLayer extends AbstractLayer implements IVectorLayer { mbMap.addLayer(mbLayer, labelLayerId); } if (!mbMap.getLayer(lineLayerId)) { - const mbLayer: MbLayer = { + const mbLayer: LayerSpecification = { id: lineLayerId, type: 'line', source: sourceId, @@ -824,7 +834,7 @@ export class AbstractVectorLayer extends AbstractLayer implements IVectorLayer { const labelLayerId = this._getMbLabelLayerId(); const labelLayer = mbMap.getLayer(labelLayerId); if (!labelLayer) { - const mbLayer: MbLayer = { + const mbLayer: LayerSpecification = { id: labelLayerId, type: 'symbol', source: this.getId(), diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.test.ts b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.test.ts index bcbc50c7e0090..7110473b11261 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.test.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.test.ts @@ -178,6 +178,7 @@ describe('ESGeoGridSource', () => { sourceMeta: null, zoom: 0, isForceRefresh: false, + isFeatureEditorOpenForLayer: false, }; describe('getGeoJsonWithMeta', () => { diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts index 54071848f9a40..2df2e119df30c 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts @@ -106,6 +106,7 @@ describe('ESSearchSource', () => { applyGlobalTime: true, applyForceRefresh: true, isForceRefresh: false, + isFeatureEditorOpenForLayer: false, }; it('Should only include required props', async () => { diff --git a/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts b/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts index c0eef8ba1ca22..944bf0ee3e0b1 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts @@ -230,7 +230,17 @@ export class AbstractESSource extends AbstractVectorSource implements IESSource allFilters.push(extentFilter); } - if (searchFilters.applyGlobalTime && (await this.isTimeAware())) { + + let isFeatureEditorOpenForLayer = false; + if ('isFeatureEditorOpenForLayer' in searchFilters) { + isFeatureEditorOpenForLayer = searchFilters.isFeatureEditorOpenForLayer; + } + + if ( + searchFilters.applyGlobalTime && + (await this.isTimeAware()) && + !isFeatureEditorOpenForLayer + ) { const timeRange = searchFilters.timeslice ? { from: new Date(searchFilters.timeslice.from).toISOString(), @@ -250,11 +260,11 @@ export class AbstractESSource extends AbstractVectorSource implements IESSource searchSource.setField('index', indexPattern); searchSource.setField('size', limit); searchSource.setField('filter', allFilters); - if (searchFilters.applyGlobalQuery) { + if (searchFilters.applyGlobalQuery && !isFeatureEditorOpenForLayer) { searchSource.setField('query', searchFilters.query); } - if (searchFilters.sourceQuery) { + if (searchFilters.sourceQuery && !isFeatureEditorOpenForLayer) { const layerSearchSource = searchService.searchSource.createEmpty(); layerSearchSource.setField('index', indexPattern); diff --git a/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx index 79830068628e5..43a2a00ca59e1 100644 --- a/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx @@ -42,6 +42,7 @@ export interface BoundsRequestMeta { sourceQuery?: Query; timeFilters: TimeRange; timeslice?: Timeslice; + isFeatureEditorOpenForLayer: boolean; joinKeyFilter?: Filter; } diff --git a/x-pack/plugins/maps/public/classes/styles/vector/components/symbol/icon_preview.tsx b/x-pack/plugins/maps/public/classes/styles/vector/components/symbol/icon_preview.tsx index 385e86cbfd693..d93be52dcc4d4 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/components/symbol/icon_preview.tsx +++ b/x-pack/plugins/maps/public/classes/styles/vector/components/symbol/icon_preview.tsx @@ -16,7 +16,7 @@ import { EuiTitle, EuiToolTip, } from '@elastic/eui'; -import { mapboxgl, Map as MapboxMap } from '@kbn/mapbox-gl'; +import { maplibregl, Map as MapboxMap } from '@kbn/mapbox-gl'; import { i18n } from '@kbn/i18n'; import { ResizeChecker } from '@kbn/kibana-utils-plugin/public'; import { @@ -94,7 +94,6 @@ export class IconPreview extends Component { } const imageData = await createSdfIcon({ svg, cutoff, radius }); if (map.hasImage(IconPreview.iconId)) { - // @ts-expect-error map.updateImage(IconPreview.iconId, imageData); } else { map.addImage(IconPreview.iconId, imageData, { @@ -128,7 +127,7 @@ export class IconPreview extends Component { } _createMapInstance(): MapboxMap { - const map = new mapboxgl.Map({ + const map = new maplibregl.Map({ container: this._containerRef!, interactive: false, center: [0, 0], diff --git a/x-pack/plugins/maps/public/classes/util/can_skip_fetch.ts b/x-pack/plugins/maps/public/classes/util/can_skip_fetch.ts index 69a5c73ba2933..71d4730880b96 100644 --- a/x-pack/plugins/maps/public/classes/util/can_skip_fetch.ts +++ b/x-pack/plugins/maps/public/classes/util/can_skip_fetch.ts @@ -86,6 +86,10 @@ export async function canSkipSourceUpdate({ return false; } + if (prevMeta.isFeatureEditorOpenForLayer !== nextRequestMeta.isFeatureEditorOpenForLayer) { + return false; + } + let updateDueToApplyGlobalTime = false; let updateDueToTime = false; let updateDueToTimeslice = false; diff --git a/x-pack/plugins/maps/public/classes/util/mb_filter_expressions.ts b/x-pack/plugins/maps/public/classes/util/mb_filter_expressions.ts index 025d1d830c87d..2f25dc84fe224 100644 --- a/x-pack/plugins/maps/public/classes/util/mb_filter_expressions.ts +++ b/x-pack/plugins/maps/public/classes/util/mb_filter_expressions.ts @@ -5,6 +5,7 @@ * 2.0. */ +import type { FilterSpecification } from '@kbn/mapbox-gl'; import { GEO_JSON_TYPE, KBN_IS_CENTROID_FEATURE } from '../../../common/constants'; import { Timeslice } from '../../../common/descriptor_types'; @@ -14,14 +15,18 @@ export interface TimesliceMaskConfig { timeslice: Timeslice; } -export const EXCLUDE_CENTROID_FEATURES = ['!=', ['get', KBN_IS_CENTROID_FEATURE], true]; +export const EXCLUDE_CENTROID_FEATURES = [ + '!=', + ['get', KBN_IS_CENTROID_FEATURE], + true, +] as FilterSpecification; function getFilterExpression( - filters: unknown[], - joinFilter?: unknown, + filters: FilterSpecification[], + joinFilter?: FilterSpecification, timesliceMaskConfig?: TimesliceMaskConfig -) { - const allFilters: unknown[] = [...filters]; +): FilterSpecification { + const allFilters: FilterSpecification[] = [...filters]; if (joinFilter) { allFilters.push(joinFilter); @@ -45,9 +50,9 @@ function getFilterExpression( } export function getFillFilterExpression( - joinFilter?: unknown, + joinFilter?: FilterSpecification, timesliceMaskConfig?: TimesliceMaskConfig -): unknown[] { +): FilterSpecification { return getFilterExpression( [ // explicit EXCLUDE_CENTROID_FEATURES filter not needed. Centroids are points and are filtered out by geometry narrowing @@ -63,9 +68,9 @@ export function getFillFilterExpression( } export function getLineFilterExpression( - joinFilter?: unknown, + joinFilter?: FilterSpecification, timesliceMaskConfig?: TimesliceMaskConfig -): unknown[] { +): FilterSpecification { return getFilterExpression( [ // explicit EXCLUDE_CENTROID_FEATURES filter not needed. Centroids are points and are filtered out by geometry narrowing @@ -89,9 +94,9 @@ const IS_POINT_FEATURE = [ ]; export function getPointFilterExpression( - joinFilter?: unknown, + joinFilter?: FilterSpecification, timesliceMaskConfig?: TimesliceMaskConfig -): unknown[] { +): FilterSpecification { return getFilterExpression( [EXCLUDE_CENTROID_FEATURES, IS_POINT_FEATURE], joinFilter, @@ -101,10 +106,10 @@ export function getPointFilterExpression( export function getLabelFilterExpression( isSourceGeoJson: boolean, - joinFilter?: unknown, + joinFilter?: FilterSpecification, timesliceMaskConfig?: TimesliceMaskConfig -): unknown[] { - const filters: unknown[] = []; +): FilterSpecification { + const filters: FilterSpecification[] = []; if (isSourceGeoJson) { // Centroid feature added to GeoJSON feature collection for LINE_STRING, MULTI_LINE_STRING, POLYGON, MULTI_POLYGON, and GEOMETRY_COLLECTION geometries diff --git a/x-pack/plugins/maps/public/classes/util/tile_meta_feature_utils.test.ts b/x-pack/plugins/maps/public/classes/util/tile_meta_feature_utils.test.ts new file mode 100644 index 0000000000000..c812dfa6b94f2 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/util/tile_meta_feature_utils.test.ts @@ -0,0 +1,378 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { TileMetaFeature } from '../../../common/descriptor_types'; +import { getAggsMeta, getAggRange, getHitsMeta } from './tile_meta_feature_utils'; + +describe('getAggsMeta', () => { + test('should extract doc_count = 0 from meta features when there are no matches', () => { + const metaFeatures = [ + { + type: 'Feature', + geometry: { + type: 'Polygon', + coordinates: [ + [ + [-101.25, 31.952162238024968], + [-95.625, 31.952162238024968], + [-95.625, 36.597889133070225], + [-101.25, 36.597889133070225], + [-101.25, 31.952162238024968], + ], + ], + }, + properties: { + '_shards.failed': 0, + '_shards.skipped': 0, + '_shards.successful': 1, + '_shards.total': 1, + 'aggregations._count.count': 0, + 'aggregations._count.sum': 0, + 'hits.total.relation': 'eq', + 'hits.total.value': 0, + timed_out: false, + took: 1, + }, + }, + { + type: 'Feature', + geometry: { + type: 'Polygon', + coordinates: [ + [ + [-106.875, 31.952162238024968], + [-101.25, 31.952162238024968], + [-101.25, 36.597889133070225], + [-106.875, 36.597889133070225], + [-106.875, 31.952162238024968], + ], + ], + }, + properties: { + '_shards.failed': 0, + '_shards.skipped': 0, + '_shards.successful': 1, + '_shards.total': 1, + 'aggregations._count.count': 0, + 'aggregations._count.sum': 0, + 'hits.total.relation': 'eq', + 'hits.total.value': 0, + timed_out: false, + took: 1, + }, + }, + ] as TileMetaFeature[]; + const { docCount } = getAggsMeta(metaFeatures); + expect(docCount).toBe(0); + }); + + test('should extract doc_count from meta features', () => { + const metaFeatures = [ + { + type: 'Feature', + geometry: { + type: 'Polygon', + coordinates: [ + [ + [-106.875, 36.597889133070225], + [-101.25, 36.597889133070225], + [-101.25, 40.979898069620134], + [-106.875, 40.979898069620134], + [-106.875, 36.597889133070225], + ], + ], + }, + properties: { + '_shards.failed': 0, + '_shards.skipped': 0, + '_shards.successful': 1, + '_shards.total': 1, + 'aggregations._count.avg': 92.3133514986376, + 'aggregations._count.count': 9175, + 'aggregations._count.max': 8297, + 'aggregations._count.min': 1, + 'aggregations._count.sum': 846975, + 'hits.total.relation': 'gte', + 'hits.total.value': 10000, + timed_out: false, + took: 968, + }, + }, + { + type: 'Feature', + geometry: { + type: 'Polygon', + coordinates: [ + [ + [-112.5, 36.597889133070225], + [-106.875, 36.597889133070225], + [-106.875, 40.979898069620134], + [-112.5, 40.979898069620134], + [-112.5, 36.597889133070225], + ], + ], + }, + properties: { + '_shards.failed': 0, + '_shards.skipped': 0, + '_shards.successful': 1, + '_shards.total': 1, + 'aggregations._count.avg': 41.19310344827586, + 'aggregations._count.count': 4495, + 'aggregations._count.max': 2398, + 'aggregations._count.min': 1, + 'aggregations._count.sum': 185163, + 'hits.total.relation': 'gte', + 'hits.total.value': 10000, + timed_out: false, + took: 522, + }, + }, + { + type: 'Feature', + geometry: { + type: 'Polygon', + coordinates: [ + [ + [-106.875, 40.979898069620134], + [-101.25, 40.979898069620134], + [-101.25, 45.08903556483102], + [-106.875, 45.08903556483102], + [-106.875, 40.979898069620134], + ], + ], + }, + properties: { + '_shards.failed': 0, + '_shards.skipped': 0, + '_shards.successful': 1, + '_shards.total': 1, + 'aggregations._count.avg': 9.938271604938272, + 'aggregations._count.count': 81, + 'aggregations._count.max': 96, + 'aggregations._count.min': 1, + 'aggregations._count.sum': 805, + 'hits.total.relation': 'eq', + 'hits.total.value': 792, + timed_out: false, + took: 12, + }, + }, + ] as TileMetaFeature[]; + const { docCount } = getAggsMeta(metaFeatures); + expect(docCount).toBe(1032943); + }); +}); + +test('getAggRange', () => { + const metaFeature = { + type: 'Feature', + geometry: { + type: 'Polygon', + coordinates: [ + [ + [-106.875, 40.979898069620134], + [-101.25, 40.979898069620134], + [-101.25, 45.08903556483102], + [-106.875, 45.08903556483102], + [-106.875, 40.979898069620134], + ], + ], + }, + properties: { + '_shards.failed': 0, + '_shards.skipped': 0, + '_shards.successful': 1, + '_shards.total': 1, + 'aggregations._count.avg': 9.938271604938272, + 'aggregations._count.count': 81, + 'aggregations._count.max': 96, + 'aggregations._count.min': 1, + 'aggregations._count.sum': 805, + 'hits.total.relation': 'eq', + 'hits.total.value': 792, + timed_out: false, + took: 12, + }, + } as TileMetaFeature; + expect(getAggRange(metaFeature, '_count')).toEqual({ + max: 96, + min: 1, + }); +}); + +describe('getHitsMeta', () => { + test('should extract 0 total hits from meta features when there are no matches', () => { + const metaFeatures = [ + { + type: 'Feature', + geometry: { + type: 'Polygon', + coordinates: [ + [ + [-101.25, 31.952162238024968], + [-95.625, 31.952162238024968], + [-95.625, 36.597889133070225], + [-101.25, 36.597889133070225], + [-101.25, 31.952162238024968], + ], + ], + }, + properties: { + '_shards.failed': 0, + '_shards.skipped': 0, + '_shards.successful': 1, + '_shards.total': 1, + 'hits.total.relation': 'eq', + 'hits.total.value': 0, + timed_out: false, + took: 7, + }, + }, + { + type: 'Feature', + geometry: { + type: 'Polygon', + coordinates: [ + [ + [-106.875, 31.952162238024968], + [-101.25, 31.952162238024968], + [-101.25, 36.597889133070225], + [-106.875, 36.597889133070225], + [-106.875, 31.952162238024968], + ], + ], + }, + properties: { + '_shards.failed': 0, + '_shards.skipped': 0, + '_shards.successful': 1, + '_shards.total': 1, + 'hits.total.relation': 'eq', + 'hits.total.value': 0, + timed_out: false, + took: 7, + }, + }, + ] as TileMetaFeature[]; + expect(getHitsMeta(metaFeatures, 10000)).toEqual({ + tilesWithFeatures: 0, + tilesWithTrimmedResults: 0, + totalFeaturesCount: 0, + }); + }); + + test('should extract hits meta from meta features', () => { + const metaFeatures = [ + { + type: 'Feature', + geometry: { + type: 'Polygon', + coordinates: [ + [ + [-106.875, 36.99268153210721], + [-102.03826904296875, 36.99268153210721], + [-102.03826904296875, 40.979898069620134], + [-106.875, 40.979898069620134], + [-106.875, 36.99268153210721], + ], + ], + }, + properties: { + '_shards.failed': 0, + '_shards.skipped': 0, + '_shards.successful': 1, + '_shards.total': 1, + 'hits.total.relation': 'gte', + 'hits.total.value': 10001, + timed_out: false, + took: 1571, + }, + }, + { + type: 'Feature', + geometry: { + type: 'Polygon', + coordinates: [ + [ + [-109.05853271484375, 36.99706886366255], + [-106.875, 36.99706886366255], + [-106.875, 40.95086262813277], + [-109.05853271484375, 40.95086262813277], + [-109.05853271484375, 36.99706886366255], + ], + ], + }, + properties: { + '_shards.failed': 0, + '_shards.skipped': 0, + '_shards.successful': 1, + '_shards.total': 1, + 'hits.total.relation': 'gte', + 'hits.total.value': 10001, + timed_out: false, + took: 1039, + }, + }, + { + type: 'Feature', + geometry: { + type: 'Polygon', + coordinates: [ + [ + [-101.25, 40.979898069620134], + [-95.625, 40.979898069620134], + [-95.625, 45.08903556483102], + [-101.25, 45.08903556483102], + [-101.25, 40.979898069620134], + ], + ], + }, + properties: { + '_shards.failed': 0, + '_shards.skipped': 0, + '_shards.successful': 1, + '_shards.total': 1, + 'hits.total.relation': 'eq', + 'hits.total.value': 0, + timed_out: false, + took: 7, + }, + }, + { + type: 'Feature', + geometry: { + type: 'Polygon', + coordinates: [ + [ + [-107.7923583984375, 40.991301354803056], + [-107.05078125, 40.991301354803056], + [-107.05078125, 41.0037390532903], + [-107.7923583984375, 41.0037390532903], + [-107.7923583984375, 40.991301354803056], + ], + ], + }, + properties: { + '_shards.failed': 0, + '_shards.skipped': 0, + '_shards.successful': 1, + '_shards.total': 1, + 'hits.total.relation': 'eq', + 'hits.total.value': 28, + timed_out: false, + took: 10, + }, + }, + ] as TileMetaFeature[]; + expect(getHitsMeta(metaFeatures, 10000)).toEqual({ + tilesWithFeatures: 3, + tilesWithTrimmedResults: 2, + totalFeaturesCount: 20030, + }); + }); +}); diff --git a/x-pack/plugins/maps/public/classes/util/tile_meta_feature_utils.ts b/x-pack/plugins/maps/public/classes/util/tile_meta_feature_utils.ts new file mode 100644 index 0000000000000..ac12399a2e011 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/util/tile_meta_feature_utils.ts @@ -0,0 +1,70 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { TileMetaFeature } from '../../../common/descriptor_types'; + +// Elasticsearch vector tile API returns "meta" layer containing a single metadata feature for each tile request +// This file contains utility methods for pulling values out of metadata features +// Placing logic in a single file to provide a centrialize location and avoid scattering logic throughout plugin + +export const ES_MVT_META_LAYER_NAME = 'meta'; +export const ES_MVT_HITS_TOTAL_RELATION = 'hits.total.relation'; +export const ES_MVT_HITS_TOTAL_VALUE = 'hits.total.value'; + +export function getAggsMeta(metaFeatures: TileMetaFeature[]): { docCount: number } { + let docCount = 0; + metaFeatures.forEach((metaFeature) => { + const count = metaFeature.properties + ? (metaFeature.properties['aggregations._count.sum'] as number) + : 0; + if (count > 0) { + docCount += count; + } + }); + + return { docCount }; +} + +export function getHitsMeta( + metaFeatures: TileMetaFeature[], + maxResultWindow: number +): { totalFeaturesCount: number; tilesWithFeatures: number; tilesWithTrimmedResults: number } { + let totalFeaturesCount = 0; + let tilesWithFeatures = 0; + let tilesWithTrimmedResults = 0; + metaFeatures.forEach((metaFeature) => { + const count = metaFeature.properties ? metaFeature.properties[ES_MVT_HITS_TOTAL_VALUE] : 0; + if (count > 0) { + totalFeaturesCount += count; + tilesWithFeatures++; + } + + if ( + metaFeature?.properties?.[ES_MVT_HITS_TOTAL_RELATION] === 'gte' && + metaFeature?.properties?.[ES_MVT_HITS_TOTAL_VALUE] >= maxResultWindow + 1 + ) { + tilesWithTrimmedResults++; + } + }); + return { totalFeaturesCount, tilesWithFeatures, tilesWithTrimmedResults }; +} + +export function getAggRange( + metaFeature: TileMetaFeature, + subAggName: string +): { min: number; max: number } | null { + const minField = `aggregations.${subAggName}.min`; + const maxField = `aggregations.${subAggName}.max`; + return metaFeature.properties && + typeof metaFeature.properties[minField] === 'number' && + typeof metaFeature.properties[maxField] === 'number' + ? { + min: metaFeature.properties[minField] as number, + max: metaFeature.properties[maxField] as number, + } + : null; +} diff --git a/x-pack/plugins/maps/public/components/global_filter_checkbox.tsx b/x-pack/plugins/maps/public/components/global_filter_checkbox.tsx index 96805e0c6b5ec..502cc1973d329 100644 --- a/x-pack/plugins/maps/public/components/global_filter_checkbox.tsx +++ b/x-pack/plugins/maps/public/components/global_filter_checkbox.tsx @@ -13,27 +13,37 @@ interface Props { applyGlobalQuery: boolean; label: string; setApplyGlobalQuery: (applyGlobalQuery: boolean) => void; + isFeatureEditorOpenForLayer?: boolean; } -export function GlobalFilterCheckbox({ applyGlobalQuery, label, setApplyGlobalQuery }: Props) { +export function GlobalFilterCheckbox({ + applyGlobalQuery, + label, + setApplyGlobalQuery, + isFeatureEditorOpenForLayer, +}: Props) { const onApplyGlobalQueryChange = (event: EuiSwitchEvent) => { setApplyGlobalQuery(event.target.checked); }; + const tooltipMessage = isFeatureEditorOpenForLayer + ? i18n.translate('xpack.maps.filterEditor.isGlobalSearchNotApplied', { + defaultMessage: 'Global search is not applied to the layer while editing features', + }) + : i18n.translate('xpack.maps.filterEditor.applyGlobalFilterHelp', { + defaultMessage: 'When enabled, results narrowed by global search', + }); + return ( - + diff --git a/x-pack/plugins/maps/public/components/global_time_checkbox.tsx b/x-pack/plugins/maps/public/components/global_time_checkbox.tsx index 70d6859b8b02a..4db771c1edbaf 100644 --- a/x-pack/plugins/maps/public/components/global_time_checkbox.tsx +++ b/x-pack/plugins/maps/public/components/global_time_checkbox.tsx @@ -12,27 +12,37 @@ interface Props { applyGlobalTime: boolean; label: string; setApplyGlobalTime: (applyGlobalTime: boolean) => void; + isFeatureEditorOpenForLayer?: boolean; } -export function GlobalTimeCheckbox({ applyGlobalTime, label, setApplyGlobalTime }: Props) { +export function GlobalTimeCheckbox({ + applyGlobalTime, + label, + setApplyGlobalTime, + isFeatureEditorOpenForLayer, +}: Props) { const onApplyGlobalTimeChange = (event: EuiSwitchEvent) => { setApplyGlobalTime(event.target.checked); }; + const tooltipMessage = isFeatureEditorOpenForLayer + ? i18n.translate('xpack.maps.filterEditor.isGlobalTimeNotApplied', { + defaultMessage: 'Global time is not applied to the layer while editing features', + }) + : i18n.translate('xpack.maps.filterEditor.applyGlobalTimeHelp', { + defaultMessage: 'When enabled, results narrowed by global time', + }); + return ( - + diff --git a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/filter_editor/filter_editor.tsx b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/filter_editor/filter_editor.tsx index afb18aa582a3c..9e3edeb1fc255 100644 --- a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/filter_editor/filter_editor.tsx +++ b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/filter_editor/filter_editor.tsx @@ -35,6 +35,7 @@ export interface Props { layer: ILayer; setLayerQuery: (id: string, query: Query) => void; updateSourceProp: (layerId: string, propName: string, value: unknown) => void; + isFeatureEditorOpenForLayer: boolean; } interface State { @@ -157,6 +158,15 @@ export class FilterEditor extends Component { } _renderQuery() { + if (this.props.isFeatureEditorOpenForLayer) { + return ( + + ); + } + const query = this.props.layer.getQuery(); if (!query || !query.query) { return ( @@ -199,6 +209,7 @@ export class FilterEditor extends Component { onClick={this._toggle} data-test-subj="mapLayerPanelOpenFilterEditorButton" iconType={openButtonIcon} + disabled={this.props.isFeatureEditorOpenForLayer} > {openButtonLabel} @@ -213,6 +224,7 @@ export class FilterEditor extends Component { })} applyGlobalTime={this.props.layer.getSource().getApplyGlobalTime()} setApplyGlobalTime={this._onApplyGlobalTimeChange} + isFeatureEditorOpenForLayer={this.props.isFeatureEditorOpenForLayer} /> ) : null; @@ -244,6 +256,7 @@ export class FilterEditor extends Component { })} applyGlobalQuery={this.props.layer.getSource().getApplyGlobalQuery()} setApplyGlobalQuery={this._onApplyGlobalQueryChange} + isFeatureEditorOpenForLayer={this.props.isFeatureEditorOpenForLayer} /> {globalTimeCheckbox} diff --git a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/filter_editor/index.ts b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/filter_editor/index.ts index 7c3db15f10236..51b19e7b05c96 100644 --- a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/filter_editor/index.ts +++ b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/filter_editor/index.ts @@ -10,13 +10,15 @@ import { ThunkDispatch } from 'redux-thunk'; import { connect } from 'react-redux'; import type { Query } from '@kbn/data-plugin/public'; import { FilterEditor } from './filter_editor'; -import { getSelectedLayer } from '../../../selectors/map_selectors'; +import { getEditState, getSelectedLayer } from '../../../selectors/map_selectors'; import { setLayerQuery, updateSourceProp } from '../../../actions'; import { MapStoreState } from '../../../reducers/store'; function mapStateToProps(state: MapStoreState) { + const layer = getSelectedLayer(state)!; return { - layer: getSelectedLayer(state)!, + layer, + isFeatureEditorOpenForLayer: getEditState(state)?.layerId === layer.getId(), }; } diff --git a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/join_editor.tsx b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/join_editor.tsx index cfa46ecf32b32..2865e2d8099d1 100644 --- a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/join_editor.tsx +++ b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/join_editor.tsx @@ -79,6 +79,7 @@ export function JoinEditor({ joins, layer, onChange, leftJoinFields, layerDispla function renderContent() { const disabledReason = layer.getJoinsDisabledReason(); + return disabledReason ? ( {disabledReason} ) : ( diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx index b6ffacc491030..df70d4b7cfd9b 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx @@ -6,14 +6,13 @@ */ import React, { Component } from 'react'; -import { Map as MbMap, Point as MbPoint } from '@kbn/mapbox-gl'; // @ts-expect-error import MapboxDraw from '@mapbox/mapbox-gl-draw'; import { Feature, Geometry, Position } from 'geojson'; import { i18n } from '@kbn/i18n'; // @ts-expect-error import * as jsts from 'jsts'; -import { MapMouseEvent } from '@kbn/mapbox-gl'; +import type { Map as MbMap, MapMouseEvent, PointLike } from '@kbn/mapbox-gl'; import { getToasts } from '../../../../kibana_services'; import { DrawControl } from '../draw_control'; import { DRAW_MODE, DRAW_SHAPE } from '../../../../../common/constants'; @@ -84,7 +83,7 @@ export class DrawFeatureControl extends Component { }; _onClick = async (event: MapMouseEvent, drawControl?: MapboxDraw) => { - const mbLngLatPoint: MbPoint = event.point; + const mbLngLatPoint: PointLike = event.point; // Currently feature deletion is the only onClick handling if (!this.props.editLayer || this.props.drawShape !== DRAW_SHAPE.DELETE) { return; @@ -103,7 +102,7 @@ export class DrawFeatureControl extends Component { x: mbLngLatPoint.x + PADDING, y: mbLngLatPoint.y + PADDING, }, - ] as [MbPoint, MbPoint]; + ] as [PointLike, PointLike]; const selectedFeatures = this.props.mbMap.queryRenderedFeatures(mbBbox, { layers: mbEditLayerIds, filter: ['all', EXCLUDE_CENTROID_FEATURES], diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx index 8c430647cbbd3..7dda17442e5e1 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx @@ -10,9 +10,8 @@ import React, { Component } from 'react'; import { Adapters } from '@kbn/inspector-plugin/public'; import { Filter } from '@kbn/es-query'; import { Action, ActionExecutionContext } from '@kbn/ui-actions-plugin/public'; - -import { mapboxgl } from '@kbn/mapbox-gl'; -import type { Map as MapboxMap, MapboxOptions, MapMouseEvent } from '@kbn/mapbox-gl'; +import { maplibregl } from '@kbn/mapbox-gl'; +import type { Map as MapboxMap, MapOptions, MapMouseEvent } from '@kbn/mapbox-gl'; import { ResizeChecker } from '@kbn/kibana-utils-plugin/public'; import { DrawFilterControl } from './draw_control/draw_filter_control'; import { ScaleControl } from './scale_control'; @@ -92,7 +91,7 @@ export class MbMap extends Component { private _prevDisableInteractive?: boolean; private _prevLayerList?: ILayer[]; private _prevTimeslice?: Timeslice; - private _navigationControl = new mapboxgl.NavigationControl({ showCompass: false }); + private _navigationControl = new maplibregl.NavigationControl({ showCompass: false }); private _tileStatusTracker?: TileStatusTracker; state: State = { @@ -176,13 +175,13 @@ export class MbMap extends Component { async _createMbMapInstance(initialView: MapCenterAndZoom | null): Promise { return new Promise((resolve) => { const mbStyle = { - version: 8, + version: 8 as 8, sources: {}, layers: [], glyphs: getGlyphUrl(), }; - const options: MapboxOptions = { + const options: MapOptions = { attributionControl: false, container: this._containerRef!, style: mbStyle, @@ -200,7 +199,7 @@ export class MbMap extends Component { } else { options.bounds = [-170, -60, 170, 75]; } - const mbMap = new mapboxgl.Map(options); + const mbMap = new maplibregl.Map(options); mbMap.dragRotate.disable(); mbMap.touchZoomRotate.disableRotation(); @@ -329,12 +328,12 @@ export class MbMap extends Component { if (goto.bounds) { // clamping ot -89/89 latitudes since Mapboxgl does not seem to handle bounds that contain the poles (logs errors to the console when using -90/90) - const lnLatBounds = new mapboxgl.LngLatBounds( - new mapboxgl.LngLat( + const lnLatBounds = new maplibregl.LngLatBounds( + new maplibregl.LngLat( clampToLonBounds(goto.bounds.minLon), clampToLatBounds(goto.bounds.minLat) ), - new mapboxgl.LngLat( + new maplibregl.LngLat( clampToLonBounds(goto.bounds.maxLon), clampToLatBounds(goto.bounds.maxLat) ) @@ -418,7 +417,6 @@ export class MbMap extends Component { for (const { symbolId, svg, cutoff, radius } of this.props.customIcons) { createSdfIcon({ svg, renderSize: CUSTOM_ICON_SIZE, cutoff, radius }).then( (imageData: ImageData) => { - // @ts-expect-error MapboxMap type is missing updateImage method if (mbMap.hasImage(symbolId)) mbMap.updateImage(symbolId, imageData); else mbMap.addImage(symbolId, imageData, { diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/sort_layers.test.ts b/x-pack/plugins/maps/public/connected_components/mb_map/sort_layers.test.ts index 74a57bd76ab8f..77ce71472df95 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/sort_layers.test.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/sort_layers.test.ts @@ -8,7 +8,7 @@ /* eslint-disable max-classes-per-file */ import _ from 'lodash'; -import type { Map as MbMap, AnyLayer as MbLayer, Style as MbStyle } from '@kbn/mapbox-gl'; +import type { Map as MbMap, LayerSpecification, StyleSpecification } from '@kbn/mapbox-gl'; import { getIsTextLayer, syncLayerOrder } from './sort_layers'; import { SPATIAL_FILTERS_LAYER_ID } from '../../../common/constants'; import { ILayer } from '../../classes/layers/layer'; @@ -16,9 +16,9 @@ import { ILayer } from '../../classes/layers/layer'; let moveCounter = 0; class MockMbMap { - private _style: MbStyle; + private _style: StyleSpecification; - constructor(style: MbStyle) { + constructor(style: StyleSpecification) { this._style = _.cloneDeep(style); } @@ -88,24 +88,24 @@ test('getIsTextLayer', () => { id: `mylayer_text`, type: 'symbol', paint: { 'text-color': 'red' }, - } as MbLayer; + } as LayerSpecification; expect(getIsTextLayer(paintLabelMbLayer)).toBe(true); const layoutLabelMbLayer = { id: `mylayer_text`, type: 'symbol', layout: { 'text-size': 'red' }, - } as MbLayer; + } as unknown as LayerSpecification; expect(getIsTextLayer(layoutLabelMbLayer)).toBe(true); const iconMbLayer = { id: `mylayer_text`, type: 'symbol', paint: { 'icon-color': 'house' }, - } as MbLayer; + } as LayerSpecification; expect(getIsTextLayer(iconMbLayer)).toBe(false); - const circleMbLayer = { id: `mylayer_text`, type: 'circle' } as MbLayer; + const circleMbLayer = { id: `mylayer_text`, type: 'circle' } as LayerSpecification; expect(getIsTextLayer(circleMbLayer)).toBe(false); }); @@ -128,22 +128,23 @@ describe('sortLayer', () => { // Initial order that styles are added to mapbox is non-deterministic and depends on the order of data fetches. test('Should sort initial layer load order to expected order', () => { const initialMbStyle = { - version: 0, + version: 8 as 8, layers: [ - { id: `${BRAVO_LAYER_ID}_text`, type: 'symbol' } as MbLayer, - { id: `${BRAVO_LAYER_ID}_circle`, type: 'circle' } as MbLayer, - { id: `${SPATIAL_FILTERS_LAYER_ID}_fill`, type: 'fill' } as MbLayer, - { id: `${SPATIAL_FILTERS_LAYER_ID}_circle`, type: 'circle' } as MbLayer, - { id: `gl-draw-polygon-fill-active.cold`, type: 'fill' } as MbLayer, + { id: `${BRAVO_LAYER_ID}_text`, type: 'symbol' } as LayerSpecification, + { id: `${BRAVO_LAYER_ID}_circle`, type: 'circle' } as LayerSpecification, + { id: `${SPATIAL_FILTERS_LAYER_ID}_fill`, type: 'fill' } as LayerSpecification, + { id: `${SPATIAL_FILTERS_LAYER_ID}_circle`, type: 'circle' } as LayerSpecification, + { id: `gl-draw-polygon-fill-active.cold`, type: 'fill' } as LayerSpecification, { id: `${CHARLIE_LAYER_ID}_text`, type: 'symbol', paint: { 'text-color': 'red' }, - } as MbLayer, - { id: `${CHARLIE_LAYER_ID}_fill`, type: 'fill' } as MbLayer, - { id: `${ALPHA_LAYER_ID}_text`, type: 'symbol' } as MbLayer, - { id: `${ALPHA_LAYER_ID}_circle`, type: 'circle' } as MbLayer, + } as LayerSpecification, + { id: `${CHARLIE_LAYER_ID}_fill`, type: 'fill' } as LayerSpecification, + { id: `${ALPHA_LAYER_ID}_text`, type: 'symbol' } as LayerSpecification, + { id: `${ALPHA_LAYER_ID}_circle`, type: 'circle' } as LayerSpecification, ], + sources: {}, }; const mbMap = new MockMbMap(initialMbStyle); syncLayerOrder(mbMap as unknown as MbMap, spatialFilterLayer, mapLayers); @@ -167,21 +168,22 @@ describe('sortLayer', () => { // Test case testing when layer is moved in Table of Contents test('Should sort single layer single move to expected order', () => { const initialMbStyle = { - version: 0, + version: 8 as 8, layers: [ - { id: `${CHARLIE_LAYER_ID}_fill`, type: 'fill' } as MbLayer, - { id: `${ALPHA_LAYER_ID}_text`, type: 'symbol' } as MbLayer, - { id: `${ALPHA_LAYER_ID}_circle`, type: 'circle' } as MbLayer, - { id: `${BRAVO_LAYER_ID}_text`, type: 'symbol' } as MbLayer, - { id: `${BRAVO_LAYER_ID}_circle`, type: 'circle' } as MbLayer, + { id: `${CHARLIE_LAYER_ID}_fill`, type: 'fill' } as LayerSpecification, + { id: `${ALPHA_LAYER_ID}_text`, type: 'symbol' } as LayerSpecification, + { id: `${ALPHA_LAYER_ID}_circle`, type: 'circle' } as LayerSpecification, + { id: `${BRAVO_LAYER_ID}_text`, type: 'symbol' } as LayerSpecification, + { id: `${BRAVO_LAYER_ID}_circle`, type: 'circle' } as LayerSpecification, { id: `${CHARLIE_LAYER_ID}_text`, type: 'symbol', paint: { 'text-color': 'red' }, - } as MbLayer, - { id: `${SPATIAL_FILTERS_LAYER_ID}_fill`, type: 'fill' } as MbLayer, - { id: `${SPATIAL_FILTERS_LAYER_ID}_circle`, type: 'circle' } as MbLayer, + } as LayerSpecification, + { id: `${SPATIAL_FILTERS_LAYER_ID}_fill`, type: 'fill' } as LayerSpecification, + { id: `${SPATIAL_FILTERS_LAYER_ID}_circle`, type: 'circle' } as LayerSpecification, ], + sources: {}, }; const mbMap = new MockMbMap(initialMbStyle); syncLayerOrder(mbMap as unknown as MbMap, spatialFilterLayer, mapLayers); @@ -205,11 +207,12 @@ describe('sortLayer', () => { test('Should sort with missing mblayers to expected order', () => { // Notice there are no bravo mbLayers in initial style. const initialMbStyle = { - version: 0, + version: 8 as 8, layers: [ - { id: `${CHARLIE_LAYER_ID}_fill`, type: 'fill' } as MbLayer, - { id: `${ALPHA_LAYER_ID}_circle`, type: 'circle' } as MbLayer, + { id: `${CHARLIE_LAYER_ID}_fill`, type: 'fill' } as LayerSpecification, + { id: `${ALPHA_LAYER_ID}_circle`, type: 'circle' } as LayerSpecification, ], + sources: {}, }; const mbMap = new MockMbMap(initialMbStyle); syncLayerOrder(mbMap as unknown as MbMap, spatialFilterLayer, mapLayers); @@ -222,21 +225,22 @@ describe('sortLayer', () => { test('Should not call move layers when layers are in expected order', () => { const initialMbStyle = { - version: 0, + version: 8 as 8, layers: [ - { id: `${CHARLIE_LAYER_ID}_fill`, type: 'fill' } as MbLayer, - { id: `${BRAVO_LAYER_ID}_text`, type: 'symbol' } as MbLayer, - { id: `${BRAVO_LAYER_ID}_circle`, type: 'circle' } as MbLayer, - { id: `${ALPHA_LAYER_ID}_text`, type: 'symbol' } as MbLayer, - { id: `${ALPHA_LAYER_ID}_circle`, type: 'circle' } as MbLayer, + { id: `${CHARLIE_LAYER_ID}_fill`, type: 'fill' } as LayerSpecification, + { id: `${BRAVO_LAYER_ID}_text`, type: 'symbol' } as LayerSpecification, + { id: `${BRAVO_LAYER_ID}_circle`, type: 'circle' } as LayerSpecification, + { id: `${ALPHA_LAYER_ID}_text`, type: 'symbol' } as LayerSpecification, + { id: `${ALPHA_LAYER_ID}_circle`, type: 'circle' } as LayerSpecification, { id: `${CHARLIE_LAYER_ID}_text`, type: 'symbol', paint: { 'text-color': 'red' }, - } as MbLayer, - { id: `${SPATIAL_FILTERS_LAYER_ID}_fill`, type: 'fill' } as MbLayer, - { id: `${SPATIAL_FILTERS_LAYER_ID}_circle`, type: 'circle' } as MbLayer, + } as LayerSpecification, + { id: `${SPATIAL_FILTERS_LAYER_ID}_fill`, type: 'fill' } as LayerSpecification, + { id: `${SPATIAL_FILTERS_LAYER_ID}_circle`, type: 'circle' } as LayerSpecification, ], + sources: {}, }; const mbMap = new MockMbMap(initialMbStyle); syncLayerOrder(mbMap as unknown as MbMap, spatialFilterLayer, mapLayers); diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/sort_layers.ts b/x-pack/plugins/maps/public/connected_components/mb_map/sort_layers.ts index ef248380af36a..b7f27755ad9cf 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/sort_layers.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/sort_layers.ts @@ -5,14 +5,14 @@ * 2.0. */ -import type { Map as MbMap, Layer as MbLayer } from '@kbn/mapbox-gl'; +import type { Map as MbMap, LayerSpecification } from '@kbn/mapbox-gl'; import { ILayer } from '../../classes/layers/layer'; // "Layer" is overloaded and can mean the following // 1) Map layer (ILayer): A single map layer consists of one to many mapbox layers. -// 2) Mapbox layer (MbLayer): Individual unit of rendering such as text, circles, polygons, or lines. +// 2) Mapbox layer (LayerSpecification): Individual unit of rendering such as text, circles, polygons, or lines. -export function getIsTextLayer(mbLayer: MbLayer) { +export function getIsTextLayer(mbLayer: LayerSpecification) { if (mbLayer.type !== 'symbol') { return false; } @@ -35,7 +35,7 @@ export function isGlDrawLayer(mbLayerId: string) { function doesMbLayerBelongToMapLayerAndClass( mapLayer: ILayer, - mbLayer: MbLayer, + mbLayer: LayerSpecification, layerClass: LAYER_CLASS ) { if (!mapLayer.ownsMbLayerId(mbLayer.id)) { @@ -58,7 +58,7 @@ enum LAYER_CLASS { function moveMapLayer( mbMap: MbMap, - mbLayers: MbLayer[], + mbLayers: LayerSpecification[], mapLayer: ILayer, layerClass: LAYER_CLASS, beneathMbLayerId?: string @@ -72,7 +72,11 @@ function moveMapLayer( }); } -function getBottomMbLayerId(mbLayers: MbLayer[], mapLayer: ILayer, layerClass: LAYER_CLASS) { +function getBottomMbLayerId( + mbLayers: LayerSpecification[], + mapLayer: ILayer, + layerClass: LAYER_CLASS +) { const bottomMbLayer = mbLayers.find((mbLayer) => { return doesMbLayerBelongToMapLayerAndClass(mapLayer, mbLayer, layerClass); }); diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/tile_status_tracker.test.ts b/x-pack/plugins/maps/public/connected_components/mb_map/tile_status_tracker.test.ts index ffc6459262c8b..6485582149db7 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/tile_status_tracker.test.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/tile_status_tracker.test.ts @@ -113,7 +113,7 @@ describe('TileStatusTracker', () => { expect(loadedMap.get('foo')).toBe(true); expect(loadedMap.get('bar')).toBe(false); // still outstanding tile requests - expect(loadedMap.has('foobar')).toBe(true); // never received tile requests + expect(loadedMap.has('foobar')).toBe(false); // never received tile requests, status should not have been reported for layer (aa11BarTile as { tile: { aborted: boolean } })!.tile.aborted = true; // abort tile mockMbMap.emit('sourcedataloading', createMockMbDataEvent('barsource', 'af1d')); @@ -125,7 +125,7 @@ describe('TileStatusTracker', () => { expect(loadedMap.get('foo')).toBe(false); // still outstanding tile requests expect(loadedMap.get('bar')).toBe(true); // tiles were aborted or errored - expect(loadedMap.has('foobar')).toBe(true); // never received tile requests + expect(loadedMap.has('foobar')).toBe(false); // never received tile requests, status should not have been reported for layer }); test('should cleanup listeners on destroy', async () => { diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/tile_status_tracker.ts b/x-pack/plugins/maps/public/connected_components/mb_map/tile_status_tracker.ts index 94a4344bac009..c349ef0ede3b6 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/tile_status_tracker.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/tile_status_tracker.ts @@ -29,8 +29,21 @@ interface Tile { } export class TileStatusTracker { - private _tileCache: Tile[]; - private _tileErrorCache: Record; + // Tile cache tracks active tile requests + // 'sourcedataloading' event adds tile request to cache + // 'sourcedata' and 'error' events remove tile request from cache + // Tile requests with 'aborted' status are removed from cache when reporting 'areTilesLoaded' status + private _tileCache: Tile[] = []; + + // Tile error cache tracks tile request errors per layer + // Error cache is cleared when map center tile changes + private _tileErrorCache: Record = {}; + + // Layer cache tracks layers that have requested one or more tiles + // Layer cache is used so that only a layer that has requested one or more tiles reports 'areTilesLoaded' status + // layer cache is never cleared + private _layerCache: Map = new Map(); + private _prevCenterTileKey?: string; private readonly _mbMap: MapboxMap; private readonly _updateTileStatus: ( @@ -48,6 +61,14 @@ export class TileStatusTracker { e.tile && (e.source.type === 'vector' || e.source.type === 'raster') ) { + const targetLayer = this._getCurrentLayerList().find((layer) => { + return layer.ownsMbSourceId(e.sourceId); + }); + const layerId = targetLayer ? targetLayer.getId() : undefined; + if (layerId && !this._layerCache.has(layerId)) { + this._layerCache.set(layerId, true); + } + const tracked = this._tileCache.find((tile) => { return ( tile.mbKey === (e.tile.tileID.key as unknown as string) && tile.mbSourceId === e.sourceId @@ -127,8 +148,6 @@ export class TileStatusTracker { updateTileStatus: (layer: ILayer, areTilesLoaded: boolean, errorMessage?: string) => void; getCurrentLayerList: () => ILayer[]; }) { - this._tileCache = []; - this._tileErrorCache = {}; this._updateTileStatus = updateTileStatus; this._getCurrentLayerList = getCurrentLayerList; @@ -146,6 +165,12 @@ export class TileStatusTracker { const layerList = this._getCurrentLayerList(); for (let i = 0; i < layerList.length; i++) { const layer: ILayer = layerList[i]; + + if (!this._layerCache.has(layer.getId())) { + // do not report status for layers that have not started loading tiles. + continue; + } + let atLeastOnePendingTile = false; for (let j = 0; j < this._tileCache.length; j++) { const tile = this._tileCache[j]; diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.tsx index a018fe0a4a200..eafa2c66b6d50 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.tsx @@ -15,12 +15,12 @@ import sinon from 'sinon'; import React from 'react'; import { mount, shallow } from 'enzyme'; import { Feature } from 'geojson'; -import type { Map as MbMap, MapMouseEvent, MapboxGeoJSONFeature } from '@kbn/mapbox-gl'; +import type { Map as MbMap, MapMouseEvent, MapGeoJSONFeature } from '@kbn/mapbox-gl'; import { TooltipControl } from './tooltip_control'; import { IVectorLayer } from '../../../classes/layers/vector_layer'; // mutable map state -let featuresAtLocation: MapboxGeoJSONFeature[] = []; +let featuresAtLocation: MapGeoJSONFeature[] = []; const layerId = 'tfi3f'; const mbLayerId = 'tfi3f_circle'; @@ -254,7 +254,7 @@ describe('TooltipControl', () => { properties: { __kbn__feature_id__: 1, }, - } as unknown as MapboxGeoJSONFeature; + } as unknown as MapGeoJSONFeature; featuresAtLocation = [feature, feature]; mount( { } _getTooltipFeatures( - mbFeatures: MapboxGeoJSONFeature[], + mbFeatures: MapGeoJSONFeature[], isLocked: boolean, tooltipId: string ): TooltipFeature[] { @@ -340,7 +341,7 @@ export class TooltipControl extends Component { }); } - _getMbFeaturesUnderPointer(mbLngLatPoint: MbPoint) { + _getMbFeaturesUnderPointer(mbLngLatPoint: Point2D) { if (!this.props.mbMap) { return []; } @@ -356,7 +357,7 @@ export class TooltipControl extends Component { x: mbLngLatPoint.x + PADDING, y: mbLngLatPoint.y + PADDING, }, - ] as [MbPoint, MbPoint]; + ] as [PointLike, PointLike]; return this.props.mbMap.queryRenderedFeatures(mbBbox, { layers: mbLayerIds, }); diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/utils.ts b/x-pack/plugins/maps/public/connected_components/mb_map/utils.ts index a79c1a1f71b76..552a618e11f7e 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/utils.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/utils.ts @@ -9,7 +9,7 @@ import type { Map as MbMap } from '@kbn/mapbox-gl'; import { TileMetaFeature } from '../../../common/descriptor_types'; import { isGlDrawLayer } from './sort_layers'; import { ILayer } from '../../classes/layers/layer'; -import { ES_MVT_META_LAYER_NAME } from '../../classes/layers/vector_layer/mvt_vector_layer/mvt_vector_layer'; +import { ES_MVT_META_LAYER_NAME } from '../../classes/util/tile_meta_feature_utils'; export function removeOrphanedSourcesAndLayers( mbMap: MbMap, @@ -66,6 +66,7 @@ export function getTileMetaFeatures(mbMap: MbMap, mbSourceId: string): TileMetaF // Tile meta will never have duplicated features since by there nature, tile meta is a feature contained within a single tile const mbFeatures = mbMap.querySourceFeatures(mbSourceId, { sourceLayer: ES_MVT_META_LAYER_NAME, + filter: [], }); return mbFeatures diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/__snapshots__/toc_entry.test.tsx.snap b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/__snapshots__/toc_entry.test.tsx.snap index 5beaf12029d2f..cec85cb0e1cd6 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/__snapshots__/toc_entry.test.tsx.snap +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/__snapshots__/toc_entry.test.tsx.snap @@ -11,7 +11,6 @@ exports[`TOCEntry is rendered 1`] = ` > {}, showTOCDetails: () => {}, - editModeActiveForLayer: false, + isFeatureEditorOpenForLayer: false, cancelEditing: () => {}, }; diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx index aeba28cf033bd..65431432d8c6d 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx @@ -31,7 +31,7 @@ export interface ReduxStateProps { hasDirtyStateSelector: boolean; isLegendDetailsOpen: boolean; isEditButtonDisabled: boolean; - editModeActiveForLayer: boolean; + isFeatureEditorOpenForLayer: boolean; } export interface ReduxDispatchProps { @@ -282,7 +282,6 @@ export class TOCEntry extends Component { openLayerSettings={this._openLayerPanelWithCheck} isEditButtonDisabled={this.props.isEditButtonDisabled} supportsFitToBounds={this.state.supportsFitToBounds} - editModeActiveForLayer={this.props.editModeActiveForLayer} /> {this._renderQuickActions()} @@ -317,7 +316,7 @@ export class TOCEntry extends Component { 'mapTocEntry-isSelected': this.props.layer.isPreviewLayer() || (this.props.selectedLayer && this.props.selectedLayer.getId() === this.props.layer.getId()), - 'mapTocEntry-isInEditingMode': this.props.editModeActiveForLayer, + 'mapTocEntry-isInEditingMode': this.props.isFeatureEditorOpenForLayer, }); return ( @@ -334,7 +333,7 @@ export class TOCEntry extends Component { {this._renderCancelModal()} - {this.props.editModeActiveForLayer && ( + {this.props.isFeatureEditorOpenForLayer && (
diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.test.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.test.tsx index ae62b75400769..cb2697663766a 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.test.tsx @@ -48,7 +48,6 @@ const defaultProps = { enableShapeEditing: () => {}, enablePointEditing: () => {}, openLayerSettings: () => {}, - editModeActiveForLayer: false, numLayers: 2, showThisLayerOnly: () => {}, }; @@ -105,9 +104,7 @@ describe('TOCEntryActionsPopover', () => { }); test('should disable Edit features when edit mode active for layer', async () => { - const component = shallow( - - ); + const component = shallow(); // Ensure all promises resolve await new Promise((resolve) => process.nextTick(resolve)); diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx index 3f3b7558409f8..5e33931a8943e 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx @@ -36,7 +36,6 @@ export interface Props { showThisLayerOnly: (layerId: string) => void; supportsFitToBounds: boolean; toggleVisible: (layerId: string) => void; - editModeActiveForLayer: boolean; numLayers: number; } @@ -90,9 +89,7 @@ export class TOCEntryActionsPopover extends Component { } if ( - (source as ESSearchSource).getApplyGlobalQuery() || (source as ESSearchSource).getSyncMeta().scalingType === SCALING_TYPES.CLUSTERS || - (await vectorLayer.isFilteredByGlobalTime()) || vectorLayer.isPreviewLayer() || !vectorLayer.isVisible() || vectorLayer.hasJoins() @@ -194,9 +191,9 @@ export class TOCEntryActionsPopover extends Component { ? null : i18n.translate('xpack.maps.layerTocActions.editFeaturesTooltip.disabledMessage', { defaultMessage: - 'Edit features only supported for document layers without clustering, term joins, time filtering, or global search.', + 'Edit features is only supported for layers without clustering and term joins', }), - disabled: !this.state.isFeatureEditingEnabled || this.props.editModeActiveForLayer, + disabled: !this.state.isFeatureEditingEnabled, onClick: async () => { this._closePopover(); const supportedShapeTypes = await ( diff --git a/x-pack/plugins/maps/public/kibana_services.ts b/x-pack/plugins/maps/public/kibana_services.ts index ebebf4b3ba7fc..22857c623c18a 100644 --- a/x-pack/plugins/maps/public/kibana_services.ts +++ b/x-pack/plugins/maps/public/kibana_services.ts @@ -32,7 +32,7 @@ export const getIsCloud = () => isCloudEnabled; export const getIndexNameFormComponent = () => pluginsStart.fileUpload.IndexNameFormComponent; export const getFileUploadComponent = () => pluginsStart.fileUpload.FileUploadComponent; export const getIndexPatternService = () => pluginsStart.data.indexPatterns; -export const getAutocompleteService = () => pluginsStart.data.autocomplete; +export const getAutocompleteService = () => pluginsStart.unifiedSearch.autocomplete; export const getInspector = () => pluginsStart.inspector; export const getFileUpload = () => pluginsStart.fileUpload; export const getUiSettings = () => coreStart.uiSettings; diff --git a/x-pack/plugins/maps/server/data_indexing/indexing_routes.ts b/x-pack/plugins/maps/server/data_indexing/indexing_routes.ts index c08bdc8b0d7ea..7f2eacc257fc5 100644 --- a/x-pack/plugins/maps/server/data_indexing/indexing_routes.ts +++ b/x-pack/plugins/maps/server/data_indexing/indexing_routes.ts @@ -49,16 +49,17 @@ export function initIndexingRoutes({ }, }, async (context, request, response) => { + const coreContext = await context.core; const { index, mappings } = request.body; const indexPatternsService = await dataPlugin.indexPatterns.indexPatternsServiceFactory( - context.core.savedObjects.client, - context.core.elasticsearch.client.asCurrentUser, + coreContext.savedObjects.client, + coreContext.elasticsearch.client.asCurrentUser, request ); const result = await createDocSource( index, mappings, - context.core.elasticsearch.client, + coreContext.elasticsearch.client, indexPatternsService ); if (result.success) { @@ -92,10 +93,11 @@ export function initIndexingRoutes({ }, }, async (context, request, response) => { + const coreContext = await context.core; const result = await writeDataToIndex( request.body.index, request.body.data, - context.core.elasticsearch.client.asCurrentUser + coreContext.elasticsearch.client.asCurrentUser ); if (result.success) { return response.ok({ body: result }); @@ -123,7 +125,8 @@ export function initIndexingRoutes({ }, async (context, request, response) => { try { - const resp = await context.core.elasticsearch.client.asCurrentUser.delete({ + const coreContext = await context.core; + const resp = await coreContext.elasticsearch.client.asCurrentUser.delete({ index: request.body.index, id: request.params.featureId, refresh: true, @@ -173,9 +176,10 @@ export function initIndexingRoutes({ }, }, async (context, request, response) => { + const coreContext = await context.core; return await getMatchingIndexes( request.query.indexPattern, - context.core.elasticsearch.client, + coreContext.elasticsearch.client, response, logger ); @@ -194,8 +198,9 @@ export function initIndexingRoutes({ async (context, request, response) => { const { index } = request.query; try { + const coreContext = await context.core; const mappingsResp = - await context.core.elasticsearch.client.asCurrentUser.indices.getMapping({ + await coreContext.elasticsearch.client.asCurrentUser.indices.getMapping({ index: request.query.index, }); const isDrawingIndex = diff --git a/x-pack/plugins/maps/server/mvt/get_grid_tile.ts b/x-pack/plugins/maps/server/mvt/get_grid_tile.ts index e88a0f0314931..eb0ddc9e13143 100644 --- a/x-pack/plugins/maps/server/mvt/get_grid_tile.ts +++ b/x-pack/plugins/maps/server/mvt/get_grid_tile.ts @@ -57,13 +57,14 @@ export async function getEsGridTile({ runtime_mappings: requestBody.runtime_mappings, }; + const esClient = (await context.core).elasticsearch.client; const tile = await core.executionContext.withContext( makeExecutionContext({ description: 'mvt:get_grid_tile', url, }), async () => { - return await context.core.elasticsearch.client.asCurrentUser.transport.request( + return await esClient.asCurrentUser.transport.request( { method: 'GET', path, diff --git a/x-pack/plugins/maps/server/mvt/get_tile.ts b/x-pack/plugins/maps/server/mvt/get_tile.ts index b4ae9e6b698d6..340a71128b43a 100644 --- a/x-pack/plugins/maps/server/mvt/get_tile.ts +++ b/x-pack/plugins/maps/server/mvt/get_tile.ts @@ -57,13 +57,14 @@ export async function getEsTile({ track_total_hits: requestBody.size + 1, }; + const esClient = (await context.core).elasticsearch.client; const tile = await core.executionContext.withContext( makeExecutionContext({ description: 'mvt:get_tile', url, }), async () => { - return await context.core.elasticsearch.client.asCurrentUser.transport.request( + return await esClient.asCurrentUser.transport.request( { method: 'GET', path, diff --git a/x-pack/plugins/maps/server/routes.ts b/x-pack/plugins/maps/server/routes.ts index d74deec8eab67..427f403927d5d 100644 --- a/x-pack/plugins/maps/server/routes.ts +++ b/x-pack/plugins/maps/server/routes.ts @@ -73,7 +73,8 @@ export async function initRoutes(coreSetup: CoreSetup, logger: Logger): Promise< } try { - const resp = await context.core.elasticsearch.client.asCurrentUser.indices.getSettings({ + const coreContext = await context.core; + const resp = await coreContext.elasticsearch.client.asCurrentUser.indices.getSettings({ index: query.indexPatternTitle, }); const indexPatternSettings = getIndexPatternSettings( diff --git a/x-pack/plugins/ml/common/constants/trained_models.ts b/x-pack/plugins/ml/common/constants/trained_models.ts index 79fe65936b231..75ea25dcc9efa 100644 --- a/x-pack/plugins/ml/common/constants/trained_models.ts +++ b/x-pack/plugins/ml/common/constants/trained_models.ts @@ -22,10 +22,10 @@ export type TrainedModelType = typeof TRAINED_MODEL_TYPE[keyof typeof TRAINED_MO export const SUPPORTED_PYTORCH_TASKS = { NER: 'ner', - // ZERO_SHOT_CLASSIFICATION: 'zero_shot_classification', - // CLASSIFICATION_LABELS: 'classification_labels', - // TEXT_CLASSIFICATION: 'text_classification', - // TEXT_EMBEDDING: 'text_embedding', + ZERO_SHOT_CLASSIFICATION: 'zero_shot_classification', + TEXT_CLASSIFICATION: 'text_classification', + TEXT_EMBEDDING: 'text_embedding', + FILL_MASK: 'fill_mask', } as const; export type SupportedPytorchTasksType = typeof SUPPORTED_PYTORCH_TASKS[keyof typeof SUPPORTED_PYTORCH_TASKS]; diff --git a/x-pack/plugins/ml/common/openapi/README.md b/x-pack/plugins/ml/common/openapi/README.md new file mode 100644 index 0000000000000..28246e8b43d3c --- /dev/null +++ b/x-pack/plugins/ml/common/openapi/README.md @@ -0,0 +1,20 @@ +# OpenAPI (Experimental) + +The current self-contained spec file can be used for online tools like those found at https://openapi.tools/. This spec is experimental and may be incomplete or change later. + +A guide about the openApi specification can be found at [https://swagger.io/docs/specification/about/](https://swagger.io/docs/specification/about/). + + ## Tools + +It is possible to validate the docs before bundling them by running the following command in the `x-pack/plugins/ml/common/openapi/` folder: + ``` + npx swagger-cli validate ml_apis.yaml + ``` + +Then generate the `bundled` files with the following commands: + + ``` + npx @redocly/openapi-cli bundle --ext yaml --output bundled.yaml ml_apis.yaml + npx @redocly/openapi-cli bundle --ext json --output bundled.json ml_apis.yaml + ``` + diff --git a/x-pack/plugins/ml/common/openapi/bundled.json b/x-pack/plugins/ml/common/openapi/bundled.json new file mode 100644 index 0000000000000..455bf02bbd232 --- /dev/null +++ b/x-pack/plugins/ml/common/openapi/bundled.json @@ -0,0 +1,225 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "Machine learning APIs", + "description": "Kibana APIs for the machine learning feature", + "version": "1.0.0", + "license": { + "name": "Elastic License 2.0", + "url": "https://www.elastic.co/licensing/elastic-license" + } + }, + "tags": [ + { + "name": "ml", + "description": "Machine learning" + } + ], + "servers": [ + { + "url": "https://localhost:5601/" + } + ], + "paths": { + "/s/{spaceId}/api/ml/saved_objects/sync": { + "get": { + "description": "Synchronizes Kibana saved objects for machine learning jobs and trained models. You must have `all` privileges for the **Machine Learning** feature in the **Analytics** section of the Kibana feature privileges. This API runs automatically when you start Kibana and periodically thereafter.\n", + "parameters": [ + { + "$ref": "#/components/parameters/spaceParam" + }, + { + "$ref": "#/components/parameters/simulateParam" + } + ], + "responses": { + "200": { + "description": "Indicates a successful call", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/syncResponse" + } + } + } + } + } + } + } + }, + "/api/ml/saved_objects/sync": { + "get": { + "description": "Synchronizes Kibana saved objects for machine learning jobs and trained models. You must have `all` privileges for the **Machine Learning** feature in the **Analytics** section of the Kibana feature privileges. This API runs automatically when you start Kibana and periodically thereafter.\n", + "parameters": [ + { + "$ref": "#/components/parameters/simulateParam" + } + ], + "responses": { + "200": { + "description": "Indicates a successful call", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/syncResponse" + } + } + } + } + } + } + } + } + }, + "components": { + "parameters": { + "spaceParam": { + "in": "path", + "name": "spaceId", + "description": "An identifier for the space.", + "required": true, + "schema": { + "type": "string" + } + }, + "simulateParam": { + "in": "query", + "name": "simulate", + "description": "When true, simulates the synchronization by returning only the list actions that would be performed.", + "required": false, + "schema": { + "type": "boolean" + }, + "example": "true" + } + }, + "securitySchemes": { + "basicAuth": { + "type": "http", + "scheme": "basic" + } + }, + "schemas": { + "syncResponse": { + "type": "object", + "properties": { + "datafeedsAdded": { + "type": "object", + "description": "If a saved object for an anomaly detection job is missing a datafeed identifier, it is added. This list contains the datafeed identifiers and indicates whether the synchronization was successful.", + "additionalProperties": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + } + } + } + }, + "datafeedsRemoved": { + "type": "object", + "description": "If a saved object for an anomaly detection job references a datafeed that no longer exists, it is deleted. This list contains the datafeed identifiers and indicates whether the synchronization was successful.", + "additionalProperties": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + } + } + } + }, + "savedObjectsCreated": { + "type": "object", + "description": "If saved objects are missing for machine learning jobs or trained models, they are created. This list contains the job and model identifiers and indicates whether the synchronization was successful.", + "properties": { + "anomaly-detector": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "example": true + } + } + } + }, + "data-frame-analytics": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "example": true + } + } + } + }, + "trained-model": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "example": true + } + } + } + } + } + }, + "savedObjectsDeleted": { + "type": "object", + "description": "If saved objects exist for machine learning jobs or trained models that no longer exist, they are deleted. This list contains the job and model identifiers and indicates whether the synchronization was successful.", + "properties": { + "anomaly-detector": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "example": true + } + } + } + }, + "data-frame-analytics": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "example": true + } + } + } + }, + "trained-model": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "example": true + } + } + } + } + } + } + } + } + } + }, + "security": [ + { + "basicAuth": [] + } + ] +} \ No newline at end of file diff --git a/x-pack/plugins/ml/common/openapi/bundled.yaml b/x-pack/plugins/ml/common/openapi/bundled.yaml new file mode 100644 index 0000000000000..235979ff1651c --- /dev/null +++ b/x-pack/plugins/ml/common/openapi/bundled.yaml @@ -0,0 +1,167 @@ +openapi: 3.0.1 +info: + title: Machine learning APIs + description: Kibana APIs for the machine learning feature + version: 1.0.0 + license: + name: Elastic License 2.0 + url: https://www.elastic.co/licensing/elastic-license +tags: + - name: ml + description: Machine learning +servers: + - url: https://localhost:5601/ +paths: + /s/{spaceId}/api/ml/saved_objects/sync: + get: + description: > + Synchronizes Kibana saved objects for machine learning jobs and trained + models. You must have `all` privileges for the **Machine Learning** + feature in the **Analytics** section of the Kibana feature privileges. + This API runs automatically when you start Kibana and periodically + thereafter. + parameters: + - $ref: '#/components/parameters/spaceParam' + - $ref: '#/components/parameters/simulateParam' + responses: + '200': + description: Indicates a successful call + content: + application/json: + schema: + items: + $ref: '#/components/schemas/syncResponse' + /api/ml/saved_objects/sync: + get: + description: > + Synchronizes Kibana saved objects for machine learning jobs and trained + models. You must have `all` privileges for the **Machine Learning** + feature in the **Analytics** section of the Kibana feature privileges. + This API runs automatically when you start Kibana and periodically + thereafter. + parameters: + - $ref: '#/components/parameters/simulateParam' + responses: + '200': + description: Indicates a successful call + content: + application/json: + schema: + items: + $ref: '#/components/schemas/syncResponse' +components: + parameters: + spaceParam: + in: path + name: spaceId + description: An identifier for the space. + required: true + schema: + type: string + simulateParam: + in: query + name: simulate + description: >- + When true, simulates the synchronization by returning only the list + actions that would be performed. + required: false + schema: + type: boolean + example: 'true' + securitySchemes: + basicAuth: + type: http + scheme: basic + schemas: + syncResponse: + type: object + properties: + datafeedsAdded: + type: object + description: >- + If a saved object for an anomaly detection job is missing a datafeed + identifier, it is added. This list contains the datafeed identifiers + and indicates whether the synchronization was successful. + additionalProperties: + type: object + properties: + success: + type: boolean + datafeedsRemoved: + type: object + description: >- + If a saved object for an anomaly detection job references a datafeed + that no longer exists, it is deleted. This list contains the + datafeed identifiers and indicates whether the synchronization was + successful. + additionalProperties: + type: object + properties: + success: + type: boolean + savedObjectsCreated: + type: object + description: >- + If saved objects are missing for machine learning jobs or trained + models, they are created. This list contains the job and model + identifiers and indicates whether the synchronization was + successful. + properties: + anomaly-detector: + type: object + additionalProperties: + type: object + properties: + success: + type: boolean + example: true + data-frame-analytics: + type: object + additionalProperties: + type: object + properties: + success: + type: boolean + example: true + trained-model: + type: object + additionalProperties: + type: object + properties: + success: + type: boolean + example: true + savedObjectsDeleted: + type: object + description: >- + If saved objects exist for machine learning jobs or trained models + that no longer exist, they are deleted. This list contains the job + and model identifiers and indicates whether the synchronization was + successful. + properties: + anomaly-detector: + type: object + additionalProperties: + type: object + properties: + success: + type: boolean + example: true + data-frame-analytics: + type: object + additionalProperties: + type: object + properties: + success: + type: boolean + example: true + trained-model: + type: object + additionalProperties: + type: object + properties: + success: + type: boolean + example: true +security: + - basicAuth: [] diff --git a/x-pack/plugins/ml/common/openapi/ml_apis.yaml b/x-pack/plugins/ml/common/openapi/ml_apis.yaml new file mode 100644 index 0000000000000..827aa1075960d --- /dev/null +++ b/x-pack/plugins/ml/common/openapi/ml_apis.yaml @@ -0,0 +1,146 @@ +openapi: 3.0.1 +info: + title: Machine learning APIs + description: Kibana APIs for the machine learning feature + version: "1.0.0" + license: + name: Elastic License 2.0 + url: https://www.elastic.co/licensing/elastic-license +tags: + - name: ml + description: Machine learning +servers: + - url: https://localhost:5601/ +paths: + /s/{spaceId}/api/ml/saved_objects/sync: + get: + description: > + Synchronizes Kibana saved objects for machine learning jobs and trained models. + You must have `all` privileges for the **Machine Learning** feature in the **Analytics** section of the Kibana feature privileges. + This API runs automatically when you start Kibana and periodically thereafter. + parameters: + - $ref: '#/components/parameters/spaceParam' + - $ref: '#/components/parameters/simulateParam' + responses: + '200': + description: Indicates a successful call + content: + application/json: + schema: + items: + $ref: '#/components/schemas/syncResponse' + /api/ml/saved_objects/sync: + get: + description: > + Synchronizes Kibana saved objects for machine learning jobs and trained models. + You must have `all` privileges for the **Machine Learning** feature in the **Analytics** section of the Kibana feature privileges. + This API runs automatically when you start Kibana and periodically thereafter. + parameters: + - $ref: '#/components/parameters/simulateParam' + responses: + '200': + description: Indicates a successful call + content: + application/json: + schema: + items: + $ref: '#/components/schemas/syncResponse' +components: + parameters: + spaceParam: + in: path + name: spaceId + description: An identifier for the space. + required: true + schema: + type: string + simulateParam: + in: query + name: simulate + description: When true, simulates the synchronization by returning only the list actions that would be performed. + required: false + schema: + type: boolean + example: 'true' + securitySchemes: + basicAuth: + type: http + scheme: basic + schemas: + syncResponse: + type: object + properties: + datafeedsAdded: + type: object + description: If a saved object for an anomaly detection job is missing a datafeed identifier, it is added. This list contains the datafeed identifiers and indicates whether the synchronization was successful. + additionalProperties: + type: object + properties: + success: + type: boolean + datafeedsRemoved: + type: object + description: If a saved object for an anomaly detection job references a datafeed that no longer exists, it is deleted. This list contains the datafeed identifiers and indicates whether the synchronization was successful. + additionalProperties: + type: object + properties: + success: + type: boolean + savedObjectsCreated: + type: object + description: If saved objects are missing for machine learning jobs or trained models, they are created. This list contains the job and model identifiers and indicates whether the synchronization was successful. + properties: + anomaly-detector: + type: object + additionalProperties: + type: object + properties: + success: + type: boolean + example: true + data-frame-analytics: + type: object + additionalProperties: + type: object + properties: + success: + type: boolean + example: true + trained-model: + type: object + additionalProperties: + type: object + properties: + success: + type: boolean + example: true + savedObjectsDeleted: + type: object + description: If saved objects exist for machine learning jobs or trained models that no longer exist, they are deleted. This list contains the job and model identifiers and indicates whether the synchronization was successful. + properties: + anomaly-detector: + type: object + additionalProperties: + type: object + properties: + success: + type: boolean + example: true + data-frame-analytics: + type: object + additionalProperties: + type: object + properties: + success: + type: boolean + example: true + trained-model: + type: object + additionalProperties: + type: object + properties: + success: + type: boolean + example: true +security: + - basicAuth: [] \ No newline at end of file diff --git a/x-pack/plugins/ml/common/util/errors/errors.test.ts b/x-pack/plugins/ml/common/util/errors/errors.test.ts index 625374857c7ce..e299c67d882f4 100644 --- a/x-pack/plugins/ml/common/util/errors/errors.test.ts +++ b/x-pack/plugins/ml/common/util/errors/errors.test.ts @@ -7,7 +7,7 @@ import Boom from '@hapi/boom'; -import { extractErrorMessage, MLHttpFetchError, MLResponseError, EsErrorBody } from '.'; +import { extractErrorMessage, MLHttpFetchError, EsErrorBody } from '.'; describe('ML - error message utils', () => { describe('extractErrorMessage', () => { @@ -39,7 +39,7 @@ describe('ML - error message utils', () => { expect(extractErrorMessage(stringMessage)).toBe(testMsg); // kibana error without attributes - const bodyWithoutAttributes: MLHttpFetchError = { + const bodyWithoutAttributes: MLHttpFetchError = { name: 'name', req: {} as Request, request: {} as Request, @@ -53,7 +53,7 @@ describe('ML - error message utils', () => { expect(extractErrorMessage(bodyWithoutAttributes)).toBe(testMsg); // kibana error with attributes - const bodyWithAttributes: MLHttpFetchError = { + const bodyWithAttributes: MLHttpFetchError = { name: 'name', req: {} as Request, request: {} as Request, diff --git a/x-pack/plugins/ml/common/util/errors/types.ts b/x-pack/plugins/ml/common/util/errors/types.ts index d1f0d3216f42e..fafbeeb4c1a12 100644 --- a/x-pack/plugins/ml/common/util/errors/types.ts +++ b/x-pack/plugins/ml/common/util/errors/types.ts @@ -45,16 +45,13 @@ export interface MLErrorObject { fullError?: EsErrorBody; } -export interface MLHttpFetchError extends HttpFetchError { +export interface MLHttpFetchErrorBase extends HttpFetchError { body: T; } -export type ErrorType = - | MLHttpFetchError - | EsErrorBody - | Boom.Boom - | string - | undefined; +export type MLHttpFetchError = MLHttpFetchErrorBase; + +export type ErrorType = MLHttpFetchError | EsErrorBody | Boom.Boom | string | undefined; export function isEsErrorBody(error: any): error is EsErrorBody { return error && error.error?.reason !== undefined; diff --git a/x-pack/plugins/ml/kibana.json b/x-pack/plugins/ml/kibana.json index 4218eea4ca72f..eb00ca117f01a 100644 --- a/x-pack/plugins/ml/kibana.json +++ b/x-pack/plugins/ml/kibana.json @@ -19,7 +19,8 @@ "share", "taskManager", "triggersActionsUi", - "uiActions" + "uiActions", + "unifiedSearch" ], "optionalPlugins": [ "alerting", diff --git a/x-pack/plugins/ml/public/application/app.tsx b/x-pack/plugins/ml/public/application/app.tsx index c4ec667e43592..833a4fade128b 100644 --- a/x-pack/plugins/ml/public/application/app.tsx +++ b/x-pack/plugins/ml/public/application/app.tsx @@ -119,7 +119,7 @@ export const renderApp = ( setDependencyCache({ timefilter: deps.data.query.timefilter, fieldFormats: deps.fieldFormats, - autocomplete: deps.data.autocomplete, + autocomplete: deps.unifiedSearch.autocomplete, config: coreStart.uiSettings!, chrome: coreStart.chrome!, docLinks: coreStart.docLinks!, diff --git a/x-pack/plugins/ml/public/application/components/anomalies_table/links_menu.tsx b/x-pack/plugins/ml/public/application/components/anomalies_table/links_menu.tsx index 1cc63a2688bf5..cb299ee9dba33 100644 --- a/x-pack/plugins/ml/public/application/components/anomalies_table/links_menu.tsx +++ b/x-pack/plugins/ml/public/application/components/anomalies_table/links_menu.tsx @@ -639,8 +639,8 @@ export const LinksMenuUI = (props: LinksMenuProps) => { return ( ); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/use_saved_search.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/use_saved_search.ts index c4611a1740913..0a75c6467f9d0 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/use_saved_search.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/use_saved_search.ts @@ -7,12 +7,12 @@ import { useState, useEffect } from 'react'; import { + buildEsQuery, + buildQueryFromFilters, decorateQuery, fromKueryExpression, - luceneStringToDsl, toElasticsearchQuery, } from '@kbn/es-query'; -import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { useMlContext } from '../../../../../contexts/ml'; import { SEARCH_QUERY_LANGUAGE } from '../../../../../../../common/constants/search'; import { getQueryFromSavedSearchObject } from '../../../../../util/index_utils'; @@ -36,19 +36,42 @@ export function useSavedSearch() { const { currentSavedSearch, currentDataView, kibanaConfig } = mlContext; const getQueryData = () => { - let qry: estypes.QueryDslQueryContainer = {}; + let qry: any = {}; let qryString; if (currentSavedSearch !== null) { - const { query } = getQueryFromSavedSearchObject(currentSavedSearch); + const { query, filter } = getQueryFromSavedSearchObject(currentSavedSearch); const queryLanguage = query.language; qryString = query.query; if (queryLanguage === SEARCH_QUERY_LANGUAGE.KUERY) { const ast = fromKueryExpression(qryString); qry = toElasticsearchQuery(ast, currentDataView); + const filterQuery = buildQueryFromFilters(filter, currentDataView); + if (qry.bool === undefined) { + qry.bool = {}; + // toElasticsearchQuery may add a single match_all item to the + // root of its returned query, rather than putting it inside + // a bool.should + // in this case, move it to a bool.should + if (qry.match_all !== undefined) { + qry.bool.should = { + match_all: qry.match_all, + }; + delete qry.match_all; + } + } + + if (Array.isArray(qry.bool.filter) === false) { + qry.bool.filter = qry.bool.filter === undefined ? [] : [qry.bool.filter]; + } + if (Array.isArray(qry.bool.must_not) === false) { + qry.bool.must_not = qry.bool.must_not === undefined ? [] : [qry.bool.must_not]; + } + qry.bool.filter = [...qry.bool.filter, ...filterQuery.filter]; + qry.bool.must_not = [...qry.bool.must_not, ...filterQuery.must_not]; } else { - qry = luceneStringToDsl(qryString); + qry = buildEsQuery(currentDataView, [query], filter); decorateQuery(qry, kibanaConfig.get('query:queryString:options')); } diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/page.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/page.tsx index c35ad5bacf371..524556e12a9af 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/page.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/page.tsx @@ -108,7 +108,7 @@ export const Page: FC<{ /> ) : null} {jobIdToUse !== undefined && ( - + { <> {isIdSelectorFlyoutVisible ? ( { ) : null} {jobId !== undefined ? ( - + { - {mapJobId || mapModelId || analyticsId ? ( + {jobId ?? modelId ? ( ) : ( diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/util/model_memory_estimator.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/util/model_memory_estimator.ts index 1e28ac6ef8a2d..a0ca9e4502cc2 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/util/model_memory_estimator.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/util/model_memory_estimator.ts @@ -24,11 +24,7 @@ import { useEffect, useMemo } from 'react'; import { DEFAULT_MODEL_MEMORY_LIMIT } from '../../../../../../../common/constants/new_job'; import { ml } from '../../../../../services/ml_api_service'; import { JobValidator, VALIDATION_DELAY_MS } from '../../job_validator/job_validator'; -import { - MLHttpFetchError, - MLResponseError, - extractErrorMessage, -} from '../../../../../../../common/util/errors'; +import { MLHttpFetchError, extractErrorMessage } from '../../../../../../../common/util/errors'; import { useMlKibana } from '../../../../../contexts/kibana'; import { JobCreator } from '../job_creator'; @@ -41,10 +37,10 @@ export const modelMemoryEstimatorProvider = ( jobValidator: JobValidator ) => { const modelMemoryCheck$ = new Subject(); - const error$ = new Subject>(); + const error$ = new Subject(); return { - get error$(): Observable> { + get error$(): Observable { return error$.asObservable(); }, get updates$(): Observable { diff --git a/x-pack/plugins/ml/public/application/management/breadcrumbs.ts b/x-pack/plugins/ml/public/application/management/breadcrumbs.ts index 1043a9a008734..514941fda2c45 100644 --- a/x-pack/plugins/ml/public/application/management/breadcrumbs.ts +++ b/x-pack/plugins/ml/public/application/management/breadcrumbs.ts @@ -11,8 +11,8 @@ import { JOBS_LIST_PATH } from './management_urls'; export function getJobsListBreadcrumbs() { return [ { - text: i18n.translate('xpack.ml.jobsList.breadcrumb', { - defaultMessage: 'Jobs', + text: i18n.translate('xpack.ml.management.breadcrumb', { + defaultMessage: 'Machine Learning', }), href: `#${JOBS_LIST_PATH}`, }, diff --git a/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx b/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx index b3837ceedeb60..15ea5852ca4b5 100644 --- a/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx +++ b/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx @@ -37,7 +37,6 @@ import { PLUGIN_ID } from '../../../../../../common/constants/app'; import { checkGetManagementMlJobsResolver } from '../../../../capabilities/check_capabilities'; -import { getDocLinks } from '../../../../util/dependency_cache'; // @ts-ignore undeclared module import { JobsListView } from '../../../../jobs/jobs_list/components/jobs_list_view'; import { DataFrameAnalyticsList } from '../../../../data_frame_analytics/pages/analytics_management/components/analytics_list'; @@ -54,6 +53,7 @@ import { ListingPageUrlState } from '../../../../../../common/types/common'; import { getDefaultDFAListState } from '../../../../data_frame_analytics/pages/analytics_management/page'; import { ExportJobsFlyout, ImportJobsFlyout } from '../../../../components/import_export_jobs'; import type { JobType, MlSavedObjectType } from '../../../../../../common/types/saved_objects'; +import { useMlKibana } from '../../../../contexts/kibana'; interface Tab extends EuiTabbedContentTab { 'data-test-subj': string; @@ -201,30 +201,6 @@ export const JobsListPage: FC<{ return null; } - const anomalyDetectionJobsUrl = getDocLinks().links.ml.anomalyDetectionJobs; - const dataFrameAnalyticsUrl = getDocLinks().links.ml.dataFrameAnalytics; - - const anomalyDetectionDocsLabel = i18n.translate( - 'xpack.ml.management.jobsList.anomalyDetectionDocsLabel', - { - defaultMessage: 'Anomaly detection jobs docs', - } - ); - const analyticsDocsLabel = i18n.translate('xpack.ml.management.jobsList.analyticsDocsLabel', { - defaultMessage: 'Analytics jobs docs', - }); - - const docsLink = ( - - {currentTabId === 'anomaly-detector' ? anomalyDetectionDocsLabel : analyticsDocsLabel} - - ); - function renderTabs() { return ( } - rightSideItems={[docsLink]} + rightSideItems={[]} bottomBorder /> @@ -329,3 +305,35 @@ export const JobsListPage: FC<{ ); }; + +const DocsLink: FC<{ currentTabId: MlSavedObjectType }> = ({ currentTabId }) => { + const { + services: { + docLinks: { + links: { ml }, + }, + }, + } = useMlKibana(); + + let href = ml.anomalyDetectionJobs; + let linkLabel = i18n.translate('xpack.ml.management.jobsList.anomalyDetectionDocsLabel', { + defaultMessage: 'Anomaly detection jobs docs', + }); + + if (currentTabId === 'data-frame-analytics') { + href = ml.dataFrameAnalytics; + linkLabel = i18n.translate('xpack.ml.management.jobsList.analyticsDocsLabel', { + defaultMessage: 'Analytics jobs docs', + }); + } else if (currentTabId === 'trained-model') { + href = ml.trainedModels; + linkLabel = i18n.translate('xpack.ml.management.jobsList.trainedModelsDocsLabel', { + defaultMessage: 'Trained models docs', + }); + } + return ( + + {linkLabel} + + ); +}; diff --git a/x-pack/plugins/ml/public/application/settings/filter_lists/components/add_item_popover/__snapshots__/add_item_popover.test.js.snap b/x-pack/plugins/ml/public/application/settings/filter_lists/components/add_item_popover/__snapshots__/add_item_popover.test.js.snap index 969406724537d..45d9296f1752e 100644 --- a/x-pack/plugins/ml/public/application/settings/filter_lists/components/add_item_popover/__snapshots__/add_item_popover.test.js.snap +++ b/x-pack/plugins/ml/public/application/settings/filter_lists/components/add_item_popover/__snapshots__/add_item_popover.test.js.snap @@ -25,6 +25,7 @@ exports[`AddItemPopover calls addItems with multiple items on clicking Add butto display="inlineBlock" hasArrow={true} id="add_item_popover" + initialFocus="#filter_list_add_item_input_row" isOpen={false} ownFocus={true} panelClassName="ml-add-filter-item-popover" @@ -37,6 +38,7 @@ exports[`AddItemPopover calls addItems with multiple items on clicking Add butto fullWidth={false} hasChildLabel={true} hasEmptyLabelSpace={false} + id="filter_list_add_item_input_row" label={
= ({ isPrimary: true, available: isTestable, onClick: setShowTestFlyout, + enabled: (item) => + isPopulatedObject(item.stats?.deployment_stats) && + item.stats?.deployment_stats?.state === DEPLOYMENT_STATE.STARTED, }, ] as Array>) ); diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/index.ts b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/index.ts new file mode 100644 index 0000000000000..ef46c223f609e --- /dev/null +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/index.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { NerInference } from './ner'; +import { + TextClassificationInference, + ZeroShotClassificationInference, + FillMaskInference, +} from './text_classification'; +import { TextEmbeddingInference } from './text_embedding'; +import { LangIdentInference } from './lang_ident'; + +export type InferrerType = + | NerInference + | TextClassificationInference + | TextEmbeddingInference + | ZeroShotClassificationInference + | FillMaskInference + | LangIdentInference; diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/inference_base.ts b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/inference_base.ts index 777ca2d314c4d..db27fb96e9c2a 100644 --- a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/inference_base.ts +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/inference_base.ts @@ -5,19 +5,38 @@ * 2.0. */ +import { BehaviorSubject } from 'rxjs'; import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { MLHttpFetchError } from '../../../../../../common/util/errors'; import { trainedModelsApiProvider } from '../../../../services/ml_api_service/trained_models'; const DEFAULT_INPUT_FIELD = 'text_field'; -export type FormattedNerResp = Array<{ +export type FormattedNerResponse = Array<{ value: string; entity: estypes.MlTrainedModelEntities | null; }>; +export interface InferResponse { + inputText: string; + response: T; + rawResponse: U; +} + +export enum RUNNING_STATE { + STOPPED, + RUNNING, + FINISHED, + FINISHED_WITH_ERRORS, +} + export abstract class InferenceBase { protected readonly inputField: string; + public inputText$ = new BehaviorSubject(''); + public inferenceResult$ = new BehaviorSubject(null); + public inferenceError$ = new BehaviorSubject(null); + public runningState$ = new BehaviorSubject(RUNNING_STATE.STOPPED); constructor( protected trainedModelsApi: ReturnType, @@ -26,5 +45,26 @@ export abstract class InferenceBase { this.inputField = model.input?.field_names[0] ?? DEFAULT_INPUT_FIELD; } - protected abstract infer(inputText: string): Promise; + public setStopped() { + this.inferenceError$.next(null); + this.runningState$.next(RUNNING_STATE.STOPPED); + } + public setRunning() { + this.inferenceError$.next(null); + this.runningState$.next(RUNNING_STATE.RUNNING); + } + + public setFinished() { + this.runningState$.next(RUNNING_STATE.FINISHED); + } + + public setFinishedWithErrors(error: MLHttpFetchError) { + this.inferenceError$.next(error); + this.runningState$.next(RUNNING_STATE.FINISHED_WITH_ERRORS); + } + + protected abstract getInputComponent(): JSX.Element; + protected abstract getOutputComponent(): JSX.Element; + + protected abstract infer(): Promise; } diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/inference_input_form.tsx b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/inference_input_form.tsx index 6503486d98211..0ee33791ef55e 100644 --- a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/inference_input_form.tsx +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/inference_input_form.tsx @@ -5,25 +5,20 @@ * 2.0. */ -import React, { FC, useState } from 'react'; +import React, { FC, useState, useMemo } from 'react'; -import { i18n } from '@kbn/i18n'; +import useObservable from 'react-use/lib/useObservable'; import { FormattedMessage } from '@kbn/i18n-react'; -import { EuiSpacer, EuiTextArea, EuiButton, EuiTabs, EuiTab } from '@elastic/eui'; - -import { LangIdentInference } from './lang_ident/lang_ident_inference'; -import { NerInference } from './ner/ner_inference'; -import type { FormattedLangIdentResp } from './lang_ident/lang_ident_inference'; -import type { FormattedNerResp } from './ner/ner_inference'; - -import { MLJobEditor } from '../../../../jobs/jobs_list/components/ml_job_editor'; +import { EuiSpacer, EuiButton, EuiTabs, EuiTab } from '@elastic/eui'; import { extractErrorMessage } from '../../../../../../common/util/errors'; import { ErrorMessage } from '../inference_error'; import { OutputLoadingContent } from '../output_loading'; +import { RUNNING_STATE } from './inference_base'; +import { RawOutput } from './raw_output'; +import type { InferrerType } from '.'; interface Props { - inferrer: LangIdentInference | NerInference; - getOutputComponent(output: any): JSX.Element; + inferrer: InferrerType; } enum TAB { @@ -31,61 +26,41 @@ enum TAB { RAW, } -export const InferenceInputForm: FC = ({ inferrer, getOutputComponent }) => { - const [inputText, setInputText] = useState(''); - const [isRunning, setIsRunning] = useState(false); - const [output, setOutput] = useState(null); - const [rawOutput, setRawOutput] = useState(null); +export const InferenceInputForm: FC = ({ inferrer }) => { const [selectedTab, setSelectedTab] = useState(TAB.TEXT); - const [showOutput, setShowOutput] = useState(false); const [errorText, setErrorText] = useState(null); + const runningState = useObservable(inferrer.runningState$); + const inputText = useObservable(inferrer.inputText$); + const inputComponent = useMemo(() => inferrer.getInputComponent(), []); + const outputComponent = useMemo(() => inferrer.getOutputComponent(), []); + async function run() { - setShowOutput(true); - setOutput(null); - setRawOutput(null); - setIsRunning(true); setErrorText(null); try { - const { response, rawResponse } = await inferrer.infer(inputText); - setOutput(response); - setRawOutput(JSON.stringify(rawResponse, null, 2)); + await inferrer.infer(); } catch (e) { - setIsRunning(false); - setOutput(null); setErrorText(extractErrorMessage(e)); - setRawOutput(JSON.stringify(e.body ?? e, null, 2)); } - setIsRunning(false); } return ( <> - { - setInputText(e.target.value); - }} - /> + <>{inputComponent}
- {showOutput === true ? ( + {runningState !== RUNNING_STATE.STOPPED ? ( <> @@ -94,7 +69,7 @@ export const InferenceInputForm: FC = ({ inferrer, getOutputComponent }) onClick={setSelectedTab.bind(null, TAB.TEXT)} > @@ -103,7 +78,7 @@ export const InferenceInputForm: FC = ({ inferrer, getOutputComponent }) onClick={setSelectedTab.bind(null, TAB.RAW)} > @@ -113,16 +88,16 @@ export const InferenceInputForm: FC = ({ inferrer, getOutputComponent }) {selectedTab === TAB.TEXT ? ( <> - {errorText !== null ? ( + {runningState === RUNNING_STATE.RUNNING ? : null} + + {errorText !== null || runningState === RUNNING_STATE.FINISHED_WITH_ERRORS ? ( - ) : output === null ? ( - - ) : ( - <>{getOutputComponent(output)} - )} + ) : null} + + {runningState === RUNNING_STATE.FINISHED ? <>{outputComponent} : null} ) : ( - + )} ) : null} diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/lang_ident/index.ts b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/lang_ident/index.ts index b3439d90e8828..8e5bd8cdbeb5f 100644 --- a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/lang_ident/index.ts +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/lang_ident/index.ts @@ -5,6 +5,6 @@ * 2.0. */ -export type { FormattedLangIdentResp } from './lang_ident_inference'; +export type { FormattedLangIdentResponse, LangIdentResponse } from './lang_ident_inference'; export { LangIdentInference } from './lang_ident_inference'; -export { LangIdentOutput } from './lang_ident_output'; +export { getLangIdentOutputComponent } from './lang_ident_output'; diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/lang_ident/lang_ident_inference.ts b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/lang_ident/lang_ident_inference.ts index 9108a59197617..34893d7dc9402 100644 --- a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/lang_ident/lang_ident_inference.ts +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/lang_ident/lang_ident_inference.ts @@ -7,62 +7,86 @@ import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { InferenceBase } from '../inference_base'; +import { InferenceBase, InferResponse } from '../inference_base'; +import { getGeneralInputComponent } from '../text_input'; +import { getLangIdentOutputComponent } from './lang_ident_output'; -export type FormattedLangIdentResp = Array<{ +export type FormattedLangIdentResponse = Array<{ className: string; classProbability: number; classScore: number; }>; -interface InferResponse { - response: FormattedLangIdentResp; - rawResponse: estypes.IngestSimulateResponse; -} +export type LangIdentResponse = InferResponse< + FormattedLangIdentResponse, + estypes.IngestSimulateResponse +>; -export class LangIdentInference extends InferenceBase { - public async infer(inputText: string) { - const payload: estypes.IngestSimulateRequest['body'] = { - pipeline: { - processors: [ - { - inference: { - model_id: this.model.model_id, - inference_config: { - // @ts-expect-error classification missing from type - classification: { - num_top_classes: 3, +export class LangIdentInference extends InferenceBase { + public async infer() { + try { + this.setRunning(); + const inputText = this.inputText$.value; + const payload: estypes.IngestSimulateRequest['body'] = { + pipeline: { + processors: [ + { + inference: { + model_id: this.model.model_id, + inference_config: { + // @ts-expect-error classification missing from type + classification: { + num_top_classes: 3, + }, }, + field_mappings: { + contents: this.inputField, + }, + target_field: '_ml.lang_ident', }, - field_mappings: { - contents: this.inputField, - }, - target_field: '_ml.lang_ident', + }, + ], + }, + docs: [ + { + _source: { + contents: inputText, }, }, ], - }, - docs: [ - { - _source: { - contents: inputText, - }, - }, - ], - }; - const resp = await this.trainedModelsApi.ingestPipelineSimulate(payload); - if (resp.docs.length) { - const topClasses = resp.docs[0].doc?._source._ml?.lang_ident?.top_classes ?? []; - - return { - response: topClasses.map((t: any) => ({ - className: t.class_name, - classProbability: t.class_probability, - classScore: t.class_score, - })), - rawResponse: resp, }; + const resp = await this.trainedModelsApi.ingestPipelineSimulate(payload); + if (resp.docs.length) { + const topClasses = resp.docs[0].doc?._source._ml?.lang_ident?.top_classes ?? []; + + const r: LangIdentResponse = { + response: topClasses.map((t: estypes.MlTopClassEntry) => ({ + className: t.class_name, + classProbability: t.class_probability, + classScore: t.class_score, + })), + rawResponse: resp, + inputText, + }; + this.inferenceResult$.next(r); + this.setFinished(); + return r; + } + const r: LangIdentResponse = { response: [], rawResponse: resp, inputText }; + this.inferenceResult$.next(r); + this.setFinished(); + return r; + } catch (error) { + this.setFinishedWithErrors(error); + throw error; } - return { response: [], rawResponse: resp }; + } + + public getInputComponent(): JSX.Element { + return getGeneralInputComponent(this); + } + + public getOutputComponent(): JSX.Element { + return getLangIdentOutputComponent(this); } } diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/lang_ident/lang_ident_output.tsx b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/lang_ident/lang_ident_output.tsx index e4968bc516f83..584e367aac784 100644 --- a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/lang_ident/lang_ident_output.tsx +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/lang_ident/lang_ident_output.tsx @@ -6,22 +6,28 @@ */ import React, { FC } from 'react'; +import useObservable from 'react-use/lib/useObservable'; import { i18n } from '@kbn/i18n'; import { EuiSpacer, EuiBasicTable, EuiTitle } from '@elastic/eui'; -import type { FormattedLangIdentResp } from './lang_ident_inference'; +import type { LangIdentInference } from './lang_ident_inference'; import { getLanguage } from './lang_codes'; const PROBABILITY_SIG_FIGS = 3; -export const LangIdentOutput: FC<{ result: FormattedLangIdentResp }> = ({ result }) => { - if (result.length === 0) { +export const getLangIdentOutputComponent = (inferrer: LangIdentInference) => ( + +); + +const LangIdentOutput: FC<{ inferrer: LangIdentInference }> = ({ inferrer }) => { + const result = useObservable(inferrer.inferenceResult$); + if (!result || result.response.length === 0) { return null; } - const lang = getLanguage(result[0].className); + const lang = getLanguage(result.response[0].className); - const items = result.map(({ className, classProbability }, i) => { + const items = result.response.map(({ className, classProbability }, i) => { return { noa: `${i + 1}`, className: getLanguage(className), @@ -70,7 +76,7 @@ export const LangIdentOutput: FC<{ result: FormattedLangIdentResp }> = ({ result }) : i18n.translate('xpack.ml.trainedModels.testModelsFlyout.langIdent.output.titleUnknown', { defaultMessage: 'Language code unknown: {code}', - values: { code: result[0].className }, + values: { code: result.response[0].className }, }); return ( diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/ner/index.ts b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/ner/index.ts index 38ddad8bdeb80..5e5a029997965 100644 --- a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/ner/index.ts +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/ner/index.ts @@ -5,6 +5,6 @@ * 2.0. */ -export type { FormattedNerResp } from './ner_inference'; +export type { FormattedNerResponse, NerResponse } from './ner_inference'; export { NerInference } from './ner_inference'; -export { NerOutput } from './ner_output'; +export { getNerOutputComponent } from './ner_output'; diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/ner/ner_inference.ts b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/ner/ner_inference.ts index e4dcfcc2c6333..4125dcd02c6db 100644 --- a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/ner/ner_inference.ts +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/ner/ner_inference.ts @@ -7,28 +7,56 @@ import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { InferenceBase } from '../inference_base'; +import { InferenceBase, InferResponse } from '../inference_base'; +import { getGeneralInputComponent } from '../text_input'; +import { getNerOutputComponent } from './ner_output'; -export type FormattedNerResp = Array<{ +export type FormattedNerResponse = Array<{ value: string; entity: estypes.MlTrainedModelEntities | null; }>; -interface InferResponse { - response: FormattedNerResp; - rawResponse: estypes.MlInferTrainedModelDeploymentResponse; -} +export type NerResponse = InferResponse< + FormattedNerResponse, + estypes.MlInferTrainedModelDeploymentResponse +>; + +export class NerInference extends InferenceBase { + public async infer() { + try { + this.setRunning(); + const inputText = this.inputText$.value; + const payload = { docs: { [this.inputField]: inputText } }; + const resp = await this.trainedModelsApi.inferTrainedModel( + this.model.model_id, + payload, + '30s' + ); + + const processedResponse: NerResponse = { + response: parseResponse(resp), + rawResponse: resp, + inputText, + }; + this.inferenceResult$.next(processedResponse); + this.setFinished(); + return processedResponse; + } catch (error) { + this.setFinishedWithErrors(error); + throw error; + } + } -export class NerInference extends InferenceBase { - public async infer(inputText: string) { - const payload = { docs: { [this.inputField]: inputText } }; - const resp = await this.trainedModelsApi.inferTrainedModel(this.model.model_id, payload, '30s'); + public getInputComponent(): JSX.Element { + return getGeneralInputComponent(this); + } - return { response: parseResponse(resp), rawResponse: resp }; + public getOutputComponent(): JSX.Element { + return getNerOutputComponent(this); } } -function parseResponse(resp: estypes.MlInferTrainedModelDeploymentResponse): FormattedNerResp { +function parseResponse(resp: estypes.MlInferTrainedModelDeploymentResponse): FormattedNerResponse { const { predicted_value: predictedValue, entities } = resp; const splitWordsAndEntitiesRegex = /(\[.*?\]\(.*?&.*?\))/; const matchEntityRegex = /(\[.*?\])\((.*?)&(.*?)\)/; diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/ner/ner_output.tsx b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/ner/ner_output.tsx index e9db3fa8efd36..76c154e1000b1 100644 --- a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/ner/ner_output.tsx +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/ner/ner_output.tsx @@ -7,6 +7,7 @@ import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import React, { FC, ReactNode } from 'react'; +import useObservable from 'react-use/lib/useObservable'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiHorizontalRule, @@ -21,7 +22,7 @@ import { useCurrentEuiTheme, EuiThemeType, } from '../../../../../components/color_range_legend/use_color_range'; -import type { FormattedNerResp } from './ner_inference'; +import type { NerInference } from './ner_inference'; const ICON_PADDING = '2px'; const PROBABILITY_SIG_FIGS = 3; @@ -60,10 +61,18 @@ const UNKNOWN_ENTITY_TYPE = { borderColor: 'euiColorVis5', }; -export const NerOutput: FC<{ result: FormattedNerResp }> = ({ result }) => { +export const getNerOutputComponent = (inferrer: NerInference) => ; + +const NerOutput: FC<{ inferrer: NerInference }> = ({ inferrer }) => { const { euiTheme } = useCurrentEuiTheme(); + const result = useObservable(inferrer.inferenceResult$); + + if (!result) { + return null; + } + const lineSplit: JSX.Element[] = []; - result.forEach(({ value, entity }) => { + result.response.forEach(({ value, entity }) => { if (entity === null) { const lines = value .split(/(\n)/) diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/raw_output.tsx b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/raw_output.tsx new file mode 100644 index 0000000000000..0031aafa81443 --- /dev/null +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/raw_output.tsx @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { FC } from 'react'; +import { Observable } from 'rxjs'; +import useObservable from 'react-use/lib/useObservable'; +import { MLJobEditor } from '../../../../jobs/jobs_list/components/ml_job_editor'; + +import type { InferrerType } from '.'; +import { NerResponse } from './ner'; +import { TextClassificationResponse } from './text_classification'; +import { TextEmbeddingResponse } from './text_embedding'; +import { LangIdentResponse } from './lang_ident'; +import { RUNNING_STATE } from './inference_base'; + +type InferenceResponse = + | LangIdentResponse + | NerResponse + | TextClassificationResponse + | TextEmbeddingResponse; + +export const RawOutput: FC<{ + inferrer: InferrerType; +}> = ({ inferrer }) => { + const inferenceError = useObservable(inferrer.inferenceError$); + const runningState = useObservable(inferrer.runningState$); + const inferenceResult = useObservable(inferrer.inferenceResult$ as Observable); + + if ( + (runningState === RUNNING_STATE.FINISHED_WITH_ERRORS && !inferenceError) || + (runningState === RUNNING_STATE.FINISHED && !inferenceResult) + ) { + return null; + } + + const rawResponse = + runningState === RUNNING_STATE.FINISHED_WITH_ERRORS + ? JSON.stringify(inferenceError?.body ?? inferenceError, null, 2) + : JSON.stringify(inferenceResult?.rawResponse, null, 2); + + return ( + <> + + + ); +}; diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/common.ts b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/common.ts new file mode 100644 index 0000000000000..d360711995f98 --- /dev/null +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/common.ts @@ -0,0 +1,84 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { InferResponse } from '../inference_base'; + +const PROBABILITY_SIG_FIGS = 3; + +export interface RawTextClassificationResponse { + predicted_value: string; + prediction_probability: number; + top_classes?: Array<{ + class_name: string; + class_probability: number; + class_score: number; + }>; +} + +export type FormattedTextClassificationResponse = Array<{ + value: string; + predictionProbability: number; +}>; + +export type TextClassificationResponse = InferResponse< + FormattedTextClassificationResponse, + RawTextClassificationResponse +>; + +export function processResponse( + resp: RawTextClassificationResponse, + model: estypes.MlTrainedModelConfig, + inputText: string +): TextClassificationResponse { + const labels: string[] = + // @ts-expect-error inference config is wrong + model.inference_config.text_classification?.classification_labels ?? []; + + let formattedResponse = [ + { + value: resp.predicted_value, + predictionProbability: resp.prediction_probability, + }, + ]; + + if (resp.top_classes !== undefined) { + // if num_top_classes has been specified in the model, + // base the returned results on this list + formattedResponse = resp.top_classes.map((topClass) => { + return { + value: topClass.class_name, + predictionProbability: topClass.class_probability, + }; + }); + } else if (labels.length === 2) { + // otherwise, if the config only contains two classification_labels + // we can safely assume the non-top value and return two results + formattedResponse = labels.map((value) => { + const predictionProbability = + resp.predicted_value === value + ? resp.prediction_probability + : 1 - resp.prediction_probability; + + return { + value, + predictionProbability, + }; + }); + } + + return { + response: formattedResponse + .map(({ value, predictionProbability }) => ({ + value, + predictionProbability: Number(predictionProbability.toPrecision(PROBABILITY_SIG_FIGS)), + })) + .sort((a, b) => a.predictionProbability - b.predictionProbability) + .reverse(), + rawResponse: resp, + inputText, + }; +} diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/fill_mask_inference.ts b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/fill_mask_inference.ts new file mode 100644 index 0000000000000..c8c993785dac2 --- /dev/null +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/fill_mask_inference.ts @@ -0,0 +1,70 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { InferenceBase } from '../inference_base'; +import type { TextClassificationResponse, RawTextClassificationResponse } from './common'; +import { processResponse } from './common'; +import { getGeneralInputComponent } from '../text_input'; +import { getFillMaskOutputComponent } from './fill_mask_output'; + +const MASK = '[MASK]'; + +export class FillMaskInference extends InferenceBase { + // @ts-expect-error model type is wrong + private numTopClasses = this.model.inference_config?.fill_mask?.num_top_classes || 5; + + public async infer() { + try { + this.setRunning(); + const inputText = this.inputText$.value; + const payload = { + docs: { [this.inputField]: inputText }, + inference_config: { fill_mask: { num_top_classes: this.numTopClasses } }, + }; + const resp = (await this.trainedModelsApi.inferTrainedModel( + this.model.model_id, + payload, + '30s' + )) as unknown as RawTextClassificationResponse; + + const processedResponse = processResponse(resp, this.model, inputText); + this.inferenceResult$.next(processedResponse); + this.setFinished(); + + return processedResponse; + } catch (error) { + this.setFinishedWithErrors(error); + throw error; + } + } + + public predictedValue() { + const result = this.inferenceResult$.value; + if (result === null) { + return ''; + } + return result.response[0]?.value + ? result.inputText.replace(MASK, result.response[0].value) + : result.inputText; + } + + public getInputComponent(): JSX.Element { + const placeholder = i18n.translate( + 'xpack.ml.trainedModels.testModelsFlyout.langIdent.inputText', + { + defaultMessage: 'Mask token: [MASK]. e.g. Paris is the [MASK] of France.', + } + ); + + return getGeneralInputComponent(this, placeholder); + } + + public getOutputComponent(): JSX.Element { + return getFillMaskOutputComponent(this); + } +} diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/fill_mask_output.tsx b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/fill_mask_output.tsx new file mode 100644 index 0000000000000..dee08392aad09 --- /dev/null +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/fill_mask_output.tsx @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { FC, useMemo } from 'react'; +import useObservable from 'react-use/lib/useObservable'; +import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiProgress, EuiTitle } from '@elastic/eui'; + +import type { FillMaskInference } from './fill_mask_inference'; + +export const getFillMaskOutputComponent = (inferrer: FillMaskInference) => ( + +); + +const FillMaskOutput: FC<{ + inferrer: FillMaskInference; +}> = ({ inferrer }) => { + const result = useObservable(inferrer.inferenceResult$); + const title = useMemo(() => inferrer.predictedValue(), []); + + if (!result) { + return null; + } + + return ( + <> + +

{title}

+
+ + + + {result.response.map(({ value, predictionProbability }) => ( + <> + + + + <> + {value} + {predictionProbability} + + + + + ))} + + ); +}; diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/index.ts b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/index.ts new file mode 100644 index 0000000000000..4eeef37519ff2 --- /dev/null +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { TextClassificationResponse, FormattedTextClassificationResponse } from './common'; + +export { TextClassificationInference } from './text_classification_inference'; +export { getTextClassificationOutputComponent } from './text_classification_output'; + +export { ZeroShotClassificationInference } from './zero_shot_classification_inference'; +export { getZeroShotClassificationInput } from './zero_shot_classification_input'; + +export { FillMaskInference } from './fill_mask_inference'; +export { getFillMaskOutputComponent } from './fill_mask_output'; diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/text_classification_inference.ts b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/text_classification_inference.ts new file mode 100644 index 0000000000000..1bebdc6ac82e4 --- /dev/null +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/text_classification_inference.ts @@ -0,0 +1,54 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { InferenceBase } from '../inference_base'; +import { processResponse } from './common'; +import type { TextClassificationResponse, RawTextClassificationResponse } from './common'; +import { getGeneralInputComponent } from '../text_input'; +import { getTextClassificationOutputComponent } from './text_classification_output'; + +export class TextClassificationInference extends InferenceBase { + // @ts-expect-error model type is wrong + private numTopClasses = this.model.inference_config?.text_classification?.num_top_classes || 5; + + public async infer() { + try { + this.setRunning(); + const inputText = this.inputText$.value; + const payload = { + docs: { [this.inputField]: inputText }, + inference_config: { text_classification: { num_top_classes: this.numTopClasses } }, + }; + const resp = (await this.trainedModelsApi.inferTrainedModel( + this.model.model_id, + payload, + '30s' + )) as unknown as RawTextClassificationResponse; + + const processedResponse: TextClassificationResponse = processResponse( + resp, + this.model, + inputText + ); + this.inferenceResult$.next(processedResponse); + this.setFinished(); + + return processedResponse; + } catch (error) { + this.setFinishedWithErrors(error); + throw error; + } + } + + public getInputComponent(): JSX.Element { + return getGeneralInputComponent(this); + } + + public getOutputComponent(): JSX.Element { + return getTextClassificationOutputComponent(this); + } +} diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/text_classification_output.tsx b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/text_classification_output.tsx new file mode 100644 index 0000000000000..faeed456d1a21 --- /dev/null +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/text_classification_output.tsx @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { FC } from 'react'; +import useObservable from 'react-use/lib/useObservable'; +import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiProgress } from '@elastic/eui'; + +import type { TextClassificationInference, ZeroShotClassificationInference } from '.'; + +export const getTextClassificationOutputComponent = ( + inferrer: TextClassificationInference | ZeroShotClassificationInference +) => ; + +const TextClassificationOutput: FC<{ + inferrer: TextClassificationInference | ZeroShotClassificationInference; +}> = ({ inferrer }) => { + const result = useObservable(inferrer.inferenceResult$); + if (!result) { + return null; + } + return ( + <> + {result.response.map(({ value, predictionProbability }) => ( + <> + + + + <> + {value} + {predictionProbability} + + + + + ))} + + ); +}; diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/zero_shot_classification_inference.ts b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/zero_shot_classification_inference.ts new file mode 100644 index 0000000000000..b8897c439ece8 --- /dev/null +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/zero_shot_classification_inference.ts @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { BehaviorSubject } from 'rxjs'; +import { InferenceBase } from '../inference_base'; +import { processResponse } from './common'; +import type { TextClassificationResponse, RawTextClassificationResponse } from './common'; + +import { getZeroShotClassificationInput } from './zero_shot_classification_input'; +import { getTextClassificationOutputComponent } from './text_classification_output'; + +export class ZeroShotClassificationInference extends InferenceBase { + public labelsText$ = new BehaviorSubject(''); + + public async infer() { + try { + this.setRunning(); + const inputText = this.inputText$.value; + const labelsText = this.labelsText$.value; + const inputLabels = labelsText?.split(',').map((l) => l.trim()); + const payload = { + docs: { [this.inputField]: inputText }, + inference_config: { + zero_shot_classification: { + labels: inputLabels, + multi_label: false, + }, + }, + }; + const resp = (await this.trainedModelsApi.inferTrainedModel( + this.model.model_id, + payload, + '30s' + )) as unknown as RawTextClassificationResponse; + + const processedResponse: TextClassificationResponse = processResponse( + resp, + this.model, + inputText + ); + this.inferenceResult$.next(processedResponse); + this.setFinished(); + + return processedResponse; + } catch (error) { + this.setFinishedWithErrors(error); + throw error; + } + } + + public getInputComponent(): JSX.Element { + return getZeroShotClassificationInput(this); + } + + public getOutputComponent(): JSX.Element { + return getTextClassificationOutputComponent(this); + } +} diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/zero_shot_classification_input.tsx b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/zero_shot_classification_input.tsx new file mode 100644 index 0000000000000..60f06bb8baf79 --- /dev/null +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_classification/zero_shot_classification_input.tsx @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { FC, useEffect, useState } from 'react'; +import useObservable from 'react-use/lib/useObservable'; +import { i18n } from '@kbn/i18n'; + +import { EuiSpacer, EuiFieldText, EuiFormRow } from '@elastic/eui'; + +import { TextInput } from '../text_input'; +import { ZeroShotClassificationInference } from './zero_shot_classification_inference'; +import { RUNNING_STATE } from '../inference_base'; + +const ClassNameInput: FC<{ + inferrer: ZeroShotClassificationInference; +}> = ({ inferrer }) => { + const [labelsText, setLabelsText] = useState(''); + + useEffect(() => { + inferrer.labelsText$.next(labelsText); + }, [labelsText]); + + const runningState = useObservable(inferrer.runningState$); + return ( + + { + setLabelsText(e.target.value); + }} + /> + + ); +}; + +export const getZeroShotClassificationInput = ( + inferrer: ZeroShotClassificationInference, + placeholder?: string +) => ( + <> + + + + +); diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_embedding/index.ts b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_embedding/index.ts new file mode 100644 index 0000000000000..cafa529c5e301 --- /dev/null +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_embedding/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { + TextEmbeddingResponse, + FormattedTextEmbeddingResponse, +} from './text_embedding_inference'; + +export { TextEmbeddingInference } from './text_embedding_inference'; +export { getTextEmbeddingOutputComponent } from './text_embedding_output'; diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_embedding/text_embedding_inference.ts b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_embedding/text_embedding_inference.ts new file mode 100644 index 0000000000000..ffddc81938f19 --- /dev/null +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_embedding/text_embedding_inference.ts @@ -0,0 +1,68 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; + +import { InferenceBase, InferResponse } from '../inference_base'; +import { getGeneralInputComponent } from '../text_input'; +import { getTextEmbeddingOutputComponent } from './text_embedding_output'; + +export interface RawTextEmbeddingResponse { + predicted_value: number[]; +} + +export interface FormattedTextEmbeddingResponse { + predictedValue: number[]; +} + +export type TextEmbeddingResponse = InferResponse< + FormattedTextEmbeddingResponse, + RawTextEmbeddingResponse +>; + +export class TextEmbeddingInference extends InferenceBase { + public async infer() { + try { + this.setRunning(); + const inputText = this.inputText$.value; + const payload = { + docs: { [this.inputField]: inputText }, + }; + const resp = (await this.trainedModelsApi.inferTrainedModel( + this.model.model_id, + payload, + '30s' + )) as unknown as RawTextEmbeddingResponse; + + const processedResponse: TextEmbeddingResponse = processResponse(resp, this.model, inputText); + this.inferenceResult$.next(processedResponse); + this.setFinished(); + + return processedResponse; + } catch (error) { + this.setFinishedWithErrors(error); + throw error; + } + } + + public getInputComponent(): JSX.Element { + return getGeneralInputComponent(this); + } + + public getOutputComponent(): JSX.Element { + return getTextEmbeddingOutputComponent(this); + } +} + +function processResponse( + resp: RawTextEmbeddingResponse, + model: estypes.MlTrainedModelConfig, + inputText: string +) { + const predictedValue = resp.predicted_value; + return { response: { predictedValue }, rawResponse: resp, inputText }; +} diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_embedding/text_embedding_output.tsx b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_embedding/text_embedding_output.tsx new file mode 100644 index 0000000000000..bb60140d39e68 --- /dev/null +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_embedding/text_embedding_output.tsx @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { FC } from 'react'; +import useObservable from 'react-use/lib/useObservable'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { EuiTextArea, EuiCopy, EuiButton } from '@elastic/eui'; + +import type { TextEmbeddingInference } from './text_embedding_inference'; + +export const getTextEmbeddingOutputComponent = (inferrer: TextEmbeddingInference) => ( + +); + +const TextEmbeddingOutput: FC<{ + inferrer: TextEmbeddingInference; +}> = ({ inferrer }) => { + const result = useObservable(inferrer.inferenceResult$); + if (!result) { + return null; + } + + const value = result.response.predictedValue.toString(); + return ( + <> + + + {(copy) => ( + + + + )} + + + ); +}; diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_input.tsx b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_input.tsx new file mode 100644 index 0000000000000..a154bf97ef56b --- /dev/null +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/models/text_input.tsx @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { FC, useState, useEffect } from 'react'; +import { i18n } from '@kbn/i18n'; +import useObservable from 'react-use/lib/useObservable'; +import { EuiTextArea } from '@elastic/eui'; +import { RUNNING_STATE } from './inference_base'; +import type { InferrerType } from '.'; + +export const TextInput: FC<{ + placeholder?: string; + inferrer: InferrerType; +}> = ({ placeholder, inferrer }) => { + const [inputText, setInputText] = useState(''); + + useEffect(() => { + inferrer.inputText$.next(inputText); + }, [inputText]); + + const runningState = useObservable(inferrer.runningState$); + + return ( + { + setInputText(e.target.value); + }} + /> + ); +}; + +export const getGeneralInputComponent = (inferrer: InferrerType, placeholder?: string) => ( + +); diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/selected_model.tsx b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/selected_model.tsx index 29dbb855b0084..50a5f9615d126 100644 --- a/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/selected_model.tsx +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/test_models/selected_model.tsx @@ -8,10 +8,17 @@ import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import React, { FC } from 'react'; -import { NerOutput, NerInference } from './models/ner'; -import type { FormattedNerResp } from './models/ner'; -import { LangIdentOutput, LangIdentInference } from './models/lang_ident'; -import type { FormattedLangIdentResp } from './models/lang_ident'; +import { NerInference } from './models/ner'; + +import { LangIdentInference } from './models/lang_ident'; + +import { + TextClassificationInference, + FillMaskInference, + ZeroShotClassificationInference, +} from './models/text_classification'; + +import { TextEmbeddingInference } from './models/text_embedding'; import { TRAINED_MODEL_TYPE, @@ -31,26 +38,37 @@ export const SelectedModel: FC = ({ model }) => { return null; } - if ( - model.model_type === TRAINED_MODEL_TYPE.PYTORCH && - Object.keys(model.inference_config)[0] === SUPPORTED_PYTORCH_TASKS.NER - ) { - const inferrer = new NerInference(trainedModels, model); - return ( - } - /> - ); + if (model.model_type === TRAINED_MODEL_TYPE.PYTORCH) { + if (Object.keys(model.inference_config)[0] === SUPPORTED_PYTORCH_TASKS.NER) { + const inferrer = new NerInference(trainedModels, model); + return ; + } + + if (Object.keys(model.inference_config)[0] === SUPPORTED_PYTORCH_TASKS.TEXT_CLASSIFICATION) { + const inferrer = new TextClassificationInference(trainedModels, model); + return ; + } + + if ( + Object.keys(model.inference_config)[0] === SUPPORTED_PYTORCH_TASKS.ZERO_SHOT_CLASSIFICATION + ) { + const inferrer = new ZeroShotClassificationInference(trainedModels, model); + return ; + } + + if (Object.keys(model.inference_config)[0] === SUPPORTED_PYTORCH_TASKS.TEXT_EMBEDDING) { + const inferrer = new TextEmbeddingInference(trainedModels, model); + return ; + } + + if (Object.keys(model.inference_config)[0] === SUPPORTED_PYTORCH_TASKS.FILL_MASK) { + const inferrer = new FillMaskInference(trainedModels, model); + return ; + } } if (model.model_type === TRAINED_MODEL_TYPE.LANG_IDENT) { const inferrer = new LangIdentInference(trainedModels, model); - return ( - } - /> - ); + return ; } return null; diff --git a/x-pack/plugins/ml/public/application/util/dependency_cache.ts b/x-pack/plugins/ml/public/application/util/dependency_cache.ts index e2269524fe6e5..3680f8b63b0c9 100644 --- a/x-pack/plugins/ml/public/application/util/dependency_cache.ts +++ b/x-pack/plugins/ml/public/application/util/dependency_cache.ts @@ -20,7 +20,7 @@ import type { ChromeRecentlyAccessed, IBasePath, } from '@kbn/core/public'; -import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import type { DashboardStart } from '@kbn/dashboard-plugin/public'; import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; import type { DataViewsContract } from '@kbn/data-views-plugin/public'; @@ -38,7 +38,7 @@ export interface DependencyCache { theme: ThemeServiceStart | null; recentlyAccessed: ChromeRecentlyAccessed | null; fieldFormats: FieldFormatsStart | null; - autocomplete: DataPublicPluginStart['autocomplete'] | null; + autocomplete: UnifiedSearchPublicPluginStart['autocomplete'] | null; basePath: IBasePath | null; savedObjectsClient: SavedObjectsClientContract | null; application: ApplicationStart | null; diff --git a/x-pack/plugins/ml/public/plugin.ts b/x-pack/plugins/ml/public/plugin.ts index b45ee5f5d3956..1ef7c73d2189a 100644 --- a/x-pack/plugins/ml/public/plugin.ts +++ b/x-pack/plugins/ml/public/plugin.ts @@ -16,6 +16,7 @@ import type { import { BehaviorSubject } from 'rxjs'; import { take } from 'rxjs/operators'; +import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import type { ManagementSetup } from '@kbn/management-plugin/public'; import type { SharePluginSetup, SharePluginStart } from '@kbn/share-plugin/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; @@ -50,6 +51,7 @@ import { PLUGIN_ICON_SOLUTION, PLUGIN_ID } from '../common/constants/app'; export interface MlStartDependencies { data: DataPublicPluginStart; + unifiedSearch: UnifiedSearchPublicPluginStart; share: SharePluginStart; uiActions: UiActionsStart; spaces?: SpacesPluginStart; @@ -109,6 +111,7 @@ export class MlPlugin implements Plugin { { charts: pluginsStart.charts, data: pluginsStart.data, + unifiedSearch: pluginsStart.unifiedSearch, dashboard: pluginsStart.dashboard, share: pluginsStart.share, security: pluginsSetup.security, diff --git a/x-pack/plugins/ml/server/lib/route_guard.ts b/x-pack/plugins/ml/server/lib/route_guard.ts index cd500cfda17cc..fa3fb88a109bb 100644 --- a/x-pack/plugins/ml/server/lib/route_guard.ts +++ b/x-pack/plugins/ml/server/lib/route_guard.ts @@ -8,7 +8,7 @@ import type { KibanaRequest, KibanaResponseFactory, - RequestHandlerContext, + CustomRequestHandlerContext, IScopedClusterClient, RequestHandler, SavedObjectsClientContract, @@ -25,9 +25,9 @@ import type { MlLicense } from '../../common/license'; import { MlClient, getMlClient } from './ml_client'; import { getDataViewsServiceFactory } from './data_views_utils'; -type MLRequestHandlerContext = RequestHandlerContext & { +type MLRequestHandlerContext = CustomRequestHandlerContext<{ alerting?: AlertingApiRequestHandlerContext; -}; +}>; type Handler

= (handlerParams: { client: IScopedClusterClient; @@ -73,12 +73,13 @@ export class RouteGuard { public fullLicenseAPIGuard(handler: Handler) { return this._guard(() => this._mlLicense.isFullLicense(), handler); } + public basicLicenseAPIGuard(handler: Handler) { return this._guard(() => this._mlLicense.isMinimumLicense(), handler); } private _guard(check: () => boolean, handler: Handler) { - return ( + return async ( context: MLRequestHandlerContext, request: KibanaRequest, response: KibanaResponseFactory @@ -87,7 +88,8 @@ export class RouteGuard { return response.forbidden(); } - const client = context.core.elasticsearch.client; + const { elasticsearch, savedObjects } = await context.core; + const client = elasticsearch.client; const mlSavedObjectClient = this._getMlSavedObjectClient(request); const internalSavedObjectsClient = this._getInternalSavedObjectClient(); if (mlSavedObjectClient === null || internalSavedObjectsClient === null) { @@ -114,7 +116,7 @@ export class RouteGuard { mlClient: getMlClient(client, mlSavedObjectService), getDataViewsService: getDataViewsServiceFactory( this._getDataViews, - context.core.savedObjects.client, + savedObjects.client, client, request ), diff --git a/x-pack/plugins/ml/server/routes/alerting.ts b/x-pack/plugins/ml/server/routes/alerting.ts index 1dd11375cdd3c..59091e1c8dfb0 100644 --- a/x-pack/plugins/ml/server/routes/alerting.ts +++ b/x-pack/plugins/ml/server/routes/alerting.ts @@ -36,7 +36,7 @@ export function alertingRoutes( routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response, client, context }) => { try { const alertingService = sharedServicesProviders.alertingServiceProvider( - context.core.savedObjects.client, + (await context.core).savedObjects.client, request ); diff --git a/x-pack/plugins/ml/server/routes/job_service.ts b/x-pack/plugins/ml/server/routes/job_service.ts index e67095d022901..5504682406a00 100644 --- a/x-pack/plugins/ml/server/routes/job_service.ts +++ b/x-pack/plugins/ml/server/routes/job_service.ts @@ -268,11 +268,8 @@ export function jobServiceRoutes({ router, routeGuard }: RouteInitialization) { }, routeGuard.fullLicenseAPIGuard(async ({ client, mlClient, request, response, context }) => { try { - const { jobsSummary } = jobServiceProvider( - client, - mlClient, - context.alerting?.getRulesClient() - ); + const alerting = await context.alerting; + const { jobsSummary } = jobServiceProvider(client, mlClient, alerting?.getRulesClient()); const { jobIds } = request.body; const resp = await jobsSummary(jobIds); @@ -304,10 +301,11 @@ export function jobServiceRoutes({ router, routeGuard }: RouteInitialization) { }, routeGuard.fullLicenseAPIGuard(async ({ client, mlClient, response, context }) => { try { + const alerting = await context.alerting; const { getJobIdsWithGeo } = jobServiceProvider( client, mlClient, - context.alerting?.getRulesClient() + alerting?.getRulesClient() ); const resp = await getJobIdsWithGeo(); @@ -409,10 +407,11 @@ export function jobServiceRoutes({ router, routeGuard }: RouteInitialization) { }, routeGuard.fullLicenseAPIGuard(async ({ client, mlClient, request, response, context }) => { try { + const alerting = await context.alerting; const { createFullJobsList } = jobServiceProvider( client, mlClient, - context.alerting?.getRulesClient() + alerting?.getRulesClient() ); const { jobIds } = request.body; const resp = await createFullJobsList(jobIds); diff --git a/x-pack/plugins/ml/server/routes/modules.ts b/x-pack/plugins/ml/server/routes/modules.ts index fb8a2efed8745..757012ba14041 100644 --- a/x-pack/plugins/ml/server/routes/modules.ts +++ b/x-pack/plugins/ml/server/routes/modules.ts @@ -190,11 +190,12 @@ export function dataRecognizer({ router, routeGuard }: RouteInitialization) { }) => { try { const { indexPatternTitle } = request.params; + const soClient = (await context.core).savedObjects.client; const dataViewService = await getDataViewsService(); const results = await recognize( client, mlClient, - context.core.savedObjects.client, + soClient, dataViewService, mlSavedObjectService, request, @@ -344,11 +345,12 @@ export function dataRecognizer({ router, routeGuard }: RouteInitialization) { // the moduleId will be an empty string. moduleId = undefined; } + const soClient = (await context.core).savedObjects.client; const dataViewService = await getDataViewsService(); const results = await getModule( client, mlClient, - context.core.savedObjects.client, + soClient, dataViewService, mlSavedObjectService, request, @@ -541,13 +543,13 @@ export function dataRecognizer({ router, routeGuard }: RouteInitialization) { estimateModelMemory, applyToAllSpaces, } = request.body as TypeOf; - + const soClient = (await context.core).savedObjects.client; const dataViewService = await getDataViewsService(); const result = await setup( client, mlClient, - context.core.savedObjects.client, + soClient, dataViewService, mlSavedObjectService, request, @@ -648,11 +650,12 @@ export function dataRecognizer({ router, routeGuard }: RouteInitialization) { }) => { try { const { moduleId } = request.params; + const soClient = (await context.core).savedObjects.client; const dataViewService = await getDataViewsService(); const result = await dataRecognizerJobsExist( client, mlClient, - context.core.savedObjects.client, + soClient, dataViewService, mlSavedObjectService, request, diff --git a/x-pack/plugins/ml/server/routes/schemas/inference_schema.ts b/x-pack/plugins/ml/server/routes/schemas/inference_schema.ts index 1b9a865dcfca9..ea18930cdec36 100644 --- a/x-pack/plugins/ml/server/routes/schemas/inference_schema.ts +++ b/x-pack/plugins/ml/server/routes/schemas/inference_schema.ts @@ -45,4 +45,5 @@ export const pipelineSchema = schema.object({ export const inferTrainedModelQuery = schema.object({ timeout: schema.maybe(schema.string()) }); export const inferTrainedModelBody = schema.object({ docs: schema.any(), + inference_config: schema.maybe(schema.any()), }); diff --git a/x-pack/plugins/ml/server/routes/trained_models.ts b/x-pack/plugins/ml/server/routes/trained_models.ts index 27a062b45767c..731d159032d45 100644 --- a/x-pack/plugins/ml/server/routes/trained_models.ts +++ b/x-pack/plugins/ml/server/routes/trained_models.ts @@ -381,7 +381,12 @@ export function trainedModelsRoutes({ router, routeGuard }: RouteInitialization) const { modelId } = request.params; const body = await mlClient.inferTrainedModelDeployment({ model_id: modelId, - docs: request.body.docs, + body: { + docs: request.body.docs, + ...(request.body.inference_config + ? { inference_config: request.body.inference_config } + : {}), + }, ...(request.query.timeout ? { timeout: request.query.timeout } : {}), }); return response.ok({ diff --git a/x-pack/plugins/monitoring/common/ccs_utils.ts b/x-pack/plugins/monitoring/common/ccs_utils.ts index 69cc1c25c372a..fea8f79bbfbbf 100644 --- a/x-pack/plugins/monitoring/common/ccs_utils.ts +++ b/x-pack/plugins/monitoring/common/ccs_utils.ts @@ -23,7 +23,7 @@ export function prefixIndexPatternWithCcs( config: MonitoringConfig, indexPattern: string, ccs?: string -) { +): string { const ccsEnabled = config.ui.ccs.enabled; if (!ccsEnabled || !ccs) { return indexPattern; @@ -67,7 +67,7 @@ export function prefixIndexPatternWithCcs( * @param {String} indexName The index's name, possibly including the cross-cluster prefix * @return {String} {@code null} if none. Otherwise the cluster prefix. */ -export function parseCrossClusterPrefix(indexName: string) { +export function parseCrossClusterPrefix(indexName: string): string | null { const colonIndex = indexName.indexOf(':'); if (colonIndex === -1) { diff --git a/x-pack/plugins/monitoring/common/http_api/apm/post_apm_instance.ts b/x-pack/plugins/monitoring/common/http_api/apm/post_apm_instance.ts index 537b68dabd888..c0bd4688ce0c0 100644 --- a/x-pack/plugins/monitoring/common/http_api/apm/post_apm_instance.ts +++ b/x-pack/plugins/monitoring/common/http_api/apm/post_apm_instance.ts @@ -6,26 +6,24 @@ */ import * as rt from 'io-ts'; +import { ccsRT, clusterUuidRT, timeRangeRT } from '../shared'; export const postApmInstanceRequestParamsRT = rt.type({ - clusterUuid: rt.string, + clusterUuid: clusterUuidRT, apmUuid: rt.string, }); export const postApmInstanceRequestPayloadRT = rt.intersection([ rt.partial({ - ccs: rt.string, + ccs: ccsRT, }), rt.type({ - timeRange: rt.type({ - min: rt.string, - max: rt.string, - }), + timeRange: timeRangeRT, }), ]); export type PostApmInstanceRequestPayload = rt.TypeOf; export const postApmInstanceResponsePayloadRT = rt.type({ - data: rt.string, + // TODO: add payload entries }); diff --git a/x-pack/plugins/monitoring/common/http_api/apm/post_apm_instances.ts b/x-pack/plugins/monitoring/common/http_api/apm/post_apm_instances.ts index 9e5510ed7a8f9..f6b10eccbea91 100644 --- a/x-pack/plugins/monitoring/common/http_api/apm/post_apm_instances.ts +++ b/x-pack/plugins/monitoring/common/http_api/apm/post_apm_instances.ts @@ -6,25 +6,23 @@ */ import * as rt from 'io-ts'; +import { ccsRT, clusterUuidRT, timeRangeRT } from '../shared'; export const postApmInstancesRequestParamsRT = rt.type({ - clusterUuid: rt.string, + clusterUuid: clusterUuidRT, }); export const postApmInstancesRequestPayloadRT = rt.intersection([ rt.partial({ - ccs: rt.string, + ccs: ccsRT, }), rt.type({ - timeRange: rt.type({ - min: rt.string, - max: rt.string, - }), + timeRange: timeRangeRT, }), ]); export type PostApmInstancesRequestPayload = rt.TypeOf; export const postApmInstancesResponsePayloadRT = rt.type({ - data: rt.string, + // TODO: add payload entries }); diff --git a/x-pack/plugins/monitoring/common/http_api/apm/post_apm_overview.ts b/x-pack/plugins/monitoring/common/http_api/apm/post_apm_overview.ts index e7da157984b1d..951d8103249d8 100644 --- a/x-pack/plugins/monitoring/common/http_api/apm/post_apm_overview.ts +++ b/x-pack/plugins/monitoring/common/http_api/apm/post_apm_overview.ts @@ -6,25 +6,23 @@ */ import * as rt from 'io-ts'; +import { ccsRT, clusterUuidRT, timeRangeRT } from '../shared'; export const postApmOverviewRequestParamsRT = rt.type({ - clusterUuid: rt.string, + clusterUuid: clusterUuidRT, }); export const postApmOverviewRequestPayloadRT = rt.intersection([ rt.partial({ - ccs: rt.string, + ccs: ccsRT, }), rt.type({ - timeRange: rt.type({ - min: rt.string, - max: rt.string, - }), + timeRange: timeRangeRT, }), ]); export type PostApmOverviewRequestPayload = rt.TypeOf; export const postApmOverviewResponsePayloadRT = rt.type({ - data: rt.string, + // TODO: add payload entries }); diff --git a/x-pack/plugins/monitoring/common/http_api/beats/index.ts b/x-pack/plugins/monitoring/common/http_api/beats/index.ts new file mode 100644 index 0000000000000..c10908392b84b --- /dev/null +++ b/x-pack/plugins/monitoring/common/http_api/beats/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './post_beats_overview'; +export * from './post_beats_listing'; +export * from './post_beat_detail'; diff --git a/x-pack/plugins/monitoring/common/http_api/beats/post_beat_detail.ts b/x-pack/plugins/monitoring/common/http_api/beats/post_beat_detail.ts new file mode 100644 index 0000000000000..6db962395a42d --- /dev/null +++ b/x-pack/plugins/monitoring/common/http_api/beats/post_beat_detail.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; +import { ccsRT, clusterUuidRT, timeRangeRT } from '../shared'; + +export const postBeatDetailRequestParamsRT = rt.type({ + clusterUuid: clusterUuidRT, + beatUuid: rt.string, +}); + +export const postBeatDetailRequestPayloadRT = rt.intersection([ + rt.partial({ + ccs: ccsRT, + }), + rt.type({ + timeRange: timeRangeRT, + }), +]); + +export type PostBeatDetailRequestPayload = rt.TypeOf; + +export const postBeatDetailResponsePayloadRT = rt.type({ + // TODO: add payload entries +}); diff --git a/x-pack/plugins/monitoring/common/http_api/beats/post_beats_listing.ts b/x-pack/plugins/monitoring/common/http_api/beats/post_beats_listing.ts new file mode 100644 index 0000000000000..007982849506b --- /dev/null +++ b/x-pack/plugins/monitoring/common/http_api/beats/post_beats_listing.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; +import { ccsRT, clusterUuidRT, timeRangeRT } from '../shared'; + +export const postBeatsListingRequestParamsRT = rt.type({ + clusterUuid: clusterUuidRT, +}); + +export const postBeatsListingRequestPayloadRT = rt.intersection([ + rt.partial({ + ccs: ccsRT, + }), + rt.type({ + timeRange: timeRangeRT, + }), +]); + +export type PostBeatsListingRequestPayload = rt.TypeOf; + +export const postBeatsListingResponsePayloadRT = rt.type({ + // TODO: add payload entries +}); diff --git a/x-pack/plugins/monitoring/common/http_api/beats/post_beats_overview.ts b/x-pack/plugins/monitoring/common/http_api/beats/post_beats_overview.ts new file mode 100644 index 0000000000000..b7d73dd0d2eab --- /dev/null +++ b/x-pack/plugins/monitoring/common/http_api/beats/post_beats_overview.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; +import { clusterUuidRT, ccsRT, timeRangeRT } from '../shared'; + +export const postBeatsOverviewRequestParamsRT = rt.type({ + clusterUuid: clusterUuidRT, +}); + +export const postBeatsOverviewRequestPayloadRT = rt.intersection([ + rt.partial({ + ccs: ccsRT, + }), + rt.type({ + timeRange: timeRangeRT, + }), +]); + +export type PostBeatsOverviewRequestPayload = rt.TypeOf; + +export const postBeatsOverviewResponsePayloadRT = rt.type({ + // TODO: add payload entries +}); diff --git a/x-pack/plugins/monitoring/common/http_api/elasticsearch/index.ts b/x-pack/plugins/monitoring/common/http_api/elasticsearch/index.ts new file mode 100644 index 0000000000000..2fa6180cc34a5 --- /dev/null +++ b/x-pack/plugins/monitoring/common/http_api/elasticsearch/index.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './post_elasticsearch_ccr'; +export * from './post_elasticsearch_ccr_shard'; +export * from './post_elasticsearch_index_detail'; +export * from './post_elasticsearch_indices'; +export * from './post_elasticsearch_ml_jobs'; +export * from './post_elasticsearch_node_detail'; +export * from './post_elasticsearch_nodes'; +export * from './post_elasticsearch_overview'; diff --git a/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_ccr.ts b/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_ccr.ts new file mode 100644 index 0000000000000..db74be0955c06 --- /dev/null +++ b/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_ccr.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; +import { clusterUuidRT, ccsRT, timeRangeRT } from '../shared'; + +export const postElasticsearchCcrRequestParamsRT = rt.type({ + clusterUuid: clusterUuidRT, +}); + +export const postElasticsearchCcrRequestPayloadRT = rt.intersection([ + rt.partial({ + ccs: ccsRT, + }), + rt.type({ + timeRange: timeRangeRT, + }), +]); + +export type PostElasticsearchCcrRequestPayload = rt.TypeOf< + typeof postElasticsearchCcrRequestPayloadRT +>; + +export const postElasticsearchCcrResponsePayloadRT = rt.type({ + // TODO: add payload entries +}); diff --git a/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_ccr_shard.ts b/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_ccr_shard.ts new file mode 100644 index 0000000000000..64f75658420f7 --- /dev/null +++ b/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_ccr_shard.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; +import { clusterUuidRT, ccsRT, timeRangeRT } from '../shared'; + +export const postElasticsearchCcrShardRequestParamsRT = rt.type({ + clusterUuid: clusterUuidRT, + index: rt.string, + shardId: rt.string, +}); + +export const postElasticsearchCcrShardRequestPayloadRT = rt.intersection([ + rt.partial({ + ccs: ccsRT, + }), + rt.type({ + timeRange: timeRangeRT, + }), +]); + +export type PostElasticsearchCcrShardRequestPayload = rt.TypeOf< + typeof postElasticsearchCcrShardRequestPayloadRT +>; + +export const postElasticsearchCcrShardResponsePayloadRT = rt.type({ + // TODO: add payload entries +}); diff --git a/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_index_detail.ts b/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_index_detail.ts new file mode 100644 index 0000000000000..b9bb491c0c387 --- /dev/null +++ b/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_index_detail.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; +import { ccsRT, clusterUuidRT, createLiteralValueFromUndefinedRT, timeRangeRT } from '../shared'; + +export const postElasticsearchIndexDetailRequestParamsRT = rt.type({ + clusterUuid: clusterUuidRT, + id: rt.string, +}); + +export const postElasticsearchIndexDetailRequestPayloadRT = rt.intersection([ + rt.partial({ + ccs: ccsRT, + }), + rt.type({ + is_advanced: rt.union([rt.boolean, createLiteralValueFromUndefinedRT(false)]), + timeRange: timeRangeRT, + }), +]); + +export type PostElasticsearchIndexDetailRequestPayload = rt.TypeOf< + typeof postElasticsearchIndexDetailRequestPayloadRT +>; + +export const postElasticsearchIndexDetailResponsePayloadRT = rt.type({ + // TODO: add payload entries +}); diff --git a/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_indices.ts b/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_indices.ts new file mode 100644 index 0000000000000..57a4b953f15dc --- /dev/null +++ b/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_indices.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; +import { + booleanFromStringRT, + ccsRT, + clusterUuidRT, + createLiteralValueFromUndefinedRT, + timeRangeRT, +} from '../shared'; + +export const postElasticsearchIndicesRequestParamsRT = rt.type({ + clusterUuid: clusterUuidRT, +}); + +export const postElasticsearchIndicesRequestPayloadRT = rt.intersection([ + rt.partial({ + ccs: ccsRT, + }), + rt.type({ + is_advanced: rt.union([rt.boolean, createLiteralValueFromUndefinedRT(false)]), + timeRange: timeRangeRT, + }), +]); + +export type PostElasticsearchIndicesRequestPayload = rt.TypeOf< + typeof postElasticsearchIndicesRequestPayloadRT +>; + +export const postElasticsearchIndicesRequestQueryRT = rt.type({ + show_system_indices: booleanFromStringRT, +}); + +export const postElasticsearchIndicesResponsePayloadRT = rt.type({ + // TODO: add payload entries +}); diff --git a/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_ml_jobs.ts b/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_ml_jobs.ts new file mode 100644 index 0000000000000..3cbe83fa5d27a --- /dev/null +++ b/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_ml_jobs.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; +import { clusterUuidRT, ccsRT, timeRangeRT } from '../shared'; + +export const postElasticsearchMlJobsRequestParamsRT = rt.type({ + clusterUuid: clusterUuidRT, +}); + +export const postElasticsearchMlJobsRequestPayloadRT = rt.intersection([ + rt.partial({ + ccs: ccsRT, + }), + rt.type({ + timeRange: timeRangeRT, + }), +]); + +export type PostElasticsearchMlJobsRequestPayload = rt.TypeOf< + typeof postElasticsearchMlJobsRequestPayloadRT +>; + +export const postElasticsearchMlJobsResponsePayloadRT = rt.type({ + // TODO: add payload entries +}); diff --git a/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_node_detail.ts b/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_node_detail.ts new file mode 100644 index 0000000000000..b29d9fb7b8daf --- /dev/null +++ b/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_node_detail.ts @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; +import { ccsRT, clusterUuidRT, createLiteralValueFromUndefinedRT, timeRangeRT } from '../shared'; + +export const postElasticsearchNodeDetailRequestParamsRT = rt.type({ + clusterUuid: clusterUuidRT, + nodeUuid: rt.string, +}); + +export const postElasticsearchNodeDetailRequestPayloadRT = rt.intersection([ + rt.partial({ + ccs: ccsRT, + showSystemIndices: rt.boolean, // show/hide system indices in shard allocation table + }), + rt.type({ + is_advanced: rt.union([rt.boolean, createLiteralValueFromUndefinedRT(false)]), + timeRange: timeRangeRT, + }), +]); + +export type PostElasticsearchNodeDetailRequestPayload = rt.TypeOf< + typeof postElasticsearchNodeDetailRequestPayloadRT +>; + +export const postElasticsearchNodeDetailResponsePayloadRT = rt.type({ + // TODO: add payload entries +}); diff --git a/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_nodes.ts b/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_nodes.ts new file mode 100644 index 0000000000000..bba6525d9a2c8 --- /dev/null +++ b/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_nodes.ts @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; +import { clusterUuidRT, ccsRT, timeRangeRT, paginationRT, sortingRT } from '../shared'; + +export const postElasticsearchNodesRequestParamsRT = rt.type({ + clusterUuid: clusterUuidRT, +}); + +export const postElasticsearchNodesRequestPayloadRT = rt.intersection([ + rt.partial({ + ccs: ccsRT, + queryText: rt.string, + sort: sortingRT, + }), + rt.type({ + timeRange: timeRangeRT, + pagination: paginationRT, + }), +]); + +export type PostElasticsearchNodesRequestPayload = rt.TypeOf< + typeof postElasticsearchNodesRequestPayloadRT +>; + +export const postElasticsearchNodesResponsePayloadRT = rt.type({ + // TODO: add payload entries +}); diff --git a/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_overview.ts b/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_overview.ts new file mode 100644 index 0000000000000..da82f7cfedbf0 --- /dev/null +++ b/x-pack/plugins/monitoring/common/http_api/elasticsearch/post_elasticsearch_overview.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; +import { clusterUuidRT, ccsRT, timeRangeRT } from '../shared'; + +export const postElasticsearchOverviewRequestParamsRT = rt.type({ + clusterUuid: clusterUuidRT, +}); + +export const postElasticsearchOverviewRequestPayloadRT = rt.intersection([ + rt.partial({ + ccs: ccsRT, + }), + rt.type({ + timeRange: timeRangeRT, + }), +]); + +export type PostElasticsearchOverviewRequestPayload = rt.TypeOf< + typeof postElasticsearchOverviewRequestPayloadRT +>; + +export const postElasticsearchOverviewResponsePayloadRT = rt.type({ + // TODO: add payload entries +}); diff --git a/x-pack/plugins/monitoring/common/http_api/shared/ccs.ts b/x-pack/plugins/monitoring/common/http_api/shared/ccs.ts new file mode 100644 index 0000000000000..041b14fa531e3 --- /dev/null +++ b/x-pack/plugins/monitoring/common/http_api/shared/ccs.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; + +export const ccsRT = rt.string; diff --git a/x-pack/plugins/monitoring/common/http_api/shared/cluster.ts b/x-pack/plugins/monitoring/common/http_api/shared/cluster.ts new file mode 100644 index 0000000000000..43a3c587c1db7 --- /dev/null +++ b/x-pack/plugins/monitoring/common/http_api/shared/cluster.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; + +export const clusterUuidRT = rt.string; diff --git a/x-pack/plugins/monitoring/common/http_api/shared/index.ts b/x-pack/plugins/monitoring/common/http_api/shared/index.ts new file mode 100644 index 0000000000000..4e47c7239e39f --- /dev/null +++ b/x-pack/plugins/monitoring/common/http_api/shared/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './ccs'; +export * from './cluster'; +export * from './literal_value'; +export * from './pagination'; +export * from './query_string_boolean'; +export * from './sorting'; +export * from './time_range'; diff --git a/x-pack/plugins/monitoring/common/http_api/shared/literal_value.ts b/x-pack/plugins/monitoring/common/http_api/shared/literal_value.ts new file mode 100644 index 0000000000000..55719d6b31b12 --- /dev/null +++ b/x-pack/plugins/monitoring/common/http_api/shared/literal_value.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; + +export const createLiteralValueFromUndefinedRT = ( + literalValue: LiteralValue +) => + rt.undefined.pipe( + new rt.Type( + 'BooleanFromString', + rt.literal(literalValue).is, + (_value, _context) => rt.success(literalValue), + () => undefined + ) + ); diff --git a/x-pack/plugins/monitoring/common/http_api/shared/pagination.ts b/x-pack/plugins/monitoring/common/http_api/shared/pagination.ts new file mode 100644 index 0000000000000..50f1f77b0361c --- /dev/null +++ b/x-pack/plugins/monitoring/common/http_api/shared/pagination.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; + +export const paginationRT = rt.type({ + index: rt.number, + size: rt.number, +}); diff --git a/x-pack/plugins/monitoring/common/http_api/shared/query_string_boolean.ts b/x-pack/plugins/monitoring/common/http_api/shared/query_string_boolean.ts new file mode 100644 index 0000000000000..b9b6fcae3780c --- /dev/null +++ b/x-pack/plugins/monitoring/common/http_api/shared/query_string_boolean.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { chain } from 'fp-ts/lib/Either'; +import { pipe } from 'fp-ts/lib/pipeable'; +import * as rt from 'io-ts'; + +export const booleanFromStringRT = new rt.Type( + 'BooleanFromString', + rt.boolean.is, + (value, context) => + pipe( + rt.string.validate(value, context), + chain((stringValue) => + stringValue === 'true' + ? rt.success(true) + : stringValue === 'false' + ? rt.success(false) + : rt.failure(value, context) + ) + ), + String +); diff --git a/x-pack/plugins/monitoring/common/http_api/shared/sorting.ts b/x-pack/plugins/monitoring/common/http_api/shared/sorting.ts new file mode 100644 index 0000000000000..c52c46a41376c --- /dev/null +++ b/x-pack/plugins/monitoring/common/http_api/shared/sorting.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; + +const sortingDirectionRT = rt.keyof({ + asc: null, + desc: null, +}); + +export const sortingRT = rt.partial({ + field: rt.string, + direction: sortingDirectionRT, +}); diff --git a/x-pack/plugins/monitoring/common/http_api/shared/time_range.ts b/x-pack/plugins/monitoring/common/http_api/shared/time_range.ts new file mode 100644 index 0000000000000..4021e8d52f4cd --- /dev/null +++ b/x-pack/plugins/monitoring/common/http_api/shared/time_range.ts @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; +import moment from 'moment'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { chain } from 'fp-ts/lib/Either'; + +export const timestampFromStringRT = new rt.Type( + 'timestampFromStringRT', + (input): input is number => typeof input === 'number', + (input, context) => + pipe( + rt.string.validate(input, context), + chain((stringInput) => { + const momentValue = moment.utc(stringInput); + return momentValue.isValid() + ? rt.success(momentValue.valueOf()) + : rt.failure(stringInput, context); + }) + ), + (output) => new Date(output).toISOString() +); + +export const timeRangeRT = rt.type({ + min: timestampFromStringRT, + max: timestampFromStringRT, +}); + +export type TimeRange = rt.TypeOf; diff --git a/x-pack/plugins/monitoring/common/types/es.ts b/x-pack/plugins/monitoring/common/types/es.ts index fc19ef0e9aab9..f4c4b385d625d 100644 --- a/x-pack/plugins/monitoring/common/types/es.ts +++ b/x-pack/plugins/monitoring/common/types/es.ts @@ -412,6 +412,7 @@ export interface ElasticsearchIndexRecoveryShard { export interface ElasticsearchMetricbeatNode { name?: string; stats?: ElasticsearchNodeStats; + master: boolean; } export interface ElasticsearchMetricbeatSource { diff --git a/x-pack/plugins/monitoring/kibana.json b/x-pack/plugins/monitoring/kibana.json index 808d052546bf1..bbb6eb374e91d 100644 --- a/x-pack/plugins/monitoring/kibana.json +++ b/x-pack/plugins/monitoring/kibana.json @@ -7,7 +7,7 @@ "githubTeam": "stack-monitoring-ui" }, "configPath": ["monitoring"], - "requiredPlugins": ["licensing", "features", "data", "navigation", "observability", "dataViews"], + "requiredPlugins": ["licensing", "features", "data", "navigation", "observability", "dataViews", "unifiedSearch"], "optionalPlugins": [ "infra", "usageCollection", diff --git a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/index_advanced_page.tsx b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/index_advanced_page.tsx index 734d59f310676..410a909a9c4ab 100644 --- a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/index_advanced_page.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/index_advanced_page.tsx @@ -29,6 +29,7 @@ export const ElasticsearchIndexAdvancedPage: React.FC = ({ clust const { index }: { index: string } = useParams(); const { zoomInfo, onBrush } = useCharts(); const clusterUuid = globalState.cluster_uuid; + const ccs = globalState.ccs; const [data, setData] = useState({} as any); const [alerts, setAlerts] = useState({}); @@ -60,6 +61,7 @@ export const ElasticsearchIndexAdvancedPage: React.FC = ({ clust const response = await services.http?.fetch(url, { method: 'POST', body: JSON.stringify({ + ccs, timeRange: { min: bounds.min.toISOString(), max: bounds.max.toISOString(), @@ -84,7 +86,7 @@ export const ElasticsearchIndexAdvancedPage: React.FC = ({ clust }); setAlerts(alertsResponse); } - }, [clusterUuid, services.data?.query.timefilter.timefilter, services.http, index]); + }, [services.data?.query.timefilter.timefilter, services.http, clusterUuid, index, ccs]); return ( = ({ clusters }) = const { index }: { index: string } = useParams(); const { zoomInfo, onBrush } = useCharts(); const clusterUuid = globalState.cluster_uuid; + const ccs = globalState.ccs; const [data, setData] = useState({} as any); const [indexLabel, setIndexLabel] = useState(labels.index as any); const [nodesByIndicesData, setNodesByIndicesData] = useState([]); @@ -72,6 +73,7 @@ export const ElasticsearchIndexPage: React.FC = ({ clusters }) = const response = await services.http?.fetch<{ shards: unknown[]; nodes: unknown[] }>(url, { method: 'POST', body: JSON.stringify({ + ccs, timeRange: { min: bounds.min.toISOString(), max: bounds.max.toISOString(), @@ -103,7 +105,7 @@ export const ElasticsearchIndexPage: React.FC = ({ clusters }) = }); setAlerts(alertsResponse); } - }, [clusterUuid, services.data?.query.timefilter.timefilter, services.http, index]); + }, [services.data?.query.timefilter.timefilter, services.http, clusterUuid, index, ccs]); return ( ; + kibana: KibanaReactContextValue< + { unifiedSearch: UnifiedSearchPublicPluginStart } & KibanaServices + >; children: RendererFunction<{ isLoadingSuggestions: boolean; loadSuggestions: (expression: string, cursorPosition: number, maxSuggestions?: number) => void; @@ -63,7 +65,7 @@ class WithKueryAutocompletionComponent extends React.Component< const { indexPattern } = this.props; const language = 'kuery'; const hasQuerySuggestions = - this.props.kibana.services.data?.autocomplete.hasQuerySuggestions(language); + this.props.kibana.services.unifiedSearch?.autocomplete.hasQuerySuggestions(language); if (!hasQuerySuggestions) { return; @@ -78,7 +80,7 @@ class WithKueryAutocompletionComponent extends React.Component< }); const suggestions = - (await this.props.kibana.services.data.autocomplete.getQuerySuggestions({ + (await this.props.kibana.services.unifiedSearch.autocomplete.getQuerySuggestions({ language, query: expression, selectionStart: cursorPosition, diff --git a/x-pack/plugins/monitoring/public/components/no_data/__snapshots__/no_data.test.js.snap b/x-pack/plugins/monitoring/public/components/no_data/__snapshots__/no_data.test.js.snap index 8852d104fe00a..e0068c8a150d8 100644 --- a/x-pack/plugins/monitoring/public/components/no_data/__snapshots__/no_data.test.js.snap +++ b/x-pack/plugins/monitoring/public/components/no_data/__snapshots__/no_data.test.js.snap @@ -38,6 +38,9 @@ exports[`NoData should show a default message if reason is unknown 1`] = `

Have you set up monitoring yet? If so, make sure that the selected time period in the upper right includes monitoring data.

+

+ If you have configured monitoring data to be sent to a dedicated monitoring cluster you should access that data with the Kibana instance attached to the monitoring cluster. +

Have you set up monitoring yet? If so, make sure that the selected time period in the upper right includes monitoring data.

+

+ If you have configured monitoring data to be sent to a dedicated monitoring cluster you should access that data with the Kibana instance attached to the monitoring cluster. +

+

+ +

diff --git a/x-pack/plugins/monitoring/server/alerts/base_rule.ts b/x-pack/plugins/monitoring/server/alerts/base_rule.ts index 9c9d993e0a340..1888265c124f6 100644 --- a/x-pack/plugins/monitoring/server/alerts/base_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/base_rule.ts @@ -344,6 +344,7 @@ export class BaseRule { if (ccs) { globalState.push(`ccs:${ccs}`); } - return `${Globals.app.url}/app/monitoring#/${link}?_g=(${globalState.toString()})`; + + return `${Globals.app.url ?? ''}/app/monitoring#/${link}?_g=(${globalState.toString()})`; } } diff --git a/x-pack/plugins/monitoring/server/lib/details/get_metrics.ts b/x-pack/plugins/monitoring/server/lib/details/get_metrics.ts index 83db64add1c69..475d2c681596e 100644 --- a/x-pack/plugins/monitoring/server/lib/details/get_metrics.ts +++ b/x-pack/plugins/monitoring/server/lib/details/get_metrics.ts @@ -13,13 +13,20 @@ import { getTimezone } from '../get_timezone'; import { LegacyRequest } from '../../types'; import { INDEX_PATTERN_TYPES } from '../../../common/constants'; -type Metric = string | { keys: string | string[]; name: string }; +export interface NamedMetricDescriptor { + keys: string | string[]; + name: string; +} + +export type SimpleMetricDescriptor = string; + +export type MetricDescriptor = SimpleMetricDescriptor | NamedMetricDescriptor; // TODO: Switch to an options object argument here export async function getMetrics( req: LegacyRequest, moduleType: INDEX_PATTERN_TYPES, - metricSet: Metric[] = [], + metricSet: MetricDescriptor[] = [], filters: Array> = [], metricOptions: Record = {}, numOfBuckets: number = 0, @@ -42,7 +49,7 @@ export async function getMetrics( } return Promise.all( - metricSet.map((metric: Metric) => { + metricSet.map((metric: MetricDescriptor) => { // metric names match the literal metric name, but they can be supplied in groups or individually let metricNames; diff --git a/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/get_node_type_class_label.ts b/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/get_node_type_class_label.ts index c0a4f4ff2a48c..057e4ec7efee0 100644 --- a/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/get_node_type_class_label.ts +++ b/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/get_node_type_class_label.ts @@ -21,7 +21,13 @@ export function getNodeTypeClassLabel( node: ElasticsearchLegacySource['source_node'] | ElasticsearchMetricbeatNode, type: keyof typeof nodeTypeLabel ) { - const nodeType = node && 'master' in node ? 'master' : type; + let nodeType = null; + if (isElasticsearchMetricbeatNode(node)) { + nodeType = node.master ? 'master' : type; + } else { + nodeType = type; + } + const returnObj = { nodeType, nodeTypeLabel: nodeTypeLabel[nodeType], @@ -29,3 +35,13 @@ export function getNodeTypeClassLabel( }; return returnObj; } + +function isElasticsearchMetricbeatNode( + node: ElasticsearchLegacySource['source_node'] | ElasticsearchMetricbeatNode +): node is ElasticsearchMetricbeatNode { + if (!node) { + return false; + } + + return 'master' in node; +} diff --git a/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/get_paginated_nodes.ts b/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/get_paginated_nodes.ts index 541320e8499f5..bf999d67a4d88 100644 --- a/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/get_paginated_nodes.ts +++ b/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/get_paginated_nodes.ts @@ -36,6 +36,9 @@ import { ElasticsearchModifiedSource } from '../../../../../common/types/es'; interface Node { name: string; uuid: string; +} + +interface NodeWithStatus extends Node { isOnline: boolean; shardCount: number; } @@ -52,7 +55,7 @@ export async function getPaginatedNodes( nodesShardCount, }: { clusterStats: { - cluster_state?: { nodes: Record }; + cluster_state?: { nodes?: Record }; elasticsearch?: ElasticsearchModifiedSource['elasticsearch']; }; nodesShardCount: { nodes: Record }; @@ -67,10 +70,11 @@ export async function getPaginatedNodes( clusterStats?.cluster_state?.nodes ?? clusterStats?.elasticsearch?.cluster?.stats?.state?.nodes ?? {}; - for (const node of nodes) { - node.isOnline = !isUndefined(clusterStateNodes && clusterStateNodes[node.uuid]); - node.shardCount = nodesShardCount?.nodes[node.uuid]?.shardCount ?? 0; - } + const nodesWithStatus: NodeWithStatus[] = nodes.map((node) => ({ + ...node, + isOnline: !isUndefined(clusterStateNodes && clusterStateNodes[node.uuid]), + shardCount: nodesShardCount?.nodes[node.uuid]?.shardCount ?? 0, + })); // `metricSet` defines a list of metrics that are sortable in the UI // but we don't need to fetch all the data for these metrics to perform @@ -80,13 +84,13 @@ export async function getPaginatedNodes( const filters = [ { terms: { - 'source_node.name': nodes.map((node) => node.name), + 'source_node.name': nodesWithStatus.map((node) => node.name), }, }, ]; const groupBy = { field: `source_node.uuid`, - include: nodes.map((node) => node.uuid), + include: nodesWithStatus.map((node) => node.uuid), size, }; const metricSeriesData = await getMetrics( @@ -94,7 +98,7 @@ export async function getPaginatedNodes( 'elasticsearch', metricSet, filters, - { nodes }, + { nodes: nodesWithStatus }, 4, groupBy ); @@ -106,7 +110,7 @@ export async function getPaginatedNodes( const metricList = metricSeriesData[metricName]; for (const metricItem of metricList[0]) { - const node = nodes.find((n) => n.uuid === metricItem.groupedBy); + const node = nodesWithStatus.find((n) => n.uuid === metricItem.groupedBy); if (!node) { continue; } @@ -124,7 +128,7 @@ export async function getPaginatedNodes( // Manually apply pagination/sorting/filtering concerns // Filtering - const filteredNodes = filter(nodes, queryText, ['name']); // We only support filtering by name right now + const filteredNodes = filter(nodesWithStatus, queryText, ['name']); // We only support filtering by name right now // Sorting const sortedNodes = sortNodes(filteredNodes, sort); diff --git a/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/sort_nodes.ts b/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/sort_nodes.ts index 33d29f2a05998..1fbd0f0130e49 100644 --- a/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/sort_nodes.ts +++ b/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/sort_nodes.ts @@ -9,7 +9,10 @@ import { orderBy } from 'lodash'; type Node = Record; -export function sortNodes(nodes: Node[], sort?: { field: string; direction: 'asc' | 'desc' }) { +export function sortNodes( + nodes: T[], + sort?: { field: string; direction: 'asc' | 'desc' } +) { if (!sort || !sort.field) { return nodes; } diff --git a/x-pack/plugins/monitoring/server/lib/elasticsearch/shards/get_shard_stats.ts b/x-pack/plugins/monitoring/server/lib/elasticsearch/shards/get_shard_stats.ts index 9c2c5cf45235a..df60ce3ffecef 100644 --- a/x-pack/plugins/monitoring/server/lib/elasticsearch/shards/get_shard_stats.ts +++ b/x-pack/plugins/monitoring/server/lib/elasticsearch/shards/get_shard_stats.ts @@ -6,22 +6,15 @@ */ import { get } from 'lodash'; -// @ts-ignore -import { checkParam } from '../../error_missing_required'; -// @ts-ignore +import { ElasticsearchModifiedSource, ElasticsearchResponse } from '../../../../common/types/es'; +import { Globals } from '../../../static_globals'; +import { LegacyRequest } from '../../../types'; +import { getNewIndexPatterns } from '../../cluster/get_index_patterns'; import { createQuery } from '../../create_query'; -// @ts-ignore import { ElasticsearchMetric } from '../../metrics'; -// @ts-ignore -import { normalizeIndexShards, normalizeNodeShards } from './normalize_shard_objects'; -// @ts-ignore -import { getShardAggs } from './get_shard_stat_aggs'; -// @ts-ignore import { calculateIndicesTotals } from './calculate_shard_stat_indices_totals'; -import { LegacyRequest } from '../../../types'; -import { ElasticsearchResponse, ElasticsearchModifiedSource } from '../../../../common/types/es'; -import { getNewIndexPatterns } from '../../cluster/get_index_patterns'; -import { Globals } from '../../../static_globals'; +import { getShardAggs } from './get_shard_stat_aggs'; +import { normalizeIndexShards, normalizeNodeShards } from './normalize_shard_objects'; export function handleResponse( resp: ElasticsearchResponse, @@ -58,7 +51,17 @@ export function handleResponse( export function getShardStats( req: LegacyRequest, cluster: ElasticsearchModifiedSource, - { includeNodes = false, includeIndices = false, indexName = null, nodeUuid = null } = {} + { + includeNodes = false, + includeIndices = false, + indexName = null, + nodeUuid = null, + }: { + includeNodes?: boolean; + includeIndices?: boolean; + indexName?: string | null; + nodeUuid?: string | null; + } = {} ) { const dataset = 'shard'; // data_stream.dataset const type = 'shards'; // legacy diff --git a/x-pack/plugins/monitoring/server/lib/logs/detect_reason.ts b/x-pack/plugins/monitoring/server/lib/logs/detect_reason.ts index 216d29d841a86..e9b906af677e8 100644 --- a/x-pack/plugins/monitoring/server/lib/logs/detect_reason.ts +++ b/x-pack/plugins/monitoring/server/lib/logs/detect_reason.ts @@ -8,7 +8,7 @@ import { LegacyRequest } from '../../types'; import { createTimeFilter } from '../create_query'; -interface Opts { +export interface FilebeatIndexCheckOpts { start: number; end: number; clusterUuid?: string; @@ -19,7 +19,7 @@ interface Opts { async function doesFilebeatIndexExist( req: LegacyRequest, filebeatIndexPattern: string, - { start, end, clusterUuid, nodeUuid, indexUuid }: Opts + { start, end, clusterUuid, nodeUuid, indexUuid }: FilebeatIndexCheckOpts ) { const metric = { timestampField: '@timestamp' }; const filter = [createTimeFilter({ start, end, metric })]; @@ -142,6 +142,10 @@ async function doesFilebeatIndexExist( }; } -export async function detectReason(req: LegacyRequest, filebeatIndexPattern: string, opts: Opts) { +export async function detectReason( + req: LegacyRequest, + filebeatIndexPattern: string, + opts: FilebeatIndexCheckOpts +) { return await doesFilebeatIndexExist(req, filebeatIndexPattern, opts); } diff --git a/x-pack/plugins/monitoring/server/lib/logs/get_logs.ts b/x-pack/plugins/monitoring/server/lib/logs/get_logs.ts index 9e9f67831ba95..c243414c3649e 100644 --- a/x-pack/plugins/monitoring/server/lib/logs/get_logs.ts +++ b/x-pack/plugins/monitoring/server/lib/logs/get_logs.ts @@ -6,17 +6,11 @@ */ import moment from 'moment'; -// @ts-ignore import { checkParam } from '../error_missing_required'; -// @ts-ignore import { createTimeFilter } from '../create_query'; -// @ts-ignore -import { detectReason } from './detect_reason'; -// @ts-ignore +import { detectReason, FilebeatIndexCheckOpts } from './detect_reason'; import { formatUTCTimestampForTimezone } from '../format_timezone'; -// @ts-ignore import { getTimezone } from '../get_timezone'; -// @ts-ignore import { detectReasonFromException } from './detect_reason_from_exception'; import { LegacyRequest } from '../../types'; import { FilebeatResponse } from '../../../common/types/filebeat'; @@ -36,7 +30,7 @@ async function handleResponse( response: FilebeatResponse, req: LegacyRequest, filebeatIndexPattern: string, - opts: { clusterUuid: string; nodeUuid: string; indexUuid: string; start: number; end: number } + opts: FilebeatIndexCheckOpts ) { const result: { enabled: boolean; logs: Log[]; reason?: any } = { enabled: false, @@ -73,13 +67,7 @@ export async function getLogs( config: MonitoringConfig, req: LegacyRequest, filebeatIndexPattern: string, - { - clusterUuid, - nodeUuid, - indexUuid, - start, - end, - }: { clusterUuid: string; nodeUuid: string; indexUuid: string; start: number; end: number } + { clusterUuid, nodeUuid, indexUuid, start, end }: FilebeatIndexCheckOpts ) { checkParam(filebeatIndexPattern, 'filebeatIndexPattern in logs/getLogs'); diff --git a/x-pack/plugins/monitoring/server/plugin.ts b/x-pack/plugins/monitoring/server/plugin.ts index ef2cc93bff652..c81fb90e614cb 100644 --- a/x-pack/plugins/monitoring/server/plugin.ts +++ b/x-pack/plugins/monitoring/server/plugin.ts @@ -326,14 +326,16 @@ export class MonitoringPlugin res: KibanaResponseFactory ) => { const plugins = (await getCoreServices())[1]; - const legacyRequest: LegacyRequest = { + const coreContext = await context.core; + const actionContext = await context.actions; + const legacyRequest: LegacyRequest = { ...req, logger: this.log, getLogger: this.getLogger, payload: req.body, getKibanaStatsCollector: () => this.legacyShimDependencies.kibanaStatsCollector, - getUiSettingsService: () => context.core.uiSettings.client, - getActionTypeRegistry: () => context.actions?.listTypes(), + getUiSettingsService: () => coreContext.uiSettings.client, + getActionTypeRegistry: () => actionContext?.listTypes(), getRulesClient: () => { try { return plugins.alerting.getRulesClientWithRequest(req); @@ -372,7 +374,7 @@ export class MonitoringPlugin const client = name === 'monitoring' ? cluster.asScoped(req).asCurrentUser - : context.core.elasticsearch.client.asCurrentUser; + : coreContext.elasticsearch.client.asCurrentUser; return await Globals.app.getLegacyClusterShim(client, endpoint, params); }, }), diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/alerts/enable.ts b/x-pack/plugins/monitoring/server/routes/api/v1/alerts/enable.ts index e23e636fe5676..9188215137565 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/alerts/enable.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/alerts/enable.ts @@ -24,6 +24,10 @@ export function enableAlertsRoute(server: LegacyServer, npRoute: RouteDependenci }, async (context, request, response) => { try { + const alertingContext = await context.alerting; + const infraContext = await context.infra; + const actionContext = await context.actions; + const alerts = AlertsFactory.getAll(); if (alerts.length) { const { isSufficientlySecure, hasPermanentEncryptionKey } = npRoute.alerting @@ -33,7 +37,7 @@ export function enableAlertsRoute(server: LegacyServer, npRoute: RouteDependenci if (!isSufficientlySecure || !hasPermanentEncryptionKey) { server.log.info( - `Skipping rule creation for "${context.infra.spaceId}" space; Stack Monitoring rules require API keys to be enabled and an encryption key to be configured.` + `Skipping rule creation for "${infraContext.spaceId}" space; Stack Monitoring rules require API keys to be enabled and an encryption key to be configured.` ); return response.ok({ body: { @@ -44,9 +48,9 @@ export function enableAlertsRoute(server: LegacyServer, npRoute: RouteDependenci } } - const rulesClient = context.alerting?.getRulesClient(); - const actionsClient = context.actions?.getActionsClient(); - const types = context.actions?.listTypes(); + const rulesClient = alertingContext?.getRulesClient(); + const actionsClient = actionContext?.getActionsClient(); + const types = actionContext?.listTypes(); if (!rulesClient || !actionsClient || !types) { return response.ok({ body: undefined }); } @@ -92,7 +96,7 @@ export function enableAlertsRoute(server: LegacyServer, npRoute: RouteDependenci } server.log.info( - `Created ${createdAlerts.length} alerts for "${context.infra.spaceId}" space` + `Created ${createdAlerts.length} alerts for "${infraContext.spaceId}" space` ); return response.ok({ body: { createdAlerts, disabledWatcherClusterAlerts } }); diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/alerts/status.ts b/x-pack/plugins/monitoring/server/routes/api/v1/alerts/status.ts index 27b21c342f037..a145d92921634 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/alerts/status.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/alerts/status.ts @@ -34,7 +34,7 @@ export function alertStatusRoute(server: any, npRoute: RouteDependencies) { try { const { clusterUuid } = request.params; const { alertTypeIds, filters } = request.body; - const rulesClient = context.alerting?.getRulesClient(); + const rulesClient = (await context.alerting)?.getRulesClient(); if (!rulesClient) { return response.ok({ body: undefined }); } diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/apm/instance.ts b/x-pack/plugins/monitoring/server/routes/api/v1/apm/instance.ts index 69b226ef3eaed..7410a91293fb9 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/apm/instance.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/apm/instance.ts @@ -19,12 +19,15 @@ import { MonitoringCore } from '../../../../types'; import { metricSet } from './metric_set_instance'; export function apmInstanceRoute(server: MonitoringCore) { + const validateParams = createValidationFunction(postApmInstanceRequestParamsRT); + const validateBody = createValidationFunction(postApmInstanceRequestPayloadRT); + server.route({ method: 'post', path: '/api/monitoring/v1/clusters/{clusterUuid}/apm/{apmUuid}', validate: { - params: createValidationFunction(postApmInstanceRequestParamsRT), - body: createValidationFunction(postApmInstanceRequestPayloadRT), + params: validateParams, + body: validateBody, }, async handler(req) { const apmUuid = req.params.apmUuid; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/apm/instances.ts b/x-pack/plugins/monitoring/server/routes/api/v1/apm/instances.ts index 960a8dc3627b0..6225bd4b553b1 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/apm/instances.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/apm/instances.ts @@ -17,12 +17,15 @@ import { handleError } from '../../../../lib/errors'; import { MonitoringCore } from '../../../../types'; export function apmInstancesRoute(server: MonitoringCore) { + const validateParams = createValidationFunction(postApmInstancesRequestParamsRT); + const validateBody = createValidationFunction(postApmInstancesRequestPayloadRT); + server.route({ method: 'post', path: '/api/monitoring/v1/clusters/{clusterUuid}/apm/instances', validate: { - params: createValidationFunction(postApmInstancesRequestParamsRT), - body: createValidationFunction(postApmInstancesRequestPayloadRT), + params: validateParams, + body: validateBody, }, async handler(req) { const config = server.config; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/apm/metric_set_instance.ts b/x-pack/plugins/monitoring/server/routes/api/v1/apm/metric_set_instance.ts index d6fc7cbd2c076..427c0610832d3 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/apm/metric_set_instance.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/apm/metric_set_instance.ts @@ -5,7 +5,9 @@ * 2.0. */ -export const metricSet = [ +import { NamedMetricDescriptor } from '../../../../lib/details/get_metrics'; + +export const metricSet: NamedMetricDescriptor[] = [ { name: 'apm_cpu', keys: ['apm_cpu_total'], diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/apm/metric_set_overview.ts b/x-pack/plugins/monitoring/server/routes/api/v1/apm/metric_set_overview.ts index b0dccb8dd34df..c6f126ca2f6b9 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/apm/metric_set_overview.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/apm/metric_set_overview.ts @@ -5,7 +5,9 @@ * 2.0. */ -export const metricSet = [ +import { NamedMetricDescriptor } from '../../../../lib/details/get_metrics'; + +export const metricSet: NamedMetricDescriptor[] = [ { name: 'apm_cpu', keys: ['apm_cpu_total'], diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/apm/overview.ts b/x-pack/plugins/monitoring/server/routes/api/v1/apm/overview.ts index 532b5fa4dc4c8..5e23b0138a72f 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/apm/overview.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/apm/overview.ts @@ -17,12 +17,15 @@ import { metricSet } from './metric_set_overview'; import { getApmClusterStatus } from './_get_apm_cluster_status'; export function apmOverviewRoute(server: MonitoringCore) { + const validateParams = createValidationFunction(postApmOverviewRequestParamsRT); + const validateBody = createValidationFunction(postApmOverviewRequestPayloadRT); + server.route({ method: 'post', path: '/api/monitoring/v1/clusters/{clusterUuid}/apm', validate: { - params: createValidationFunction(postApmOverviewRequestParamsRT), - body: createValidationFunction(postApmOverviewRequestPayloadRT), + params: validateParams, + body: validateBody, }, async handler(req) { const config = server.config; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/beats/beat_detail.js b/x-pack/plugins/monitoring/server/routes/api/v1/beats/beat_detail.js deleted file mode 100644 index 8c28dd420675a..0000000000000 --- a/x-pack/plugins/monitoring/server/routes/api/v1/beats/beat_detail.js +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { schema } from '@kbn/config-schema'; -import { prefixIndexPatternWithCcs } from '../../../../../common/ccs_utils'; -import { getBeatSummary } from '../../../../lib/beats'; -import { getMetrics } from '../../../../lib/details/get_metrics'; -import { handleError } from '../../../../lib/errors'; -import { metricSet } from './metric_set_detail'; -import { INDEX_PATTERN_BEATS } from '../../../../../common/constants'; - -export function beatsDetailRoute(server) { - server.route({ - method: 'POST', - path: '/api/monitoring/v1/clusters/{clusterUuid}/beats/beat/{beatUuid}', - config: { - validate: { - params: schema.object({ - clusterUuid: schema.string(), - beatUuid: schema.string(), - }), - body: schema.object({ - ccs: schema.maybe(schema.string()), - timeRange: schema.object({ - min: schema.string(), - max: schema.string(), - }), - }), - }, - }, - async handler(req) { - const clusterUuid = req.params.clusterUuid; - const beatUuid = req.params.beatUuid; - const config = server.config; - const ccs = req.payload.ccs; - const beatsIndexPattern = prefixIndexPatternWithCcs(config, INDEX_PATTERN_BEATS, ccs); - - const summaryOptions = { - clusterUuid, - beatUuid, - start: req.payload.timeRange.min, - end: req.payload.timeRange.max, - }; - - try { - const [summary, metrics] = await Promise.all([ - getBeatSummary(req, beatsIndexPattern, summaryOptions), - getMetrics(req, 'beats', metricSet, [{ term: { 'beats_stats.beat.uuid': beatUuid } }]), - ]); - - return { - summary, - metrics, - }; - } catch (err) { - throw handleError(err, req); - } - }, - }); -} diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/beats/beat_detail.ts b/x-pack/plugins/monitoring/server/routes/api/v1/beats/beat_detail.ts new file mode 100644 index 0000000000000..26477b3611360 --- /dev/null +++ b/x-pack/plugins/monitoring/server/routes/api/v1/beats/beat_detail.ts @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { prefixIndexPatternWithCcs } from '../../../../../common/ccs_utils'; +import { INDEX_PATTERN_BEATS } from '../../../../../common/constants'; +import { + postBeatDetailRequestParamsRT, + postBeatDetailRequestPayloadRT, + postBeatDetailResponsePayloadRT, +} from '../../../../../common/http_api/beats'; +import { getBeatSummary } from '../../../../lib/beats'; +import { createValidationFunction } from '../../../../lib/create_route_validation_function'; +import { getMetrics } from '../../../../lib/details/get_metrics'; +import { handleError } from '../../../../lib/errors'; +import { MonitoringCore } from '../../../../types'; +import { metricSet } from './metric_set_detail'; + +export function beatsDetailRoute(server: MonitoringCore) { + const validateParams = createValidationFunction(postBeatDetailRequestParamsRT); + const validateBody = createValidationFunction(postBeatDetailRequestPayloadRT); + + server.route({ + method: 'post', + path: '/api/monitoring/v1/clusters/{clusterUuid}/beats/beat/{beatUuid}', + validate: { + params: validateParams, + body: validateBody, + }, + async handler(req) { + const clusterUuid = req.params.clusterUuid; + const beatUuid = req.params.beatUuid; + const config = server.config; + const ccs = req.payload.ccs; + const beatsIndexPattern = prefixIndexPatternWithCcs(config, INDEX_PATTERN_BEATS, ccs); + + const summaryOptions = { + clusterUuid, + beatUuid, + start: req.payload.timeRange.min, + end: req.payload.timeRange.max, + }; + + try { + const [summary, metrics] = await Promise.all([ + getBeatSummary(req, beatsIndexPattern, summaryOptions), + getMetrics(req, 'beats', metricSet, [{ term: { 'beats_stats.beat.uuid': beatUuid } }]), + ]); + + return postBeatDetailResponsePayloadRT.encode({ + summary, + metrics, + }); + } catch (err) { + throw handleError(err, req); + } + }, + }); +} diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/beats/beats.js b/x-pack/plugins/monitoring/server/routes/api/v1/beats/beats.js deleted file mode 100644 index 83403eaa355bd..0000000000000 --- a/x-pack/plugins/monitoring/server/routes/api/v1/beats/beats.js +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { schema } from '@kbn/config-schema'; -import { prefixIndexPatternWithCcs } from '../../../../../common/ccs_utils'; -import { getStats, getBeats } from '../../../../lib/beats'; -import { handleError } from '../../../../lib/errors'; -import { INDEX_PATTERN_BEATS } from '../../../../../common/constants'; - -export function beatsListingRoute(server) { - server.route({ - method: 'POST', - path: '/api/monitoring/v1/clusters/{clusterUuid}/beats/beats', - config: { - validate: { - params: schema.object({ - clusterUuid: schema.string(), - }), - body: schema.object({ - ccs: schema.maybe(schema.string()), - timeRange: schema.object({ - min: schema.string(), - max: schema.string(), - }), - }), - }, - }, - async handler(req) { - const config = server.config; - const ccs = req.payload.ccs; - const clusterUuid = req.params.clusterUuid; - const beatsIndexPattern = prefixIndexPatternWithCcs(config, INDEX_PATTERN_BEATS, ccs); - - try { - const [stats, listing] = await Promise.all([ - getStats(req, beatsIndexPattern, clusterUuid), - getBeats(req, beatsIndexPattern, clusterUuid), - ]); - - return { - stats, - listing, - }; - } catch (err) { - throw handleError(err, req); - } - }, - }); -} diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/beats/beats.ts b/x-pack/plugins/monitoring/server/routes/api/v1/beats/beats.ts new file mode 100644 index 0000000000000..385950d23f836 --- /dev/null +++ b/x-pack/plugins/monitoring/server/routes/api/v1/beats/beats.ts @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { prefixIndexPatternWithCcs } from '../../../../../common/ccs_utils'; +import { INDEX_PATTERN_BEATS } from '../../../../../common/constants'; +import { + postBeatsListingRequestParamsRT, + postBeatsListingRequestPayloadRT, + postBeatsListingResponsePayloadRT, +} from '../../../../../common/http_api/beats'; +import { getBeats, getStats } from '../../../../lib/beats'; +import { createValidationFunction } from '../../../../lib/create_route_validation_function'; +import { handleError } from '../../../../lib/errors'; +import { MonitoringCore } from '../../../../types'; + +export function beatsListingRoute(server: MonitoringCore) { + const validateParams = createValidationFunction(postBeatsListingRequestParamsRT); + const validateBody = createValidationFunction(postBeatsListingRequestPayloadRT); + + server.route({ + method: 'post', + path: '/api/monitoring/v1/clusters/{clusterUuid}/beats/beats', + validate: { + params: validateParams, + body: validateBody, + }, + async handler(req) { + const config = server.config; + const ccs = req.payload.ccs; + const clusterUuid = req.params.clusterUuid; + const beatsIndexPattern = prefixIndexPatternWithCcs(config, INDEX_PATTERN_BEATS, ccs); + + try { + const [stats, listing] = await Promise.all([ + getStats(req, beatsIndexPattern, clusterUuid), + getBeats(req, beatsIndexPattern, clusterUuid), + ]); + + return postBeatsListingResponsePayloadRT.encode({ + stats, + listing, + }); + } catch (err) { + throw handleError(err, req); + } + }, + }); +} diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/beats/index.js b/x-pack/plugins/monitoring/server/routes/api/v1/beats/index.ts similarity index 100% rename from x-pack/plugins/monitoring/server/routes/api/v1/beats/index.js rename to x-pack/plugins/monitoring/server/routes/api/v1/beats/index.ts diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/beats/metric_set_detail.js b/x-pack/plugins/monitoring/server/routes/api/v1/beats/metric_set_detail.js deleted file mode 100644 index c6c1e7598658a..0000000000000 --- a/x-pack/plugins/monitoring/server/routes/api/v1/beats/metric_set_detail.js +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export const metricSet = [ - { - keys: [ - 'beat_pipeline_events_total_rate', - 'beat_output_events_total', - 'beat_output_events_ack_rate', - 'beat_pipeline_events_emitted_rate', - ], - name: 'beat_event_rates', - }, - { - keys: [ - 'beat_pipeline_events_failed_rate', - 'beat_pipeline_events_dropped_rate', - 'beat_output_events_dropped_rate', - 'beat_pipeline_events_retry_rate', - ], - name: 'beat_fail_rates', - }, - { - keys: ['beat_bytes_written', 'beat_output_write_bytes_rate'], - name: 'beat_throughput_rates', - }, - { - keys: ['beat_output_sending_errors', 'beat_output_receiving_errors'], - name: 'beat_output_errors', - }, - { - keys: ['beat_mem_alloc', 'beat_mem_rss', 'beat_mem_gc_next'], - name: 'beat_memory', - }, - 'beat_cpu_utilization', - { - keys: ['beat_system_os_load_1', 'beat_system_os_load_5', 'beat_system_os_load_15'], - name: 'beat_os_load', - }, - { - name: 'beat_handles', - keys: ['beat_handles_open'], - }, -]; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/beats/metric_set_detail.ts b/x-pack/plugins/monitoring/server/routes/api/v1/beats/metric_set_detail.ts new file mode 100644 index 0000000000000..a3cc7f409a7f7 --- /dev/null +++ b/x-pack/plugins/monitoring/server/routes/api/v1/beats/metric_set_detail.ts @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { MetricDescriptor } from '../../../../lib/details/get_metrics'; + +export const metricSet: MetricDescriptor[] = [ + { + keys: [ + 'beat_pipeline_events_total_rate', + 'beat_output_events_total', + 'beat_output_events_ack_rate', + 'beat_pipeline_events_emitted_rate', + ], + name: 'beat_event_rates', + }, + { + keys: [ + 'beat_pipeline_events_failed_rate', + 'beat_pipeline_events_dropped_rate', + 'beat_output_events_dropped_rate', + 'beat_pipeline_events_retry_rate', + ], + name: 'beat_fail_rates', + }, + { + keys: ['beat_bytes_written', 'beat_output_write_bytes_rate'], + name: 'beat_throughput_rates', + }, + { + keys: ['beat_output_sending_errors', 'beat_output_receiving_errors'], + name: 'beat_output_errors', + }, + { + keys: ['beat_mem_alloc', 'beat_mem_rss', 'beat_mem_gc_next'], + name: 'beat_memory', + }, + 'beat_cpu_utilization', + { + keys: ['beat_system_os_load_1', 'beat_system_os_load_5', 'beat_system_os_load_15'], + name: 'beat_os_load', + }, + { + name: 'beat_handles', + keys: ['beat_handles_open'], + }, +]; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/beats/metric_set_overview.js b/x-pack/plugins/monitoring/server/routes/api/v1/beats/metric_set_overview.js deleted file mode 100644 index c5f0c73dd082d..0000000000000 --- a/x-pack/plugins/monitoring/server/routes/api/v1/beats/metric_set_overview.js +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export const metricSet = [ - { - keys: [ - 'beat_cluster_pipeline_events_total_rate', - 'beat_cluster_output_events_total', - 'beat_cluster_output_events_ack_rate', - 'beat_cluster_pipeline_events_emitted_rate', - ], - name: 'beat_event_rates', - }, - { - keys: [ - 'beat_cluster_pipeline_events_failed_rate', - 'beat_cluster_pipeline_events_dropped_rate', - 'beat_cluster_output_events_dropped_rate', - 'beat_cluster_pipeline_events_retry_rate', - ], - name: 'beat_fail_rates', - }, - { - keys: ['beat_cluster_output_write_bytes_rate', 'beat_cluster_output_read_bytes_rate'], - name: 'beat_throughput_rates', - }, - { - keys: ['beat_cluster_output_sending_errors', 'beat_cluster_output_receiving_errors'], - name: 'beat_output_errors', - }, -]; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/beats/metric_set_overview.ts b/x-pack/plugins/monitoring/server/routes/api/v1/beats/metric_set_overview.ts new file mode 100644 index 0000000000000..64f066799c193 --- /dev/null +++ b/x-pack/plugins/monitoring/server/routes/api/v1/beats/metric_set_overview.ts @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { MetricDescriptor } from '../../../../lib/details/get_metrics'; + +export const metricSet: MetricDescriptor[] = [ + { + keys: [ + 'beat_cluster_pipeline_events_total_rate', + 'beat_cluster_output_events_total', + 'beat_cluster_output_events_ack_rate', + 'beat_cluster_pipeline_events_emitted_rate', + ], + name: 'beat_event_rates', + }, + { + keys: [ + 'beat_cluster_pipeline_events_failed_rate', + 'beat_cluster_pipeline_events_dropped_rate', + 'beat_cluster_output_events_dropped_rate', + 'beat_cluster_pipeline_events_retry_rate', + ], + name: 'beat_fail_rates', + }, + { + keys: ['beat_cluster_output_write_bytes_rate', 'beat_cluster_output_read_bytes_rate'], + name: 'beat_throughput_rates', + }, + { + keys: ['beat_cluster_output_sending_errors', 'beat_cluster_output_receiving_errors'], + name: 'beat_output_errors', + }, +]; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/beats/overview.js b/x-pack/plugins/monitoring/server/routes/api/v1/beats/overview.js deleted file mode 100644 index 9cd9bcd9787e2..0000000000000 --- a/x-pack/plugins/monitoring/server/routes/api/v1/beats/overview.js +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { schema } from '@kbn/config-schema'; -import { prefixIndexPatternWithCcs } from '../../../../../common/ccs_utils'; -import { getMetrics } from '../../../../lib/details/get_metrics'; -import { getLatestStats, getStats } from '../../../../lib/beats'; -import { handleError } from '../../../../lib/errors'; -import { metricSet } from './metric_set_overview'; -import { INDEX_PATTERN_BEATS } from '../../../../../common/constants'; - -export function beatsOverviewRoute(server) { - server.route({ - method: 'POST', - path: '/api/monitoring/v1/clusters/{clusterUuid}/beats', - config: { - validate: { - params: schema.object({ - clusterUuid: schema.string(), - }), - body: schema.object({ - ccs: schema.maybe(schema.string()), - timeRange: schema.object({ - min: schema.string(), - max: schema.string(), - }), - }), - }, - }, - async handler(req) { - const config = server.config; - const ccs = req.payload.ccs; - const clusterUuid = req.params.clusterUuid; - const beatsIndexPattern = prefixIndexPatternWithCcs(config, INDEX_PATTERN_BEATS, ccs); - - try { - const [latest, stats, metrics] = await Promise.all([ - getLatestStats(req, beatsIndexPattern, clusterUuid), - getStats(req, beatsIndexPattern, clusterUuid), - getMetrics(req, 'beats', metricSet), - ]); - - return { - ...latest, - stats, - metrics, - }; - } catch (err) { - throw handleError(err, req); - } - }, - }); -} diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/beats/overview.ts b/x-pack/plugins/monitoring/server/routes/api/v1/beats/overview.ts new file mode 100644 index 0000000000000..f36d6cd0b1aeb --- /dev/null +++ b/x-pack/plugins/monitoring/server/routes/api/v1/beats/overview.ts @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { prefixIndexPatternWithCcs } from '../../../../../common/ccs_utils'; +import { INDEX_PATTERN_BEATS } from '../../../../../common/constants'; +import { + postBeatsOverviewRequestParamsRT, + postBeatsOverviewRequestPayloadRT, + postBeatsOverviewResponsePayloadRT, +} from '../../../../../common/http_api/beats'; +import { getLatestStats, getStats } from '../../../../lib/beats'; +import { createValidationFunction } from '../../../../lib/create_route_validation_function'; +import { getMetrics } from '../../../../lib/details/get_metrics'; +import { handleError } from '../../../../lib/errors'; +import { MonitoringCore } from '../../../../types'; +import { metricSet } from './metric_set_overview'; + +export function beatsOverviewRoute(server: MonitoringCore) { + const validateParams = createValidationFunction(postBeatsOverviewRequestParamsRT); + const validateBody = createValidationFunction(postBeatsOverviewRequestPayloadRT); + + server.route({ + method: 'post', + path: '/api/monitoring/v1/clusters/{clusterUuid}/beats', + validate: { + params: validateParams, + body: validateBody, + }, + async handler(req) { + const config = server.config; + const ccs = req.payload.ccs; + const clusterUuid = req.params.clusterUuid; + const beatsIndexPattern = prefixIndexPatternWithCcs(config, INDEX_PATTERN_BEATS, ccs); + + try { + const [latest, stats, metrics] = await Promise.all([ + getLatestStats(req, beatsIndexPattern, clusterUuid), + getStats(req, beatsIndexPattern, clusterUuid), + getMetrics(req, 'beats', metricSet), + ]); + + return postBeatsOverviewResponsePayloadRT.encode({ + ...latest, + stats, + metrics, + }); + } catch (err) { + throw handleError(err, req); + } + }, + }); +} diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr.ts b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr.ts index 3dd4feb3db805..726ed7b2500d1 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr.ts @@ -5,21 +5,24 @@ * 2.0. */ -import { schema } from '@kbn/config-schema'; -import moment from 'moment'; import { get, groupBy } from 'lodash'; -// @ts-ignore -import { handleError } from '../../../../lib/errors/handle_error'; -// @ts-ignore import { prefixIndexPatternWithCcs } from '../../../../../common/ccs_utils'; import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../common/constants'; import { - ElasticsearchResponse, + postElasticsearchCcrRequestParamsRT, + postElasticsearchCcrRequestPayloadRT, + postElasticsearchCcrResponsePayloadRT, +} from '../../../../../common/http_api/elasticsearch'; +import { TimeRange } from '../../../../../common/http_api/shared'; +import { ElasticsearchLegacySource, ElasticsearchMetricbeatSource, + ElasticsearchResponse, } from '../../../../../common/types/es'; -import { LegacyRequest } from '../../../../types'; import { MonitoringConfig } from '../../../../config'; +import { createValidationFunction } from '../../../../lib/create_route_validation_function'; +import { handleError } from '../../../../lib/errors/handle_error'; +import { LegacyRequest, MonitoringCore } from '../../../../types'; function getBucketScript(max: string, min: string) { return { @@ -33,9 +36,12 @@ function getBucketScript(max: string, min: string) { }; } -function buildRequest(req: LegacyRequest, config: MonitoringConfig, esIndexPattern: string) { - const min = moment.utc(req.payload.timeRange.min).valueOf(); - const max = moment.utc(req.payload.timeRange.max).valueOf(); +function buildRequest( + req: LegacyRequest, + config: MonitoringConfig, + esIndexPattern: string +) { + const { min, max } = req.payload.timeRange; const maxBucketSize = config.ui.max_bucket_size; const aggs = { ops_synced_max: { @@ -195,25 +201,18 @@ function buildRequest(req: LegacyRequest, config: MonitoringConfig, esIndexPatte }; } -export function ccrRoute(server: { route: (p: any) => void; config: MonitoringConfig }) { +export function ccrRoute(server: MonitoringCore) { + const validateParams = createValidationFunction(postElasticsearchCcrRequestParamsRT); + const validateBody = createValidationFunction(postElasticsearchCcrRequestPayloadRT); + server.route({ - method: 'POST', + method: 'post', path: '/api/monitoring/v1/clusters/{clusterUuid}/elasticsearch/ccr', - config: { - validate: { - params: schema.object({ - clusterUuid: schema.string(), - }), - body: schema.object({ - ccs: schema.maybe(schema.string()), - timeRange: schema.object({ - min: schema.string(), - max: schema.string(), - }), - }), - }, + validate: { + params: validateParams, + body: validateBody, }, - async handler(req: LegacyRequest) { + async handler(req) { const config = server.config; const ccs = req.payload.ccs; const esIndexPattern = prefixIndexPatternWithCcs(config, INDEX_PATTERN_ELASTICSEARCH, ccs); @@ -322,7 +321,7 @@ export function ccrRoute(server: { route: (p: any) => void; config: MonitoringCo return accum; }, []); - return { data }; + return postElasticsearchCcrResponsePayloadRT.encode({ data }); } catch (err) { return handleError(err, req); } diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr_shard.ts b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr_shard.ts index 44a1eb1807595..797b8addd02cf 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr_shard.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr_shard.ts @@ -5,18 +5,19 @@ * 2.0. */ -import moment from 'moment'; -import { schema } from '@kbn/config-schema'; -// @ts-ignore -import { handleError } from '../../../../lib/errors/handle_error'; -// @ts-ignore -import { prefixIndexPatternWithCcs } from '../../../../../common/ccs_utils'; -// @ts-ignore -import { getMetrics } from '../../../../lib/details/get_metrics'; +import { + postElasticsearchCcrShardRequestParamsRT, + postElasticsearchCcrShardRequestPayloadRT, + postElasticsearchCcrShardResponsePayloadRT, +} from '../../../../../common/http_api/elasticsearch'; +import { TimeRange } from '../../../../../common/http_api/shared'; import { ElasticsearchResponse } from '../../../../../common/types/es'; -import { LegacyRequest } from '../../../../types'; import { getNewIndexPatterns } from '../../../../lib/cluster/get_index_patterns'; +import { createValidationFunction } from '../../../../lib/create_route_validation_function'; +import { getMetrics } from '../../../../lib/details/get_metrics'; +import { handleError } from '../../../../lib/errors/handle_error'; import { Globals } from '../../../../static_globals'; +import { LegacyRequest, MonitoringCore } from '../../../../types'; function getFormattedLeaderIndex(leaderIndex: string) { let leader = leaderIndex; @@ -27,10 +28,12 @@ function getFormattedLeaderIndex(leaderIndex: string) { return leader; } -async function getCcrStat(req: LegacyRequest, esIndexPattern: string, filters: unknown[]) { - const min = moment.utc(req.payload.timeRange.min).valueOf(); - const max = moment.utc(req.payload.timeRange.max).valueOf(); - +async function getCcrStat( + req: LegacyRequest, + esIndexPattern: string, + filters: unknown[] +) { + const { min, max } = req.payload.timeRange; const { callWithRequest } = req.server.plugins.elasticsearch.getCluster('monitoring'); const params = { @@ -78,27 +81,18 @@ async function getCcrStat(req: LegacyRequest, esIndexPattern: string, filters: u return await callWithRequest(req, 'search', params); } -export function ccrShardRoute(server: { route: (p: any) => void; config: () => {} }) { +export function ccrShardRoute(server: MonitoringCore) { + const validateParams = createValidationFunction(postElasticsearchCcrShardRequestParamsRT); + const validateBody = createValidationFunction(postElasticsearchCcrShardRequestPayloadRT); + server.route({ - method: 'POST', + method: 'post', path: '/api/monitoring/v1/clusters/{clusterUuid}/elasticsearch/ccr/{index}/shard/{shardId}', - config: { - validate: { - params: schema.object({ - clusterUuid: schema.string(), - index: schema.string(), - shardId: schema.string(), - }), - body: schema.object({ - ccs: schema.maybe(schema.string()), - timeRange: schema.object({ - min: schema.string(), - max: schema.string(), - }), - }), - }, + validate: { + params: validateParams, + body: validateBody, }, - async handler(req: LegacyRequest) { + async handler(req) { const index = req.params.index; const shardId = req.params.shardId; const moduleType = 'elasticsearch'; @@ -171,7 +165,7 @@ export function ccrShardRoute(server: { route: (p: any) => void; config: () => { const leaderIndex = mbStat ? mbStat?.leader?.index : legacyStat?.leader_index; - return { + return postElasticsearchCcrShardResponsePayloadRT.encode({ metrics, stat: mbStat ?? legacyStat, formattedLeader: getFormattedLeaderIndex(leaderIndex ?? ''), @@ -179,7 +173,7 @@ export function ccrShardRoute(server: { route: (p: any) => void; config: () => { ccrResponse.hits?.hits[0]?._source['@timestamp'] ?? ccrResponse.hits?.hits[0]?._source.timestamp, oldestStat: oldestMBStat ?? oldestLegacyStat, - }; + }); } catch (err) { return handleError(err, req); } diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/index.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/index.ts similarity index 100% rename from x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/index.js rename to x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/index.ts diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/index_detail.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/index_detail.js deleted file mode 100644 index b4f317c9a435d..0000000000000 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/index_detail.js +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { get } from 'lodash'; -import { schema } from '@kbn/config-schema'; -import { getClusterStats } from '../../../../lib/cluster/get_cluster_stats'; -import { getIndexSummary } from '../../../../lib/elasticsearch/indices'; -import { getMetrics } from '../../../../lib/details/get_metrics'; -import { getShardAllocation, getShardStats } from '../../../../lib/elasticsearch/shards'; -import { handleError } from '../../../../lib/errors/handle_error'; -import { prefixIndexPatternWithCcs } from '../../../../../common/ccs_utils'; -import { metricSet } from './metric_set_index_detail'; -import { getLogs } from '../../../../lib/logs/get_logs'; -import { CCS_REMOTE_PATTERN } from '../../../../../common/constants'; - -const { advanced: metricSetAdvanced, overview: metricSetOverview } = metricSet; - -export function esIndexRoute(server) { - server.route({ - method: 'POST', - path: '/api/monitoring/v1/clusters/{clusterUuid}/elasticsearch/indices/{id}', - config: { - validate: { - params: schema.object({ - clusterUuid: schema.string(), - id: schema.string(), - }), - body: schema.object({ - ccs: schema.maybe(schema.string()), - timeRange: schema.object({ - min: schema.string(), - max: schema.string(), - }), - is_advanced: schema.boolean(), - }), - }, - }, - handler: async (req) => { - try { - const config = server.config; - const clusterUuid = req.params.clusterUuid; - const indexUuid = req.params.id; - const start = req.payload.timeRange.min; - const end = req.payload.timeRange.max; - const filebeatIndexPattern = prefixIndexPatternWithCcs( - config, - config.ui.logs.index, - CCS_REMOTE_PATTERN - ); - const isAdvanced = req.payload.is_advanced; - const metricSet = isAdvanced ? metricSetAdvanced : metricSetOverview; - - const cluster = await getClusterStats(req, clusterUuid); - const showSystemIndices = true; // hardcode to true, because this could be a system index - - const shardStats = await getShardStats(req, cluster, { - includeNodes: true, - includeIndices: true, - indexName: indexUuid, - }); - const indexSummary = await getIndexSummary(req, shardStats, { - clusterUuid, - indexUuid, - start, - end, - }); - const metrics = await getMetrics(req, 'elasticsearch', metricSet, [ - { term: { 'index_stats.index': indexUuid } }, - ]); - - let logs; - let shardAllocation; - if (!isAdvanced) { - // TODO: Why so many fields needed for a single component (shard legend)? - const shardFilter = { - bool: { - should: [ - { term: { 'shard.index': indexUuid } }, - { term: { 'elasticsearch.index.name': indexUuid } }, - ], - }, - }; - const stateUuid = get( - cluster, - 'elasticsearch.cluster.stats.state.state_uuid', - get(cluster, 'cluster_state.state_uuid') - ); - const allocationOptions = { - shardFilter, - stateUuid, - showSystemIndices, - }; - const shards = await getShardAllocation(req, allocationOptions); - - logs = await getLogs(config, req, filebeatIndexPattern, { - clusterUuid, - indexUuid, - start, - end, - }); - - shardAllocation = { - shards, - shardStats: { nodes: shardStats.nodes }, - nodes: shardStats.nodes, // for identifying nodes that shard relocates to - stateUuid, // for debugging/troubleshooting - }; - } - - return { - indexSummary, - metrics, - logs, - ...shardAllocation, - }; - } catch (err) { - throw handleError(err, req); - } - }, - }); -} diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/index_detail.ts b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/index_detail.ts new file mode 100644 index 0000000000000..1d31064f71ebb --- /dev/null +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/index_detail.ts @@ -0,0 +1,122 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { get } from 'lodash'; +import { prefixIndexPatternWithCcs } from '../../../../../common/ccs_utils'; +import { CCS_REMOTE_PATTERN } from '../../../../../common/constants'; +import { + postElasticsearchIndexDetailRequestParamsRT, + postElasticsearchIndexDetailRequestPayloadRT, + postElasticsearchIndexDetailResponsePayloadRT, +} from '../../../../../common/http_api/elasticsearch'; +import { getClusterStats } from '../../../../lib/cluster/get_cluster_stats'; +import { createValidationFunction } from '../../../../lib/create_route_validation_function'; +import { getMetrics } from '../../../../lib/details/get_metrics'; +import { getIndexSummary } from '../../../../lib/elasticsearch/indices'; +import { getShardAllocation, getShardStats } from '../../../../lib/elasticsearch/shards'; +import { handleError } from '../../../../lib/errors/handle_error'; +import { getLogs } from '../../../../lib/logs/get_logs'; +import { MonitoringCore } from '../../../../types'; +import { metricSets } from './metric_set_index_detail'; + +const { advanced: metricSetAdvanced, overview: metricSetOverview } = metricSets; + +export function esIndexRoute(server: MonitoringCore) { + const validateParams = createValidationFunction(postElasticsearchIndexDetailRequestParamsRT); + const validateBody = createValidationFunction(postElasticsearchIndexDetailRequestPayloadRT); + + server.route({ + method: 'post', + path: '/api/monitoring/v1/clusters/{clusterUuid}/elasticsearch/indices/{id}', + validate: { + params: validateParams, + body: validateBody, + }, + handler: async (req) => { + try { + const config = server.config; + const clusterUuid = req.params.clusterUuid; + const indexUuid = req.params.id; + const start = req.payload.timeRange.min; + const end = req.payload.timeRange.max; + const filebeatIndexPattern = prefixIndexPatternWithCcs( + config, + config.ui.logs.index, + CCS_REMOTE_PATTERN + ); + const isAdvanced = req.payload.is_advanced; + const metricSet = isAdvanced ? metricSetAdvanced : metricSetOverview; + + const cluster = await getClusterStats(req, clusterUuid); + const showSystemIndices = true; // hardcode to true, because this could be a system index + + const shardStats = await getShardStats(req, cluster, { + includeNodes: true, + includeIndices: true, + indexName: indexUuid, + }); + const indexSummary = await getIndexSummary(req, shardStats, { + clusterUuid, + indexUuid, + start, + end, + }); + const metrics = await getMetrics(req, 'elasticsearch', metricSet, [ + { term: { 'index_stats.index': indexUuid } }, + ]); + + let logs; + let shardAllocation; + if (!isAdvanced) { + // TODO: Why so many fields needed for a single component (shard legend)? + const shardFilter = { + bool: { + should: [ + { term: { 'shard.index': indexUuid } }, + { term: { 'elasticsearch.index.name': indexUuid } }, + ], + }, + }; + const stateUuid = get( + cluster, + 'elasticsearch.cluster.stats.state.state_uuid', + get(cluster, 'cluster_state.state_uuid') + ); + const allocationOptions = { + shardFilter, + stateUuid, + showSystemIndices, + }; + const shards = await getShardAllocation(req, allocationOptions); + + logs = await getLogs(config, req, filebeatIndexPattern, { + clusterUuid, + indexUuid, + start, + end, + }); + + shardAllocation = { + shards, + shardStats: { nodes: shardStats.nodes }, + nodes: shardStats.nodes, // for identifying nodes that shard relocates to + stateUuid, // for debugging/troubleshooting + }; + } + + return postElasticsearchIndexDetailResponsePayloadRT.encode({ + indexSummary, + metrics, + logs, + ...shardAllocation, + }); + } catch (err) { + throw handleError(err, req); + } + }, + }); +} diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/indices.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/indices.js deleted file mode 100644 index de41137791108..0000000000000 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/indices.js +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { schema } from '@kbn/config-schema'; -import { getClusterStats } from '../../../../lib/cluster/get_cluster_stats'; -import { getClusterStatus } from '../../../../lib/cluster/get_cluster_status'; -import { getIndices } from '../../../../lib/elasticsearch/indices'; -import { handleError } from '../../../../lib/errors/handle_error'; -import { getIndicesUnassignedShardStats } from '../../../../lib/elasticsearch/shards/get_indices_unassigned_shard_stats'; - -export function esIndicesRoute(server) { - server.route({ - method: 'POST', - path: '/api/monitoring/v1/clusters/{clusterUuid}/elasticsearch/indices', - config: { - validate: { - params: schema.object({ - clusterUuid: schema.string(), - }), - query: schema.object({ - show_system_indices: schema.boolean(), - }), - body: schema.object({ - ccs: schema.maybe(schema.string()), - timeRange: schema.object({ - min: schema.string(), - max: schema.string(), - }), - }), - }, - }, - async handler(req) { - const { clusterUuid } = req.params; - const { show_system_indices: showSystemIndices } = req.query; - const { ccs } = req.payload; - - try { - const clusterStats = await getClusterStats(req, clusterUuid, ccs); - const indicesUnassignedShardStats = await getIndicesUnassignedShardStats(req, clusterStats); - const indices = await getIndices(req, showSystemIndices, indicesUnassignedShardStats); - - return { - clusterStatus: getClusterStatus(clusterStats, indicesUnassignedShardStats), - indices, - }; - } catch (err) { - throw handleError(err, req); - } - }, - }); -} diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/indices.ts b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/indices.ts new file mode 100644 index 0000000000000..00956410d8c4d --- /dev/null +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/indices.ts @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + postElasticsearchIndicesRequestParamsRT, + postElasticsearchIndicesRequestPayloadRT, + postElasticsearchIndicesRequestQueryRT, + postElasticsearchIndicesResponsePayloadRT, +} from '../../../../../common/http_api/elasticsearch'; +import { getClusterStats } from '../../../../lib/cluster/get_cluster_stats'; +import { getClusterStatus } from '../../../../lib/cluster/get_cluster_status'; +import { createValidationFunction } from '../../../../lib/create_route_validation_function'; +import { getIndices } from '../../../../lib/elasticsearch/indices'; +import { getIndicesUnassignedShardStats } from '../../../../lib/elasticsearch/shards/get_indices_unassigned_shard_stats'; +import { handleError } from '../../../../lib/errors/handle_error'; +import { MonitoringCore } from '../../../../types'; + +export function esIndicesRoute(server: MonitoringCore) { + const validateParams = createValidationFunction(postElasticsearchIndicesRequestParamsRT); + const validateQuery = createValidationFunction(postElasticsearchIndicesRequestQueryRT); + const validateBody = createValidationFunction(postElasticsearchIndicesRequestPayloadRT); + + server.route({ + method: 'post', + path: '/api/monitoring/v1/clusters/{clusterUuid}/elasticsearch/indices', + validate: { + params: validateParams, + query: validateQuery, + body: validateBody, + }, + async handler(req) { + const { clusterUuid } = req.params; + const { show_system_indices: showSystemIndices } = req.query; + + try { + const clusterStats = await getClusterStats(req, clusterUuid); + const indicesUnassignedShardStats = await getIndicesUnassignedShardStats(req, clusterStats); + const indices = await getIndices(req, showSystemIndices, indicesUnassignedShardStats); + + return postElasticsearchIndicesResponsePayloadRT.encode({ + clusterStatus: getClusterStatus(clusterStats, indicesUnassignedShardStats), + indices, + }); + } catch (err) { + throw handleError(err, req); + } + }, + }); +} diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/metric_set_index_detail.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/metric_set_index_detail.js deleted file mode 100644 index fce09eac4918f..0000000000000 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/metric_set_index_detail.js +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export const metricSet = { - advanced: [ - { - keys: ['index_mem_fixed_bit_set', 'index_mem_versions'], - name: 'index_3', - }, - { - keys: [ - 'index_mem_query_cache', - 'index_mem_request_cache', - 'index_mem_fielddata', - 'index_mem_writer', - ], - name: 'index_4', - }, - { - keys: ['index_searching_total', 'index_indexing_total'], - name: 'index_total', - }, - { - keys: ['index_searching_time', 'index_indexing_total_time', 'index_indexing_primaries_time'], - name: 'index_time', - }, - { - keys: ['index_throttling_indexing_total_time', 'index_throttling_indexing_primaries_time'], - name: 'index_throttling', - }, - { - keys: ['index_segment_refresh_total_time', 'index_segment_refresh_primaries_time'], - name: 'index_refresh', - }, - { - keys: [ - 'index_store_total_size', - 'index_store_primaries_size', - 'index_segment_merge_total_size', - 'index_segment_merge_primaries_size', - ], - name: 'index_disk', - }, - { - keys: ['index_segment_count_total', 'index_segment_count_primaries'], - name: 'index_segment_count', - }, - { - keys: ['index_index_latency', 'index_query_latency'], - name: 'index_latency', - }, - ], - overview: [ - 'index_search_request_rate', - { - keys: ['index_request_rate_total', 'index_request_rate_primary'], - name: 'index_request_rate', - }, - { - keys: ['index_store_total_size', 'index_store_primaries_size'], - name: 'index_size', - }, - 'index_document_count', - { - keys: ['index_segment_count_total', 'index_segment_count_primaries'], - name: 'index_segment_count', - }, - ], -}; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/metric_set_index_detail.ts b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/metric_set_index_detail.ts new file mode 100644 index 0000000000000..36e3cef797967 --- /dev/null +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/metric_set_index_detail.ts @@ -0,0 +1,78 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { MetricDescriptor } from '../../../../lib/details/get_metrics'; + +export const metricSets: { + advanced: MetricDescriptor[]; + overview: MetricDescriptor[]; +} = { + advanced: [ + { + keys: ['index_mem_fixed_bit_set', 'index_mem_versions'], + name: 'index_3', + }, + { + keys: [ + 'index_mem_query_cache', + 'index_mem_request_cache', + 'index_mem_fielddata', + 'index_mem_writer', + ], + name: 'index_4', + }, + { + keys: ['index_searching_total', 'index_indexing_total'], + name: 'index_total', + }, + { + keys: ['index_searching_time', 'index_indexing_total_time', 'index_indexing_primaries_time'], + name: 'index_time', + }, + { + keys: ['index_throttling_indexing_total_time', 'index_throttling_indexing_primaries_time'], + name: 'index_throttling', + }, + { + keys: ['index_segment_refresh_total_time', 'index_segment_refresh_primaries_time'], + name: 'index_refresh', + }, + { + keys: [ + 'index_store_total_size', + 'index_store_primaries_size', + 'index_segment_merge_total_size', + 'index_segment_merge_primaries_size', + ], + name: 'index_disk', + }, + { + keys: ['index_segment_count_total', 'index_segment_count_primaries'], + name: 'index_segment_count', + }, + { + keys: ['index_index_latency', 'index_query_latency'], + name: 'index_latency', + }, + ], + overview: [ + 'index_search_request_rate', + { + keys: ['index_request_rate_total', 'index_request_rate_primary'], + name: 'index_request_rate', + }, + { + keys: ['index_store_total_size', 'index_store_primaries_size'], + name: 'index_size', + }, + 'index_document_count', + { + keys: ['index_segment_count_total', 'index_segment_count_primaries'], + name: 'index_segment_count', + }, + ], +}; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/metric_set_node_detail.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/metric_set_node_detail.js deleted file mode 100644 index 5303dc452f850..0000000000000 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/metric_set_node_detail.js +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export const metricSets = { - advanced: [ - { - keys: ['node_jvm_mem_max_in_bytes', 'node_jvm_mem_used_in_bytes'], - name: 'node_jvm_mem', - }, - { - keys: ['node_jvm_gc_old_count', 'node_jvm_gc_young_count'], - name: 'node_gc', - }, - { - keys: ['node_jvm_gc_old_time', 'node_jvm_gc_young_time'], - name: 'node_gc_time', - }, - { - keys: ['node_index_mem_fixed_bit_set', 'node_index_mem_versions'], - name: 'node_index_3', - }, - { - keys: [ - 'node_index_mem_query_cache', - 'node_index_mem_request_cache', - 'node_index_mem_fielddata', - 'node_index_mem_writer', - ], - name: 'node_index_4', - }, - { - keys: ['node_search_total', 'node_index_total'], - name: 'node_request_total', - }, - { - keys: ['node_index_time', 'node_throttle_index_time'], - name: 'node_index_time', - }, - { - keys: ['node_index_threads_write_queue', 'node_index_threads_write_rejected'], - name: 'node_index_threads', - }, - { - keys: [ - 'node_index_threads_search_queue', - 'node_index_threads_search_rejected', - 'node_index_threads_get_queue', - 'node_index_threads_get_rejected', - ], - name: 'node_read_threads', - }, - { - keys: ['node_cpu_utilization', 'node_cgroup_quota'], - name: 'node_cpu_utilization', - }, - { - keys: ['node_cgroup_usage', 'node_cgroup_throttled'], - name: 'node_cgroup_cpu', - }, - { - keys: ['node_cgroup_periods', 'node_cgroup_throttled_count'], - name: 'node_cgroup_stats', - }, - { - keys: ['node_query_latency', 'node_index_latency'], - name: 'node_latency', - }, - ], - overview: [ - { - keys: ['node_total_cumul_io', 'node_total_read_io', 'node_total_write_io'], - name: 'node_total_io', - }, - { - keys: ['node_query_latency', 'node_index_latency'], - name: 'node_latency', - }, - { - keys: ['node_jvm_mem_max_in_bytes', 'node_jvm_mem_used_in_bytes'], - name: 'node_jvm_mem', - }, - { - keys: [], - name: 'node_cpu_metric', - }, - 'node_load_average', - 'node_segment_count', - ], -}; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/metric_set_node_detail.ts b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/metric_set_node_detail.ts new file mode 100644 index 0000000000000..9de51af5ecbaa --- /dev/null +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/metric_set_node_detail.ts @@ -0,0 +1,98 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { MetricDescriptor } from '../../../../lib/details/get_metrics'; + +export const metricSets: { + advanced: MetricDescriptor[]; + overview: MetricDescriptor[]; +} = { + advanced: [ + { + keys: ['node_jvm_mem_max_in_bytes', 'node_jvm_mem_used_in_bytes'], + name: 'node_jvm_mem', + }, + { + keys: ['node_jvm_gc_old_count', 'node_jvm_gc_young_count'], + name: 'node_gc', + }, + { + keys: ['node_jvm_gc_old_time', 'node_jvm_gc_young_time'], + name: 'node_gc_time', + }, + { + keys: ['node_index_mem_fixed_bit_set', 'node_index_mem_versions'], + name: 'node_index_3', + }, + { + keys: [ + 'node_index_mem_query_cache', + 'node_index_mem_request_cache', + 'node_index_mem_fielddata', + 'node_index_mem_writer', + ], + name: 'node_index_4', + }, + { + keys: ['node_search_total', 'node_index_total'], + name: 'node_request_total', + }, + { + keys: ['node_index_time', 'node_throttle_index_time'], + name: 'node_index_time', + }, + { + keys: ['node_index_threads_write_queue', 'node_index_threads_write_rejected'], + name: 'node_index_threads', + }, + { + keys: [ + 'node_index_threads_search_queue', + 'node_index_threads_search_rejected', + 'node_index_threads_get_queue', + 'node_index_threads_get_rejected', + ], + name: 'node_read_threads', + }, + { + keys: ['node_cpu_utilization', 'node_cgroup_quota'], + name: 'node_cpu_utilization', + }, + { + keys: ['node_cgroup_usage', 'node_cgroup_throttled'], + name: 'node_cgroup_cpu', + }, + { + keys: ['node_cgroup_periods', 'node_cgroup_throttled_count'], + name: 'node_cgroup_stats', + }, + { + keys: ['node_query_latency', 'node_index_latency'], + name: 'node_latency', + }, + ], + overview: [ + { + keys: ['node_total_cumul_io', 'node_total_read_io', 'node_total_write_io'], + name: 'node_total_io', + }, + { + keys: ['node_query_latency', 'node_index_latency'], + name: 'node_latency', + }, + { + keys: ['node_jvm_mem_max_in_bytes', 'node_jvm_mem_used_in_bytes'], + name: 'node_jvm_mem', + }, + { + keys: [], + name: 'node_cpu_metric', + }, + 'node_load_average', + 'node_segment_count', + ], +}; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/metric_set_overview.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/metric_set_overview.js deleted file mode 100644 index 317486bce4adf..0000000000000 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/metric_set_overview.js +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export const metricSet = [ - 'cluster_search_request_rate', - 'cluster_query_latency', - { - keys: ['cluster_index_request_rate_total', 'cluster_index_request_rate_primary'], - name: 'cluster_index_request_rate', - }, - 'cluster_index_latency', -]; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/metric_set_overview.ts b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/metric_set_overview.ts new file mode 100644 index 0000000000000..9ea00bf8a503a --- /dev/null +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/metric_set_overview.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { MetricDescriptor } from '../../../../lib/details/get_metrics'; + +export const metricSet: MetricDescriptor[] = [ + 'cluster_search_request_rate', + 'cluster_query_latency', + { + keys: ['cluster_index_request_rate_total', 'cluster_index_request_rate_primary'], + name: 'cluster_index_request_rate', + }, + 'cluster_index_latency', +]; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ml_jobs.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ml_jobs.js deleted file mode 100644 index f2f0698bae18c..0000000000000 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ml_jobs.js +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { schema } from '@kbn/config-schema'; -import { getClusterStats } from '../../../../lib/cluster/get_cluster_stats'; -import { getClusterStatus } from '../../../../lib/cluster/get_cluster_status'; -import { getMlJobs } from '../../../../lib/elasticsearch/get_ml_jobs'; -import { handleError } from '../../../../lib/errors/handle_error'; -import { getIndicesUnassignedShardStats } from '../../../../lib/elasticsearch/shards/get_indices_unassigned_shard_stats'; - -export function mlJobRoute(server) { - server.route({ - method: 'POST', - path: '/api/monitoring/v1/clusters/{clusterUuid}/elasticsearch/ml_jobs', - config: { - validate: { - params: schema.object({ - clusterUuid: schema.string(), - }), - body: schema.object({ - ccs: schema.maybe(schema.string()), - timeRange: schema.object({ - min: schema.string(), - max: schema.string(), - }), - }), - }, - }, - async handler(req) { - const clusterUuid = req.params.clusterUuid; - - try { - const clusterStats = await getClusterStats(req, clusterUuid); - const indicesUnassignedShardStats = await getIndicesUnassignedShardStats(req, clusterStats); - const rows = await getMlJobs(req); - return { - clusterStatus: getClusterStatus(clusterStats, indicesUnassignedShardStats), - rows, - }; - } catch (err) { - throw handleError(err, req); - } - }, - }); -} diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ml_jobs.ts b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ml_jobs.ts new file mode 100644 index 0000000000000..f51ca41ee4e9f --- /dev/null +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ml_jobs.ts @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + postElasticsearchMlJobsRequestParamsRT, + postElasticsearchMlJobsRequestPayloadRT, + postElasticsearchMlJobsResponsePayloadRT, +} from '../../../../../common/http_api/elasticsearch'; +import { getClusterStats } from '../../../../lib/cluster/get_cluster_stats'; +import { getClusterStatus } from '../../../../lib/cluster/get_cluster_status'; +import { createValidationFunction } from '../../../../lib/create_route_validation_function'; +import { getMlJobs } from '../../../../lib/elasticsearch/get_ml_jobs'; +import { getIndicesUnassignedShardStats } from '../../../../lib/elasticsearch/shards/get_indices_unassigned_shard_stats'; +import { handleError } from '../../../../lib/errors/handle_error'; +import { MonitoringCore } from '../../../../types'; + +export function mlJobRoute(server: MonitoringCore) { + const validateParams = createValidationFunction(postElasticsearchMlJobsRequestParamsRT); + const validateBody = createValidationFunction(postElasticsearchMlJobsRequestPayloadRT); + + server.route({ + method: 'post', + path: '/api/monitoring/v1/clusters/{clusterUuid}/elasticsearch/ml_jobs', + validate: { + params: validateParams, + body: validateBody, + }, + async handler(req) { + const clusterUuid = req.params.clusterUuid; + + try { + const clusterStats = await getClusterStats(req, clusterUuid); + const indicesUnassignedShardStats = await getIndicesUnassignedShardStats(req, clusterStats); + const rows = await getMlJobs(req); + return postElasticsearchMlJobsResponsePayloadRT.encode({ + clusterStatus: getClusterStatus(clusterStats, indicesUnassignedShardStats), + rows, + }); + } catch (err) { + throw handleError(err, req); + } + }, + }); +} diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/node_detail.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/node_detail.js deleted file mode 100644 index 1504bb076101e..0000000000000 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/node_detail.js +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { get } from 'lodash'; -import { schema } from '@kbn/config-schema'; -import { getClusterStats } from '../../../../lib/cluster/get_cluster_stats'; -import { getNodeSummary } from '../../../../lib/elasticsearch/nodes'; -import { getShardStats, getShardAllocation } from '../../../../lib/elasticsearch/shards'; -import { getMetrics } from '../../../../lib/details/get_metrics'; -import { handleError } from '../../../../lib/errors/handle_error'; -import { prefixIndexPatternWithCcs } from '../../../../../common/ccs_utils'; -import { metricSets } from './metric_set_node_detail'; -import { getLogs } from '../../../../lib/logs/get_logs'; -import { CCS_REMOTE_PATTERN } from '../../../../../common/constants'; - -const { advanced: metricSetAdvanced, overview: metricSetOverview } = metricSets; - -export function esNodeRoute(server) { - server.route({ - method: 'POST', - path: '/api/monitoring/v1/clusters/{clusterUuid}/elasticsearch/nodes/{nodeUuid}', - config: { - validate: { - params: schema.object({ - clusterUuid: schema.string(), - nodeUuid: schema.string(), - }), - body: schema.object({ - ccs: schema.maybe(schema.string()), - showSystemIndices: schema.boolean({ defaultValue: false }), // show/hide system indices in shard allocation table - timeRange: schema.object({ - min: schema.string(), - max: schema.string(), - }), - is_advanced: schema.boolean(), - }), - }, - }, - async handler(req) { - const config = server.config; - const ccs = req.payload.ccs; - const showSystemIndices = req.payload.showSystemIndices; - const clusterUuid = req.params.clusterUuid; - const nodeUuid = req.params.nodeUuid; - const start = req.payload.timeRange.min; - const end = req.payload.timeRange.max; - const filebeatIndexPattern = prefixIndexPatternWithCcs( - config, - config.ui.logs.index, - CCS_REMOTE_PATTERN - ); - const isAdvanced = req.payload.is_advanced; - - let metricSet; - if (isAdvanced) { - metricSet = metricSetAdvanced; - } else { - metricSet = metricSetOverview; - // set the cgroup option if needed - const showCgroupMetricsElasticsearch = config.ui.container.elasticsearch.enabled; - const metricCpu = metricSet.find((m) => m.name === 'node_cpu_metric'); - if (showCgroupMetricsElasticsearch) { - metricCpu.keys = ['node_cgroup_quota_as_cpu_utilization']; - } else { - metricCpu.keys = ['node_cpu_utilization']; - } - } - - try { - const cluster = await getClusterStats(req, clusterUuid, ccs); - - const clusterState = get( - cluster, - 'cluster_state', - get(cluster, 'elasticsearch.cluster.stats.state') - ); - - const shardStats = await getShardStats(req, cluster, { - includeIndices: true, - includeNodes: true, - nodeUuid, - }); - const nodeSummary = await getNodeSummary(req, clusterState, shardStats, { - clusterUuid, - nodeUuid, - start, - end, - }); - const metrics = await getMetrics(req, 'elasticsearch', metricSet, [ - { term: { 'source_node.uuid': nodeUuid } }, - ]); - let logs; - let shardAllocation; - if (!isAdvanced) { - // TODO: Why so many fields needed for a single component (shard legend)? - const shardFilter = { - bool: { - should: [ - { term: { 'shard.node': nodeUuid } }, - { term: { 'elasticsearch.node.name': nodeUuid } }, - ], - }, - }; - const stateUuid = get( - cluster, - 'cluster_state.state_uuid', - get(cluster, 'elasticsearch.cluster.stats.state.state_uuid') - ); - const allocationOptions = { - shardFilter, - stateUuid, - showSystemIndices, - }; - const shards = await getShardAllocation(req, allocationOptions); - - shardAllocation = { - shards, - shardStats: { indices: shardStats.indices }, - nodes: shardStats.nodes, // for identifying nodes that shard relocates to - stateUuid, // for debugging/troubleshooting - }; - - logs = await getLogs(config, req, filebeatIndexPattern, { - clusterUuid, - nodeUuid, - start, - end, - }); - } - - return { - nodeSummary, - metrics, - logs, - ...shardAllocation, - }; - } catch (err) { - throw handleError(err, req); - } - }, - }); -} diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/node_detail.ts b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/node_detail.ts new file mode 100644 index 0000000000000..85ba1d1a2bb8e --- /dev/null +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/node_detail.ts @@ -0,0 +1,149 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { get } from 'lodash'; +import { prefixIndexPatternWithCcs } from '../../../../../common/ccs_utils'; +import { CCS_REMOTE_PATTERN } from '../../../../../common/constants'; +import { + postElasticsearchNodeDetailRequestParamsRT, + postElasticsearchNodeDetailRequestPayloadRT, + postElasticsearchNodeDetailResponsePayloadRT, +} from '../../../../../common/http_api/elasticsearch'; +import { getClusterStats } from '../../../../lib/cluster/get_cluster_stats'; +import { createValidationFunction } from '../../../../lib/create_route_validation_function'; +import { + getMetrics, + MetricDescriptor, + NamedMetricDescriptor, +} from '../../../../lib/details/get_metrics'; +import { getNodeSummary } from '../../../../lib/elasticsearch/nodes'; +import { getShardAllocation, getShardStats } from '../../../../lib/elasticsearch/shards'; +import { handleError } from '../../../../lib/errors/handle_error'; +import { getLogs } from '../../../../lib/logs/get_logs'; +import { MonitoringCore } from '../../../../types'; +import { metricSets } from './metric_set_node_detail'; + +const { advanced: metricSetAdvanced, overview: metricSetOverview } = metricSets; + +export function esNodeRoute(server: MonitoringCore) { + const validateParams = createValidationFunction(postElasticsearchNodeDetailRequestParamsRT); + const validateBody = createValidationFunction(postElasticsearchNodeDetailRequestPayloadRT); + + server.route({ + method: 'post', + path: '/api/monitoring/v1/clusters/{clusterUuid}/elasticsearch/nodes/{nodeUuid}', + validate: { + params: validateParams, + body: validateBody, + }, + async handler(req) { + const config = server.config; + const showSystemIndices = req.payload.showSystemIndices ?? false; + const clusterUuid = req.params.clusterUuid; + const nodeUuid = req.params.nodeUuid; + const start = req.payload.timeRange.min; + const end = req.payload.timeRange.max; + const filebeatIndexPattern = prefixIndexPatternWithCcs( + config, + config.ui.logs.index, + CCS_REMOTE_PATTERN + ); + const isAdvanced = req.payload.is_advanced; + + let metricSet: MetricDescriptor[]; + if (isAdvanced) { + metricSet = metricSetAdvanced; + } else { + metricSet = metricSetOverview; + // set the cgroup option if needed + const showCgroupMetricsElasticsearch = config.ui.container.elasticsearch.enabled; + const metricCpu = metricSet.find( + (m): m is NamedMetricDescriptor => typeof m === 'object' && m.name === 'node_cpu_metric' + ); + if (metricCpu) { + if (showCgroupMetricsElasticsearch) { + metricCpu.keys = ['node_cgroup_quota_as_cpu_utilization']; + } else { + metricCpu.keys = ['node_cpu_utilization']; + } + } + } + + try { + const cluster = await getClusterStats(req, clusterUuid); + + const clusterState = get( + cluster, + 'cluster_state', + get(cluster, 'elasticsearch.cluster.stats.state') + ); + + const shardStats = await getShardStats(req, cluster, { + includeIndices: true, + includeNodes: true, + nodeUuid, + }); + const nodeSummary = await getNodeSummary(req, clusterState, shardStats, { + clusterUuid, + nodeUuid, + start, + end, + }); + const metrics = await getMetrics(req, 'elasticsearch', metricSet, [ + { term: { 'source_node.uuid': nodeUuid } }, + ]); + let logs; + let shardAllocation; + if (!isAdvanced) { + // TODO: Why so many fields needed for a single component (shard legend)? + const shardFilter = { + bool: { + should: [ + { term: { 'shard.node': nodeUuid } }, + { term: { 'elasticsearch.node.name': nodeUuid } }, + ], + }, + }; + const stateUuid = get( + cluster, + 'cluster_state.state_uuid', + get(cluster, 'elasticsearch.cluster.stats.state.state_uuid') + ); + const allocationOptions = { + shardFilter, + stateUuid, + showSystemIndices, + }; + const shards = await getShardAllocation(req, allocationOptions); + + shardAllocation = { + shards, + shardStats: { indices: shardStats.indices }, + nodes: shardStats.nodes, // for identifying nodes that shard relocates to + stateUuid, // for debugging/troubleshooting + }; + + logs = await getLogs(config, req, filebeatIndexPattern, { + clusterUuid, + nodeUuid, + start, + end, + }); + } + + return postElasticsearchNodeDetailResponsePayloadRT.encode({ + nodeSummary, + metrics, + logs, + ...shardAllocation, + }); + } catch (err) { + throw handleError(err, req); + } + }, + }); +} diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/nodes.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/nodes.js deleted file mode 100644 index fa0329f957f54..0000000000000 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/nodes.js +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { schema } from '@kbn/config-schema'; -import { getClusterStats } from '../../../../lib/cluster/get_cluster_stats'; -import { getClusterStatus } from '../../../../lib/cluster/get_cluster_status'; -import { getNodes } from '../../../../lib/elasticsearch/nodes'; -import { getNodesShardCount } from '../../../../lib/elasticsearch/shards/get_nodes_shard_count'; -import { handleError } from '../../../../lib/errors/handle_error'; -import { getPaginatedNodes } from '../../../../lib/elasticsearch/nodes/get_nodes/get_paginated_nodes'; -import { LISTING_METRICS_NAMES } from '../../../../lib/elasticsearch/nodes/get_nodes/nodes_listing_metrics'; -import { getIndicesUnassignedShardStats } from '../../../../lib/elasticsearch/shards/get_indices_unassigned_shard_stats'; - -export function esNodesRoute(server) { - server.route({ - method: 'POST', - path: '/api/monitoring/v1/clusters/{clusterUuid}/elasticsearch/nodes', - config: { - validate: { - params: schema.object({ - clusterUuid: schema.string(), - }), - body: schema.object({ - ccs: schema.maybe(schema.string()), - timeRange: schema.object({ - min: schema.string(), - max: schema.string(), - }), - pagination: schema.object({ - index: schema.number(), - size: schema.number(), - }), - sort: schema.object({ - field: schema.string({ defaultValue: '' }), - direction: schema.string({ defaultValue: '' }), - }), - queryText: schema.string({ defaultValue: '' }), - }), - }, - }, - async handler(req) { - const { ccs, pagination, sort, queryText } = req.payload; - const clusterUuid = req.params.clusterUuid; - - try { - const clusterStats = await getClusterStats(req, clusterUuid); - const nodesShardCount = await getNodesShardCount(req, clusterStats); - const indicesUnassignedShardStats = await getIndicesUnassignedShardStats(req, clusterStats); - const clusterStatus = getClusterStatus(clusterStats, indicesUnassignedShardStats); - - const metricSet = LISTING_METRICS_NAMES; - const { pageOfNodes, totalNodeCount } = await getPaginatedNodes( - req, - { clusterUuid }, - metricSet, - pagination, - sort, - queryText, - { - clusterStats, - nodesShardCount, - }, - ccs - ); - - const nodes = await getNodes(req, pageOfNodes, clusterStats, nodesShardCount); - return { clusterStatus, nodes, totalNodeCount }; - } catch (err) { - throw handleError(err, req); - } - }, - }); -} diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/nodes.ts b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/nodes.ts new file mode 100644 index 0000000000000..f291af318bf9b --- /dev/null +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/nodes.ts @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + postElasticsearchNodesRequestParamsRT, + postElasticsearchNodesRequestPayloadRT, + postElasticsearchNodesResponsePayloadRT, +} from '../../../../../common/http_api/elasticsearch'; +import { getClusterStats } from '../../../../lib/cluster/get_cluster_stats'; +import { getClusterStatus } from '../../../../lib/cluster/get_cluster_status'; +import { createValidationFunction } from '../../../../lib/create_route_validation_function'; +import { getNodes } from '../../../../lib/elasticsearch/nodes'; +import { getPaginatedNodes } from '../../../../lib/elasticsearch/nodes/get_nodes/get_paginated_nodes'; +import { LISTING_METRICS_NAMES } from '../../../../lib/elasticsearch/nodes/get_nodes/nodes_listing_metrics'; +import { getIndicesUnassignedShardStats } from '../../../../lib/elasticsearch/shards/get_indices_unassigned_shard_stats'; +import { getNodesShardCount } from '../../../../lib/elasticsearch/shards/get_nodes_shard_count'; +import { handleError } from '../../../../lib/errors/handle_error'; +import { MonitoringCore } from '../../../../types'; + +export function esNodesRoute(server: MonitoringCore) { + const validateParams = createValidationFunction(postElasticsearchNodesRequestParamsRT); + const validateBody = createValidationFunction(postElasticsearchNodesRequestPayloadRT); + + server.route({ + method: 'post', + path: '/api/monitoring/v1/clusters/{clusterUuid}/elasticsearch/nodes', + validate: { + params: validateParams, + body: validateBody, + }, + async handler(req) { + const { + pagination, + sort: { field = '', direction = 'asc' } = {}, + queryText = '', + } = req.payload; + const clusterUuid = req.params.clusterUuid; + + try { + const clusterStats = await getClusterStats(req, clusterUuid); + const nodesShardCount = await getNodesShardCount(req, clusterStats); + const indicesUnassignedShardStats = await getIndicesUnassignedShardStats(req, clusterStats); + const clusterStatus = getClusterStatus(clusterStats, indicesUnassignedShardStats); + + const metricSet = LISTING_METRICS_NAMES; + const { pageOfNodes, totalNodeCount } = await getPaginatedNodes( + req, + { clusterUuid }, + metricSet, + pagination, + { + field, + direction, + }, + queryText, + { + clusterStats, + nodesShardCount, + } + ); + + const nodes = await getNodes(req, pageOfNodes, clusterStats, nodesShardCount); + return postElasticsearchNodesResponsePayloadRT.encode({ + clusterStatus, + nodes, + totalNodeCount, + }); + } catch (err) { + throw handleError(err, req); + } + }, + }); +} diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/overview.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/overview.js deleted file mode 100644 index 35066bb33784d..0000000000000 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/overview.js +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { schema } from '@kbn/config-schema'; -import { getClusterStats } from '../../../../lib/cluster/get_cluster_stats'; -import { getClusterStatus } from '../../../../lib/cluster/get_cluster_status'; -import { getLastRecovery } from '../../../../lib/elasticsearch/get_last_recovery'; -import { getMetrics } from '../../../../lib/details/get_metrics'; -import { handleError } from '../../../../lib/errors/handle_error'; -import { prefixIndexPatternWithCcs } from '../../../../../common/ccs_utils'; -import { metricSet } from './metric_set_overview'; -import { getLogs } from '../../../../lib/logs'; -import { getIndicesUnassignedShardStats } from '../../../../lib/elasticsearch/shards/get_indices_unassigned_shard_stats'; -import { CCS_REMOTE_PATTERN } from '../../../../../common/constants'; - -export function esOverviewRoute(server) { - server.route({ - method: 'POST', - path: '/api/monitoring/v1/clusters/{clusterUuid}/elasticsearch', - config: { - validate: { - params: schema.object({ - clusterUuid: schema.string(), - }), - body: schema.object({ - ccs: schema.maybe(schema.string()), - timeRange: schema.object({ - min: schema.string(), - max: schema.string(), - }), - }), - }, - }, - async handler(req) { - const config = server.config; - const clusterUuid = req.params.clusterUuid; - const filebeatIndexPattern = prefixIndexPatternWithCcs( - config, - config.ui.logs.index, - CCS_REMOTE_PATTERN - ); - - const start = req.payload.timeRange.min; - const end = req.payload.timeRange.max; - - try { - const [clusterStats, metrics, shardActivity, logs] = await Promise.all([ - getClusterStats(req, clusterUuid), - getMetrics(req, 'elasticsearch', metricSet), - getLastRecovery(req, config.ui.max_bucket_size), - // TODO this call is missing some items from the signature of `getLogs`, will need to resolve during TS conversion - getLogs(config, req, filebeatIndexPattern, { clusterUuid, start, end }), - ]); - const indicesUnassignedShardStats = await getIndicesUnassignedShardStats(req, clusterStats); - - const result = { - clusterStatus: getClusterStatus(clusterStats, indicesUnassignedShardStats), - metrics, - logs, - shardActivity, - }; - return result; - } catch (err) { - throw handleError(err, req); - } - }, - }); -} diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/overview.ts b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/overview.ts new file mode 100644 index 0000000000000..52410dd09f8df --- /dev/null +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/overview.ts @@ -0,0 +1,69 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { prefixIndexPatternWithCcs } from '../../../../../common/ccs_utils'; +import { CCS_REMOTE_PATTERN } from '../../../../../common/constants'; +import { + postElasticsearchOverviewRequestParamsRT, + postElasticsearchOverviewRequestPayloadRT, + postElasticsearchOverviewResponsePayloadRT, +} from '../../../../../common/http_api/elasticsearch'; +import { getClusterStats } from '../../../../lib/cluster/get_cluster_stats'; +import { getClusterStatus } from '../../../../lib/cluster/get_cluster_status'; +import { createValidationFunction } from '../../../../lib/create_route_validation_function'; +import { getMetrics } from '../../../../lib/details/get_metrics'; +import { getLastRecovery } from '../../../../lib/elasticsearch/get_last_recovery'; +import { getIndicesUnassignedShardStats } from '../../../../lib/elasticsearch/shards/get_indices_unassigned_shard_stats'; +import { handleError } from '../../../../lib/errors/handle_error'; +import { getLogs } from '../../../../lib/logs'; +import { MonitoringCore } from '../../../../types'; +import { metricSet } from './metric_set_overview'; + +export function esOverviewRoute(server: MonitoringCore) { + const validateParams = createValidationFunction(postElasticsearchOverviewRequestParamsRT); + const validateBody = createValidationFunction(postElasticsearchOverviewRequestPayloadRT); + + server.route({ + method: 'post', + path: '/api/monitoring/v1/clusters/{clusterUuid}/elasticsearch', + validate: { + params: validateParams, + body: validateBody, + }, + async handler(req) { + const config = server.config; + const clusterUuid = req.params.clusterUuid; + const filebeatIndexPattern = prefixIndexPatternWithCcs( + config, + config.ui.logs.index, + CCS_REMOTE_PATTERN + ); + const { min: start, max: end } = req.payload.timeRange; + + try { + const [clusterStats, metrics, shardActivity, logs] = await Promise.all([ + getClusterStats(req, clusterUuid), + getMetrics(req, 'elasticsearch', metricSet), + getLastRecovery(req, config.ui.max_bucket_size), + // TODO this call is missing some items from the signature of `getLogs`, will need to resolve during TS conversion + getLogs(config, req, filebeatIndexPattern, { clusterUuid, start, end }), + ]); + const indicesUnassignedShardStats = await getIndicesUnassignedShardStats(req, clusterStats); + + const result = { + clusterStatus: getClusterStatus(clusterStats, indicesUnassignedShardStats), + metrics, + logs, + shardActivity, + }; + return postElasticsearchOverviewResponsePayloadRT.encode(result); + } catch (err) { + throw handleError(err, req); + } + }, + }); +} diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch_settings/check/internal_monitoring.ts b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch_settings/check/internal_monitoring.ts index d456826176e9b..8bee3f273e107 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch_settings/check/internal_monitoring.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch_settings/check/internal_monitoring.ts @@ -43,7 +43,7 @@ const queryBody = { }; const checkLatestMonitoringIsLegacy = async (context: RequestHandlerContext, index: string) => { - const client = context.core.elasticsearch.client.asCurrentUser; + const client = (await context.core).elasticsearch.client.asCurrentUser; const result = await client.search>({ index, body: queryBody, diff --git a/x-pack/plugins/monitoring/server/static_globals.ts b/x-pack/plugins/monitoring/server/static_globals.ts index e601dd0c55155..429ec8693a3e7 100644 --- a/x-pack/plugins/monitoring/server/static_globals.ts +++ b/x-pack/plugins/monitoring/server/static_globals.ts @@ -6,7 +6,6 @@ */ import { CoreSetup, ElasticsearchClient, Logger, PluginInitializerContext } from '@kbn/core/server'; -import url from 'url'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { MonitoringConfig } from './config'; import { PluginsSetup } from './types'; @@ -32,7 +31,7 @@ export type EndpointTypes = export type ClientParams = estypes.SearchRequest | undefined; interface IAppGlobals { - url: string; + url?: string; isCloud: boolean; config: MonitoringConfig; getLogger: GetLogger; @@ -79,11 +78,8 @@ export class Globals { return body; }); - const { protocol, hostname, port } = coreSetup.http.getServerInfo(); - const pathname = coreSetup.http.basePath.serverBasePath; - Globals._app = { - url: url.format({ protocol, hostname, port, pathname }), + url: coreSetup.http.basePath.publicBaseUrl, isCloud: setupPlugins.cloud?.isCloudEnabled || false, config, getLogger, diff --git a/x-pack/plugins/monitoring/server/types.ts b/x-pack/plugins/monitoring/server/types.ts index ee7deb63ec848..5977484518146 100644 --- a/x-pack/plugins/monitoring/server/types.ts +++ b/x-pack/plugins/monitoring/server/types.ts @@ -10,7 +10,7 @@ import type { IRouter, Logger, ICustomClusterClient, - RequestHandlerContext, + CustomRequestHandlerContext, ElasticsearchClient, } from '@kbn/core/server'; import type Boom from '@hapi/boom'; @@ -58,12 +58,12 @@ export interface PluginsSetup { cloud?: CloudSetup; } -export interface RequestHandlerContextMonitoringPlugin extends RequestHandlerContext { +export type RequestHandlerContextMonitoringPlugin = CustomRequestHandlerContext<{ actions?: ActionsApiRequestHandlerContext; alerting?: AlertingApiRequestHandlerContext; infra: InfraRequestHandlerContext; ruleRegistry?: RacApiRequestHandlerContext; -} +}>; export interface PluginsStart { alerting: AlertingPluginStartContract; @@ -80,16 +80,22 @@ export interface RouteDependencies { logger: Logger; } -export type MonitoringRouteConfig = { - method: RouteMethod; -} & RouteConfig & { - handler: (request: LegacyRequest) => any; - }; +type LegacyHandler = (req: LegacyRequest) => Promise; + +export type MonitoringRouteConfig = RouteConfig< + Params, + Query, + Body, + Method +> & { + method: Method; + handler: LegacyHandler; +}; export interface MonitoringCore { config: MonitoringConfig; log: Logger; - route: ( + route: ( options: MonitoringRouteConfig ) => void; } @@ -112,15 +118,12 @@ export interface MonitoringPluginSetup { getKibanaStats: IBulkUploader['getKibanaStats']; } -export interface LegacyRequest { +export interface LegacyRequest { logger: Logger; getLogger: (...scopes: string[]) => Logger; - payload: { - [key: string]: any; - }; - params: { - [key: string]: string; - }; + payload: Body; + params: Params; + query: Query; getKibanaStatsCollector: () => any; getUiSettingsService: () => any; getActionTypeRegistry: () => any; @@ -177,6 +180,7 @@ export interface Bucket { export interface Aggregation { buckets: Bucket[]; } + export interface ClusterSettingsReasonResponse { found: boolean; reason?: { @@ -227,10 +231,12 @@ export interface PipelineResponse { throughput?: PipelineMetricsProcessed; }; } + export interface PipelinesResponse { pipelines: PipelineResponse[]; totalPipelineCount: number; } + export interface PipelineMetrics { bucket_size: string; timeRange: { @@ -248,6 +254,7 @@ export interface PipelineMetrics { isDerivative: boolean; }; } + export type PipelineMetricsRes = PipelineMetrics & { data: Array<[number, { [key: string]: number }]>; }; diff --git a/x-pack/plugins/monitoring_collection/server/routes/dynamic_route.ts b/x-pack/plugins/monitoring_collection/server/routes/dynamic_route.ts index 0e11e1495ba5e..944037dd17a7b 100644 --- a/x-pack/plugins/monitoring_collection/server/routes/dynamic_route.ts +++ b/x-pack/plugins/monitoring_collection/server/routes/dynamic_route.ts @@ -47,9 +47,10 @@ export function registerDynamicRoute({ }, async (context, req, res) => { const type = req.params.type; + const esClient = (await context.core).elasticsearch.client; const [data, clusterUuid, kibana] = await Promise.all([ getMetric(type), - getESClusterUuid(context.core.elasticsearch.client), + getESClusterUuid(esClient), getKibanaStats({ config, getStatus }), ]); diff --git a/x-pack/plugins/observability/public/application/application.test.tsx b/x-pack/plugins/observability/public/application/application.test.tsx index a3160d713d1b7..a03f007c2d751 100644 --- a/x-pack/plugins/observability/public/application/application.test.tsx +++ b/x-pack/plugins/observability/public/application/application.test.tsx @@ -63,7 +63,6 @@ describe('renderApp', () => { unsafe: { alertingExperience: { enabled: true }, cases: { enabled: true }, - overviewNext: { enabled: false }, rules: { enabled: true }, }, }; diff --git a/x-pack/plugins/observability/public/components/app/observability_status/observability_status_progress.tsx b/x-pack/plugins/observability/public/components/app/observability_status/observability_status_progress.tsx index 04e77669e963c..050da44457969 100644 --- a/x-pack/plugins/observability/public/components/app/observability_status/observability_status_progress.tsx +++ b/x-pack/plugins/observability/public/components/app/observability_status/observability_status_progress.tsx @@ -24,9 +24,11 @@ import { useGuidedSetupProgress } from '../../../hooks/use_guided_setup_progress interface ObservabilityStatusProgressProps { onViewDetailsClick: () => void; + onDismissClick?: () => void; } export function ObservabilityStatusProgress({ onViewDetailsClick, + onDismissClick, }: ObservabilityStatusProgressProps) { const { hasDataMap, isAllRequestsComplete } = useHasData(); const trackMetric = useUiTracker({ app: 'observability-overview' }); @@ -52,8 +54,11 @@ export function ObservabilityStatusProgress({ const dismissGuidedSetup = useCallback(() => { dismissGuidedSetupProgress(); + if (onDismissClick) { + onDismissClick(); + } trackMetric({ metric: 'guided_setup_progress_dismiss' }); - }, [dismissGuidedSetupProgress, trackMetric]); + }, [dismissGuidedSetupProgress, trackMetric, onDismissClick]); const showDetails = () => { onViewDetailsClick(); diff --git a/x-pack/plugins/observability/public/components/app/section/alerts/index.tsx b/x-pack/plugins/observability/public/components/app/section/alerts/index.tsx deleted file mode 100644 index 9c65df16d9060..0000000000000 --- a/x-pack/plugins/observability/public/components/app/section/alerts/index.tsx +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - EuiBadge, - EuiFlexGroup, - EuiFlexItem, - EuiLink, - EuiText, - EuiSpacer, - EuiTitle, - EuiButtonEmpty, - EuiLoadingSpinner, - EuiCallOut, - EuiPanel, -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n-react'; -import moment from 'moment'; -import React, { useState, useMemo } from 'react'; -import { EuiSelect } from '@elastic/eui'; -import { uniqBy } from 'lodash'; -import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { usePluginContext } from '../../../../hooks/use_plugin_context'; -import { FETCH_STATUS, useFetcher } from '../../../../hooks/use_fetcher'; -import { getObservabilityAlerts } from '../../../../services/get_observability_alerts'; -import { paths } from '../../../../config'; -import { ObservabilityAppServices } from '../../../../application/types'; - -const ALL_TYPES = 'ALL_TYPES'; -const allTypes = { - value: ALL_TYPES, - text: i18n.translate('xpack.observability.overview.alert.allTypes', { - defaultMessage: 'All types', - }), -}; - -export function AlertsSection() { - const { config } = usePluginContext(); - const { http } = useKibana().services; - const [filter, setFilter] = useState(ALL_TYPES); - const manageLink = config.unsafe.alertingExperience.enabled - ? http.basePath.prepend(paths.observability.alerts) - : http.basePath.prepend(paths.management.rules); - - const { data, status } = useFetcher(() => getObservabilityAlerts({ http }), [http]); - - const alerts = useMemo(() => data ?? [], [data]); - - const filterOptions = useMemo(() => { - if (!alerts) { - return []; - } - return uniqBy(alerts, (alert) => alert.consumer).map(({ consumer }) => ({ - value: consumer, - text: consumer, - })); - }, [alerts]); - - const isError = status === FETCH_STATUS.FAILURE; - const isLoading = status !== FETCH_STATUS.SUCCESS && !isError; - - if (isLoading) { - return ( - - - - - - ); - } - - if (isError) { - return ( - - - -

- -

-
-
-
- ); - } - - return ( -
- - - -

- {i18n.translate('xpack.observability.overview.alerts.title', { - defaultMessage: 'Alerts', - })} -

-
-
- - - {i18n.translate('xpack.observability.overview.alert.appLink', { - defaultMessage: 'Show all alerts', - })} - - -
- <> - - - setFilter(e.target.value)} - prepend="Show" - /> - - - {alerts - .filter((alert) => filter === ALL_TYPES || alert.consumer === filter) - .map((alert, index) => { - return ( - - - - - - - {alert.name} - - - - - - {alert.alertTypeId} - - {alert.tags.map((tag, idx) => { - return ( - - {tag} - - ); - })} - - - - - {alert.muteAll && ( - - - {i18n.translate('xpack.observability.overview.alerts.muted', { - defaultMessage: 'Muted', - })} - - - )} - - - Last updated{' '} - {moment.duration(moment().diff(alert.updatedAt)).humanize()} ago - - - - - - - - - ); - })} - -
- ); -} diff --git a/x-pack/plugins/observability/public/components/app/section/apm/index.test.tsx b/x-pack/plugins/observability/public/components/app/section/apm/index.test.tsx index a8f49f7d9cbb4..179e8ef70deb1 100644 --- a/x-pack/plugins/observability/public/components/app/section/apm/index.test.tsx +++ b/x-pack/plugins/observability/public/components/app/section/apm/index.test.tsx @@ -48,7 +48,6 @@ describe('APMSection', () => { unsafe: { alertingExperience: { enabled: true }, cases: { enabled: true }, - overviewNext: { enabled: false }, rules: { enabled: true }, }, }, diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts index 6ff6e8ed3f586..cce0a0a3bc5f6 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts @@ -785,7 +785,7 @@ export class LensAttributes { }; } - getJSON(): TypedLensByValueInput['attributes'] { + getJSON(lastRefresh?: number): TypedLensByValueInput['attributes'] { const uniqueIndexPatternsIds = Array.from( new Set([...this.layerConfigs.map(({ indexPattern }) => indexPattern.id)]) ); @@ -794,7 +794,7 @@ export class LensAttributes { return { title: 'Prefilled from exploratory view app', - description: '', + description: lastRefresh ? `Last refreshed at ${new Date(lastRefresh).toISOString()}` : '', visualizationType: 'lnsXY', references: [ ...uniqueIndexPatternsIds.map((patternId) => ({ diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/exploratory_view.test.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/exploratory_view.test.tsx index f6a41fb6bef67..2bd79116dc45b 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/exploratory_view.test.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/exploratory_view.test.tsx @@ -63,7 +63,6 @@ describe('ExploratoryView', () => { it('shows/hides the chart', async () => { render(); - expect(screen.queryByText('Refresh')).toBeInTheDocument(); const toggleButton = await screen.findByText('Hide chart'); expect(toggleButton).toBeInTheDocument(); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/exploratory_view.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/exploratory_view.tsx index 905f6f20a2e6b..ac4e094e5abbc 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/exploratory_view.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/exploratory_view.tsx @@ -9,7 +9,6 @@ import { i18n } from '@kbn/i18n'; import React, { useEffect, useRef, useState } from 'react'; import styled from 'styled-components'; import { - EuiButton, EuiButtonEmpty, EuiResizableContainer, EuiTitle, @@ -26,7 +25,6 @@ import { useAppDataViewContext } from './hooks/use_app_data_view'; import { SeriesViews } from './views/series_views'; import { LensEmbeddable } from './lens_embeddable'; import { EmptyView } from './components/empty_view'; -import { ChartTimeRange, LastUpdated } from './header/last_updated'; import { useExpViewTimeRange } from './hooks/use_time_range'; import { ExpViewActionMenu } from './components/action_menu'; import { useExploratoryView } from './contexts/exploratory_view_config'; @@ -49,15 +47,14 @@ export function ExploratoryView({ const { isEditMode } = useExploratoryView(); - const [chartTimeRangeContext, setChartTimeRangeContext] = useState(); - const [lensAttributes, setLensAttributes] = useState( null ); const { loadDataView, loading } = useAppDataViewContext(); - const { firstSeries, allSeries, lastRefresh, reportType, setLastRefresh } = useSeriesStorage(); + const { firstSeries, allSeries, lastRefresh, reportType, setChartTimeRangeContext } = + useSeriesStorage(); const lensAttributesT = useLensAttributes(); const timeRange = useExpViewTimeRange(); @@ -115,7 +112,7 @@ export function ExploratoryView({ return ( <> - + - {hiddenPanel === 'chartPanel' ? null : ( - <> - - - - - setLastRefresh(Date.now())} - size="s" - > - {REFRESH_LABEL} - - - - )} .euiPanel { padding-bottom: 0; + padding-top: 0; + } + .expExpressionRenderer__expression { + padding-bottom: 0 !important; + padding-top: 0 !important; } } `; @@ -218,6 +204,10 @@ const ShowPreview = styled(EuiButtonEmpty)` bottom: 34px; `; +const PREVIEW_LABEL = i18n.translate('xpack.observability.overview.exploratoryView.preview', { + defaultMessage: 'Preview', +}); + const HIDE_CHART_LABEL = i18n.translate('xpack.observability.overview.exploratoryView.hideChart', { defaultMessage: 'Hide chart', }); @@ -226,14 +216,6 @@ const SHOW_CHART_LABEL = i18n.translate('xpack.observability.overview.explorator defaultMessage: 'Show chart', }); -const PREVIEW_LABEL = i18n.translate('xpack.observability.overview.exploratoryView.preview', { - defaultMessage: 'Preview', -}); - -const REFRESH_LABEL = i18n.translate('xpack.observability.overview.exploratoryView.refresh', { - defaultMessage: 'Refresh', -}); - const LENS_NOT_AVAILABLE = i18n.translate( 'xpack.observability.overview.exploratoryView.lensDisabled', { diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/header/refresh_button.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/header/refresh_button.tsx new file mode 100644 index 0000000000000..eb31669453dbb --- /dev/null +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/header/refresh_button.tsx @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { LastUpdated } from './last_updated'; +import { useSeriesStorage } from '../hooks/use_series_storage'; + +export function RefreshButton() { + const { setLastRefresh, chartTimeRangeContext } = useSeriesStorage(); + + return ( + + + + + + setLastRefresh(Date.now())}> + {REFRESH_LABEL} + + + + ); +} + +export const REFRESH_LABEL = i18n.translate( + 'xpack.observability.overview.exploratoryView.refresh', + { + defaultMessage: 'Refresh', + } +); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_lens_attributes.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_lens_attributes.ts index 8d47d42e2007e..0e4620f1d520b 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_lens_attributes.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_lens_attributes.ts @@ -121,7 +121,7 @@ export const useLensAttributes = (): TypedLensByValueInput['attributes'] | null const lensAttributes = new LensAttributes(layerConfigs); - return lensAttributes.getJSON(); + return lensAttributes.getJSON(lastRefresh); // we also want to check the state on allSeries changes // eslint-disable-next-line react-hooks/exhaustive-deps }, [dataViews, reportType, storage, theme, lastRefresh, allSeries]); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_series_storage.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_series_storage.tsx index 24d5fc1d20615..8da1a4591a73d 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_series_storage.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_series_storage.tsx @@ -8,6 +8,7 @@ import React, { createContext, useContext, useState, useEffect, useCallback } from 'react'; import { IKbnUrlStateStorage, ISessionStorageStateStorage } from '@kbn/kibana-utils-plugin/public'; import { OperationType, SeriesType } from '@kbn/lens-plugin/public'; +import { ChartTimeRange } from '../header/last_updated'; import { useUiTracker } from '../../../../hooks/use_track_metric'; import type { AppDataType, @@ -32,6 +33,8 @@ export interface SeriesContextValue { setReportType: (reportType: ReportViewType) => void; storage: IKbnUrlStateStorage | ISessionStorageStateStorage; reportType: ReportViewType; + chartTimeRangeContext?: ChartTimeRange; + setChartTimeRangeContext: React.Dispatch>; } export const UrlStorageContext = createContext({} as SeriesContextValue); @@ -56,6 +59,8 @@ export function UrlStorageContextProvider({ const [lastRefresh, setLastRefresh] = useState(() => Date.now()); + const [chartTimeRangeContext, setChartTimeRangeContext] = useState(); + const [reportType, setReportType] = useState( () => ((storage as IKbnUrlStateStorage).get(reportTypeKey) ?? '') as ReportViewType ); @@ -135,6 +140,8 @@ export function UrlStorageContextProvider({ setLastRefresh, setReportType, reportType, + chartTimeRangeContext, + setChartTimeRangeContext, firstSeries: firstSeries!, }; return {children}; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/index.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/index.tsx index f9a58a8ff7433..82713f152aa4a 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/index.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/index.tsx @@ -22,6 +22,7 @@ import { DataViewContextProvider } from './hooks/use_app_data_view'; import { UrlStorageContextProvider } from './hooks/use_series_storage'; import { useTrackPageview } from '../../..'; import { usePluginContext } from '../../../hooks/use_plugin_context'; +import { RefreshButton } from './header/refresh_button'; const PAGE_TITLE = i18n.translate('xpack.observability.expView.heading.label', { defaultMessage: 'Explore data', @@ -72,13 +73,18 @@ export function ExploratoryViewPage({ }); return ( - - - + + ], + }} + > + - - - + + + ); } diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/lens_embeddable.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/lens_embeddable.tsx index cd1fd4cc014bc..3f7583f874bee 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/lens_embeddable.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/lens_embeddable.tsx @@ -46,7 +46,7 @@ export function LensEmbeddable(props: Props) { (isLoading) => { const timeLoaded = Date.now(); - setChartTimeRangeContext({ + setChartTimeRangeContext?.({ lastUpdated: timeLoaded, to: parseRelativeDate(timeRange?.to || '')?.valueOf(), from: parseRelativeDate(timeRange?.from || '')?.valueOf(), diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/rtl_helpers.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/rtl_helpers.tsx index 23c635be3ba81..fe7fe29ee4637 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/rtl_helpers.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/rtl_helpers.tsx @@ -319,6 +319,7 @@ function mockSeriesStorageContext({ firstSeries: mockDataSeries[0], allSeries: mockDataSeries, setReportType: jest.fn(), + setChartTimeRangeContext: jest.fn(), storage: { get: jest .fn() diff --git a/x-pack/plugins/observability/public/config/register_alerts_table_configuration.tsx b/x-pack/plugins/observability/public/config/register_alerts_table_configuration.tsx new file mode 100644 index 0000000000000..1999fe82e3a6d --- /dev/null +++ b/x-pack/plugins/observability/public/config/register_alerts_table_configuration.tsx @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { AlertsTableConfigurationRegistryContract } from '@kbn/triggers-actions-ui-plugin/public'; + +import { observabilityFeatureId } from '../../common'; +import { columns as alertO11yColumns } from '../pages/alerts/containers/alerts_table_t_grid/alerts_table_t_grid'; + +const registerAlertsTableConfiguration = (registry: AlertsTableConfigurationRegistryContract) => { + if (registry.has(observabilityFeatureId)) { + return; + } + registry.register({ + id: observabilityFeatureId, + columns: alertO11yColumns, + }); +}; + +export { registerAlertsTableConfiguration }; diff --git a/x-pack/plugins/observability/public/config/translations.ts b/x-pack/plugins/observability/public/config/translations.ts index db1378d5b5a54..13f6470ecb202 100644 --- a/x-pack/plugins/observability/public/config/translations.ts +++ b/x-pack/plugins/observability/public/config/translations.ts @@ -65,6 +65,12 @@ export const translations = { defaultMessage: 'View rule details', } ), + viewAlertDetailsButtonText: i18n.translate( + 'xpack.observability.alertsTable.viewAlertDetailsButtonText', + { + defaultMessage: 'View alert details', + } + ), }, alertsFlyout: { statusLabel: i18n.translate('xpack.observability.alertsFlyout.statusLabel', { diff --git a/x-pack/plugins/observability/public/hooks/use_fetch_rules.ts b/x-pack/plugins/observability/public/hooks/use_fetch_rules.ts index 00cb58e504bdc..a09626654e6f8 100644 --- a/x-pack/plugins/observability/public/hooks/use_fetch_rules.ts +++ b/x-pack/plugins/observability/public/hooks/use_fetch_rules.ts @@ -42,7 +42,7 @@ export function useFetchRules({ page, searchText, typesFilter: typesFilter.length > 0 ? typesFilter : OBSERVABILITY_RULE_TYPES, - ruleStatusesFilter: ruleLastResponseFilter, + ruleExecutionStatusesFilter: ruleLastResponseFilter, sort, }); setRulesState((oldState) => ({ diff --git a/x-pack/plugins/observability/public/index.ts b/x-pack/plugins/observability/public/index.ts index cfabbaaec4afa..19468ef0e2736 100644 --- a/x-pack/plugins/observability/public/index.ts +++ b/x-pack/plugins/observability/public/index.ts @@ -36,7 +36,6 @@ export interface ConfigSchema { alertingExperience: { enabled: boolean }; rules: { enabled: boolean }; cases: { enabled: boolean }; - overviewNext: { enabled: boolean }; }; } diff --git a/x-pack/plugins/observability/public/observability_public_plugins_start.mock.ts b/x-pack/plugins/observability/public/observability_public_plugins_start.mock.ts index 62edefc1b737d..930b75f578eb1 100644 --- a/x-pack/plugins/observability/public/observability_public_plugins_start.mock.ts +++ b/x-pack/plugins/observability/public/observability_public_plugins_start.mock.ts @@ -36,6 +36,8 @@ const triggersActionsUiStartMock = { createStart() { return { getAddAlertFlyout: jest.fn(), + getRuleStatusDropdown: jest.fn(), + getRuleTagBadge: jest.fn(), ruleTypeRegistry: { has: jest.fn(), register: jest.fn(), diff --git a/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/alerts_page.tsx b/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/alerts_page.tsx index e9256993c5857..e99a3195d0f30 100644 --- a/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/alerts_page.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/alerts_page.tsx @@ -18,6 +18,7 @@ import { useKibana } from '@kbn/kibana-react-plugin/public'; import { loadRuleAggregations } from '@kbn/triggers-actions-ui-plugin/public'; import { ParsedTechnicalFields } from '@kbn/rule-registry-plugin/common/parse_technical_fields'; import { ParsedExperimentalFields } from '@kbn/rule-registry-plugin/common/parse_experimental_fields'; +import { Storage } from '@kbn/kibana-utils-plugin/public'; import { AlertStatusFilterButton } from '../../../../../common/typings'; import { useGetUserCasesPermissions } from '../../../../hooks/use_get_user_cases_permissions'; import { observabilityFeatureId } from '../../../../../common'; @@ -38,6 +39,7 @@ import { import './styles.scss'; import { AlertsStatusFilter, AlertsDisclaimer, AlertsSearchBar } from '../../components'; import { ObservabilityAppServices } from '../../../../application/types'; +import { OBSERVABILITY_RULE_TYPES } from '../../../rules/config'; interface RuleStatsState { total: number; @@ -70,6 +72,8 @@ const ALERT_STATUS_REGEX = new RegExp( 'gm' ); +const ALERT_TABLE_STATE_STORAGE_KEY = 'xpack.observability.alert.tableState'; + function AlertsPage() { const { ObservabilityPageTemplate, config } = usePluginContext(); const [alertFilterStatus, setAlertFilterStatus] = useState('' as AlertStatusFilterButton); @@ -112,6 +116,7 @@ function AlertsPage() { try { const response = await loadRuleAggregations({ http, + typesFilter: OBSERVABILITY_RULE_TYPES, }); const { ruleExecutionStatus, ruleMutedStatus, ruleEnabledStatus, ruleSnoozedStatus } = response; @@ -330,6 +335,8 @@ function AlertsPage() { rangeTo={rangeTo} kuery={kuery} setRefetch={setRefetch} + stateStorageKey={ALERT_TABLE_STATE_STORAGE_KEY} + storage={new Storage(window.localStorage)} /> diff --git a/x-pack/plugins/observability/public/pages/alerts/containers/alerts_table_t_grid/alerts_table_t_grid.tsx b/x-pack/plugins/observability/public/pages/alerts/containers/alerts_table_t_grid/alerts_table_t_grid.tsx index a151cfabf280b..686ae9a15d8de 100644 --- a/x-pack/plugins/observability/public/pages/alerts/containers/alerts_table_t_grid/alerts_table_t_grid.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/containers/alerts_table_t_grid/alerts_table_t_grid.tsx @@ -34,6 +34,8 @@ import { EuiToolTip, } from '@elastic/eui'; +import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; + import styled from 'styled-components'; import React, { Suspense, useMemo, useState, useCallback, useEffect } from 'react'; @@ -68,13 +70,13 @@ import { addDisplayNames } from './add_display_names'; import { ADD_TO_EXISTING_CASE, ADD_TO_NEW_CASE } from './translations'; import { ObservabilityAppServices } from '../../../../application/types'; -const ALERT_TABLE_STATE_STORAGE_KEY = 'xpack.observability.alert.tableState'; - interface AlertsTableTGridProps { indexNames: string[]; rangeFrom: string; rangeTo: string; kuery?: string; + stateStorageKey: string; + storage: IStorageWrapper; setRefetch: (ref: () => void) => void; } @@ -232,8 +234,29 @@ function ObservabilityActions({ , ] : []), + + ...[ + { + closeActionsPopover(); + setFlyoutAlert(alert); + }} + > + {translations.alertsTable.viewAlertDetailsButtonText} + , + ], ]; - }, [casePermissions?.crud, handleAddToExistingCaseClick, handleAddToNewCaseClick, linkToRule]); + }, [ + casePermissions?.crud, + handleAddToExistingCaseClick, + handleAddToNewCaseClick, + linkToRule, + alert, + setFlyoutAlert, + closeActionsPopover, + ]); const actionsToolTip = actionsMenuItems.length <= 0 @@ -243,18 +266,6 @@ function ObservabilityActions({ return ( <> - - - setFlyoutAlert(alert)} - data-test-subj="openFlyoutButton" - aria-label={translations.alertsTable.viewDetailsTextLabel} - /> - - (undefined); const [tGridState, setTGridState] = useState | null>( - JSON.parse(localStorage.getItem(ALERT_TABLE_STATE_STORAGE_KEY) ?? 'null') + storage.get(stateStorageKey) ); const casePermissions = useGetUserCasesPermissions(); @@ -330,17 +341,17 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) { useEffect(() => { if (tGridState) { - const newState = JSON.stringify({ + const newState = { ...tGridState, columns: tGridState.columns?.map((c) => pick(c, ['columnHeaderType', 'displayAsText', 'id', 'initialWidth', 'linkField']) ), - }); - if (newState !== localStorage.getItem(ALERT_TABLE_STATE_STORAGE_KEY)) { - localStorage.setItem(ALERT_TABLE_STATE_STORAGE_KEY, newState); + }; + if (newState !== storage.get(stateStorageKey)) { + storage.set(stateStorageKey, newState); } } - }, [tGridState]); + }, [tGridState, stateStorageKey, storage]); const setEventsDeleted = useCallback((action) => { if (action.isDeleted) { diff --git a/x-pack/plugins/observability/public/pages/cases/empty_page.tsx b/x-pack/plugins/observability/public/pages/cases/empty_page.tsx index faeafa6b4730f..5f8be8483c9d3 100644 --- a/x-pack/plugins/observability/public/pages/cases/empty_page.tsx +++ b/x-pack/plugins/observability/public/pages/cases/empty_page.tsx @@ -103,7 +103,7 @@ const EmptyPageComponent = React.memo(({ actions, message, title return ( {title}} body={message &&

{message}

} actions={{renderActions}} diff --git a/x-pack/plugins/observability/public/pages/overview/index.test.tsx b/x-pack/plugins/observability/public/pages/overview/index.test.tsx deleted file mode 100644 index 45206e4440205..0000000000000 --- a/x-pack/plugins/observability/public/pages/overview/index.test.tsx +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import React from 'react'; -import { shallow } from 'enzyme'; -import * as PluginContext from '../../hooks/use_plugin_context'; -import { PluginContextValue } from '../../context/plugin_context'; -import { OverviewPage } from '.'; -import { OverviewPage as OldOverviewPage } from './old_overview_page'; -import { OverviewPage as NewOverviewPage } from './overview_page'; - -describe('Overview page', () => { - it('should render the old overview page when feature flag is disabled and queryParams are empty', () => { - const pluginContext = { - config: { - unsafe: { - overviewNext: { enabled: false }, - }, - }, - }; - - jest - .spyOn(PluginContext, 'usePluginContext') - .mockReturnValue(pluginContext as PluginContextValue); - - const component = shallow(); - expect(component.find(OldOverviewPage)).toHaveLength(1); - expect(component.find(NewOverviewPage)).toHaveLength(0); - }); - - it('should render the new overview page when feature flag is enabled and queryParams are empty', () => { - const pluginContext = { - config: { - unsafe: { - overviewNext: { enabled: true }, - }, - }, - }; - - jest - .spyOn(PluginContext, 'usePluginContext') - .mockReturnValue(pluginContext as PluginContextValue); - - const component = shallow(); - expect(component.find(OldOverviewPage)).toHaveLength(0); - expect(component.find(NewOverviewPage)).toHaveLength(1); - }); - - it('should render the new overview page when feature flag is enabled and alpha param is in the url', () => { - const pluginContext = { - config: { - unsafe: { - overviewNext: { enabled: true }, - }, - }, - }; - - jest - .spyOn(PluginContext, 'usePluginContext') - .mockReturnValue(pluginContext as PluginContextValue); - - const component = shallow(); - expect(component.find(OldOverviewPage)).toHaveLength(0); - expect(component.find(NewOverviewPage)).toHaveLength(1); - }); - - it('should render the new overview page when feature flag is disabled and alpha param is in the url', () => { - const pluginContext = { - config: { - unsafe: { - overviewNext: { enabled: false }, - }, - }, - }; - - jest - .spyOn(PluginContext, 'usePluginContext') - .mockReturnValue(pluginContext as PluginContextValue); - - const component = shallow(); - expect(component.find(OldOverviewPage)).toHaveLength(0); - expect(component.find(NewOverviewPage)).toHaveLength(1); - }); -}); diff --git a/x-pack/plugins/observability/public/pages/overview/index.tsx b/x-pack/plugins/observability/public/pages/overview/index.tsx index 6b773b303031e..9ceabf7c3111a 100644 --- a/x-pack/plugins/observability/public/pages/overview/index.tsx +++ b/x-pack/plugins/observability/public/pages/overview/index.tsx @@ -4,25 +4,354 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React from 'react'; -import { RouteParams } from '../../routes'; +import { + EuiButton, + EuiButtonEmpty, + EuiFlexGroup, + EuiFlexItem, + EuiFlyout, + EuiFlyoutBody, + EuiFlyoutHeader, + EuiHorizontalRule, + EuiSpacer, + EuiText, + EuiTitle, + EuiTourStep, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import React, { useMemo, useRef, useCallback, useState, useEffect } from 'react'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { Storage } from '@kbn/kibana-utils-plugin/public'; +import { observabilityFeatureId } from '../../../common'; +import { useTrackPageview, useUiTracker } from '../..'; +import { EmptySections } from '../../components/app/empty_sections'; +import { ObservabilityHeaderMenu } from '../../components/app/header'; +import { NewsFeed } from '../../components/app/news_feed'; +import { Resources } from '../../components/app/resources'; +import { DatePicker } from '../../components/shared/date_picker'; +import { useBreadcrumbs } from '../../hooks/use_breadcrumbs'; +import { useFetcher } from '../../hooks/use_fetcher'; +import { useHasData } from '../../hooks/use_has_data'; import { usePluginContext } from '../../hooks/use_plugin_context'; -import { OverviewPage as OldOverviewPage } from './old_overview_page'; -import { OverviewPage as NewOverviewPage } from './overview_page'; +import { useAlertIndexNames } from '../../hooks/use_alert_index_names'; +import { RouteParams } from '../../routes'; +import { getNewsFeed } from '../../services/get_news_feed'; +import { getBucketSize } from '../../utils/get_bucket_size'; +import { getNoDataConfig } from '../../utils/no_data_config'; +import { DataSections } from './data_sections'; +import { LoadingObservability } from './loading_observability'; +import { AlertsTableTGrid } from '../alerts/containers/alerts_table_t_grid/alerts_table_t_grid'; +import { SectionContainer } from '../../components/app/section'; +import { ObservabilityAppServices } from '../../application/types'; +import { useGetUserCasesPermissions } from '../../hooks/use_get_user_cases_permissions'; +import { paths } from '../../config'; +import { useDatePickerContext } from '../../hooks/use_date_picker_context'; +import { ObservabilityStatusProgress } from '../../components/app/observability_status/observability_status_progress'; +import { ObservabilityStatus } from '../../components/app/observability_status'; +import { useGuidedSetupProgress } from '../../hooks/use_guided_setup_progress'; -export type { BucketSize } from './old_overview_page'; +export type BucketSize = ReturnType; interface Props { routeParams: RouteParams<'/overview'>; } -export function OverviewPage(props: Props) { - const { config } = usePluginContext(); - const alpha = props.routeParams.query.alpha; +const CAPABILITIES_KEYS = ['logs', 'infrastructure', 'apm', 'uptime']; - if (config.unsafe.overviewNext.enabled || alpha) { - return ; - } else { - return ; +function calculateBucketSize({ start, end }: { start?: number; end?: number }) { + if (start && end) { + return getBucketSize({ start, end, minInterval: '60s' }); } } + +const ALERT_TABLE_STATE_STORAGE_KEY = 'xpack.observability.overview.alert.tableState'; + +export function OverviewPage({ routeParams }: Props) { + const trackMetric = useUiTracker({ app: 'observability-overview' }); + useTrackPageview({ app: 'observability-overview', path: 'overview' }); + useTrackPageview({ app: 'observability-overview', path: 'overview', delay: 15000 }); + useBreadcrumbs([ + { + text: i18n.translate('xpack.observability.breadcrumbs.overviewLinkText', { + defaultMessage: 'Overview', + }), + }, + ]); + const [isFlyoutVisible, setIsFlyoutVisible] = useState(false); + + const indexNames = useAlertIndexNames(); + const { + cases, + docLinks, + http, + application: { capabilities }, + } = useKibana().services; + + const { ObservabilityPageTemplate, config } = usePluginContext(); + const { relativeStart, relativeEnd, absoluteStart, absoluteEnd } = useDatePickerContext(); + + const { data: newsFeed } = useFetcher(() => getNewsFeed({ http }), [http]); + + const { hasAnyData, isAllRequestsComplete } = useHasData(); + const refetch = useRef<() => void>(); + + const [isGuidedSetupTourVisible, setGuidedSetupTourVisible] = useState(false); + const hideGuidedSetupTour = useCallback(() => setGuidedSetupTourVisible(false), []); + const { isGuidedSetupProgressDismissed } = useGuidedSetupProgress(); + + const bucketSize = useMemo( + () => + calculateBucketSize({ + start: absoluteStart, + end: absoluteEnd, + }), + [absoluteStart, absoluteEnd] + ); + + const setRefetch = useCallback((ref) => { + refetch.current = ref; + }, []); + + const handleGuidedSetupClick = useCallback(() => { + if (isGuidedSetupProgressDismissed) { + trackMetric({ metric: 'guided_setup_view_details_after_dismiss' }); + } + hideGuidedSetupTour(); + setIsFlyoutVisible(true); + }, [trackMetric, isGuidedSetupProgressDismissed, hideGuidedSetupTour]); + + const onTimeRangeRefresh = useCallback(() => { + return refetch.current && refetch.current(); + }, []); + + const CasesContext = cases.ui.getCasesContext(); + const userPermissions = useGetUserCasesPermissions(); + + useEffect(() => { + if (hasAnyData !== true) { + return; + } + + CAPABILITIES_KEYS.forEach((feature) => { + if (capabilities[feature].show === false) { + trackMetric({ + metric: `oblt_disabled_feature_${feature === 'infrastructure' ? 'metrics' : feature}`, + }); + } + }); + }, [capabilities, hasAnyData, trackMetric]); + + if (hasAnyData === undefined) { + return ; + } + + const hasData = hasAnyData === true || (isAllRequestsComplete === false ? undefined : false); + + const noDataConfig = getNoDataConfig({ + hasData, + basePath: http.basePath, + docsLink: docLinks.links.observability.guide, + }); + + const alertsLink = config.unsafe.alertingExperience.enabled + ? paths.observability.alerts + : paths.management.rules; + + return ( + + ), + } + : undefined + } + > + {hasData && ( + <> + + setIsFlyoutVisible(true)} + onDismissClick={() => setGuidedSetupTourVisible(true)} + /> + + + + + + + + + + {/* Data sections */} + {hasAnyData && } + + + + + + + + {/* Resources / What's New sections */} + + + {!!newsFeed?.items?.length && } + + + + + + + + + )} + {isFlyoutVisible && ( + setIsFlyoutVisible(false)} + aria-labelledby="statusVisualizationFlyoutTitle" + > + + +

+ +

+
+ + +

+ +

+
+
+ + + +
+ )} +
+ ); +} + +interface PageHeaderProps { + showTour?: boolean; + onTourDismiss: () => void; + handleGuidedSetupClick: () => void; + onTimeRangeRefresh: () => void; +} + +function PageHeader({ + showTour = false, + onTourDismiss, + handleGuidedSetupClick, + onTimeRangeRefresh, +}: PageHeaderProps) { + const { relativeStart, relativeEnd, refreshInterval, refreshPaused } = useDatePickerContext(); + const buttonRef = useRef(); + + return ( + + + +

{overviewPageTitle}

+
+
+ + + + + + + + {showTour ? ( + buttonRef.current} + isStepOpen + title={i18n.translate('xpack.observability.overview.guidedSetupTourTitle', { + defaultMessage: 'Guided setup is always available', + })} + content={ + + + + } + step={1} + stepsTotal={1} + maxWidth={400} + onFinish={onTourDismiss} + footerAction={ + + + + } + /> + ) : null} + +
+ ); +} + +const overviewPageTitle = i18n.translate('xpack.observability.overview.pageTitle', { + defaultMessage: 'Overview', +}); diff --git a/x-pack/plugins/observability/public/pages/overview/old_overview_page.tsx b/x-pack/plugins/observability/public/pages/overview/old_overview_page.tsx deleted file mode 100644 index 4afe1fe7dedb1..0000000000000 --- a/x-pack/plugins/observability/public/pages/overview/old_overview_page.tsx +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - EuiFlexGroup, - EuiFlexItem, - EuiSpacer, - EuiHorizontalRule, - EuiButton, - EuiFlyout, - EuiFlyoutHeader, - EuiTitle, - EuiFlyoutBody, - EuiText, -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n-react'; -import React, { useMemo, useRef, useCallback, useState, useEffect } from 'react'; -import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { observabilityFeatureId } from '../../../common'; -import { useTrackPageview, useUiTracker } from '../..'; -import { EmptySections } from '../../components/app/empty_sections'; -import { ObservabilityHeaderMenu } from '../../components/app/header'; -import { NewsFeed } from '../../components/app/news_feed'; -import { Resources } from '../../components/app/resources'; -import { DatePicker } from '../../components/shared/date_picker'; -import { useBreadcrumbs } from '../../hooks/use_breadcrumbs'; -import { useFetcher } from '../../hooks/use_fetcher'; -import { useHasData } from '../../hooks/use_has_data'; -import { usePluginContext } from '../../hooks/use_plugin_context'; -import { useAlertIndexNames } from '../../hooks/use_alert_index_names'; -import { RouteParams } from '../../routes'; -import { getNewsFeed } from '../../services/get_news_feed'; -import { getBucketSize } from '../../utils/get_bucket_size'; -import { getNoDataConfig } from '../../utils/no_data_config'; -import { DataSections } from './data_sections'; -import { LoadingObservability } from './loading_observability'; -import { AlertsTableTGrid } from '../alerts/containers/alerts_table_t_grid/alerts_table_t_grid'; -import { SectionContainer } from '../../components/app/section'; -import { ObservabilityAppServices } from '../../application/types'; -import { useGetUserCasesPermissions } from '../../hooks/use_get_user_cases_permissions'; -import { paths } from '../../config'; -import { useDatePickerContext } from '../../hooks/use_date_picker_context'; -import { ObservabilityStatusProgress } from '../../components/app/observability_status/observability_status_progress'; -import { ObservabilityStatus } from '../../components/app/observability_status'; -import { useGuidedSetupProgress } from '../../hooks/use_guided_setup_progress'; -interface Props { - routeParams: RouteParams<'/overview'>; -} -export type BucketSize = ReturnType; - -const CAPABILITIES_KEYS = ['logs', 'infrastructure', 'apm', 'uptime']; - -function calculateBucketSize({ start, end }: { start?: number; end?: number }) { - if (start && end) { - return getBucketSize({ start, end, minInterval: '60s' }); - } -} - -export function OverviewPage({ routeParams }: Props) { - const trackMetric = useUiTracker({ app: 'observability-overview' }); - useTrackPageview({ app: 'observability-overview', path: 'overview' }); - useTrackPageview({ app: 'observability-overview', path: 'overview', delay: 15000 }); - useBreadcrumbs([ - { - text: i18n.translate('xpack.observability.breadcrumbs.overviewLinkText', { - defaultMessage: 'Overview', - }), - }, - ]); - const [isFlyoutVisible, setIsFlyoutVisible] = useState(false); - - const indexNames = useAlertIndexNames(); - const { - cases, - docLinks, - http, - application: { capabilities }, - } = useKibana().services; - - const { ObservabilityPageTemplate, config } = usePluginContext(); - const { relativeStart, relativeEnd, absoluteStart, absoluteEnd } = useDatePickerContext(); - - const { data: newsFeed } = useFetcher(() => getNewsFeed({ http }), [http]); - - const { hasAnyData, isAllRequestsComplete } = useHasData(); - const refetch = useRef<() => void>(); - - const { isGuidedSetupProgressDismissed } = useGuidedSetupProgress(); - - const bucketSize = useMemo( - () => - calculateBucketSize({ - start: absoluteStart, - end: absoluteEnd, - }), - [absoluteStart, absoluteEnd] - ); - - const setRefetch = useCallback((ref) => { - refetch.current = ref; - }, []); - - const handleGuidedSetupClick = useCallback(() => { - if (isGuidedSetupProgressDismissed) { - trackMetric({ metric: 'guided_setup_view_details_after_dismiss' }); - } - - setIsFlyoutVisible(true); - }, [trackMetric, isGuidedSetupProgressDismissed]); - - const onTimeRangeRefresh = useCallback(() => { - return refetch.current && refetch.current(); - }, []); - - const CasesContext = cases.ui.getCasesContext(); - const userPermissions = useGetUserCasesPermissions(); - - useEffect(() => { - if (hasAnyData !== true) { - return; - } - - CAPABILITIES_KEYS.forEach((feature) => { - if (capabilities[feature].show === false) { - trackMetric({ - metric: `oblt_disabled_feature_${feature === 'infrastructure' ? 'metrics' : feature}`, - }); - } - }); - }, [capabilities, hasAnyData, trackMetric]); - - if (hasAnyData === undefined) { - return ; - } - - const hasData = hasAnyData === true || (isAllRequestsComplete === false ? undefined : false); - - const noDataConfig = getNoDataConfig({ - hasData, - basePath: http.basePath, - docsLink: docLinks.links.observability.guide, - }); - - const alertsLink = config.unsafe.alertingExperience.enabled - ? paths.observability.alerts - : paths.management.rules; - - return ( - - ), - } - : undefined - } - > - {hasData && ( - <> - - setIsFlyoutVisible(true)} /> - - - - - - - - - - {/* Data sections */} - {hasAnyData && } - - - - - - - - {/* Resources / What's New sections */} - - - {!!newsFeed?.items?.length && } - - - - - - - - - )} - {isFlyoutVisible && ( - setIsFlyoutVisible(false)} - aria-labelledby="statusVisualizationFlyoutTitle" - > - - -

- -

-
- - -

- -

-
-
- - - -
- )} -
- ); -} - -interface PageHeaderProps { - handleGuidedSetupClick: () => void; - onTimeRangeRefresh: () => void; -} - -function PageHeader({ handleGuidedSetupClick, onTimeRangeRefresh }: PageHeaderProps) { - const { relativeStart, relativeEnd, refreshInterval, refreshPaused } = useDatePickerContext(); - return ( - - - -

{overviewPageTitle}

-
-
- - - - - - - - -
- ); -} - -const overviewPageTitle = i18n.translate('xpack.observability.overview.pageTitle', { - defaultMessage: 'Overview', -}); diff --git a/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx b/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx index b975e45ac06df..95d263168f82e 100644 --- a/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx +++ b/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx @@ -85,7 +85,6 @@ const withCore = makeDecorator({ unsafe: { alertingExperience: { enabled: true }, cases: { enabled: true }, - overviewNext: { enabled: false }, rules: { enabled: true }, }, }, diff --git a/x-pack/plugins/observability/public/pages/overview/overview_page.tsx b/x-pack/plugins/observability/public/pages/overview/overview_page.tsx deleted file mode 100644 index 7f81f71cf6683..0000000000000 --- a/x-pack/plugins/observability/public/pages/overview/overview_page.tsx +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { i18n } from '@kbn/i18n'; -import React, { useState } from 'react'; -import { EuiButton, EuiFlyout, EuiFlyoutBody, EuiFlyoutHeader, EuiTitle } from '@elastic/eui'; -import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { useTrackPageview } from '../..'; -import { DatePicker } from '../../components/shared/date_picker'; -import { useBreadcrumbs } from '../../hooks/use_breadcrumbs'; -import { useHasData } from '../../hooks/use_has_data'; -import { usePluginContext } from '../../hooks/use_plugin_context'; -import { useDatePickerContext } from '../../hooks/use_date_picker_context'; -import { RouteParams } from '../../routes'; -import { getNoDataConfig } from '../../utils/no_data_config'; -import { LoadingObservability } from './loading_observability'; -import { ObservabilityStatus } from '../../components/app/observability_status'; -import { ObservabilityAppServices } from '../../application/types'; - -interface Props { - routeParams: RouteParams<'/overview'>; -} - -export function OverviewPage({ routeParams }: Props) { - useTrackPageview({ app: 'observability-overview', path: 'overview' }); - useTrackPageview({ app: 'observability-overview', path: 'overview', delay: 15000 }); - useBreadcrumbs([ - { - text: i18n.translate('xpack.observability.breadcrumbs.overviewLinkText', { - defaultMessage: 'Overview', - }), - }, - ]); - - const [isFlyoutVisible, setIsFlyoutVisible] = useState(false); - - const { docLinks, http } = useKibana().services; - const { ObservabilityPageTemplate } = usePluginContext(); - - const { relativeStart, relativeEnd } = useDatePickerContext(); - - const relativeTime = { start: relativeStart, end: relativeEnd }; - - const { hasAnyData, isAllRequestsComplete } = useHasData(); - - if (hasAnyData === undefined) { - return ; - } - - const hasData = hasAnyData === true || (isAllRequestsComplete === false ? undefined : false); - - const noDataConfig = getNoDataConfig({ - hasData, - basePath: http.basePath, - docsLink: docLinks.links.observability.guide, - }); - - const { refreshInterval = 10000, refreshPaused = true } = routeParams.query; - - return ( - , - ], - } - : undefined - } - > - {hasData && ( - <> - setIsFlyoutVisible(true)}>Show observability status - {isFlyoutVisible && ( - setIsFlyoutVisible(false)} - aria-labelledby="flyout-id" - > - - -

Status

-
-
- - - -
- )} - - )} -
- ); -} - -const overviewPageTitle = i18n.translate('xpack.observability.overview.pageTitle', { - defaultMessage: 'Overview', -}); diff --git a/x-pack/plugins/observability/public/pages/rules/components/execution_status.tsx b/x-pack/plugins/observability/public/pages/rules/components/execution_status.tsx index 81dfe9ebd1606..c0c7413aa9c15 100644 --- a/x-pack/plugins/observability/public/pages/rules/components/execution_status.tsx +++ b/x-pack/plugins/observability/public/pages/rules/components/execution_status.tsx @@ -5,14 +5,22 @@ * 2.0. */ -import React from 'react'; -import { EuiHealth, EuiToolTip, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import React, { useState } from 'react'; +import { EuiHealth, EuiToolTip, EuiFlexGroup, EuiFlexItem, EuiButtonEmpty } from '@elastic/eui'; import { RuleExecutionStatusErrorReasons } from '@kbn/alerting-plugin/common'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { ManageLicenseModal } from './manage_license_model'; import { getHealthColor, rulesStatusesTranslationsMapping } from '../config'; import { RULE_STATUS_LICENSE_ERROR } from '../translations'; import { ExecutionStatusProps } from '../types'; +import { useKibana } from '../../../utils/kibana_react'; -export function ExecutionStatus({ executionStatus }: ExecutionStatusProps) { +export function ExecutionStatus({ executionStatus, item, licenseType }: ExecutionStatusProps) { + const { http } = useKibana().services; + const [manageLicenseModalOpts, setManageLicenseModalOpts] = useState<{ + licenseType: string; + ruleTypeId: string; + } | null>(null); const healthColor = getHealthColor(executionStatus.status); const tooltipMessage = executionStatus.status === 'error' ? `Error: ${executionStatus?.error?.message}` : null; @@ -38,6 +46,36 @@ export function ExecutionStatus({ executionStatus }: ExecutionStatusProps) { return ( {healthWithTooltip} + {isLicenseError && ( + + + setManageLicenseModalOpts({ + licenseType, + ruleTypeId: item.ruleTypeId, + }) + } + > + + + + )} + {manageLicenseModalOpts && ( + { + window.open(`${http.basePath.get()}/app/management/stack/license_management`, '_blank'); + setManageLicenseModalOpts(null); + }} + onCancel={() => setManageLicenseModalOpts(null)} + /> + )} ); } diff --git a/x-pack/plugins/observability/public/pages/rules/components/manage_license_model.tsx b/x-pack/plugins/observability/public/pages/rules/components/manage_license_model.tsx new file mode 100644 index 0000000000000..e273c7d5a3044 --- /dev/null +++ b/x-pack/plugins/observability/public/pages/rules/components/manage_license_model.tsx @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { EuiConfirmModal } from '@elastic/eui'; +import { capitalize } from 'lodash'; + +interface Props { + licenseType: string; + ruleTypeId: string; + onConfirm: () => void; + onCancel: () => void; +} + +export function ManageLicenseModal({ licenseType, ruleTypeId, onConfirm, onCancel }: Props) { + const licenseRequired = capitalize(licenseType); + return ( + +

+ +

+
+ ); +} diff --git a/x-pack/plugins/observability/public/pages/rules/components/status.tsx b/x-pack/plugins/observability/public/pages/rules/components/status.tsx deleted file mode 100644 index 612d6f8f30bdd..0000000000000 --- a/x-pack/plugins/observability/public/pages/rules/components/status.tsx +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useMemo } from 'react'; -import { EuiBadge } from '@elastic/eui'; -import { noop } from 'lodash/fp'; -import { StatusProps } from '../types'; -import { statusMap } from '../config'; -import { RULES_CHANGE_STATUS } from '../translations'; - -export function Status({ type, disabled, onClick }: StatusProps) { - const props = useMemo( - () => ({ - color: statusMap[type].color, - ...(!disabled ? { onClick } : { onClick: noop }), - ...(!disabled ? { iconType: 'arrowDown', iconSide: 'right' as const } : {}), - ...(!disabled ? { iconOnClick: onClick } : { iconOnClick: noop }), - }), - [disabled, onClick, type] - ); - return ( - - {statusMap[type].label} - - ); -} diff --git a/x-pack/plugins/observability/public/pages/rules/components/status_context.tsx b/x-pack/plugins/observability/public/pages/rules/components/status_context.tsx deleted file mode 100644 index c7bd29d85b17a..0000000000000 --- a/x-pack/plugins/observability/public/pages/rules/components/status_context.tsx +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useState, useCallback, useMemo } from 'react'; -import { - EuiPopover, - EuiContextMenuItem, - EuiContextMenuPanel, - EuiLoadingSpinner, -} from '@elastic/eui'; -import { Status } from './status'; -import { RuleStatus, StatusContextProps } from '../types'; -import { statusMap } from '../config'; - -export function StatusContext({ - item, - disabled = false, - onStatusChanged, - enableRule, - disableRule, - muteRule, - unMuteRule, -}: StatusContextProps) { - const [isPopoverOpen, setIsPopoverOpen] = useState(false); - const [isUpdating, setIsUpdating] = useState(false); - const togglePopover = useCallback(() => setIsPopoverOpen(!isPopoverOpen), [isPopoverOpen]); - - let currentStatus: RuleStatus; - if (item.enabled) { - currentStatus = item.muteAll ? RuleStatus.snoozed : RuleStatus.enabled; - } else { - currentStatus = RuleStatus.disabled; - } - const popOverButton = useMemo( - () => , - [disabled, currentStatus, togglePopover] - ); - - const onContextMenuItemClick = useCallback( - async (status: RuleStatus) => { - togglePopover(); - if (currentStatus !== status) { - setIsUpdating(true); - - if (status === RuleStatus.enabled) { - await enableRule({ ...item, enabled: true }); - if (item.muteAll) { - await unMuteRule({ ...item, muteAll: false }); - } - } else if (status === RuleStatus.disabled) { - await disableRule({ ...item, enabled: false }); - } else if (status === RuleStatus.snoozed) { - await muteRule({ ...item, muteAll: true }); - } - setIsUpdating(false); - onStatusChanged(status); - } - }, - [ - item, - togglePopover, - enableRule, - disableRule, - muteRule, - unMuteRule, - currentStatus, - onStatusChanged, - ] - ); - - const panelItems = useMemo( - () => - Object.values(RuleStatus).map((status: RuleStatus) => ( - onContextMenuItemClick(status)} - disabled={status === RuleStatus.snoozed && currentStatus === RuleStatus.disabled} - > - {statusMap[status].label} - - )), - [currentStatus, onContextMenuItemClick] - ); - - return isUpdating ? ( - - ) : ( - setIsPopoverOpen(false)} - anchorPosition="downLeft" - isOpen={isPopoverOpen} - panelPaddingSize="none" - > - - - ); -} diff --git a/x-pack/plugins/observability/public/pages/rules/index.tsx b/x-pack/plugins/observability/public/pages/rules/index.tsx index 03e8ca86b2fa2..3d005c30fc747 100644 --- a/x-pack/plugins/observability/public/pages/rules/index.tsx +++ b/x-pack/plugins/observability/public/pages/rules/index.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useState, useMemo, useEffect } from 'react'; +import React, { useState, useMemo, useCallback } from 'react'; import { capitalize, sortBy } from 'lodash'; import { EuiButton, @@ -15,10 +15,8 @@ import { EuiButtonEmpty, EuiText, EuiHorizontalRule, - EuiAutoRefreshButton, EuiTableSortingType, EuiFieldSearch, - OnRefreshChangeProps, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -27,12 +25,14 @@ import { RuleTableItem, enableRule, disableRule, - muteRule, + snoozeRule, useLoadRuleTypes, - unmuteRule, + unsnoozeRule, } from '@kbn/triggers-actions-ui-plugin/public'; import { RuleExecutionStatus, ALERTS_FEATURE_ID } from '@kbn/alerting-plugin/common'; import { usePluginContext } from '../../hooks/use_plugin_context'; +import { Provider, rulesPageStateContainer, useRulesPageStateContainer } from './state_container'; + import { useBreadcrumbs } from '../../hooks/use_breadcrumbs'; import { useKibana } from '../../utils/kibana_react'; import { useFetchRules } from '../../hooks/use_fetch_rules'; @@ -40,7 +40,6 @@ import { RulesTable } from './components/rules_table'; import { Name } from './components/name'; import { LastResponseFilter } from './components/last_response_filter'; import { TypeFilter } from './components/type_filter'; -import { StatusContext } from './components/status_context'; import { ExecutionStatus } from './components/execution_status'; import { LastRun } from './components/last_run'; import { EditRuleFlyout } from './components/edit_rule_flyout'; @@ -74,7 +73,7 @@ import { import { ExperimentalBadge } from '../../components/shared/experimental_badge'; const ENTER_KEY = 13; -export function RulesPage() { +function RulesPage() { const { ObservabilityPageTemplate, kibanaFeatures } = usePluginContext(); const { http, @@ -83,6 +82,7 @@ export function RulesPage() { application: { capabilities }, notifications: { toasts }, } = useKibana().services; + const { lastResponse, setLastResponse } = useRulesPageStateContainer(); const documentationLink = docLinks.links.observability.createAlerts; const ruleTypeRegistry = triggersActionsUi.ruleTypeRegistry; const canExecuteActions = hasExecuteActionsCapability(capabilities); @@ -93,13 +93,12 @@ export function RulesPage() { }); const [inputText, setInputText] = useState(); const [searchText, setSearchText] = useState(); - const [refreshInterval, setRefreshInterval] = useState(60000); - const [isPaused, setIsPaused] = useState(false); - const [ruleLastResponseFilter, setRuleLastResponseFilter] = useState([]); + // const [ruleLastResponseFilter, setRuleLastResponseFilter] = useState([]); const [typesFilter, setTypesFilter] = useState([]); const [currentRuleToEdit, setCurrentRuleToEdit] = useState(null); const [rulesToDelete, setRulesToDelete] = useState([]); const [createRuleFlyoutVisibility, setCreateRuleFlyoutVisibility] = useState(false); + const [tagPopoverOpenIndex, setTagPopoverOpenIndex] = useState(-1); const isRuleTypeEditableInContext = (ruleTypeId: string) => ruleTypeRegistry.has(ruleTypeId) ? !ruleTypeRegistry.get(ruleTypeId).requiresAppContext : false; @@ -108,17 +107,9 @@ export function RulesPage() { setCurrentRuleToEdit(ruleItem); }; - const onRefreshChange = ({ - isPaused: isPausedChanged, - refreshInterval: refreshIntervalChanged, - }: OnRefreshChangeProps) => { - setIsPaused(isPausedChanged); - setRefreshInterval(refreshIntervalChanged); - }; - const { rulesState, setRulesState, reload, noData, initialLoad } = useFetchRules({ searchText, - ruleLastResponseFilter, + ruleLastResponseFilter: lastResponse, typesFilter, page, setPage, @@ -160,15 +151,6 @@ export function RulesPage() { (ruleType) => ruleType.authorizedConsumers[ALERTS_FEATURE_ID]?.all ); - useEffect(() => { - const interval = setInterval(() => { - if (!isPaused) { - reload(); - } - }, refreshInterval); - return () => clearInterval(interval); - }, [refreshInterval, reload, isPaused]); - useBreadcrumbs([ { text: i18n.translate('xpack.observability.breadcrumbs.alertsLinkText', { @@ -192,6 +174,23 @@ export function RulesPage() { 'data-test-subj': 'rulesTableCell-name', render: (name: string, rule: RuleTableItem) => , }, + { + field: 'tags', + name: '', + sortable: false, + width: '50px', + 'data-test-subj': 'rulesTableCell-tagsPopover', + render: (tags: string[], item: RuleTableItem) => { + return tags.length > 0 + ? triggersActionsUi.getRuleTagBadge({ + isOpen: tagPopoverOpenIndex === item.index, + tags, + onClick: () => setTagPopoverOpenIndex(item.index), + onClose: () => setTagPopoverOpenIndex(-1), + }) + : null; + }, + }, { field: 'executionStatus.lastExecutionDate', name: LAST_RUN_COLUMN_TITLE, @@ -206,7 +205,11 @@ export function RulesPage() { width: '120px', 'data-test-subj': 'rulesTableCell-status', render: (_executionStatus: RuleExecutionStatus, item: RuleTableItem) => ( - + ), }, { @@ -214,17 +217,17 @@ export function RulesPage() { name: STATUS_COLUMN_TITLE, sortable: true, render: (_enabled: boolean, item: RuleTableItem) => { - return ( - reload()} - enableRule={async () => await enableRule({ http, id: item.id })} - disableRule={async () => await disableRule({ http, id: item.id })} - muteRule={async () => await muteRule({ http, id: item.id })} - unMuteRule={async () => await unmuteRule({ http, id: item.id })} - /> - ); + return triggersActionsUi.getRuleStatusDropdown({ + rule: item, + enableRule: async () => await enableRule({ http, id: item.id }), + disableRule: async () => await disableRule({ http, id: item.id }), + onRuleChanged: () => reload(), + isEditable: item.isEditable && isRuleTypeEditableInContext(item.ruleTypeId), + snoozeRule: async (snoozeEndTime: string | -1) => { + await snoozeRule({ http, id: item.id, snoozeEndTime }); + }, + unsnoozeRule: async () => await unsnoozeRule({ http, id: item.id }), + }); }, }, { @@ -284,6 +287,13 @@ export function RulesPage() { [] ); + const setExecutionStatusFilter = useCallback( + (ids: string[]) => { + setLastResponse(ids); + }, + [setLastResponse] + ); + const getRulesTable = () => { if (noData && !rulesState.isLoading) { return authorizedToCreateAnyRules ? ( @@ -298,6 +308,10 @@ export function RulesPage() { if (initialLoad) { return ; } + + // const nextSearchParams = new URLSearchParams(history.location.search); + // const xx = [...nextSearchParams.getAll('executionStatus')] || []; + // console.log(xx, '!!'); return ( <> @@ -335,8 +349,8 @@ export function RulesPage() { setRuleLastResponseFilter(ids)} + selectedStatuses={lastResponse} + onChange={setExecutionStatusFilter} /> @@ -368,14 +382,6 @@ export function RulesPage() { /> - - - @@ -469,3 +475,13 @@ export function RulesPage() { ); } + +function WrappedRulesPage() { + return ( + + + + ); +} + +export { WrappedRulesPage as RulesPage }; diff --git a/x-pack/plugins/observability/public/pages/rules/state_container/index.tsx b/x-pack/plugins/observability/public/pages/rules/state_container/index.tsx new file mode 100644 index 0000000000000..7820342482035 --- /dev/null +++ b/x-pack/plugins/observability/public/pages/rules/state_container/index.tsx @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { Provider, rulesPageStateContainer } from './state_container'; +export { useRulesPageStateContainer } from './use_rules_page_state_container'; diff --git a/x-pack/plugins/observability/public/pages/rules/state_container/state_container.tsx b/x-pack/plugins/observability/public/pages/rules/state_container/state_container.tsx new file mode 100644 index 0000000000000..b36ffca96972e --- /dev/null +++ b/x-pack/plugins/observability/public/pages/rules/state_container/state_container.tsx @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + createStateContainer, + createStateContainerReactHelpers, +} from '@kbn/kibana-utils-plugin/public'; + +interface RulesPageContainerState { + lastResponse: string[]; +} + +const defaultState: RulesPageContainerState = { + lastResponse: [], +}; + +interface RulesPageStateTransitions { + setLastResponse: ( + state: RulesPageContainerState + ) => (lastResponse: string[]) => RulesPageContainerState; +} + +const transitions: RulesPageStateTransitions = { + setLastResponse: (state) => (lastResponse) => { + const filteredIds = lastResponse; + lastResponse.forEach((id) => { + const isPreviouslyChecked = state.lastResponse.includes(id); + if (!isPreviouslyChecked) { + filteredIds.concat(id); + } else { + filteredIds.filter((val) => { + return val !== id; + }); + } + }); + return { ...state, lastResponse: filteredIds }; + }, +}; + +const rulesPageStateContainer = createStateContainer(defaultState, transitions); + +type RulesPageStateContainer = typeof rulesPageStateContainer; +const { Provider, useContainer } = createStateContainerReactHelpers(); + +export { Provider, rulesPageStateContainer, useContainer, defaultState }; +export type { RulesPageStateContainer, RulesPageContainerState, RulesPageStateTransitions }; diff --git a/x-pack/plugins/observability/public/pages/rules/state_container/use_rules_page_state_container.tsx b/x-pack/plugins/observability/public/pages/rules/state_container/use_rules_page_state_container.tsx new file mode 100644 index 0000000000000..6b44dc8ae31d5 --- /dev/null +++ b/x-pack/plugins/observability/public/pages/rules/state_container/use_rules_page_state_container.tsx @@ -0,0 +1,96 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useEffect } from 'react'; +import { useHistory } from 'react-router-dom'; + +import { + createKbnUrlStateStorage, + syncState, + IKbnUrlStateStorage, + useContainerSelector, +} from '@kbn/kibana-utils-plugin/public'; + +import { + useContainer, + defaultState, + RulesPageStateContainer, + RulesPageContainerState, +} from './state_container'; + +export function useRulesPageStateContainer() { + const stateContainer = useContainer(); + + useUrlStateSyncEffect(stateContainer); + + const { setLastResponse } = stateContainer.transitions; + const { lastResponse } = useContainerSelector(stateContainer, (state) => state); + + return { + lastResponse, + setLastResponse, + }; +} + +function useUrlStateSyncEffect(stateContainer: RulesPageStateContainer) { + const history = useHistory(); + + useEffect(() => { + const urlStateStorage = createKbnUrlStateStorage({ + history, + useHash: false, + useHashQuery: false, + }); + const { start, stop } = setupUrlStateSync(stateContainer, urlStateStorage); + + start(); + + syncUrlStateWithInitialContainerState(stateContainer, urlStateStorage); + + return stop; + }, [stateContainer, history]); +} + +function setupUrlStateSync( + stateContainer: RulesPageStateContainer, + stateStorage: IKbnUrlStateStorage +) { + // This handles filling the state when an incomplete URL set is provided + const setWithDefaults = (changedState: Partial | null) => { + stateContainer.set({ ...defaultState, ...changedState }); + }; + return syncState({ + storageKey: '_a', + stateContainer: { + ...stateContainer, + set: setWithDefaults, + }, + stateStorage, + }); +} + +function syncUrlStateWithInitialContainerState( + stateContainer: RulesPageStateContainer, + urlStateStorage: IKbnUrlStateStorage +) { + const urlState = urlStateStorage.get>('_a'); + + if (urlState) { + const newState = { + ...defaultState, + ...urlState, + }; + + stateContainer.set(newState); + } else { + // Reset the state container when no URL state or timefilter range is set to avoid accidentally + // re-using state set on a previous visit to the page in the same session + stateContainer.set(defaultState); + } + + urlStateStorage.set('_a', stateContainer.get()); +} diff --git a/x-pack/plugins/observability/public/pages/rules/types.ts b/x-pack/plugins/observability/public/pages/rules/types.ts index cbcd97919cddc..8b3e337b99bd8 100644 --- a/x-pack/plugins/observability/public/pages/rules/types.ts +++ b/x-pack/plugins/observability/public/pages/rules/types.ts @@ -45,6 +45,8 @@ export interface StatusFilterProps { export interface ExecutionStatusProps { executionStatus: RuleExecutionStatus; + item: RuleTableItem; + licenseType: string; } export interface LastRunProps { diff --git a/x-pack/plugins/observability/public/plugin.ts b/x-pack/plugins/observability/public/plugin.ts index a19c5dfa0c3ce..cb8dcaf2dd7e4 100644 --- a/x-pack/plugins/observability/public/plugin.ts +++ b/x-pack/plugins/observability/public/plugin.ts @@ -32,6 +32,7 @@ import { TriggersAndActionsUIPublicPluginStart, } from '@kbn/triggers-actions-ui-plugin/public'; import { KibanaFeature } from '@kbn/features-plugin/common'; + import { ConfigSchema } from '.'; import { observabilityAppId, observabilityFeatureId, casesPath } from '../common'; import { createLazyObservabilityPageTemplate } from './components/shared'; @@ -144,6 +145,12 @@ export class Plugin const { renderApp } = await import('./application'); // Get start services const [coreStart, pluginsStart, { navigation }] = await coreSetup.getStartServices(); + // Register alerts metadata + const { registerAlertsTableConfiguration } = await import( + './config/register_alerts_table_configuration' + ); + const { alertsTableConfigurationRegistry } = pluginsStart.triggersActionsUi; + registerAlertsTableConfiguration(alertsTableConfigurationRegistry); // The `/api/features` endpoint requires the "Global All" Kibana privilege. Users with a // subset of this privilege are not authorized to access this endpoint and will receive a 404 // error that causes the Alerting view to fail to load. @@ -268,7 +275,6 @@ export class Plugin public start(coreStart: CoreStart, pluginsStart: ObservabilityPublicPluginsStart) { const { application } = coreStart; - const config = this.initializerContext.config.get(); updateGlobalNavigation({ diff --git a/x-pack/plugins/observability/public/utils/test_helper.tsx b/x-pack/plugins/observability/public/utils/test_helper.tsx index d5607b5ee8b48..bdbb9dd71164a 100644 --- a/x-pack/plugins/observability/public/utils/test_helper.tsx +++ b/x-pack/plugins/observability/public/utils/test_helper.tsx @@ -26,7 +26,6 @@ const config = { unsafe: { alertingExperience: { enabled: true }, cases: { enabled: true }, - overviewNext: { enabled: false }, rules: { enabled: true }, }, }; diff --git a/x-pack/plugins/observability/server/index.ts b/x-pack/plugins/observability/server/index.ts index 39537a67a8cbf..ab2a566fc6b85 100644 --- a/x-pack/plugins/observability/server/index.ts +++ b/x-pack/plugins/observability/server/index.ts @@ -35,7 +35,6 @@ export const config: PluginConfigDescriptor = { alertingExperience: schema.object({ enabled: schema.boolean({ defaultValue: true }) }), rules: schema.object({ enabled: schema.boolean({ defaultValue: true }) }), cases: schema.object({ enabled: schema.boolean({ defaultValue: true }) }), - overviewNext: schema.object({ enabled: schema.boolean({ defaultValue: false }) }), }), }), }; diff --git a/x-pack/plugins/observability/server/lib/annotations/bootstrap_annotations.ts b/x-pack/plugins/observability/server/lib/annotations/bootstrap_annotations.ts index 45fe9fd4b920c..cb3f350cb24f8 100644 --- a/x-pack/plugins/observability/server/lib/annotations/bootstrap_annotations.ts +++ b/x-pack/plugins/observability/server/lib/annotations/bootstrap_annotations.ts @@ -25,7 +25,7 @@ export type ScopedAnnotationsClientFactory = Awaited< ReturnType >['getScopedAnnotationsClient']; -export type ScopedAnnotationsClient = ReturnType; +export type ScopedAnnotationsClient = Awaited>; export type AnnotationsAPI = Awaited>; export async function bootstrapAnnotations({ index, core, context }: Params) { @@ -38,15 +38,19 @@ export async function bootstrapAnnotations({ index, core, context }: Params) { }); return { - getScopedAnnotationsClient: ( - requestContext: RequestHandlerContext & { licensing: LicensingApiRequestHandlerContext }, + getScopedAnnotationsClient: async ( + requestContext: RequestHandlerContext & { + licensing: Promise; + }, request: KibanaRequest ) => { + const esClient = (await requestContext.core).elasticsearch.client; + const { license } = await requestContext.licensing; return createAnnotationsClient({ index, - esClient: requestContext.core.elasticsearch.client.asCurrentUser, + esClient: esClient.asCurrentUser, logger, - license: requestContext.licensing?.license, + license, }); }, }; diff --git a/x-pack/plugins/observability/server/lib/annotations/register_annotation_apis.ts b/x-pack/plugins/observability/server/lib/annotations/register_annotation_apis.ts index 216c83feb53df..6eb0ba6d6e96c 100644 --- a/x-pack/plugins/observability/server/lib/annotations/register_annotation_apis.ts +++ b/x-pack/plugins/observability/server/lib/annotations/register_annotation_apis.ts @@ -57,13 +57,14 @@ export function registerAnnotationAPIs({ }); } - const esClient = context.core.elasticsearch.client.asCurrentUser; + const esClient = (await context.core).elasticsearch.client.asCurrentUser; + const license = (await context.licensing)?.license; const client = createAnnotationsClient({ index, esClient, logger, - license: context.licensing?.license, + license, }); try { diff --git a/x-pack/plugins/observability/server/types.ts b/x-pack/plugins/observability/server/types.ts index 0a3e2054f9213..75f67d933f681 100644 --- a/x-pack/plugins/observability/server/types.ts +++ b/x-pack/plugins/observability/server/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { IRouter, RequestHandlerContext } from '@kbn/core/server'; +import type { IRouter, CustomRequestHandlerContext } from '@kbn/core/server'; import type { AlertingApiRequestHandlerContext } from '@kbn/alerting-plugin/server'; import type { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server'; @@ -20,10 +20,10 @@ export type { /** * @internal */ -export interface ObservabilityRequestHandlerContext extends RequestHandlerContext { +export type ObservabilityRequestHandlerContext = CustomRequestHandlerContext<{ licensing: LicensingApiRequestHandlerContext; alerting: AlertingApiRequestHandlerContext; -} +}>; /** * @internal diff --git a/x-pack/plugins/osquery/common/schemas/common/utils.ts b/x-pack/plugins/osquery/common/schemas/common/utils.ts new file mode 100644 index 0000000000000..95b2bdd7a4050 --- /dev/null +++ b/x-pack/plugins/osquery/common/schemas/common/utils.ts @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { isEmpty, reduce } from 'lodash'; + +export const convertECSMappingToArray = (ecsMapping: Record | undefined) => + ecsMapping + ? Object.entries(ecsMapping).map((item) => ({ + key: item[0], + value: item[1], + })) + : undefined; + +export const convertECSMappingToObject = ( + ecsMapping: Array<{ + key: string; + result: { + type: string; + value: string; + }; + }> +): Record => + reduce( + ecsMapping, + (acc, value) => { + if (!isEmpty(value?.key) && !isEmpty(value.result?.type) && !isEmpty(value.result?.value)) { + acc[value.key] = { + [value.result.type]: value.result.value, + }; + } + + return acc; + }, + {} as Record + ); diff --git a/x-pack/plugins/osquery/cypress/fixtures/saved_objects/rule.ndjson b/x-pack/plugins/osquery/cypress/fixtures/saved_objects/rule.ndjson index 75bdecb5be428..f688dc0731c7f 100644 --- a/x-pack/plugins/osquery/cypress/fixtures/saved_objects/rule.ndjson +++ b/x-pack/plugins/osquery/cypress/fixtures/saved_objects/rule.ndjson @@ -8,10 +8,7 @@ "version": "WzE5MjksMV0=", "attributes": { "name": "Test-rule", - "tags": [ - "__internal_rule_id:22308402-5e0e-421b-8d22-a47ddc4b0188", - "__internal_immutable:false" - ], + "tags": [], "alertTypeId": "siem.queryRule", "consumer": "siem", "params": { diff --git a/x-pack/plugins/osquery/cypress/integration/all/alerts.spec.ts b/x-pack/plugins/osquery/cypress/integration/all/alerts.spec.ts index 7813a94e2bfe3..21d3584b9fc46 100644 --- a/x-pack/plugins/osquery/cypress/integration/all/alerts.spec.ts +++ b/x-pack/plugins/osquery/cypress/integration/all/alerts.spec.ts @@ -37,6 +37,7 @@ describe('Alert Event Details', () => { it('should be able to run live query', () => { const PACK_NAME = 'testpack'; const RULE_NAME = 'Test-rule'; + const TIMELINE_NAME = 'Untitled timeline'; navigateTo('/app/osquery/packs'); preparePack(PACK_NAME); findAndClickButton('Edit'); @@ -57,6 +58,7 @@ describe('Alert Event Details', () => { cy.getBySel('ruleSwitch').click(); cy.getBySel('ruleSwitch').should('have.attr', 'aria-checked', 'true'); cy.visit('/app/security/alerts'); + cy.wait(500); cy.getBySel('expand-event').first().click(); cy.getBySel('take-action-dropdown-btn').click(); cy.getBySel('osquery-action-item').click(); @@ -64,12 +66,16 @@ describe('Alert Event Details', () => { inputQuery('select * from uptime;'); submitQuery(); checkResults(); - + cy.contains('Save for later').click(); + cy.contains('Save query'); + cy.get('.euiButtonEmpty--flushLeft').contains('Cancel').click(); + cy.getBySel('add-to-timeline').first().click(); + cy.getBySel('globalToastList').contains('Added'); cy.getBySel(RESULTS_TABLE).within(() => { cy.getBySel(RESULTS_TABLE_BUTTON).should('not.exist'); }); - cy.contains('Save for later').click(); - cy.contains('Save query'); - cy.contains(/^Save$/); + cy.contains('Cancel').click(); + cy.contains(TIMELINE_NAME).click(); + cy.getBySel('draggableWrapperKeyboardHandler').contains('action_id: "'); }); }); diff --git a/x-pack/plugins/osquery/cypress/integration/all/delete_all_ecs_mappings.spec.ts b/x-pack/plugins/osquery/cypress/integration/all/delete_all_ecs_mappings.spec.ts index dab935d919a28..1ce25a77f834a 100644 --- a/x-pack/plugins/osquery/cypress/integration/all/delete_all_ecs_mappings.spec.ts +++ b/x-pack/plugins/osquery/cypress/integration/all/delete_all_ecs_mappings.spec.ts @@ -31,7 +31,10 @@ describe('ALL - Delete ECS Mappings', () => { }).click(); cy.contains('Custom key/value pairs.').should('exist'); cy.contains('Hours of uptime').should('exist'); - cy.react('EuiButtonIcon', { props: { id: 'labels-trash' } }).click(); + cy.react('ECSComboboxFieldComponent', { props: { field: { value: 'labels' } } }) + .parents('[data-test-subj="ECSMappingEditorForm"]') + .react('EuiButtonIcon', { props: { iconType: 'trash' } }) + .click(); cy.react('EuiButton').contains('Update query').click(); cy.wait(5000); diff --git a/x-pack/plugins/osquery/cypress/integration/all/live_query.spec.ts b/x-pack/plugins/osquery/cypress/integration/all/live_query.spec.ts index 1ddec794f41be..7cdc55c014505 100644 --- a/x-pack/plugins/osquery/cypress/integration/all/live_query.spec.ts +++ b/x-pack/plugins/osquery/cypress/integration/all/live_query.spec.ts @@ -42,10 +42,10 @@ describe('ALL - Live Query', () => { cy.contains('View in Lens').should('exist'); cy.react(RESULTS_TABLE_CELL_WRRAPER, { props: { id: 'osquery.days.number', index: 1 }, - }); + }).should('exist'); cy.react(RESULTS_TABLE_CELL_WRRAPER, { props: { id: 'osquery.hours.number', index: 2 }, - }); + }).should('exist'); getAdvancedButton().click(); typeInECSFieldInput('message{downArrow}{enter}'); @@ -58,9 +58,11 @@ describe('ALL - Live Query', () => { }); cy.react(RESULTS_TABLE_CELL_WRRAPER, { props: { id: 'message', index: 1 }, - }); + }).should('exist'); cy.react(RESULTS_TABLE_CELL_WRRAPER, { props: { id: 'osquery.days.number', index: 2 }, - }).react('EuiIconIndexMapping'); + }) + .react('EuiIconTip', { props: { type: 'indexMapping' } }) + .should('exist'); }); }); diff --git a/x-pack/plugins/osquery/cypress/integration/all/packs.spec.ts b/x-pack/plugins/osquery/cypress/integration/all/packs.spec.ts index 255dabbc433b0..917147fe88457 100644 --- a/x-pack/plugins/osquery/cypress/integration/all/packs.spec.ts +++ b/x-pack/plugins/osquery/cypress/integration/all/packs.spec.ts @@ -55,7 +55,7 @@ describe('ALL - Packs', () => { cy.react('List').first().click(); findAndClickButton('Add query'); cy.contains('Attach next query'); - getSavedQueriesDropdown().click().type(`${SAVED_QUERY_ID}{downArrow}{enter}`); + getSavedQueriesDropdown().type(`${SAVED_QUERY_ID}{downArrow}{enter}`); cy.react('EuiFormRow', { props: { label: 'Interval (s)' } }) .click() .clear() @@ -92,7 +92,7 @@ describe('ALL - Packs', () => { findAndClickButton('Add query'); cy.contains('Attach next query'); cy.contains('ID must be unique').should('not.exist'); - getSavedQueriesDropdown().click().type(`${SAVED_QUERY_ID}{downArrow}{enter}`); + getSavedQueriesDropdown().type(`${SAVED_QUERY_ID}{downArrow}{enter}`); cy.contains('ID must be unique').should('exist'); cy.react('EuiFlyoutFooter').react('EuiButtonEmpty').contains('Cancel').click(); }); @@ -170,7 +170,7 @@ describe('ALL - Packs', () => { findAndClickButton('Add query'); - getSavedQueriesDropdown().click().type('Multiple {downArrow} {enter}'); + getSavedQueriesDropdown().type('Multiple {downArrow} {enter}'); cy.contains('Custom key/value pairs'); cy.contains('Days of uptime'); cy.contains('List of keywords used to tag each'); @@ -178,7 +178,7 @@ describe('ALL - Packs', () => { cy.contains('Client network address.'); cy.contains('Total uptime seconds'); - getSavedQueriesDropdown().click().type('NOMAPPING {downArrow} {enter}'); + getSavedQueriesDropdown().type('NOMAPPING {downArrow} {enter}'); cy.contains('Custom key/value pairs').should('not.exist'); cy.contains('Days of uptime').should('not.exist'); cy.contains('List of keywords used to tag each').should('not.exist'); @@ -186,7 +186,7 @@ describe('ALL - Packs', () => { cy.contains('Client network address.').should('not.exist'); cy.contains('Total uptime seconds').should('not.exist'); - getSavedQueriesDropdown().click().type('ONE_MAPPING {downArrow} {enter}'); + getSavedQueriesDropdown().type('ONE_MAPPING {downArrow} {enter}'); cy.contains('Name of the continent'); cy.contains('Seconds of uptime'); diff --git a/x-pack/plugins/osquery/cypress/integration/roles/alert_test.spec.ts b/x-pack/plugins/osquery/cypress/integration/roles/alert_test.spec.ts new file mode 100644 index 0000000000000..5d25b6599b13c --- /dev/null +++ b/x-pack/plugins/osquery/cypress/integration/roles/alert_test.spec.ts @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ROLES } from '../../test'; +import { ArchiverMethod, runKbnArchiverScript } from '../../tasks/archiver'; +import { login } from '../../tasks/login'; +import { findAndClickButton, findFormFieldByRowsLabelAndType } from '../../tasks/live_query'; +import { preparePack } from '../../tasks/packs'; +import { closeModalIfVisible } from '../../tasks/integrations'; +import { navigateTo } from '../../tasks/navigation'; + +describe('Alert_Test', () => { + before(() => { + runKbnArchiverScript(ArchiverMethod.LOAD, 'pack'); + runKbnArchiverScript(ArchiverMethod.LOAD, 'rule'); + }); + beforeEach(() => { + login(ROLES.alert_test); + }); + + after(() => { + runKbnArchiverScript(ArchiverMethod.UNLOAD, 'pack'); + runKbnArchiverScript(ArchiverMethod.UNLOAD, 'rule'); + }); + + it('should be able to run live query', () => { + const PACK_NAME = 'testpack'; + const RULE_NAME = 'Test-rule'; + navigateTo('/app/osquery'); + preparePack(PACK_NAME); + findAndClickButton('Edit'); + cy.contains(`Edit ${PACK_NAME}`); + findFormFieldByRowsLabelAndType( + 'Scheduled agent policies (optional)', + 'fleet server {downArrow}{enter}' + ); + findAndClickButton('Update pack'); + closeModalIfVisible(); + cy.contains(PACK_NAME); + cy.visit('/app/security/rules'); + cy.contains(RULE_NAME).click(); + cy.wait(2000); + cy.getBySel('ruleSwitch').should('have.attr', 'aria-checked', 'true'); + cy.getBySel('ruleSwitch').click(); + cy.getBySel('ruleSwitch').should('have.attr', 'aria-checked', 'false'); + cy.getBySel('ruleSwitch').click(); + cy.getBySel('ruleSwitch').should('have.attr', 'aria-checked', 'true'); + cy.visit('/app/security/alerts'); + cy.getBySel('expand-event').first().click(); + cy.getBySel('take-action-dropdown-btn').click(); + cy.getBySel('osquery-action-item').click(); + + cy.contains('Run Osquery'); + cy.contains('Permission denied'); + }); +}); diff --git a/x-pack/plugins/osquery/cypress/integration/roles/t1_analyst.spec.ts b/x-pack/plugins/osquery/cypress/integration/roles/t1_analyst.spec.ts index 64d72c92dda04..51270332e0a51 100644 --- a/x-pack/plugins/osquery/cypress/integration/roles/t1_analyst.spec.ts +++ b/x-pack/plugins/osquery/cypress/integration/roles/t1_analyst.spec.ts @@ -60,7 +60,7 @@ describe('T1 Analyst - READ + runSavedQueries ', () => { cy.waitForReact(1000); cy.contains('New live query').should('not.be.disabled').click(); selectAllAgents(); - getSavedQueriesDropdown().click().type(`${SAVED_QUERY_ID}{downArrow} {enter}`); + getSavedQueriesDropdown().type(`${SAVED_QUERY_ID}{downArrow} {enter}`); cy.contains('select * from uptime'); submitQuery(); checkResults(); diff --git a/x-pack/plugins/osquery/cypress/integration/roles/t2_analyst.spec.ts b/x-pack/plugins/osquery/cypress/integration/roles/t2_analyst.spec.ts index 805eb134a44f5..28a8f8a7880ac 100644 --- a/x-pack/plugins/osquery/cypress/integration/roles/t2_analyst.spec.ts +++ b/x-pack/plugins/osquery/cypress/integration/roles/t2_analyst.spec.ts @@ -74,10 +74,10 @@ describe('T2 Analyst - READ + Write Live/Saved + runSavedQueries ', () => { cy.contains('View in Lens').should('not.exist'); cy.react('EuiDataGridHeaderCellWrapper', { props: { id: 'osquery.days.number', index: 1 }, - }); + }).should('exist'); cy.react('EuiDataGridHeaderCellWrapper', { props: { id: 'osquery.hours.number', index: 2 }, - }); + }).should('exist'); cy.react('EuiAccordion', { props: { buttonContent: 'Advanced' } }).click(); typeInECSFieldInput('message{downArrow}{enter}'); @@ -87,10 +87,14 @@ describe('T2 Analyst - READ + Write Live/Saved + runSavedQueries ', () => { checkResults(); cy.react('EuiDataGridHeaderCellWrapper', { props: { id: 'message', index: 1 }, - }); + }).should('exist'); cy.react('EuiDataGridHeaderCellWrapper', { props: { id: 'osquery.days.number', index: 2 }, - }).react('EuiIconIndexMapping'); + }).within(() => { + cy.get('.euiToolTipAnchor').within(() => { + cy.get('svg').should('exist'); + }); + }); }); it('to click the edit button and edit pack', () => { navigateTo('/app/osquery/saved_queries'); @@ -100,7 +104,10 @@ describe('T2 Analyst - READ + Write Live/Saved + runSavedQueries ', () => { }).click(); cy.contains('Custom key/value pairs.').should('exist'); cy.contains('Hours of uptime').should('exist'); - cy.react('EuiButtonIcon', { props: { id: 'labels-trash' } }).click(); + cy.react('ECSComboboxFieldComponent', { props: { field: { value: 'labels' } } }) + .parents('[data-test-subj="ECSMappingEditorForm"]') + .react('EuiButtonIcon', { props: { iconType: 'trash' } }) + .click(); cy.react('EuiButton').contains('Update query').click(); cy.wait(5000); diff --git a/x-pack/plugins/osquery/cypress/tasks/live_query.ts b/x-pack/plugins/osquery/cypress/tasks/live_query.ts index b3006a3d1074a..ca232d8507d2a 100644 --- a/x-pack/plugins/osquery/cypress/tasks/live_query.ts +++ b/x-pack/plugins/osquery/cypress/tasks/live_query.ts @@ -8,14 +8,15 @@ import { LIVE_QUERY_EDITOR } from '../screens/live_query'; export const DEFAULT_QUERY = 'select * from processes;'; -export const BIG_QUERY = 'select * from processes, users;'; +export const BIG_QUERY = 'select * from processes, users limit 200;'; export const selectAllAgents = () => { - cy.react('EuiComboBox', { props: { placeholder: 'Select agents or groups' } }).type('All agents'); + cy.react('AgentsTable').find('input').should('not.be.disabled'); + cy.react('AgentsTable EuiComboBox', { + props: { placeholder: 'Select agents or groups' }, + }).click(); cy.react('EuiFilterSelectItem').contains('All agents').should('exist'); - cy.react('EuiComboBox', { props: { placeholder: 'Select agents or groups' } }).type( - '{downArrow}{enter}{esc}' - ); + cy.react('AgentsTable EuiComboBox').type('{downArrow}{enter}{esc}'); cy.contains('1 agent selected.'); }; @@ -24,12 +25,11 @@ export const inputQuery = (query: string) => cy.get(LIVE_QUERY_EDITOR).type(quer export const submitQuery = () => cy.contains('Submit').click(); export const checkResults = () => - cy.getBySel('dataGridRowCell', { timeout: 60000 }).should('have.lengthOf.above', 0); + cy.getBySel('dataGridRowCell', { timeout: 120000 }).should('have.lengthOf.above', 0); -export const typeInECSFieldInput = (text: string) => - cy.getBySel('ECS-field-input').click().type(text); +export const typeInECSFieldInput = (text: string) => cy.getBySel('ECS-field-input').type(text); export const typeInOsqueryFieldInput = (text: string) => - cy.react('OsqueryColumnFieldComponent').first().react('ResultComboBox').click().type(text); + cy.react('OsqueryColumnFieldComponent').first().react('ResultComboBox').type(text); export const findFormFieldByRowsLabelAndType = (label: string, text: string) => { cy.react('EuiFormRow', { props: { label } }).type(text); diff --git a/x-pack/plugins/osquery/cypress/test/index.ts b/x-pack/plugins/osquery/cypress/test/index.ts index 53261d54e84b0..11cca6c93c553 100644 --- a/x-pack/plugins/osquery/cypress/test/index.ts +++ b/x-pack/plugins/osquery/cypress/test/index.ts @@ -15,4 +15,5 @@ export enum ROLES { rule_author = 'rule_author', platform_engineer = 'platform_engineer', detections_admin = 'detections_admin', + alert_test = 'alert_test', } diff --git a/x-pack/plugins/osquery/kibana.json b/x-pack/plugins/osquery/kibana.json index 619bcbeed14f4..1ea8468529b85 100644 --- a/x-pack/plugins/osquery/kibana.json +++ b/x-pack/plugins/osquery/kibana.json @@ -12,7 +12,6 @@ "requiredPlugins": [ "actions", "data", - "dataEnhanced", "discover", "features", "navigation", diff --git a/x-pack/plugins/osquery/public/action_results/use_action_results.ts b/x-pack/plugins/osquery/public/action_results/use_action_results.ts index e567c7ccdb635..d8dd3186238f7 100644 --- a/x-pack/plugins/osquery/public/action_results/use_action_results.ts +++ b/x-pack/plugins/osquery/public/action_results/use_action_results.ts @@ -9,7 +9,7 @@ import { flatten, reverse, uniqBy } from 'lodash/fp'; import { useQuery } from 'react-query'; import { i18n } from '@kbn/i18n'; -import { firstValueFrom } from 'rxjs'; +import { lastValueFrom } from 'rxjs'; import { createFilter, getInspectResponse, @@ -68,7 +68,7 @@ export const useActionResults = ({ return useQuery( ['actionResults', { actionId }], async () => { - const responseData = await firstValueFrom( + const responseData = await lastValueFrom( data.search.search( { actionId, diff --git a/x-pack/plugins/osquery/public/actions/use_action_details.ts b/x-pack/plugins/osquery/public/actions/use_action_details.ts index 1a6550d8f47dd..32b8d4578cb77 100644 --- a/x-pack/plugins/osquery/public/actions/use_action_details.ts +++ b/x-pack/plugins/osquery/public/actions/use_action_details.ts @@ -8,7 +8,7 @@ import { useQuery } from 'react-query'; import { i18n } from '@kbn/i18n'; -import { firstValueFrom } from 'rxjs'; +import { lastValueFrom } from 'rxjs'; import { createFilter } from '../common/helpers'; import { useKibana } from '../common/lib/kibana'; import { @@ -37,7 +37,7 @@ export const useActionDetails = ({ actionId, filterQuery, skip = false }: UseAct return useQuery( ['actionDetails', { actionId, filterQuery }], async () => { - const responseData = await firstValueFrom( + const responseData = await lastValueFrom( data.search.search( { actionId, diff --git a/x-pack/plugins/osquery/public/actions/use_all_actions.ts b/x-pack/plugins/osquery/public/actions/use_all_actions.ts index d1fe00c81a0b5..34a25fa47b6e9 100644 --- a/x-pack/plugins/osquery/public/actions/use_all_actions.ts +++ b/x-pack/plugins/osquery/public/actions/use_all_actions.ts @@ -8,7 +8,7 @@ import { useQuery } from 'react-query'; import { i18n } from '@kbn/i18n'; -import { firstValueFrom } from 'rxjs'; +import { lastValueFrom } from 'rxjs'; import { createFilter, generateTablePaginationOptions, @@ -60,7 +60,7 @@ export const useAllActions = ({ return useQuery( ['actions', { activePage, direction, limit, sortField }], async () => { - const responseData = await firstValueFrom( + const responseData = await lastValueFrom( data.search.search( { factoryQueryType: OsqueryQueries.actions, diff --git a/x-pack/plugins/osquery/public/agents/agents_table.tsx b/x-pack/plugins/osquery/public/agents/agents_table.tsx index 55e63456fe916..75d073c4d9292 100644 --- a/x-pack/plugins/osquery/public/agents/agents_table.tsx +++ b/x-pack/plugins/osquery/public/agents/agents_table.tsx @@ -6,13 +6,13 @@ */ import { find } from 'lodash/fp'; -import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; import { EuiComboBox, EuiHealth, EuiHighlight, EuiSpacer } from '@elastic/eui'; +import deepEqual from 'fast-deep-equal'; import useDebounce from 'react-use/lib/useDebounce'; import { useAllAgents } from './use_all_agents'; import { useAgentGroups } from './use_agent_groups'; -import { useOsqueryPolicies } from './use_osquery_policies'; import { AgentGrouper } from './agent_grouper'; import { getNumAgentsInGrouping, @@ -61,19 +61,16 @@ const AgentsTableComponent: React.FC = ({ agentSelection, onCh ); // grouping related - const osqueryPolicyData = useOsqueryPolicies(); const { - loading: groupsLoading, - totalCount: totalNumAgents, - groups, + isLoading: groupsLoading, + data: agentGroupsData, isFetched: groupsFetched, - } = useAgentGroups(osqueryPolicyData); - const grouper = useMemo(() => new AgentGrouper(), []); + } = useAgentGroups(); const { isLoading: agentsLoading, data: agents, isFetched: agentsFetched, - } = useAllAgents(osqueryPolicyData, debouncedSearchValue, { + } = useAllAgents(debouncedSearchValue, { perPage, }); @@ -96,7 +93,7 @@ const AgentsTableComponent: React.FC = ({ agentSelection, onCh selectedGroups: SelectedGroups; } = generateAgentSelection(selection); if (newAgentSelection.allAgentsSelected) { - setNumAgentsSelected(totalNumAgents); + setNumAgentsSelected(agentGroupsData?.totalCount ?? 0); } else { const checkAgent = generateAgentCheck(selectedGroups); setNumAgentsSelected( @@ -105,14 +102,14 @@ const AgentsTableComponent: React.FC = ({ agentSelection, onCh // add the number of agents added via policy and platform groups getNumAgentsInGrouping(selectedGroups) - // subtract the number of agents double counted by policy/platform selections - getNumOverlapped(selectedGroups, groups.overlap) + getNumOverlapped(selectedGroups, agentGroupsData?.groups?.overlap ?? {}) ); } onChange(newAgentSelection); setSelectedOptions(selection); }, - [groups, onChange, totalNumAgents] + [agentGroupsData, onChange] ); useEffect(() => { @@ -154,26 +151,18 @@ const AgentsTableComponent: React.FC = ({ agentSelection, onCh }, [agentSelection, onSelection, options, selectedOptions]); useEffect(() => { - if (agentsFetched && groupsFetched) { + if (agentsFetched && groupsFetched && agentGroupsData) { + const grouper = new AgentGrouper(); // update the groups when groups or agents have changed - grouper.setTotalAgents(totalNumAgents); - grouper.updateGroup(AGENT_GROUP_KEY.Platform, groups.platforms); - grouper.updateGroup(AGENT_GROUP_KEY.Policy, groups.policies); + grouper.setTotalAgents(agentGroupsData?.totalCount); + grouper.updateGroup(AGENT_GROUP_KEY.Platform, agentGroupsData?.groups.platforms); + grouper.updateGroup(AGENT_GROUP_KEY.Policy, agentGroupsData?.groups.policies); // @ts-expect-error update types grouper.updateGroup(AGENT_GROUP_KEY.Agent, agents); const newOptions = grouper.generateOptions(); - setOptions(newOptions); + setOptions((prevOptions) => (!deepEqual(prevOptions, newOptions) ? newOptions : prevOptions)); } - }, [ - groups.platforms, - groups.policies, - totalNumAgents, - groupsLoading, - agents, - agentsFetched, - groupsFetched, - grouper, - ]); + }, [groupsLoading, agents, agentsFetched, groupsFetched, agentGroupsData]); const renderOption = useCallback((option, searchVal, contentClassName) => { const { label, value } = option; @@ -202,6 +191,7 @@ const AgentsTableComponent: React.FC = ({ agentSelection, onCh return (
= ({ agentSelection, onCh ); }; +AgentsTableComponent.displayName = 'AgentsTable'; + export const AgentsTable = React.memo(AgentsTableComponent); diff --git a/x-pack/plugins/osquery/public/agents/helpers.ts b/x-pack/plugins/osquery/public/agents/helpers.ts index 1c23eac3ca201..db48b5d417c96 100644 --- a/x-pack/plugins/osquery/public/agents/helpers.ts +++ b/x-pack/plugins/osquery/public/agents/helpers.ts @@ -38,7 +38,17 @@ interface Aggs extends estypes.AggregationsTermsAggregateBase { buckets: AggregationDataPoint[]; } -export const processAggregations = (aggs: Record) => { +export const processAggregations = ( + aggs: Record | undefined +) => { + if (!aggs) { + return { + platforms: [], + overlap: {}, + policies: [], + }; + } + const platforms: Group[] = []; const overlap: Overlap = {}; const platformTerms = aggs.platforms as Aggs; diff --git a/x-pack/plugins/osquery/public/agents/use_agent_groups.ts b/x-pack/plugins/osquery/public/agents/use_agent_groups.ts index 2dba1c471a786..3dc96c1f150c7 100644 --- a/x-pack/plugins/osquery/public/agents/use_agent_groups.ts +++ b/x-pack/plugins/osquery/public/agents/use_agent_groups.ts @@ -4,10 +4,9 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { useState } from 'react'; import { useQuery } from 'react-query'; import { i18n } from '@kbn/i18n'; -import { firstValueFrom } from 'rxjs'; +import { lastValueFrom } from 'rxjs'; import { useKibana } from '../common/lib/kibana'; import { useAgentPolicies } from './use_agent_policies'; @@ -19,28 +18,27 @@ import { import { processAggregations } from './helpers'; import { generateTablePaginationOptions } from '../common/helpers'; -import { Overlap, Group } from './types'; import { useErrorToast } from '../common/hooks/use_error_toast'; +import { useOsqueryPolicies } from './use_osquery_policies'; -interface UseAgentGroups { - osqueryPolicies: string[]; - osqueryPoliciesLoading: boolean; -} - -export const useAgentGroups = ({ osqueryPolicies, osqueryPoliciesLoading }: UseAgentGroups) => { +export const useAgentGroups = () => { const { data } = useKibana().services; const setErrorToast = useErrorToast(); + const { data: osqueryPolicies, isFetched: isOsqueryPoliciesFetched } = useOsqueryPolicies(); const { agentPoliciesLoading, agentPolicyById } = useAgentPolicies(osqueryPolicies); - const [platforms, setPlatforms] = useState([]); - const [policies, setPolicies] = useState([]); - const [loading, setLoading] = useState(true); - const [overlap, setOverlap] = useState(() => ({})); - const [totalCount, setTotalCount] = useState(0); - const { isFetched } = useQuery( + + return useQuery< + AgentsStrategyResponse, + unknown, + { + totalCount: number; + groups: ReturnType; + } + >( ['agentGroups'], async () => { - const responseData = await firstValueFrom( + const responseData = await lastValueFrom( data.search.search( { filterQuery: { terms: { policy_id: osqueryPolicies } }, @@ -76,32 +74,54 @@ export const useAgentGroups = ({ osqueryPolicies, osqueryPoliciesLoading }: UseA ) ); - if (responseData.rawResponse.aggregations) { - const { - platforms: newPlatforms, - overlap: newOverlap, - policies: newPolicies, - } = processAggregations(responseData.rawResponse.aggregations); - - setPlatforms(newPlatforms); - setOverlap(newOverlap); - setPolicies( - newPolicies.map((p) => { - const name = agentPolicyById[p.id]?.name ?? p.name; - - return { - ...p, - name, - }; - }) - ); - } - - setLoading(false); - setTotalCount(responseData.totalCount); + return responseData; }, { - enabled: !osqueryPoliciesLoading && !agentPoliciesLoading, + select: (response) => { + const { platforms, overlap, policies } = processAggregations( + response.rawResponse.aggregations + ); + + return { + totalCount: response.totalCount, + groups: { + platforms, + overlap, + policies: policies.map((p) => { + const name = agentPolicyById[p.id]?.name ?? p.name; + + return { + ...p, + name, + }; + }), + }, + }; + }, + placeholderData: { + totalCount: 0, + edges: [], + pageInfo: { + activePage: 1, + fakeTotalCount: 100, + showMorePagesIndicator: true, + }, + rawResponse: { + took: 0, + timed_out: false, + _shards: { + failed: 0, + successful: 0, + total: 0, + }, + hits: { + hits: [], + }, + }, + }, + refetchOnWindowFocus: false, + keepPreviousData: true, + enabled: isOsqueryPoliciesFetched && !agentPoliciesLoading, onSuccess: () => setErrorToast(), onError: (error) => setErrorToast(error as Error, { @@ -111,15 +131,4 @@ export const useAgentGroups = ({ osqueryPolicies, osqueryPoliciesLoading }: UseA }), } ); - - return { - isFetched, - loading, - totalCount, - groups: { - platforms, - policies, - overlap, - }, - }; }; diff --git a/x-pack/plugins/osquery/public/agents/use_all_agents.ts b/x-pack/plugins/osquery/public/agents/use_all_agents.ts index 9ffcaae16bc6d..defe625eb9a28 100644 --- a/x-pack/plugins/osquery/public/agents/use_all_agents.ts +++ b/x-pack/plugins/osquery/public/agents/use_all_agents.ts @@ -11,11 +11,7 @@ import { useQuery } from 'react-query'; import { GetAgentsResponse } from '@kbn/fleet-plugin/common'; import { useErrorToast } from '../common/hooks/use_error_toast'; import { useKibana } from '../common/lib/kibana'; - -interface UseAllAgents { - osqueryPolicies: string[]; - osqueryPoliciesLoading: boolean; -} +import { useOsqueryPolicies } from './use_osquery_policies'; interface RequestOptions { perPage?: number; @@ -23,22 +19,24 @@ interface RequestOptions { } // TODO: break out the paginated vs all cases into separate hooks -export const useAllAgents = ( - { osqueryPolicies, osqueryPoliciesLoading }: UseAllAgents, - searchValue = '', - opts: RequestOptions = { perPage: 9000 } -) => { +export const useAllAgents = (searchValue = '', opts: RequestOptions = { perPage: 9000 }) => { const { perPage } = opts; const { http } = useKibana().services; const setErrorToast = useErrorToast(); + const { data: osqueryPolicies, isFetched } = useOsqueryPolicies(); + return useQuery( ['agents', osqueryPolicies, searchValue, perPage], () => { - let kuery = `(${osqueryPolicies.map((p) => `policy_id:${p}`).join(' or ')})`; + let kuery = ''; + + if (osqueryPolicies?.length) { + kuery = `(${osqueryPolicies.map((p) => `policy_id:${p}`).join(' or ')})`; - if (searchValue) { - kuery += ` and (local_metadata.host.hostname:*${searchValue}* or local_metadata.elastic.agent.id:*${searchValue}*)`; + if (searchValue) { + kuery += ` and (local_metadata.host.hostname:*${searchValue}* or local_metadata.elastic.agent.id:*${searchValue}*)`; + } } return http.get(`/internal/osquery/fleet_wrapper/agents`, { @@ -51,7 +49,7 @@ export const useAllAgents = ( { // @ts-expect-error update types select: (data) => data?.agents || [], - enabled: !osqueryPoliciesLoading && osqueryPolicies.length > 0, + enabled: isFetched && !!osqueryPolicies?.length, onSuccess: () => setErrorToast(), onError: (error) => // @ts-expect-error update types diff --git a/x-pack/plugins/osquery/public/agents/use_osquery_policies.ts b/x-pack/plugins/osquery/public/agents/use_osquery_policies.ts index 679aeef1bd23b..9ecf5d14c6b38 100644 --- a/x-pack/plugins/osquery/public/agents/use_osquery_policies.ts +++ b/x-pack/plugins/osquery/public/agents/use_osquery_policies.ts @@ -7,7 +7,6 @@ import { uniq } from 'lodash'; import { useQuery } from 'react-query'; -import { useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { useKibana } from '../common/lib/kibana'; import { useErrorToast } from '../common/hooks/use_error_toast'; @@ -16,7 +15,7 @@ export const useOsqueryPolicies = () => { const { http } = useKibana().services; const setErrorToast = useErrorToast(); - const { isLoading: osqueryPoliciesLoading, data: osqueryPolicies = [] } = useQuery( + return useQuery( ['osqueryPolicies'], () => http.get<{ items: Array<{ policy_id: string }> }>( @@ -33,9 +32,4 @@ export const useOsqueryPolicies = () => { }), } ); - - return useMemo( - () => ({ osqueryPoliciesLoading, osqueryPolicies }), - [osqueryPoliciesLoading, osqueryPolicies] - ); }; diff --git a/x-pack/plugins/osquery/public/assets/use_assets_status.ts b/x-pack/plugins/osquery/public/assets/use_assets_status.ts index fd6a2fecb2793..a3ae65c964cca 100644 --- a/x-pack/plugins/osquery/public/assets/use_assets_status.ts +++ b/x-pack/plugins/osquery/public/assets/use_assets_status.ts @@ -18,6 +18,7 @@ export const useAssetsStatus = () => { () => http.get('/internal/osquery/assets'), { keepPreviousData: true, + retry: false, } ); }; diff --git a/x-pack/plugins/osquery/public/live_queries/form/index.tsx b/x-pack/plugins/osquery/public/live_queries/form/index.tsx index f082ca0baeebe..6a72a0b59979f 100644 --- a/x-pack/plugins/osquery/public/live_queries/form/index.tsx +++ b/x-pack/plugins/osquery/public/live_queries/form/index.tsx @@ -8,22 +8,21 @@ import { EuiButton, EuiButtonEmpty, - EuiSteps, EuiSpacer, EuiFlexGroup, EuiFlexItem, EuiAccordion, EuiAccordionProps, } from '@elastic/eui'; -import { EuiContainedStepProps } from '@elastic/eui/src/components/steps/steps'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import React, { useCallback, useEffect, useMemo, useState, useRef } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useMutation } from 'react-query'; import deepMerge from 'deepmerge'; import styled from 'styled-components'; -import { pickBy, isEmpty } from 'lodash'; +import { pickBy, isEmpty, map } from 'lodash'; +import { convertECSMappingToObject } from '../../../common/schemas/common/utils'; import { UseField, Form, FormData, useForm, useFormData, FIELD_TYPES } from '../../shared_imports'; import { AgentsTableField } from './agents_table_field'; import { LiveQueryQueryField } from './live_query_query_field'; @@ -33,16 +32,13 @@ import { queryFieldValidation } from '../../common/validations'; import { fieldValidators } from '../../shared_imports'; import { SavedQueryFlyout } from '../../saved_queries'; import { useErrorToast } from '../../common/hooks/use_error_toast'; -import { - ECSMappingEditorField, - ECSMappingEditorFieldRef, -} from '../../packs/queries/lazy_ecs_mapping_editor_field'; +import { ECSMappingEditorField } from '../../packs/queries/lazy_ecs_mapping_editor_field'; import { SavedQueriesDropdown } from '../../saved_queries/saved_queries_dropdown'; const FORM_ID = 'liveQueryForm'; const StyledEuiAccordion = styled(EuiAccordion)` - ${({ isDisabled }: { isDisabled: boolean }) => isDisabled && 'display: none;'} + ${({ isDisabled }: { isDisabled?: boolean }) => isDisabled && 'display: none;'} .euiAccordion__button { color: ${({ theme }) => theme.eui.euiColorPrimary}; } @@ -55,27 +51,26 @@ const GhostFormField = () => <>; type FormType = 'simple' | 'steps'; interface LiveQueryFormProps { - defaultValue?: Partial | undefined; + defaultValue?: Partial; onSuccess?: () => void; - agentsField?: boolean; queryField?: boolean; ecsMappingField?: boolean; formType?: FormType; enabled?: boolean; - hideFullscreen?: true; + hideAgentsField?: boolean; + addToTimeline?: (payload: { query: [string, string]; isIcon?: true }) => React.ReactElement; } const LiveQueryFormComponent: React.FC = ({ defaultValue, onSuccess, - agentsField = true, queryField = true, ecsMappingField = true, formType = 'steps', enabled = true, - hideFullscreen, + hideAgentsField = false, + addToTimeline, }) => { - const ecsFieldRef = useRef(); const permissions = useKibana().services.application.capabilities.osquery; const { http } = useKibana().services; const [advancedContentState, setAdvancedContentState] = @@ -136,7 +131,7 @@ const LiveQueryFormComponent: React.FC = ({ ], }, ecs_mapping: { - defaultValue: {}, + defaultValue: [], type: FIELD_TYPES.JSON, validations: [], }, @@ -146,18 +141,9 @@ const LiveQueryFormComponent: React.FC = ({ id: FORM_ID, schema: formSchema, onSubmit: async (formData, isValid) => { - const ecsFieldValue = await ecsFieldRef?.current?.validate(); - if (isValid && (!ecsMappingField || !!ecsFieldValue)) { + if (isValid) { try { - await mutateAsync( - pickBy( - { - ...formData, - ...(isEmpty(ecsFieldValue) ? {} : { ecs_mapping: ecsFieldValue }), - }, - (value) => !isEmpty(value) - ) - ); + await mutateAsync(pickBy(formData, (value) => !isEmpty(value))); // eslint-disable-next-line no-empty } catch (e) {} } @@ -165,8 +151,16 @@ const LiveQueryFormComponent: React.FC = ({ options: { stripEmptyFields: false, }, - serializer: ({ savedQueryId, ...formData }) => - pickBy({ ...formData, saved_query_id: savedQueryId }, (value) => !isEmpty(value)), + // eslint-disable-next-line @typescript-eslint/naming-convention + serializer: ({ savedQueryId, ecs_mapping, ...formData }) => + pickBy( + { + ...formData, + saved_query_id: savedQueryId, + ecs_mapping: convertECSMappingToObject(ecs_mapping), + }, + (value) => !isEmpty(value) + ), defaultValue: deepMerge( { agentSelection: { @@ -177,12 +171,13 @@ const LiveQueryFormComponent: React.FC = ({ }, query: '', savedQueryId: null, + ecs_mapping: [], }, defaultValue ?? {} ), }); - const { setFieldValue, submit, isSubmitting } = form; + const { updateFieldValues, setFieldValue, submit, isSubmitting } = form; const actionId = useMemo(() => data?.actions[0].action_id, [data?.actions]); const agentIds = useMemo(() => data?.actions[0].agents, [data?.actions]); @@ -207,13 +202,12 @@ const LiveQueryFormComponent: React.FC = ({ const queryValueProvided = useMemo(() => !!query?.length, [query]); const queryStatus = useMemo(() => { - if (!agentSelected) return 'disabled'; - if (isError || !form.getFields().query.isValid) return 'danger'; + if (isError || !form.getFields().query?.isValid) return 'danger'; if (isLoading) return 'loading'; if (isSuccess) return 'complete'; return 'incomplete'; - }, [agentSelected, isError, isLoading, isSuccess, form]); + }, [isError, isLoading, isSuccess, form]); const resultsStatus = useMemo( () => (queryStatus === 'complete' ? 'incomplete' : 'disabled'), @@ -223,19 +217,28 @@ const LiveQueryFormComponent: React.FC = ({ const handleSavedQueryChange = useCallback( (savedQuery) => { if (savedQuery) { - setFieldValue('query', savedQuery.query); - setFieldValue('savedQueryId', savedQuery.savedQueryId); + updateFieldValues({ + query: savedQuery.query, + savedQueryId: savedQuery.savedQueryId, + ecs_mapping: savedQuery.ecs_mapping + ? map(savedQuery.ecs_mapping, (value, key) => ({ + key, + result: { + type: Object.keys(value)[0], + value: Object.values(value)[0], + }, + })) + : [], + }); + if (!isEmpty(savedQuery.ecs_mapping)) { - setFieldValue('ecs_mapping', savedQuery.ecs_mapping); setAdvancedContentState('open'); - } else { - setFieldValue('ecs_mapping', {}); } } else { setFieldValue('savedQueryId', null); } }, - [setFieldValue] + [setFieldValue, updateFieldValues] ); const commands = useMemo( @@ -251,10 +254,9 @@ const LiveQueryFormComponent: React.FC = ({ const queryComponentProps = useMemo( () => ({ - disabled: queryStatus === 'disabled', commands, }), - [queryStatus, commands] + [commands] ); const flyoutFormDefaultValue = useMemo( @@ -275,9 +277,8 @@ const LiveQueryFormComponent: React.FC = ({ ); const isSavedQueryDisabled = useMemo( - () => - queryComponentProps.disabled || !permissions.runSavedQueries || !permissions.readSavedQueries, - [permissions.readSavedQueries, permissions.runSavedQueries, queryComponentProps.disabled] + () => !permissions.runSavedQueries || !permissions.readSavedQueries, + [permissions.readSavedQueries, permissions.runSavedQueries] ); const queryFieldStepContent = useMemo( @@ -314,16 +315,9 @@ const LiveQueryFormComponent: React.FC = ({ forceState={advancedContentState} onToggle={handleToggle} buttonContent="Advanced" - isDisabled={queryComponentProps.disabled} > - + ) : ( @@ -372,7 +366,6 @@ const LiveQueryFormComponent: React.FC = ({ ecsMappingField, advancedContentState, handleToggle, - query, ecsFieldProps, formType, agentSelected, @@ -393,80 +386,49 @@ const LiveQueryFormComponent: React.FC = ({ actionId={actionId} endDate={data?.actions[0].expiration} agentIds={agentIds} - hideFullscreen={hideFullscreen} + addToTimeline={addToTimeline} /> ) : null, - [actionId, agentIds, data?.actions, hideFullscreen] - ); - - const formSteps: EuiContainedStepProps[] = useMemo( - () => [ - { - title: i18n.translate('xpack.osquery.liveQueryForm.steps.agentsStepHeading', { - defaultMessage: 'Select agents', - }), - children: , - status: agentSelected ? 'complete' : 'incomplete', - }, - { - title: i18n.translate('xpack.osquery.liveQueryForm.steps.queryStepHeading', { - defaultMessage: 'Enter query', - }), - children: queryFieldStepContent, - status: queryStatus, - }, - { - title: i18n.translate('xpack.osquery.liveQueryForm.steps.resultsStepHeading', { - defaultMessage: 'Check results', - }), - children: resultsStepContent, - status: resultsStatus, - }, - ], - [agentSelected, queryFieldStepContent, queryStatus, resultsStepContent, resultsStatus] - ); - - const simpleForm = useMemo( - () => ( - - - {queryFieldStepContent} - {resultsStepContent} - - ), - [agentsField, queryFieldStepContent, resultsStepContent] + [actionId, agentIds, data?.actions, addToTimeline] ); useEffect(() => { - if (defaultValue?.agentSelection) { - setFieldValue('agentSelection', defaultValue?.agentSelection); - } - - if (defaultValue?.query) { - setFieldValue('query', defaultValue?.query); - } - - // TODO: Set query and ECS mapping from savedQueryId object - if (defaultValue?.savedQueryId) { - setFieldValue('savedQueryId', defaultValue?.savedQueryId); - } - - if (!isEmpty(defaultValue?.ecs_mapping)) { - setFieldValue('ecs_mapping', defaultValue?.ecs_mapping); + if (defaultValue) { + updateFieldValues({ + agentSelection: defaultValue.agentSelection, + query: defaultValue.query, + savedQueryId: defaultValue.savedQueryId, + ecs_mapping: defaultValue.ecs_mapping + ? map(defaultValue.ecs_mapping, (value, key) => ({ + key, + result: { + type: Object.keys(value)[0], + value: Object.values(value)[0], + }, + })) + : undefined, + }); } - }, [defaultValue, setFieldValue]); + }, [defaultValue, updateFieldValues]); return ( <>
- {formType === 'steps' ? : simpleForm} + + + + + {queryFieldStepContent} + {resultsStepContent} + {showSavedQueryFlyout ? ( diff --git a/x-pack/plugins/osquery/public/live_queries/form/schema.ts b/x-pack/plugins/osquery/public/live_queries/form/schema.ts deleted file mode 100644 index 3d0195a112fec..0000000000000 --- a/x-pack/plugins/osquery/public/live_queries/form/schema.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { FIELD_TYPES, FormSchema } from '../../shared_imports'; - -export const formSchema: FormSchema = { - agents: { - type: FIELD_TYPES.MULTI_SELECT, - }, - query: { - type: FIELD_TYPES.TEXTAREA, - validations: [], - }, -}; diff --git a/x-pack/plugins/osquery/public/live_queries/index.tsx b/x-pack/plugins/osquery/public/live_queries/index.tsx index fdde03d6076a6..a147f929f7f25 100644 --- a/x-pack/plugins/osquery/public/live_queries/index.tsx +++ b/x-pack/plugins/osquery/public/live_queries/index.tsx @@ -28,7 +28,8 @@ interface LiveQueryProps { ecsMappingField?: boolean; enabled?: boolean; formType?: 'steps' | 'simple'; - hideFullscreen?: true; + hideAgentsField?: boolean; + addToTimeline?: (payload: { query: [string, string]; isIcon?: true }) => React.ReactElement; } const LiveQueryComponent: React.FC = ({ @@ -40,12 +41,12 @@ const LiveQueryComponent: React.FC = ({ savedQueryId, // eslint-disable-next-line @typescript-eslint/naming-convention ecs_mapping, - agentsField, queryField, ecsMappingField, formType, enabled, - hideFullscreen, + hideAgentsField, + addToTimeline, }) => { const { data: hasActionResultsPrivileges, isLoading } = useActionResultsPrivileges(); @@ -108,14 +109,14 @@ const LiveQueryComponent: React.FC = ({ return ( ); }; diff --git a/x-pack/plugins/osquery/public/packs/queries/ecs_mapping_editor_field.tsx b/x-pack/plugins/osquery/public/packs/queries/ecs_mapping_editor_field.tsx index bca3036d19f4c..a9c663051e273 100644 --- a/x-pack/plugins/osquery/public/packs/queries/ecs_mapping_editor_field.tsx +++ b/x-pack/plugins/osquery/public/packs/queries/ecs_mapping_editor_field.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import { produce } from 'immer'; import { castArray, each, @@ -19,16 +18,7 @@ import { trim, get, } from 'lodash'; -import React, { - forwardRef, - useCallback, - useEffect, - useMemo, - useRef, - useState, - useImperativeHandle, - MutableRefObject, -} from 'react'; +import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'; import { EuiFormLabel, EuiButtonIcon, @@ -49,7 +39,6 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import styled from 'styled-components'; import deepEqual from 'fast-deep-equal'; -import deepmerge from 'deepmerge'; import ECSSchema from '../../common/schemas/ecs/v8.2.0.json'; import osquerySchema from '../../common/schemas/osquery/v5.2.2.json'; @@ -57,17 +46,17 @@ import osquerySchema from '../../common/schemas/osquery/v5.2.2.json'; import { FieldIcon } from '../../common/lib/kibana'; import { FIELD_TYPES, - Form, - FormData, FieldHook, getFieldValidityAndErrorMessage, - useForm, useFormData, Field, getUseField, fieldValidators, ValidationFuncArg, UseMultiFields, + UseArray, + ArrayItem, + FormArrayField, } from '../../shared_imports'; import { OsqueryIcon } from '../../components/osquery_icon'; @@ -179,7 +168,7 @@ const ECSComboboxFieldComponent: React.FC = ({ setSelected(newSelectedOptions); setValue(newSelectedOptions[0]?.label ?? ''); }, - [setSelected, setValue] + [setValue] ); // TODO: Create own component for this. @@ -339,7 +328,7 @@ const OsqueryColumnFieldComponent: React.FC = ({ }) => { const inputRef = useRef(); const { setValue } = resultValue; - const { setValue: setType } = resultType; + const { value: typeValue, setValue: setType } = resultType; const { isInvalid, errorMessage } = getFieldValidityAndErrorMessage(resultValue); const describedByIds = useMemo(() => (idAria ? [idAria] : []), [idAria]); const [selectedOptions, setSelected] = useState< @@ -383,12 +372,12 @@ const OsqueryColumnFieldComponent: React.FC = ({ const onTypeChange = useCallback( (newType) => { - if (newType !== resultType.value) { + if (newType !== typeValue) { setType(newType); setValue(newType === 'value' && euiFieldProps.singleSelection === false ? [] : ''); } }, - [resultType.value, setType, setValue, euiFieldProps.singleSelection] + [typeValue, setType, setValue, euiFieldProps.singleSelection] ); const handleCreateOption = useCallback( @@ -416,8 +405,9 @@ const OsqueryColumnFieldComponent: React.FC = ({ const Prepend = useMemo( () => ( = ({ onChange={onTypeChange} /> ), - [onTypeChange, resultType.value] + [euiFieldProps.isDisabled, onTypeChange, typeValue] ); useEffect(() => { @@ -438,8 +428,7 @@ const OsqueryColumnFieldComponent: React.FC = ({ if (!euiFieldProps?.singleSelection && !isArray(resultValue.value)) { setValue(resultValue.value.length ? [resultValue.value] : []); } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [euiFieldProps?.singleSelection, setValue]); + }, [euiFieldProps?.singleSelection, resultValue.value, setValue]); useEffect(() => { setSelected(() => { @@ -482,7 +471,7 @@ const OsqueryColumnFieldComponent: React.FC = ({ rowHeight={32} isClearable {...euiFieldProps} - options={(resultType.value === 'field' && euiFieldProps.options) || EMPTY_ARRAY} + options={(typeValue === 'field' && euiFieldProps.options) || EMPTY_ARRAY} /> @@ -490,105 +479,96 @@ const OsqueryColumnFieldComponent: React.FC = ({ ); }; -export const OsqueryColumnField = React.memo( - OsqueryColumnFieldComponent, - (prevProps, nextProps) => - prevProps.resultType.value === nextProps.resultType.value && - prevProps.resultType.isChangingValue === nextProps.resultType.isChangingValue && - prevProps.resultType.errors === nextProps.resultType.errors && - prevProps.resultValue.value === nextProps.resultValue.value && - prevProps.resultValue.isChangingValue === nextProps.resultValue.isChangingValue && - prevProps.resultValue.errors === nextProps.resultValue.errors && - deepEqual(prevProps.euiFieldProps, nextProps.euiFieldProps) -); - -export interface ECSMappingEditorFieldRef { - validate: () => Promise< - | Record< - string, - { - field: string; - } - > - | false - | {} - >; -} +export const OsqueryColumnField = React.memo(OsqueryColumnFieldComponent); export interface ECSMappingEditorFieldProps { - field: FieldHook>; - query: string; - fieldRef: MutableRefObject; - euiFieldProps: EuiComboBoxProps<{}>; + euiFieldProps?: EuiComboBoxProps<{}>; } interface ECSMappingEditorFormProps { isDisabled?: boolean; osquerySchemaOptions: OsquerySchemaOption[]; - defaultValue?: FormData; - onAdd?: (payload: FormData) => void; - onChange?: (payload: FormData) => void; - onDelete?: (key: string) => void; + item: ArrayItem; + isLastItem?: boolean; + onDelete?: FormArrayField['removeItem']; } -const getEcsFieldValidator = - (editForm: boolean) => - (args: ValidationFuncArg) => { - const fieldRequiredError = fieldValidators.emptyField( - i18n.translate('xpack.osquery.pack.queryFlyoutForm.ecsFieldRequiredErrorMessage', { - defaultMessage: 'ECS field is required.', - }) - )(args); - +const ecsFieldValidator = ( + args: ValidationFuncArg & { + customData: { + value: { + editForm: boolean; + }; + }; + } +) => { + const editForm: boolean = args.customData.value?.editForm; + const rootPath = args.path.split('.')[0]; + + const fieldRequiredError = fieldValidators.emptyField( + i18n.translate('xpack.osquery.pack.queryFlyoutForm.ecsFieldRequiredErrorMessage', { + defaultMessage: 'ECS field is required.', + }) + )(args); + + if ( + fieldRequiredError && // @ts-expect-error update types - if (fieldRequiredError && ((!editForm && args.formData['result.value'].length) || editForm)) { - return fieldRequiredError; - } + ((!editForm && args.formData[`${rootPath}.result.value`]?.length) || editForm) + ) { + return fieldRequiredError; + } - return undefined; - }; + return undefined; +}; -const getOsqueryResultFieldValidator = - (osquerySchemaOptions: OsquerySchemaOption[], editForm: boolean) => - ( - args: ValidationFuncArg - ) => { - const fieldRequiredError = fieldValidators.emptyField( - i18n.translate('xpack.osquery.pack.queryFlyoutForm.osqueryResultFieldRequiredErrorMessage', { - defaultMessage: 'Value is required.', - }) - )(args); - - if (fieldRequiredError && ((!editForm && args.formData.key.length) || editForm)) { - return fieldRequiredError; - } +const osqueryResultFieldValidator = async ( + args: ValidationFuncArg & { + customData: { + value: { + editForm: boolean; + osquerySchemaOptions: OsquerySchemaOption[]; + }; + }; + } +) => { + const rootPath = args.path.split('.')[0]; + const { editForm, osquerySchemaOptions } = args.customData.value; + const fieldRequiredError = fieldValidators.emptyField( + i18n.translate('xpack.osquery.pack.queryFlyoutForm.osqueryResultFieldRequiredErrorMessage', { + defaultMessage: 'Value is required.', + }) + )(args); + + // @ts-expect-error update types + if (fieldRequiredError && ((!editForm && args.formData[`${rootPath}.key`]?.length) || editForm)) { + return fieldRequiredError; + } - // @ts-expect-error update types - if (!args.value?.length || args.formData['result.type'] !== 'field') return; - - const osqueryColumnExists = find(osquerySchemaOptions, ['label', args.value]); - - return !osqueryColumnExists - ? { - code: 'ERR_FIELD_FORMAT', - path: args.path, - message: i18n.translate( - 'xpack.osquery.pack.queryFlyoutForm.osqueryResultFieldValueMissingErrorMessage', - { - defaultMessage: 'The current query does not return a {columnName} field', - values: { - columnName: args.value, - }, - } - ), - __isBlocking__: false, - } - : undefined; - }; + // @ts-expect-error update types + if (!args.value?.length || args.formData[`${rootPath}.result.type`] !== 'field') return; + + const osqueryColumnExists = find(osquerySchemaOptions, [ + 'label', + isArray(args.value) ? args.value[0] : args.value, + ]); -const FORM_DEFAULT_VALUE = { - key: '', - value: { field: '' }, + return !osqueryColumnExists + ? { + code: 'ERR_FIELD_FORMAT', + path: args.path, + message: i18n.translate( + 'xpack.osquery.pack.queryFlyoutForm.osqueryResultFieldValueMissingErrorMessage', + { + defaultMessage: 'The current query does not return a {columnName} field', + values: { + columnName: args.value, + }, + } + ), + __isBlocking__: false, + } + : undefined; }; interface ECSMappingEditorFormData { @@ -599,217 +579,141 @@ interface ECSMappingEditorFormData { }; } -interface ECSMappingEditorFormRef { - validate: () => Promise<{ - data: ECSMappingEditorFormData | {}; - isValid: boolean; - }>; -} +export const ECSMappingEditorForm: React.FC = ({ + isDisabled, + osquerySchemaOptions, + item, + isLastItem, + onDelete, +}) => { + const multipleValuesField = useRef(false); -export const ECSMappingEditorForm = forwardRef( - ({ isDisabled, osquerySchemaOptions, defaultValue, onAdd, onChange, onDelete }, ref) => { - const editForm = !!defaultValue; - const multipleValuesField = useRef(false); - const currentFormData = useRef(defaultValue); - const formSchema = useMemo( - () => ({ - key: { - type: FIELD_TYPES.COMBO_BOX, - fieldsToValidateOnChange: ['result.value', 'key'], - validations: [ - { - validator: getEcsFieldValidator(editForm), + const MultiFields = useMemo( + () => ( + ({ - key: data.key ?? '', - result: { - type: data.value - ? Object.keys(data.value)[0] - : OSQUERY_COLUMN_VALUE_TYPE_OPTIONS[0].value, - value: data.value ? Object.values(data.value)[0] : '', - }, - }), - }); - - const { submit, reset, validate, validateFields } = form; - - const [formData] = useFormData({ form }); - - const handleSubmit = useCallback(async () => { - validate(); - validateFields(['result.value', 'key']); - const { data, isValid } = await submit(); - - if (isValid) { - const serializedData = { - key: data.key, - value: { - [data.result.type]: data.result.value, }, - }; - if (onAdd) { - onAdd(serializedData); - } - - if (onChange) { - onChange(serializedData); - } - - reset(); - } - }, [validate, validateFields, submit, onAdd, onChange, reset]); - - const handleDeleteClick = useCallback(() => { - if (defaultValue?.key && onDelete) { - onDelete(defaultValue.key); - } - }, [defaultValue, onDelete]); - - const MultiFields = useMemo( - () => ( - - {(fields) => ( - - )} - - ), - [osquerySchemaOptions, isDisabled] - ); - - const ecsComboBoxEuiFieldProps = useMemo(() => ({ isDisabled }), [isDisabled]); + }, + }} + > + {(fields) => ( + + )} + + ), + [item.path, osquerySchemaOptions, isLastItem, isDisabled] + ); - useImperativeHandle( - ref, - () => ({ - validate: async () => { - if (!editForm && deepEqual(formData, FORM_DEFAULT_VALUE)) { - return { data: {}, isValid: true }; - } + const ecsComboBoxEuiFieldProps = useMemo(() => ({ isDisabled }), [isDisabled]); - validateFields(['result.value', 'key']); - const isValid = await validate(); + const validationData = useMemo(() => ({ editForm: !isLastItem }), [isLastItem]); - return { - data: formData?.key?.length - ? { - [formData.key]: { - [formData.result.type]: formData.result.value, - }, - } - : {}, - isValid, - }; + const config = useMemo( + () => ({ + valueChangeDebounceTime: 300, + fieldsToValidateOnChange: [`${item.path}.key`, `${item.path}.result.value`], + validations: [ + { + validator: ecsFieldValidator, }, - }), - [validateFields, editForm, formData, validate] - ); + ], + }), + [item.path] + ); - useEffect(() => { - if (!deepEqual(formData, currentFormData.current)) { - currentFormData.current = formData; - const ecsOption = find(ECSSchemaOptions, ['label', formData.key]); - multipleValuesField.current = - ecsOption?.value?.normalization === 'array' && formData.result.type === 'value'; - handleSubmit(); - } - }, [handleSubmit, formData, onAdd]); + const handleDeleteClick = useCallback(() => { + if (onDelete) { + onDelete(item.id); + } + }, [item.id, onDelete]); - return ( -
- - - - - - + return ( + <> + + + + + + + + + : + + + + + + + {MultiFields} + {!isDisabled && ( - - : - + + {!isLastItem && ( + + )} + - - - - - {MultiFields} - {!isDisabled && ( - - - {defaultValue && ( - - )} - - - )} - - - - - - ); - } -); + )} + + +
+ + + ); +}; interface OsquerySchemaOption { label: string; @@ -831,177 +735,155 @@ interface OsqueryColumn { } export const ECSMappingEditorField = React.memo( - ({ field, query, fieldRef, euiFieldProps }: ECSMappingEditorFieldProps) => { - const { setValue, value = {} } = field; - const [osquerySchemaOptions, setOsquerySchemaOptions] = useState([]); - const formRefs = useRef>({}); - - useImperativeHandle( - fieldRef, - () => ({ - validate: async () => { - const validations = await Promise.all( - Object.values(formRefs.current).map(async (formRef) => { - const { data, isValid } = await formRef.validate(); - - return [data, isValid]; - }) - ); - - if (find(validations, (result) => result[1] === false)) { - return false; - } - - return deepmerge.all(map(validations, '[0]')); - }, - }), - [] - ); + ({ euiFieldProps }: ECSMappingEditorFieldProps) => { + const lastItemPath = useRef(); + const onAdd = useRef(); + const osquerySchemaOptions = useRef([]); + const [{ query, ...formData }, formDataSerializer, isMounted] = useFormData(); useEffect(() => { - setOsquerySchemaOptions((currentValue) => { - if (!query?.length) { - return currentValue; - } + if (!query?.length) { + return; + } - // eslint-disable-next-line @typescript-eslint/no-explicit-any - let ast: Record | undefined; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let ast: Record | undefined; - try { - ast = sqlParser.parse(query)?.value; - } catch (e) { - return currentValue; - } + try { + ast = sqlParser.parse(query)?.value; + } catch (e) { + return; + } - const astOsqueryTables: Record< - string, - { - columns: OsqueryColumn[]; - order: number; - } - > = - ast?.from?.value?.reduce( - ( - acc: { - [x: string]: { - columns: OsqueryColumn[]; - order: number; - }; - }, - table: { - value: { - left?: { value: { value: string }; alias?: { value: string } }; - right?: { value: { value: string }; alias?: { value: string } }; - value?: { value: string }; - alias?: { value: string }; - }; - } - ) => { - each(['value.left', 'value.right', 'value'], (valueKey) => { - if (valueKey) { - const osqueryTable = find(osquerySchema, [ - 'name', - get(table, `${valueKey}.value.value`), - ]); - - if (osqueryTable) { - acc[ - get(table, `${valueKey}.alias.value`) ?? get(table, `${valueKey}.value.value`) - ] = { - columns: osqueryTable.columns, - order: Object.keys(acc).length, - }; - } + const astOsqueryTables: Record< + string, + { + columns: OsqueryColumn[]; + order: number; + } + > = + ast?.from?.value?.reduce( + ( + acc: { + [x: string]: { + columns: OsqueryColumn[]; + order: number; + }; + }, + table: { + value: { + left?: { value: { value: string }; alias?: { value: string } }; + right?: { value: { value: string }; alias?: { value: string } }; + value?: { value: string }; + alias?: { value: string }; + }; + } + ) => { + each(['value.left', 'value.right', 'value'], (valueKey) => { + if (valueKey) { + const osqueryTable = find(osquerySchema, [ + 'name', + get(table, `${valueKey}.value.value`), + ]); + + if (osqueryTable) { + acc[ + get(table, `${valueKey}.alias.value`) ?? get(table, `${valueKey}.value.value`) + ] = { + columns: osqueryTable.columns, + order: Object.keys(acc).length, + }; } - }); + } + }); - return acc; - }, - {} - ) ?? {}; + return acc; + }, + {} + ) ?? {}; - // Table doesn't exist in osquery schema - if (isEmpty(astOsqueryTables)) { - return currentValue; - } + // Table doesn't exist in osquery schema + if (isEmpty(astOsqueryTables)) { + return; + } - const suggestions = - isArray(ast?.selectItems?.value) && - ast?.selectItems?.value - ?.map((selectItem: { type: string; value: string; hasAs: boolean; alias?: string }) => { - if (selectItem.type === 'Identifier') { - /* + const suggestions = + isArray(ast?.selectItems?.value) && + ast?.selectItems?.value + ?.map((selectItem: { type: string; value: string; hasAs: boolean; alias?: string }) => { + if (selectItem.type === 'Identifier') { + /* select * from routes, uptime; */ - if (ast?.selectItems?.value.length === 1 && selectItem.value === '*') { - return reduce( - astOsqueryTables, - (acc, { columns: osqueryColumns, order: tableOrder }, table) => { - acc.push( - ...osqueryColumns.map((osqueryColumn) => ({ - label: osqueryColumn.name, - value: { - name: osqueryColumn.name, - description: osqueryColumn.description, - table, - tableOrder, - suggestion_label: osqueryColumn.name, - }, - })) - ); - - return acc; - }, - [] as OsquerySchemaOption[] - ); - } - - /* - select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid; - */ - - const [table, column] = selectItem.value.includes('.') - ? selectItem.value?.split('.') - : [Object.keys(astOsqueryTables)[0], selectItem.value]; - - if (column === '*' && astOsqueryTables[table]) { - const { columns: osqueryColumns, order: tableOrder } = astOsqueryTables[table]; - - return osqueryColumns.map((osqueryColumn) => ({ - label: osqueryColumn.name, - value: { - name: osqueryColumn.name, - description: osqueryColumn.description, - table, - tableOrder, - suggestion_label: `${osqueryColumn.name}`, - }, - })); - } - - if (astOsqueryTables[table]) { - const osqueryColumn = find(astOsqueryTables[table].columns, ['name', column]); - - if (osqueryColumn) { - const label = selectItem.hasAs ? selectItem.alias : column; - - return [ - { - label, + if (ast?.selectItems?.value.length === 1 && selectItem.value === '*') { + return reduce( + astOsqueryTables, + (acc, { columns: osqueryColumns, order: tableOrder }, table) => { + acc.push( + ...osqueryColumns.map((osqueryColumn) => ({ + label: osqueryColumn.name, value: { name: osqueryColumn.name, description: osqueryColumn.description, table, - tableOrder: astOsqueryTables[table].order, - suggestion_label: `${label}`, + tableOrder, + suggestion_label: osqueryColumn.name, }, + })) + ); + + return acc; + }, + [] as OsquerySchemaOption[] + ); + } + + /* + select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid; + */ + + const [table, column] = selectItem.value.includes('.') + ? selectItem.value?.split('.') + : [Object.keys(astOsqueryTables)[0], selectItem.value]; + + if (column === '*' && astOsqueryTables[table]) { + const { columns: osqueryColumns, order: tableOrder } = astOsqueryTables[table]; + + return osqueryColumns.map((osqueryColumn) => ({ + label: osqueryColumn.name, + value: { + name: osqueryColumn.name, + description: osqueryColumn.description, + table, + tableOrder, + suggestion_label: `${osqueryColumn.name}`, + }, + })); + } + + if (astOsqueryTables[table]) { + const osqueryColumn = find(astOsqueryTables[table].columns, ['name', column]); + + if (osqueryColumn) { + const label = selectItem.hasAs ? selectItem.alias : column; + + return [ + { + label, + value: { + name: osqueryColumn.name, + description: osqueryColumn.description, + table, + tableOrder: astOsqueryTables[table].order, + suggestion_label: `${label}`, }, - ]; - } + }, + ]; } } + } - /* + /* SELECT pid, uid, name, ROUND(( (user_time + system_time) / (cpu_time.tsb - cpu_time.itsb) ) * 100, 2) AS percentage @@ -1015,95 +897,57 @@ export const ECSMappingEditorField = React.memo( LIMIT 5; */ - if (selectItem.hasAs && selectItem.alias) { - return [ - { - label: selectItem.alias, - value: { - name: selectItem.alias, - description: '', - table: '', - tableOrder: -1, - suggestion_label: selectItem.alias, - }, + if (selectItem.hasAs && selectItem.alias) { + return [ + { + label: selectItem.alias, + value: { + name: selectItem.alias, + description: '', + table: '', + tableOrder: -1, + suggestion_label: selectItem.alias, }, - ]; - } + }, + ]; + } - return []; - }) - .flat(); + return []; + }) + .flat(); - // Remove column duplicates by keeping the column from the table that appears last in the query - return sortedUniqBy( - orderBy(suggestions, ['value.suggestion_label', 'value.tableOrder'], ['asc', 'desc']), - 'label' - ); - }); + // Remove column duplicates by keeping the column from the table that appears last in the query + osquerySchemaOptions.current = sortedUniqBy( + orderBy(suggestions, ['value.suggestion_label', 'value.tableOrder'], ['asc', 'desc']), + 'label' + ); }, [query]); - useEffect(() => { - Object.keys(formRefs.current).forEach((key) => { - if (!value[key]) { - delete formRefs.current[key]; - } - }); - }, [value]); - - const handleAddRow = useCallback( - (newRow) => { - if (newRow?.key && newRow?.value) { - setValue( - produce((draft) => { - draft[newRow.key] = newRow.value; - - return draft; - }) - ); - } - }, - [setValue] - ); - - const handleUpdateRow = useCallback( - (currentKey: string) => (updatedRow: FormData) => { - if (updatedRow?.key && updatedRow?.value) { - setValue( - produce((draft) => { - if (currentKey !== updatedRow.key) { - delete draft[currentKey]; - } + useLayoutEffect(() => { + if (isMounted) { + if (!lastItemPath.current && onAdd.current) { + onAdd.current(); - draft[updatedRow.key] = updatedRow.value; + return; + } - return draft; - }) - ); + if (euiFieldProps?.isDisabled) { + return; } - }, - [setValue] - ); - const handleDeleteRow = useCallback( - (key) => { - if (key) { - setValue( - produce((draft) => { - if (draft[key]) { - delete draft[key]; - } + const itemKey = get(formData, `${lastItemPath.current}.key`); - return draft; - }) - ); + if (itemKey) { + const serializedFormData = formDataSerializer(); + const itemValue = + serializedFormData.ecs_mapping && serializedFormData.ecs_mapping[`${itemKey}`]?.field; - if (formRefs.current[key]) { - delete formRefs.current[key]; + if (itemValue && onAdd.current) { + onAdd.current(); } } - }, - [setValue] - ); + } + }, [euiFieldProps?.isDisabled, formData, formDataSerializer, isMounted, onAdd]); return ( <> @@ -1145,45 +989,31 @@ export const ECSMappingEditorField = React.memo( - {Object.entries(value).map(([ecsKey, ecsValue]) => ( - { - if (formRef) { - formRefs.current[ecsKey] = formRef; - } - }} - key={ecsKey} - osquerySchemaOptions={osquerySchemaOptions} - // eslint-disable-next-line react-perf/jsx-no-new-object-as-prop - defaultValue={{ - key: ecsKey, - value: ecsValue, - }} - onChange={handleUpdateRow(ecsKey)} - onDelete={handleDeleteRow} - isDisabled={!!euiFieldProps?.isDisabled} - /> - ))} - {!euiFieldProps?.isDisabled && ( - { - if (formRef) { - formRefs.current.new = formRef; - } - }} - osquerySchemaOptions={osquerySchemaOptions} - onAdd={handleAddRow} - /> - )} + + {({ items, addItem, removeItem }) => { + lastItemPath.current = items[items.length - 1]?.path; + onAdd.current = addItem; + + return ( + <> + {items.map((item, index) => ( + + ))} + + ); + }} + ); }, - (prevProps, nextProps) => - prevProps.field.value === nextProps.field.value && - prevProps.query === nextProps.query && - deepEqual(prevProps.euiFieldProps, nextProps.euiFieldProps) + (prevProps, nextProps) => deepEqual(prevProps.euiFieldProps, nextProps.euiFieldProps) ); // eslint-disable-next-line import/no-default-export diff --git a/x-pack/plugins/osquery/public/packs/queries/lazy_ecs_mapping_editor_field.tsx b/x-pack/plugins/osquery/public/packs/queries/lazy_ecs_mapping_editor_field.tsx index 69c3e4bc477c9..e2e4d45b669ee 100644 --- a/x-pack/plugins/osquery/public/packs/queries/lazy_ecs_mapping_editor_field.tsx +++ b/x-pack/plugins/osquery/public/packs/queries/lazy_ecs_mapping_editor_field.tsx @@ -6,14 +6,11 @@ */ import React, { lazy, Suspense } from 'react'; -import type { - ECSMappingEditorFieldProps, - ECSMappingEditorFieldRef, -} from './ecs_mapping_editor_field'; +import type { ECSMappingEditorFieldProps } from './ecs_mapping_editor_field'; const LazyECSMappingEditorField = lazy(() => import('./ecs_mapping_editor_field')); -export type { ECSMappingEditorFieldProps, ECSMappingEditorFieldRef }; +export type { ECSMappingEditorFieldProps }; export const ECSMappingEditorField = (props: ECSMappingEditorFieldProps) => ( diff --git a/x-pack/plugins/osquery/public/packs/queries/query_flyout.tsx b/x-pack/plugins/osquery/public/packs/queries/query_flyout.tsx index 8590968b58fb0..9bb0b521fb132 100644 --- a/x-pack/plugins/osquery/public/packs/queries/query_flyout.tsx +++ b/x-pack/plugins/osquery/public/packs/queries/query_flyout.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { isEmpty } from 'lodash'; +import { map } from 'lodash'; import { EuiFlyout, EuiTitle, @@ -19,17 +19,17 @@ import { EuiButton, EuiText, } from '@elastic/eui'; -import React, { useCallback, useMemo, useState, useRef } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { CodeEditorField } from '../../saved_queries/form/code_editor_field'; -import { Form, getUseField, Field, useFormData } from '../../shared_imports'; +import { Form, getUseField, Field } from '../../shared_imports'; import { PlatformCheckBoxGroupField } from './platform_checkbox_group_field'; import { ALL_OSQUERY_VERSIONS_OPTIONS } from './constants'; import { UsePackQueryFormProps, PackFormData, usePackQueryForm } from './use_pack_query_form'; import { SavedQueriesDropdown } from '../../saved_queries/saved_queries_dropdown'; -import { ECSMappingEditorField, ECSMappingEditorFieldRef } from './lazy_ecs_mapping_editor_field'; +import { ECSMappingEditorField } from './lazy_ecs_mapping_editor_field'; const CommonUseField = getUseField({ component: Field }); @@ -46,70 +46,46 @@ const QueryFlyoutComponent: React.FC = ({ onSave, onClose, }) => { - const ecsFieldRef = useRef(); const [isEditMode] = useState(!!defaultValue); const { form } = usePackQueryForm({ uniqueQueryIds, defaultValue, - handleSubmit: async (payload, isValid) => { - const ecsFieldValue = await ecsFieldRef?.current?.validate(); - const isEcsFieldValueValid = - ecsFieldValue && - Object.values(ecsFieldValue).every((field) => !isEmpty(Object.values(field)[0])); - - return new Promise((resolve) => { - if (isValid && isEcsFieldValueValid) { - onSave({ - ...payload, - ...(isEmpty(ecsFieldValue) ? {} : { ecs_mapping: ecsFieldValue }), - }); + handleSubmit: async (payload, isValid) => + new Promise((resolve) => { + if (isValid) { + onSave(payload); onClose(); } resolve(); - }); - }, + }), }); - const { submit, setFieldValue, reset, isSubmitting, validate } = form; - - const [{ query }] = useFormData({ - form, - watch: ['query'], - }); + const { submit, isSubmitting, updateFieldValues } = form; const handleSetQueryValue = useCallback( (savedQuery) => { - reset(); - if (savedQuery) { - setFieldValue('id', savedQuery.id); - setFieldValue('query', savedQuery.query); - - if (savedQuery.description) { - setFieldValue('description', savedQuery.description); - } - - if (savedQuery.interval) { - setFieldValue('interval', savedQuery.interval); - } - - if (savedQuery.platform) { - setFieldValue('platform', savedQuery.platform); - } - - if (savedQuery.version) { - setFieldValue('version', [savedQuery.version]); - } - - if (savedQuery.ecs_mapping) { - setFieldValue('ecs_mapping', savedQuery.ecs_mapping); - } + updateFieldValues({ + id: savedQuery.id, + query: savedQuery.query, + description: savedQuery.description, + platform: savedQuery.platform, + version: savedQuery.version, + interval: savedQuery.interval, + // @ts-expect-error update types + ecs_mapping: + map(savedQuery.ecs_mapping, (value, key) => ({ + key, + result: { + type: Object.keys(value)[0], + value: Object.values(value)[0], + }, + })) ?? [], + }); } - - validate(); }, - [reset, validate, setFieldValue] + [updateFieldValues] ); /* Avoids accidental closing of the flyout when the user clicks outside of the flyout */ const maskProps = useMemo(() => ({ onClick: () => ({}) }), []); @@ -190,12 +166,7 @@ const QueryFlyoutComponent: React.FC = ({ - + diff --git a/x-pack/plugins/osquery/public/packs/queries/schema.tsx b/x-pack/plugins/osquery/public/packs/queries/schema.tsx index d5b169b2c116c..526de9b73b0ea 100644 --- a/x-pack/plugins/osquery/public/packs/queries/schema.tsx +++ b/x-pack/plugins/osquery/public/packs/queries/schema.tsx @@ -71,7 +71,7 @@ export const createFormSchema = (ids: Set) => ({ validations: [], }, ecs_mapping: { - defaultValue: {}, + defaultValue: [], type: FIELD_TYPES.JSON, validations: [], }, diff --git a/x-pack/plugins/osquery/public/packs/queries/use_pack_query_form.tsx b/x-pack/plugins/osquery/public/packs/queries/use_pack_query_form.tsx index b46230a65267e..2b044a443004d 100644 --- a/x-pack/plugins/osquery/public/packs/queries/use_pack_query_form.tsx +++ b/x-pack/plugins/osquery/public/packs/queries/use_pack_query_form.tsx @@ -5,11 +5,12 @@ * 2.0. */ -import { isArray, isEmpty, xor } from 'lodash'; +import { isArray, isEmpty, xor, map } from 'lodash'; import uuid from 'uuid'; import { produce } from 'immer'; import { useMemo } from 'react'; +import { convertECSMappingToObject } from '../../../common/schemas/common/utils'; import { FormConfig, useForm } from '../../shared_imports'; import { createFormSchema } from './schema'; @@ -37,11 +38,14 @@ export interface PackFormData { platform?: string | undefined; version?: string | undefined; ecs_mapping?: - | Record< - string, - { - field: string; - } + | Array< + Record< + string, + { + field?: string; + value?: string; + } + > > | undefined; } @@ -76,7 +80,7 @@ export const usePackQueryForm = ({ id: '', query: '', interval: 3600, - ecs_mapping: {}, + ecs_mapping: [], }, // @ts-expect-error update types serializer: (payload) => @@ -100,6 +104,9 @@ export const usePackQueryForm = ({ if (isEmpty(draft.ecs_mapping)) { delete draft.ecs_mapping; + } else { + // @ts-expect-error update types + draft.ecs_mapping = convertECSMappingToObject(payload.ecs_mapping); } return draft; @@ -114,7 +121,17 @@ export const usePackQueryForm = ({ interval: payload.interval, platform: payload.platform, version: payload.version ? [payload.version] : [], - ecs_mapping: payload.ecs_mapping ?? {}, + ecs_mapping: !isArray(payload.ecs_mapping) + ? map(payload.ecs_mapping, (value, key) => ({ + key, + result: { + // @ts-expect-error update types + type: Object.keys(value)[0], + // @ts-expect-error update types + value: Object.values(value)[0], + }, + })) + : payload.ecs_mapping, }; }, // @ts-expect-error update types diff --git a/x-pack/plugins/osquery/public/results/results_table.tsx b/x-pack/plugins/osquery/public/results/results_table.tsx index dec1d08a0d012..229714eaaed99 100644 --- a/x-pack/plugins/osquery/public/results/results_table.tsx +++ b/x-pack/plugins/osquery/public/results/results_table.tsx @@ -18,6 +18,8 @@ import { EuiProgress, EuiSpacer, EuiIconTip, + EuiDataGridCellValueElementProps, + EuiDataGridControlColumn, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -46,7 +48,7 @@ interface ResultsTableComponentProps { agentIds?: string[]; endDate?: string; startDate?: string; - hideFullscreen?: true; + addToTimeline?: (payload: { query: [string, string]; isIcon?: true }) => React.ReactElement; } const ResultsTableComponent: React.FC = ({ @@ -54,7 +56,7 @@ const ResultsTableComponent: React.FC = ({ agentIds, startDate, endDate, - hideFullscreen, + addToTimeline, }) => { const [isLive, setIsLive] = useState(true); const { data: hasActionResultsPrivileges } = useActionResultsPrivileges(); @@ -107,11 +109,7 @@ const ResultsTableComponent: React.FC = ({ ]); const [columns, setColumns] = useState([]); - const { - data: allResultsData, - isFetched, - isLoading, - } = useAllResults({ + const { data: allResultsData, isLoading } = useAllResults({ actionId, activePage: pagination.pageIndex, limit: pagination.pageSize, @@ -309,10 +307,30 @@ const ResultsTableComponent: React.FC = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [allResultsData?.columns.length, ecsMappingColumns, getHeaderDisplay]); + const leadingControlColumns: EuiDataGridControlColumn[] = useMemo(() => { + const data = allResultsData?.edges; + if (addToTimeline && data) { + return [ + { + id: 'timeline', + width: 38, + headerCellRender: () => null, + rowCellRender: (actionProps: EuiDataGridCellValueElementProps) => { + const eventId = data[actionProps.rowIndex]._id; + + return addToTimeline({ query: ['_id', eventId], isIcon: true }); + }, + }, + ]; + } + + return []; + }, [addToTimeline, allResultsData?.edges]); + const toolbarVisibility = useMemo( () => ({ showDisplaySelector: false, - showFullScreenSelector: !hideFullscreen, + showFullScreenSelector: !addToTimeline, additionalControls: ( <> = ({ endDate={endDate} startDate={startDate} /> + {addToTimeline && addToTimeline({ query: ['action_id', actionId] })} ), }), - [actionId, endDate, startDate, hideFullscreen] + [actionId, addToTimeline, endDate, startDate] ); useEffect( @@ -338,20 +357,44 @@ const ResultsTableComponent: React.FC = ({ setIsLive(() => { if (!agentIds?.length || expired) return false; - return !!(aggregations.totalResponded !== agentIds?.length); + return !!( + aggregations.totalResponded !== agentIds?.length || + allResultsData?.totalCount !== aggregations?.totalRowCount || + (allResultsData?.totalCount && !allResultsData?.edges.length) + ); }), - [agentIds?.length, aggregations.failed, aggregations.totalResponded, expired] + [ + agentIds?.length, + aggregations.totalResponded, + aggregations?.totalRowCount, + allResultsData?.edges.length, + allResultsData?.totalCount, + expired, + ] ); if (!hasActionResultsPrivileges) { return ( - + + } + color="danger" + iconType="alert" + >

- {'Your user role doesn’t have index read permissions on the '} - logs-{OSQUERY_INTEGRATION_NAME}.result* - { - 'index. Access to this index is required to view osquery results. Administrators can update role permissions in Stack Management > Roles.' - } + read, + logs: logs-{OSQUERY_INTEGRATION_NAME}.result*, + }} + />

); @@ -365,13 +408,12 @@ const ResultsTableComponent: React.FC = ({ <> {isLive && } - {isFetched && !allResultsData?.edges.length && !aggregations?.totalRowCount ? ( + {!allResultsData?.edges.length ? ( <> ) : ( - // @ts-expect-error update types = ({ columnVisibility={columnVisibility} rowCount={allResultsData?.totalCount ?? 0} renderCellValue={renderCellValue} + leadingControlColumns={leadingControlColumns} sorting={tableSorting} pagination={tablePagination} height="500px" diff --git a/x-pack/plugins/osquery/public/results/use_all_results.ts b/x-pack/plugins/osquery/public/results/use_all_results.ts index c35ce881586b1..aa63e584bccef 100644 --- a/x-pack/plugins/osquery/public/results/use_all_results.ts +++ b/x-pack/plugins/osquery/public/results/use_all_results.ts @@ -8,7 +8,7 @@ import { useQuery } from 'react-query'; import { i18n } from '@kbn/i18n'; -import { firstValueFrom } from 'rxjs'; +import { lastValueFrom } from 'rxjs'; import { createFilter, generateTablePaginationOptions, @@ -62,7 +62,7 @@ export const useAllResults = ({ return useQuery( ['allActionResults', { actionId, activePage, limit, sort }], async () => { - const responseData = await firstValueFrom( + const responseData = await lastValueFrom( data.search.search( { actionId, diff --git a/x-pack/plugins/osquery/public/routes/saved_queries/edit/form.tsx b/x-pack/plugins/osquery/public/routes/saved_queries/edit/form.tsx index 432a108c8ece3..75969fd8f5dd1 100644 --- a/x-pack/plugins/osquery/public/routes/saved_queries/edit/form.tsx +++ b/x-pack/plugins/osquery/public/routes/saved_queries/edit/form.tsx @@ -13,12 +13,12 @@ import { EuiFlexItem, EuiSpacer, } from '@elastic/eui'; -import React, { useRef } from 'react'; +import React from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { useRouterNavigate } from '../../../common/lib/kibana'; import { Form } from '../../../shared_imports'; -import { SavedQueryForm, SavedQueryFormRefObject } from '../../../saved_queries/form'; +import { SavedQueryForm } from '../../../saved_queries/form'; import { useSavedQueryForm } from '../../../saved_queries/form/use_saved_query_form'; interface EditSavedQueryFormProps { @@ -32,19 +32,17 @@ const EditSavedQueryFormComponent: React.FC = ({ handleSubmit, viewMode, }) => { - const savedQueryFormRef = useRef(null); const savedQueryListProps = useRouterNavigate('saved_queries'); const { form } = useSavedQueryForm({ defaultValue, - savedQueryFormRef, handleSubmit, }); const { submit, isSubmitting } = form; return (
- + {!viewMode && ( <> diff --git a/x-pack/plugins/osquery/public/routes/saved_queries/edit/tabs.tsx b/x-pack/plugins/osquery/public/routes/saved_queries/edit/tabs.tsx index d0a48aa99781f..76e8bfd9dd029 100644 --- a/x-pack/plugins/osquery/public/routes/saved_queries/edit/tabs.tsx +++ b/x-pack/plugins/osquery/public/routes/saved_queries/edit/tabs.tsx @@ -17,7 +17,7 @@ interface ResultTabsProps { agentIds?: string[]; startDate?: string; endDate?: string; - hideFullscreen?: true; + addToTimeline?: (payload: { query: [string, string]; isIcon?: true }) => React.ReactElement; } const ResultTabsComponent: React.FC = ({ @@ -25,7 +25,7 @@ const ResultTabsComponent: React.FC = ({ agentIds, endDate, startDate, - hideFullscreen, + addToTimeline, }) => { const tabs = useMemo( () => [ @@ -40,7 +40,7 @@ const ResultTabsComponent: React.FC = ({ agentIds={agentIds} startDate={startDate} endDate={endDate} - hideFullscreen={hideFullscreen} + addToTimeline={addToTimeline} /> ), @@ -60,7 +60,7 @@ const ResultTabsComponent: React.FC = ({ ), }, ], - [actionId, agentIds, endDate, startDate, hideFullscreen] + [actionId, agentIds, endDate, startDate, addToTimeline] ); return ( diff --git a/x-pack/plugins/osquery/public/routes/saved_queries/new/form.tsx b/x-pack/plugins/osquery/public/routes/saved_queries/new/form.tsx index 80899c476f2a3..414cfaabf7f83 100644 --- a/x-pack/plugins/osquery/public/routes/saved_queries/new/form.tsx +++ b/x-pack/plugins/osquery/public/routes/saved_queries/new/form.tsx @@ -13,12 +13,12 @@ import { EuiFlexItem, EuiSpacer, } from '@elastic/eui'; -import React, { useRef } from 'react'; +import React from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { useRouterNavigate } from '../../../common/lib/kibana'; import { Form } from '../../../shared_imports'; -import { SavedQueryForm, SavedQueryFormRefObject } from '../../../saved_queries/form'; +import { SavedQueryForm } from '../../../saved_queries/form'; import { useSavedQueryForm } from '../../../saved_queries/form/use_saved_query_form'; interface NewSavedQueryFormProps { @@ -30,19 +30,17 @@ const NewSavedQueryFormComponent: React.FC = ({ defaultValue, handleSubmit, }) => { - const savedQueryFormRef = useRef(null); const savedQueryListProps = useRouterNavigate('saved_queries'); const { form } = useSavedQueryForm({ defaultValue, - savedQueryFormRef, handleSubmit, }); const { submit, isSubmitting, isValid } = form; return ( - + diff --git a/x-pack/plugins/osquery/public/saved_queries/form/index.tsx b/x-pack/plugins/osquery/public/saved_queries/form/index.tsx index cc0aa8ee08ca4..44fae4efd3608 100644 --- a/x-pack/plugins/osquery/public/saved_queries/form/index.tsx +++ b/x-pack/plugins/osquery/public/saved_queries/form/index.tsx @@ -13,25 +13,15 @@ import { EuiText, EuiButtonEmpty, } from '@elastic/eui'; -import React, { - useCallback, - useMemo, - useRef, - forwardRef, - useImperativeHandle, - useState, -} from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { ALL_OSQUERY_VERSIONS_OPTIONS } from '../../packs/queries/constants'; import { PlatformCheckBoxGroupField } from '../../packs/queries/platform_checkbox_group_field'; -import { Field, getUseField, UseField, useFormData } from '../../shared_imports'; +import { Field, getUseField, UseField } from '../../shared_imports'; import { CodeEditorField } from './code_editor_field'; -import { - ECSMappingEditorField, - ECSMappingEditorFieldRef, -} from '../../packs/queries/lazy_ecs_mapping_editor_field'; +import { ECSMappingEditorField } from '../../packs/queries/lazy_ecs_mapping_editor_field'; import { PlaygroundFlyout } from './playground_flyout'; export const CommonUseField = getUseField({ component: Field }); @@ -41,131 +31,112 @@ interface SavedQueryFormProps { hasPlayground?: boolean; isValid?: boolean; } -export interface SavedQueryFormRefObject { - validateEcsMapping: ECSMappingEditorFieldRef['validate']; -} -const SavedQueryFormComponent = forwardRef( - ({ viewMode, hasPlayground, isValid }, ref) => { - const [playgroundVisible, setPlaygroundVisible] = useState(false); - const ecsFieldRef = useRef(); - - const euiFieldProps = useMemo( - () => ({ - isDisabled: !!viewMode, - }), - [viewMode] - ); +const SavedQueryFormComponent: React.FC = ({ + viewMode, + hasPlayground, + isValid, +}) => { + const [playgroundVisible, setPlaygroundVisible] = useState(false); - const [{ query }] = useFormData({ watch: ['query'] }); + const euiFieldProps = useMemo( + () => ({ + isDisabled: !!viewMode, + }), + [viewMode] + ); - const handleHidePlayground = useCallback(() => setPlaygroundVisible(false), []); + const handleHidePlayground = useCallback(() => setPlaygroundVisible(false), []); - const handleTogglePlayground = useCallback( - () => setPlaygroundVisible((prevValue) => !prevValue), - [] - ); + const handleTogglePlayground = useCallback( + () => setPlaygroundVisible((prevValue) => !prevValue), + [] + ); - useImperativeHandle( - ref, - () => ({ - validateEcsMapping: () => { - if (ecsFieldRef.current) { - return ecsFieldRef.current.validate(); - } + const intervalEuiFieldProps = useMemo( + () => ({ + append: 's', + ...euiFieldProps, + }), + [euiFieldProps] + ); - return Promise.resolve(false); - }, + const versionEuiFieldProps = useMemo( + () => ({ + noSuggestions: false, + singleSelection: { asPlainText: true }, + placeholder: i18n.translate('xpack.osquery.pack.queriesTable.osqueryVersionAllLabel', { + defaultMessage: 'ALL', }), - [] - ); + options: ALL_OSQUERY_VERSIONS_OPTIONS, + onCreateOption: undefined, + ...euiFieldProps, + }), + [euiFieldProps] + ); - return ( - <> - - - - - - + return ( + <> + + + + + + + + + + + + {!viewMode && hasPlayground && ( - - + + + Test configuration + - {!viewMode && hasPlayground && ( - - - - Test configuration - - - - )} - - - - -
- -
-
- + )} + + + + +
- - - - - - - + + + - - - - - - - - {playgroundVisible && ( - - )} - - ); - } -); + + + + + + + + + + + + + + + {playgroundVisible && ( + + )} + + ); +}; + +SavedQueryFormComponent.displayName = 'SavedQueryForm'; export const SavedQueryForm = React.memo(SavedQueryFormComponent); diff --git a/x-pack/plugins/osquery/public/saved_queries/form/playground_flyout.tsx b/x-pack/plugins/osquery/public/saved_queries/form/playground_flyout.tsx index 60f1dff400867..b5af2652fd110 100644 --- a/x-pack/plugins/osquery/public/saved_queries/form/playground_flyout.tsx +++ b/x-pack/plugins/osquery/public/saved_queries/form/playground_flyout.tsx @@ -6,7 +6,7 @@ */ import { EuiFlyout, EuiFlyoutHeader, EuiTitle, EuiFlyoutBody } from '@elastic/eui'; -import React from 'react'; +import React, { useMemo } from 'react'; import styled from 'styled-components'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -26,11 +26,14 @@ interface PlaygroundFlyoutProps { } const PlaygroundFlyoutComponent: React.FC = ({ enabled, onClose }) => { - // eslint-disable-next-line @typescript-eslint/naming-convention - const [{ query, ecs_mapping, id }] = useFormData({ + const [{ query, ecs_mapping: ecsMapping, id }, formDataSerializer] = useFormData({ watch: ['query', 'ecs_mapping', 'savedQueryId'], }); + /* recalculate the form data when ecs_mapping changes */ + // eslint-disable-next-line react-hooks/exhaustive-deps + const serializedFormData = useMemo(() => formDataSerializer(), [ecsMapping, formDataSerializer]); + return ( @@ -48,7 +51,7 @@ const PlaygroundFlyoutComponent: React.FC = ({ enabled, o enabled={enabled && query !== ''} formType="simple" query={query} - ecs_mapping={ecs_mapping} + ecs_mapping={serializedFormData.ecs_mapping} savedQueryId={id} queryField={false} ecsMappingField={false} diff --git a/x-pack/plugins/osquery/public/saved_queries/form/use_saved_query_form.tsx b/x-pack/plugins/osquery/public/saved_queries/form/use_saved_query_form.tsx index bf4123fd86128..6da252f78aedf 100644 --- a/x-pack/plugins/osquery/public/saved_queries/form/use_saved_query_form.tsx +++ b/x-pack/plugins/osquery/public/saved_queries/form/use_saved_query_form.tsx @@ -8,27 +8,22 @@ import { isArray, isEmpty, map } from 'lodash'; import uuid from 'uuid'; import { produce } from 'immer'; -import { RefObject, useMemo } from 'react'; +import { useMemo } from 'react'; +import { convertECSMappingToObject } from '../../../common/schemas/common/utils'; import { useForm } from '../../shared_imports'; import { createFormSchema } from '../../packs/queries/schema'; import { PackFormData } from '../../packs/queries/use_pack_query_form'; import { useSavedQueries } from '../use_saved_queries'; -import { SavedQueryFormRefObject } from '.'; const SAVED_QUERY_FORM_ID = 'savedQueryForm'; interface UseSavedQueryFormProps { defaultValue?: unknown; handleSubmit: (payload: unknown) => Promise; - savedQueryFormRef: RefObject; } -export const useSavedQueryForm = ({ - defaultValue, - handleSubmit, - savedQueryFormRef, -}: UseSavedQueryFormProps) => { +export const useSavedQueryForm = ({ defaultValue, handleSubmit }: UseSavedQueryFormProps) => { const { data } = useSavedQueries({}); const ids: string[] = useMemo( () => map(data?.saved_objects, 'attributes.id') ?? [], @@ -50,14 +45,9 @@ export const useSavedQueryForm = ({ id: SAVED_QUERY_FORM_ID + uuid.v4(), schema: formSchema, onSubmit: async (formData, isValid) => { - const ecsFieldValue = await savedQueryFormRef?.current?.validateEcsMapping(); - - if (isValid && !!ecsFieldValue) { + if (isValid) { try { - await handleSubmit({ - ...formData, - ecs_mapping: ecsFieldValue, - }); + await handleSubmit(formData); // eslint-disable-next-line no-empty } catch (e) {} } @@ -82,9 +72,12 @@ export const useSavedQueryForm = ({ } } - if (isEmpty(draft.ecs_mapping)) { + if (isEmpty(payload.ecs_mapping)) { // @ts-expect-error update types delete draft.ecs_mapping; + } else { + // @ts-expect-error update types + draft.ecs_mapping = convertECSMappingToObject(payload.ecs_mapping); } // @ts-expect-error update types @@ -103,7 +96,16 @@ export const useSavedQueryForm = ({ interval: payload.interval ?? 3600, platform: payload.platform, version: payload.version ? [payload.version] : [], - ecs_mapping: payload.ecs_mapping ?? {}, + ecs_mapping: + (!isEmpty(payload.ecs_mapping) && + map(payload.ecs_mapping, (value, key) => ({ + key, + result: { + type: Object.keys(value)[0], + value: Object.values(value)[0], + }, + }))) ?? + [], }; }, }); diff --git a/x-pack/plugins/osquery/public/saved_queries/saved_queries_dropdown.tsx b/x-pack/plugins/osquery/public/saved_queries/saved_queries_dropdown.tsx index 4d352b7fd2516..eec949fbe312b 100644 --- a/x-pack/plugins/osquery/public/saved_queries/saved_queries_dropdown.tsx +++ b/x-pack/plugins/osquery/public/saved_queries/saved_queries_dropdown.tsx @@ -12,7 +12,6 @@ import { SimpleSavedObject } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import styled from 'styled-components'; -import deepEqual from 'fast-deep-equal'; import { useSavedQueries } from './use_saved_queries'; import { useFormData } from '../shared_imports'; @@ -47,10 +46,7 @@ const SavedQueriesDropdownComponent: React.FC = ({ }) => { const [selectedOptions, setSelectedOptions] = useState([]); - // eslint-disable-next-line @typescript-eslint/naming-convention - const [{ query, ecs_mapping, savedQueryId }] = useFormData({ - watch: ['ecs_mapping', 'query', 'savedQueryId'], - }); + const [{ savedQueryId }] = useFormData(); const { data } = useSavedQueries({}); @@ -122,15 +118,11 @@ const SavedQueriesDropdownComponent: React.FC = ({ if ( selectedOptions.length && // @ts-expect-error update types - (selectedOptions[0].value.savedQueryId !== savedQueryId || - // @ts-expect-error update types - selectedOptions[0].value.query !== query || - // @ts-expect-error update types - !deepEqual(selectedOptions[0].value.ecs_mapping, ecs_mapping)) + selectedOptions[0].value.savedQueryId !== savedQueryId ) { setSelectedOptions([]); } - }, [ecs_mapping, query, savedQueryId, selectedOptions]); + }, [savedQueryId, selectedOptions]); return ( void; + isExternal?: boolean; } -const SavedQueryFlyoutComponent: React.FC = ({ defaultValue, onClose }) => { - const savedQueryFormRef = useRef(null); +const additionalZIndexStyle = { style: 'z-index: 6000' }; + +const SavedQueryFlyoutComponent: React.FC = ({ + defaultValue, + onClose, + isExternal, +}) => { const createSavedQueryMutation = useCreateSavedQuery({ withRedirect: false }); const handleSubmit = useCallback( @@ -41,7 +47,6 @@ const SavedQueryFlyoutComponent: React.FC = ({ defaultValue const { form } = useSavedQueryForm({ defaultValue, - savedQueryFormRef, handleSubmit, }); const { submit, isSubmitting } = form; @@ -53,8 +58,7 @@ const SavedQueryFlyoutComponent: React.FC = ({ defaultValue ownFocus onClose={onClose} aria-labelledby="flyoutTitle" - // eslint-disable-next-line react-perf/jsx-no-new-object-as-prop - maskProps={{ style: 'z-index: 6000' }} // For an edge case to display above the alerts flyout + maskProps={isExternal ? additionalZIndexStyle : undefined} // For an edge case to display above the alerts flyout > @@ -68,7 +72,7 @@ const SavedQueryFlyoutComponent: React.FC = ({ defaultValue - + diff --git a/x-pack/plugins/osquery/public/shared_components/osquery_action/index.tsx b/x-pack/plugins/osquery/public/shared_components/osquery_action/index.tsx index a0ee8bf314e57..01285ed69c5d0 100644 --- a/x-pack/plugins/osquery/public/shared_components/osquery_action/index.tsx +++ b/x-pack/plugins/osquery/public/shared_components/osquery_action/index.tsx @@ -8,7 +8,14 @@ import { EuiErrorBoundary, EuiLoadingContent, EuiEmptyPrompt, EuiCode } from '@elastic/eui'; import React, { useMemo } from 'react'; import { QueryClientProvider } from 'react-query'; -import { i18n } from '@kbn/i18n'; +import { CoreStart } from '@kbn/core/public'; +import { + AGENT_STATUS_ERROR, + EMPTY_PROMPT, + NOT_AVAILABLE, + PERMISSION_DENIED, + SHORT_EMPTY_TITLE, +} from './translations'; import { KibanaContextProvider, useKibana } from '../../common/lib/kibana'; import { LiveQuery } from '../../live_queries'; @@ -16,17 +23,20 @@ import { queryClient } from '../../query_client'; import { OsqueryIcon } from '../../components/osquery_icon'; import { KibanaThemeProvider } from '../../shared_imports'; import { useIsOsqueryAvailable } from './use_is_osquery_available'; +import { StartPlugins } from '../../types'; interface OsqueryActionProps { agentId?: string; formType: 'steps' | 'simple'; - hideFullscreen?: true; + hideAgentsField?: boolean; + addToTimeline?: (payload: { query: [string, string]; isIcon?: true }) => React.ReactElement; } const OsqueryActionComponent: React.FC = ({ agentId, formType = 'simple', - hideFullscreen, + hideAgentsField, + addToTimeline, }) => { const permissions = useKibana().services.application.capabilities.osquery; @@ -34,22 +44,9 @@ const OsqueryActionComponent: React.FC = ({ () => ( } - title={ -

- {i18n.translate('xpack.osquery.action.shortEmptyTitle', { - defaultMessage: 'Osquery is not available', - })} -

- } + title={

{SHORT_EMPTY_TITLE}

} titleSize="xs" - body={ -

- {i18n.translate('xpack.osquery.action.empty', { - defaultMessage: - 'An Elastic Agent is not installed on this host. To run queries, install Elastic Agent on the host, and then add the Osquery Manager integration to the agent policy in Fleet.', - })} -

- } + body={

{EMPTY_PROMPT}

} /> ), [] @@ -61,17 +58,14 @@ const OsqueryActionComponent: React.FC = ({ return emptyPrompt; } - if (!(permissions.runSavedQueries || permissions.writeLiveQueries)) { + if ( + (!permissions.runSavedQueries || !permissions.readSavedQueries) && + !permissions.writeLiveQueries + ) { return ( } - title={ -

- {i18n.translate('xpack.osquery.action.permissionDenied', { - defaultMessage: 'Permission denied', - })} -

- } + title={

{PERMISSION_DENIED}

} titleSize="xs" body={

@@ -95,22 +89,9 @@ const OsqueryActionComponent: React.FC = ({ return ( } - title={ -

- {i18n.translate('xpack.osquery.action.shortEmptyTitle', { - defaultMessage: 'Osquery is not available', - })} -

- } + title={

{SHORT_EMPTY_TITLE}

} titleSize="xs" - body={ -

- {i18n.translate('xpack.osquery.action.unavailable', { - defaultMessage: - 'The Osquery Manager integration is not added to the agent policy. To run queries on the host, add the Osquery Manager integration to the agent policy in Fleet.', - })} -

- } + body={

{NOT_AVAILABLE}

} /> ); } @@ -119,38 +100,44 @@ const OsqueryActionComponent: React.FC = ({ return ( } - title={ -

- {i18n.translate('xpack.osquery.action.shortEmptyTitle', { - defaultMessage: 'Osquery is not available', - })} -

- } + title={

{SHORT_EMPTY_TITLE}

} titleSize="xs" - body={ -

- {i18n.translate('xpack.osquery.action.agentStatus', { - defaultMessage: - 'To run queries on this host, the Elastic Agent must be active. Check the status of this agent in Fleet.', - })} -

- } + body={

{AGENT_STATUS_ERROR}

} /> ); } - return ; + return ( + + ); }; -const OsqueryAction = React.memo(OsqueryActionComponent); +export const OsqueryAction = React.memo(OsqueryActionComponent); -// @ts-expect-error update types -const OsqueryActionWrapperComponent = ({ services, agentId, formType, hideFullscreen }) => ( +type OsqueryActionWrapperProps = { services: CoreStart & StartPlugins } & OsqueryActionProps; + +const OsqueryActionWrapperComponent: React.FC = ({ + services, + agentId, + formType, + hideAgentsField = false, + addToTimeline, +}) => ( - + diff --git a/x-pack/plugins/osquery/public/shared_components/osquery_action/osquery_action.test.tsx b/x-pack/plugins/osquery/public/shared_components/osquery_action/osquery_action.test.tsx new file mode 100644 index 0000000000000..4c9214ca3ea14 --- /dev/null +++ b/x-pack/plugins/osquery/public/shared_components/osquery_action/osquery_action.test.tsx @@ -0,0 +1,155 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; +import { render } from '@testing-library/react'; +import { QueryClientProvider } from 'react-query'; + +import { OsqueryAction } from '.'; +import { queryClient } from '../../query_client'; +import * as hooks from './use_is_osquery_available'; +import { useKibana } from '../../common/lib/kibana'; +import { AGENT_STATUS_ERROR, EMPTY_PROMPT, NOT_AVAILABLE, PERMISSION_DENIED } from './translations'; + +jest.mock('../../common/lib/kibana'); + +const useKibanaMock = useKibana as jest.MockedFunction; + +const defaultUseOsqueryAvailableResult = { + osqueryAvailable: true, + agentFetched: true, + isLoading: false, + policyFetched: true, + policyLoading: false, +}; + +const spyUseIsOsqueryAvailable = jest + .spyOn(hooks, 'useIsOsqueryAvailable') + .mockImplementation(() => ({ + ...defaultUseOsqueryAvailableResult, + agentData: {}, + })); + +const defaultPermissions = { + osquery: { + runSavedQueries: false, + readSavedQueries: false, + }, +}; + +const mockKibana = (permissionType: unknown = defaultPermissions) => { + useKibanaMock.mockReturnValue({ + services: { + application: { + capabilities: permissionType, + }, + }, + } as unknown as ReturnType); +}; + +const spyOsquery = (data: Record = {}) => { + spyUseIsOsqueryAvailable.mockImplementation(() => ({ + ...defaultUseOsqueryAvailableResult, + ...data, + })); +}; + +const properPermissions = { + osquery: { + runSavedQueries: true, + writeLiveQueries: true, + }, +}; + +const renderWithContext = (Element: React.ReactElement) => + render( + + {Element} + + ); + +describe('Osquery Action', () => { + it('should return empty prompt when agentFetched and no agentData', async () => { + spyOsquery(); + mockKibana(); + + const { getByText } = renderWithContext(); + expect(getByText(EMPTY_PROMPT)).toBeInTheDocument(); + }); + it('should return empty prompt when no agentId', async () => { + spyOsquery(); + mockKibana(); + + const { getByText } = renderWithContext(); + expect(getByText(EMPTY_PROMPT)).toBeInTheDocument(); + }); + it('should return permission denied when agentFetched and agentData available', async () => { + spyOsquery({ agentData: {} }); + mockKibana(); + + const { getByText } = renderWithContext(); + expect(getByText(PERMISSION_DENIED)).toBeInTheDocument(); + }); + it('should return agent status error when permissions are ok and agent status is wrong', async () => { + spyOsquery({ agentData: {} }); + mockKibana(properPermissions); + const { getByText } = renderWithContext(); + expect(getByText(AGENT_STATUS_ERROR)).toBeInTheDocument(); + }); + it('should return permission denied if just one permission (runSavedQueries) is available', async () => { + spyOsquery({ agentData: {} }); + mockKibana({ + osquery: { + runSavedQueries: true, + }, + }); + const { getByText } = renderWithContext(); + expect(getByText(PERMISSION_DENIED)).toBeInTheDocument(); + }); + it('should return permission denied if just one permission (readSavedQueries) is available', async () => { + spyOsquery({ agentData: {} }); + mockKibana({ + osquery: { + readSavedQueries: true, + }, + }); + const { getByText } = renderWithContext(); + expect(getByText(PERMISSION_DENIED)).toBeInTheDocument(); + }); + it('should return permission denied if no writeLiveQueries', async () => { + spyOsquery({ agentData: {} }); + mockKibana({ + osquery: { + writeLiveQueries: true, + }, + }); + const { getByText } = renderWithContext(); + expect(getByText(AGENT_STATUS_ERROR)).toBeInTheDocument(); + }); + it('should return not available prompt if osquery is not available', async () => { + spyOsquery({ agentData: {}, osqueryAvailable: false }); + mockKibana({ + osquery: { + writeLiveQueries: true, + }, + }); + const { getByText } = renderWithContext(); + expect(getByText(NOT_AVAILABLE)).toBeInTheDocument(); + }); + it('should not return any errors when all data is ok', async () => { + spyOsquery({ agentData: { status: 'online' } }); + mockKibana(properPermissions); + + const { queryByText } = renderWithContext( + + ); + expect(queryByText(EMPTY_PROMPT)).not.toBeInTheDocument(); + expect(queryByText(PERMISSION_DENIED)).not.toBeInTheDocument(); + expect(queryByText(AGENT_STATUS_ERROR)).not.toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/osquery/public/shared_components/osquery_action/translations.ts b/x-pack/plugins/osquery/public/shared_components/osquery_action/translations.ts new file mode 100644 index 0000000000000..cd49b6de7b7c0 --- /dev/null +++ b/x-pack/plugins/osquery/public/shared_components/osquery_action/translations.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const SHORT_EMPTY_TITLE = i18n.translate('xpack.osquery.action.shortEmptyTitle', { + defaultMessage: 'Osquery is not available', +}); + +export const EMPTY_PROMPT = i18n.translate('xpack.osquery.action.empty', { + defaultMessage: + 'An Elastic Agent is not installed on this host. To run queries, install Elastic Agent on the host, and then add the Osquery Manager integration to the agent policy in Fleet.', +}); +export const PERMISSION_DENIED = i18n.translate('xpack.osquery.action.permissionDenied', { + defaultMessage: 'Permission denied', +}); + +export const NOT_AVAILABLE = i18n.translate('xpack.osquery.action.unavailable', { + defaultMessage: + 'The Osquery Manager integration is not added to the agent policy. To run queries on the host, add the Osquery Manager integration to the agent policy in Fleet.', +}); +export const AGENT_STATUS_ERROR = i18n.translate('xpack.osquery.action.agentStatus', { + defaultMessage: + 'To run queries on this host, the Elastic Agent must be active. Check the status of this agent in Fleet.', +}); diff --git a/x-pack/plugins/osquery/public/shared_components/osquery_action/use_is_osquery_available.ts b/x-pack/plugins/osquery/public/shared_components/osquery_action/use_is_osquery_available.ts index 5cd84739cd7d1..4fa52dcb75f01 100644 --- a/x-pack/plugins/osquery/public/shared_components/osquery_action/use_is_osquery_available.ts +++ b/x-pack/plugins/osquery/public/shared_components/osquery_action/use_is_osquery_available.ts @@ -7,11 +7,24 @@ import { useMemo } from 'react'; import { find } from 'lodash'; +import { AgentStatus } from '@kbn/fleet-plugin/common'; import { useAgentDetails } from '../../agents/use_agent_details'; import { useAgentPolicy } from '../../agent_policies'; import { OSQUERY_INTEGRATION_NAME } from '../../../common'; -export const useIsOsqueryAvailable = (agentId?: string) => { +interface IIsOsqueryAvailable { + osqueryAvailable: boolean; + agentFetched: boolean; + isLoading: boolean; + policyFetched: boolean; + policyLoading: boolean; + agentData?: { + status?: AgentStatus; + policy_id?: string; + }; +} + +export const useIsOsqueryAvailable = (agentId?: string): IIsOsqueryAvailable => { const { data: agentData, isFetched: agentFetched, diff --git a/x-pack/plugins/osquery/public/shared_imports.ts b/x-pack/plugins/osquery/public/shared_imports.ts index 4e08bcd46d9ee..843cc512826c6 100644 --- a/x-pack/plugins/osquery/public/shared_imports.ts +++ b/x-pack/plugins/osquery/public/shared_imports.ts @@ -23,6 +23,8 @@ export { Form, FormDataProvider, UseArray, + ArrayItem, + FormArrayField, UseField, UseMultiFields, useForm, diff --git a/x-pack/plugins/osquery/scripts/roles_users/alert_test/delete_user.sh b/x-pack/plugins/osquery/scripts/roles_users/alert_test/delete_user.sh new file mode 100755 index 0000000000000..f9198c39bdbc5 --- /dev/null +++ b/x-pack/plugins/osquery/scripts/roles_users/alert_test/delete_user.sh @@ -0,0 +1,11 @@ + +# +# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +# or more contributor license agreements. Licensed under the Elastic License +# 2.0; you may not use this file except in compliance with the Elastic License +# 2.0. +# + +curl -v -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\ + -u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \ +-XDELETE ${ELASTICSEARCH_URL}/_security/user/alert_test diff --git a/x-pack/plugins/osquery/scripts/roles_users/alert_test/get_role.sh b/x-pack/plugins/osquery/scripts/roles_users/alert_test/get_role.sh new file mode 100755 index 0000000000000..06400b4e74876 --- /dev/null +++ b/x-pack/plugins/osquery/scripts/roles_users/alert_test/get_role.sh @@ -0,0 +1,11 @@ + +# +# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +# or more contributor license agreements. Licensed under the Elastic License +# 2.0; you may not use this file except in compliance with the Elastic License +# 2.0. +# + +curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\ + -u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \ +-XGET ${KIBANA_URL}/api/security/role/alert_test | jq -S . diff --git a/x-pack/plugins/osquery/scripts/roles_users/alert_test/index.ts b/x-pack/plugins/osquery/scripts/roles_users/alert_test/index.ts new file mode 100644 index 0000000000000..7f79ece04cccc --- /dev/null +++ b/x-pack/plugins/osquery/scripts/roles_users/alert_test/index.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as alertTestUser from './user.json'; +import * as alertTestRole from './role.json'; + +export { alertTestUser, alertTestRole }; diff --git a/x-pack/plugins/osquery/scripts/roles_users/alert_test/post_role.sh b/x-pack/plugins/osquery/scripts/roles_users/alert_test/post_role.sh new file mode 100755 index 0000000000000..6150119851abe --- /dev/null +++ b/x-pack/plugins/osquery/scripts/roles_users/alert_test/post_role.sh @@ -0,0 +1,14 @@ + +# +# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +# or more contributor license agreements. Licensed under the Elastic License +# 2.0; you may not use this file except in compliance with the Elastic License +# 2.0. +# + +ROLE_CONFIG=(${@:-./detections_role.json}) + +curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\ + -u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \ +-XPUT ${KIBANA_URL}/api/security/role/alert_test \ +-d @${ROLE_CONFIG} diff --git a/x-pack/plugins/osquery/scripts/roles_users/alert_test/post_user.sh b/x-pack/plugins/osquery/scripts/roles_users/alert_test/post_user.sh new file mode 100755 index 0000000000000..c58aad8f74516 --- /dev/null +++ b/x-pack/plugins/osquery/scripts/roles_users/alert_test/post_user.sh @@ -0,0 +1,14 @@ + +# +# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +# or more contributor license agreements. Licensed under the Elastic License +# 2.0; you may not use this file except in compliance with the Elastic License +# 2.0. +# + +USER=(${@:-./detections_user.json}) + +curl -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'\ + -u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \ + ${ELASTICSEARCH_URL}/_security/user/alert_test \ +-d @${USER} diff --git a/x-pack/plugins/osquery/scripts/roles_users/alert_test/role.json b/x-pack/plugins/osquery/scripts/roles_users/alert_test/role.json new file mode 100644 index 0000000000000..4b97c372a1d40 --- /dev/null +++ b/x-pack/plugins/osquery/scripts/roles_users/alert_test/role.json @@ -0,0 +1,33 @@ +{ + "elasticsearch": { + "cluster": ["manage"], + "indices": [ + { + "names": [".items-*", ".lists-*", ".alerts-security.alerts-*", ".siem-signals-*"], + "privileges": ["manage", "read", "write", "view_index_metadata", "maintenance"] + }, + { + "names": ["*"], + "privileges": ["read"] + }, + { + "names": ["logs-osquery_manager*"], + "privileges": ["read"] + } + ] + }, + "kibana": [ + { + "feature": { + "discover": ["read"], + "infrastructure": ["read"], + "ml": ["all"], + "siem": ["all"], + "osquery": ["read", "packs_all"], + "visualize": ["read"] + }, + "spaces": ["*"] + } + ] +} + diff --git a/x-pack/plugins/osquery/scripts/roles_users/alert_test/user.json b/x-pack/plugins/osquery/scripts/roles_users/alert_test/user.json new file mode 100644 index 0000000000000..92eb767f964ba --- /dev/null +++ b/x-pack/plugins/osquery/scripts/roles_users/alert_test/user.json @@ -0,0 +1,6 @@ +{ + "password": "changeme", + "roles": ["alert_test"], + "full_name": "Alert Test", + "email": "osquery@example.com" +} diff --git a/x-pack/plugins/osquery/scripts/roles_users/index.ts b/x-pack/plugins/osquery/scripts/roles_users/index.ts index 755b09387770d..2bb4c94108373 100644 --- a/x-pack/plugins/osquery/scripts/roles_users/index.ts +++ b/x-pack/plugins/osquery/scripts/roles_users/index.ts @@ -10,3 +10,4 @@ export * from './reader'; export * from './t1_analyst'; export * from './t2_analyst'; export * from './soc_manager'; +export * from './alert_test'; diff --git a/x-pack/plugins/osquery/server/routes/action/create_action_route.ts b/x-pack/plugins/osquery/server/routes/action/create_action_route.ts index ee9338fc50108..a67b6ee95b9d3 100644 --- a/x-pack/plugins/osquery/server/routes/action/create_action_route.ts +++ b/x-pack/plugins/osquery/server/routes/action/create_action_route.ts @@ -35,8 +35,9 @@ export const createActionRoute = (router: IRouter, osqueryContext: OsqueryAppCon }, }, async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asInternalUser; - const soClient = context.core.savedObjects.client; + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asInternalUser; + const soClient = coreContext.savedObjects.client; const internalSavedObjectsClient = await getInternalSavedObjectsClient( osqueryContext.getStartServices ); diff --git a/x-pack/plugins/osquery/server/routes/asset/get_assets_status_route.ts b/x-pack/plugins/osquery/server/routes/asset/get_assets_status_route.ts index d2b590f08f453..2b8c8b0de23d5 100644 --- a/x-pack/plugins/osquery/server/routes/asset/get_assets_status_route.ts +++ b/x-pack/plugins/osquery/server/routes/asset/get_assets_status_route.ts @@ -25,7 +25,7 @@ export const getAssetsStatusRoute = (router: IRouter, osqueryContext: OsqueryApp options: { tags: [`access:${PLUGIN_ID}-writePacks`] }, }, async (context, request, response) => { - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; let installation; diff --git a/x-pack/plugins/osquery/server/routes/asset/update_assets_route.ts b/x-pack/plugins/osquery/server/routes/asset/update_assets_route.ts index a852d02d0115b..9990c8dbc7b82 100644 --- a/x-pack/plugins/osquery/server/routes/asset/update_assets_route.ts +++ b/x-pack/plugins/osquery/server/routes/asset/update_assets_route.ts @@ -30,7 +30,7 @@ export const updateAssetsRoute = (router: IRouter, osqueryContext: OsqueryAppCon options: { tags: [`access:${PLUGIN_ID}-writePacks`] }, }, async (context, request, response) => { - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; const currentUser = await osqueryContext.security.authc.getCurrentUser(request)?.username; let installation; diff --git a/x-pack/plugins/osquery/server/routes/pack/create_pack_route.ts b/x-pack/plugins/osquery/server/routes/pack/create_pack_route.ts index 14158a4d5fb08..bf34152078582 100644 --- a/x-pack/plugins/osquery/server/routes/pack/create_pack_route.ts +++ b/x-pack/plugins/osquery/server/routes/pack/create_pack_route.ts @@ -60,8 +60,9 @@ export const createPackRoute = (router: IRouter, osqueryContext: OsqueryAppConte options: { tags: [`access:${PLUGIN_ID}-writePacks`] }, }, async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asCurrentUser; - const savedObjectsClient = context.core.savedObjects.client; + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asCurrentUser; + const savedObjectsClient = coreContext.savedObjects.client; const internalSavedObjectsClient = await getInternalSavedObjectsClient( osqueryContext.getStartServices ); diff --git a/x-pack/plugins/osquery/server/routes/pack/delete_pack_route.ts b/x-pack/plugins/osquery/server/routes/pack/delete_pack_route.ts index a32a0feac4784..9fc8713348c14 100644 --- a/x-pack/plugins/osquery/server/routes/pack/delete_pack_route.ts +++ b/x-pack/plugins/osquery/server/routes/pack/delete_pack_route.ts @@ -28,8 +28,9 @@ export const deletePackRoute = (router: IRouter, osqueryContext: OsqueryAppConte options: { tags: [`access:${PLUGIN_ID}-writePacks`] }, }, async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asCurrentUser; - const savedObjectsClient = context.core.savedObjects.client; + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asCurrentUser; + const savedObjectsClient = coreContext.savedObjects.client; const packagePolicyService = osqueryContext.service.getPackagePolicyService(); const currentPackSO = await savedObjectsClient.get<{ name: string }>( diff --git a/x-pack/plugins/osquery/server/routes/pack/find_pack_route.ts b/x-pack/plugins/osquery/server/routes/pack/find_pack_route.ts index 333a6a7cdeecf..b9e2326d941b9 100644 --- a/x-pack/plugins/osquery/server/routes/pack/find_pack_route.ts +++ b/x-pack/plugins/osquery/server/routes/pack/find_pack_route.ts @@ -34,7 +34,8 @@ export const findPackRoute = (router: IRouter, osqueryContext: OsqueryAppContext options: { tags: [`access:${PLUGIN_ID}-readPacks`] }, }, async (context, request, response) => { - const savedObjectsClient = context.core.savedObjects.client; + const coreContext = await context.core; + const savedObjectsClient = coreContext.savedObjects.client; const soClientResponse = await savedObjectsClient.find({ type: packSavedObjectType, diff --git a/x-pack/plugins/osquery/server/routes/pack/read_pack_route.ts b/x-pack/plugins/osquery/server/routes/pack/read_pack_route.ts index 53845de3f48ab..bd9f27a569af8 100644 --- a/x-pack/plugins/osquery/server/routes/pack/read_pack_route.ts +++ b/x-pack/plugins/osquery/server/routes/pack/read_pack_route.ts @@ -29,7 +29,8 @@ export const readPackRoute = (router: IRouter, osqueryContext: OsqueryAppContext options: { tags: [`access:${PLUGIN_ID}-readPacks`] }, }, async (context, request, response) => { - const savedObjectsClient = context.core.savedObjects.client; + const coreContext = await context.core; + const savedObjectsClient = coreContext.savedObjects.client; const { attributes, references, ...rest } = await savedObjectsClient.get( diff --git a/x-pack/plugins/osquery/server/routes/pack/update_pack_route.ts b/x-pack/plugins/osquery/server/routes/pack/update_pack_route.ts index c37e7fb184b50..82d880c70fbd6 100644 --- a/x-pack/plugins/osquery/server/routes/pack/update_pack_route.ts +++ b/x-pack/plugins/osquery/server/routes/pack/update_pack_route.ts @@ -70,8 +70,9 @@ export const updatePackRoute = (router: IRouter, osqueryContext: OsqueryAppConte options: { tags: [`access:${PLUGIN_ID}-writePacks`] }, }, async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asCurrentUser; - const savedObjectsClient = context.core.savedObjects.client; + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asCurrentUser; + const savedObjectsClient = coreContext.savedObjects.client; const internalSavedObjectsClient = await getInternalSavedObjectsClient( osqueryContext.getStartServices ); diff --git a/x-pack/plugins/osquery/server/routes/saved_query/create_saved_query_route.ts b/x-pack/plugins/osquery/server/routes/saved_query/create_saved_query_route.ts index 9a62ad3e2a380..e8bcb9d6bb3b2 100644 --- a/x-pack/plugins/osquery/server/routes/saved_query/create_saved_query_route.ts +++ b/x-pack/plugins/osquery/server/routes/saved_query/create_saved_query_route.ts @@ -30,7 +30,8 @@ export const createSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAp options: { tags: [`access:${PLUGIN_ID}-writeSavedQueries`] }, }, async (context, request, response) => { - const savedObjectsClient = context.core.savedObjects.client; + const coreContext = await context.core; + const savedObjectsClient = coreContext.savedObjects.client; // eslint-disable-next-line @typescript-eslint/naming-convention const { id, description, platform, query, version, interval, ecs_mapping } = request.body; diff --git a/x-pack/plugins/osquery/server/routes/saved_query/delete_saved_query_route.ts b/x-pack/plugins/osquery/server/routes/saved_query/delete_saved_query_route.ts index c8c08904a240b..c2a2ad7fa8619 100644 --- a/x-pack/plugins/osquery/server/routes/saved_query/delete_saved_query_route.ts +++ b/x-pack/plugins/osquery/server/routes/saved_query/delete_saved_query_route.ts @@ -22,7 +22,8 @@ export const deleteSavedQueryRoute = (router: IRouter) => { options: { tags: [`access:${PLUGIN_ID}-writeSavedQueries`] }, }, async (context, request, response) => { - const savedObjectsClient = context.core.savedObjects.client; + const coreContext = await context.core; + const savedObjectsClient = coreContext.savedObjects.client; await savedObjectsClient.delete(savedQuerySavedObjectType, request.params.id, { refresh: 'wait_for', diff --git a/x-pack/plugins/osquery/server/routes/saved_query/find_saved_query_route.ts b/x-pack/plugins/osquery/server/routes/saved_query/find_saved_query_route.ts index cd1200a5d7778..a2b85dbf539d9 100644 --- a/x-pack/plugins/osquery/server/routes/saved_query/find_saved_query_route.ts +++ b/x-pack/plugins/osquery/server/routes/saved_query/find_saved_query_route.ts @@ -29,7 +29,8 @@ export const findSavedQueryRoute = (router: IRouter) => { options: { tags: [`access:${PLUGIN_ID}-readSavedQueries`] }, }, async (context, request, response) => { - const savedObjectsClient = context.core.savedObjects.client; + const coreContext = await context.core; + const savedObjectsClient = coreContext.savedObjects.client; const savedQueries = await savedObjectsClient.find<{ ecs_mapping: Array<{ field: string; value: string }>; diff --git a/x-pack/plugins/osquery/server/routes/saved_query/read_saved_query_route.ts b/x-pack/plugins/osquery/server/routes/saved_query/read_saved_query_route.ts index 7887fdce22f0c..1c206464d1f65 100644 --- a/x-pack/plugins/osquery/server/routes/saved_query/read_saved_query_route.ts +++ b/x-pack/plugins/osquery/server/routes/saved_query/read_saved_query_route.ts @@ -23,7 +23,8 @@ export const readSavedQueryRoute = (router: IRouter) => { options: { tags: [`access:${PLUGIN_ID}-readSavedQueries`] }, }, async (context, request, response) => { - const savedObjectsClient = context.core.savedObjects.client; + const coreContext = await context.core; + const savedObjectsClient = coreContext.savedObjects.client; const savedQuery = await savedObjectsClient.get<{ ecs_mapping: Array<{ key: string; value: Record }>; diff --git a/x-pack/plugins/osquery/server/routes/saved_query/update_saved_query_route.ts b/x-pack/plugins/osquery/server/routes/saved_query/update_saved_query_route.ts index 5ac4ad711c2a6..1d2bf153afd7f 100644 --- a/x-pack/plugins/osquery/server/routes/saved_query/update_saved_query_route.ts +++ b/x-pack/plugins/osquery/server/routes/saved_query/update_saved_query_route.ts @@ -48,7 +48,8 @@ export const updateSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAp options: { tags: [`access:${PLUGIN_ID}-writeSavedQueries`] }, }, async (context, request, response) => { - const savedObjectsClient = context.core.savedObjects.client; + const coreContext = await context.core; + const savedObjectsClient = coreContext.savedObjects.client; const currentUser = await osqueryContext.security.authc.getCurrentUser(request)?.username; const { diff --git a/x-pack/plugins/osquery/server/routes/status/create_status_route.ts b/x-pack/plugins/osquery/server/routes/status/create_status_route.ts index 613ad6e7720af..019582addabb5 100644 --- a/x-pack/plugins/osquery/server/routes/status/create_status_route.ts +++ b/x-pack/plugins/osquery/server/routes/status/create_status_route.ts @@ -27,7 +27,8 @@ export const createStatusRoute = (router: IRouter, osqueryContext: OsqueryAppCon options: { tags: [`access:${PLUGIN_ID}-read`] }, }, async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asInternalUser; const internalSavedObjectsClient = await getInternalSavedObjectsClient( osqueryContext.getStartServices ); diff --git a/x-pack/plugins/osquery/tsconfig.json b/x-pack/plugins/osquery/tsconfig.json index 5c70e5ffbb944..4eac1baa43d79 100644 --- a/x-pack/plugins/osquery/tsconfig.json +++ b/x-pack/plugins/osquery/tsconfig.json @@ -24,7 +24,6 @@ // requiredPlugins from ./kibana.json { "path": "../../../src/plugins/data/tsconfig.json" }, { "path": "../../../src/plugins/navigation/tsconfig.json" }, - { "path": "../data_enhanced/tsconfig.json" }, { "path": "../fleet/tsconfig.json" }, // optionalPlugins from ./kibana.json diff --git a/x-pack/plugins/painless_lab/server/routes/api/execute.ts b/x-pack/plugins/painless_lab/server/routes/api/execute.ts index 58cb9f4328d29..88f2156a5fb4c 100644 --- a/x-pack/plugins/painless_lab/server/routes/api/execute.ts +++ b/x-pack/plugins/painless_lab/server/routes/api/execute.ts @@ -25,7 +25,7 @@ export function registerExecuteRoute({ router, license }: RouteDependencies) { const body = req.body; try { - const client = ctx.core.elasticsearch.client.asCurrentUser; + const client = (await ctx.core).elasticsearch.client.asCurrentUser; const response = await client.scriptsPainlessExecute( { // @ts-expect-error `ExecutePainlessScriptRequest.body` does not allow `string` diff --git a/x-pack/plugins/remote_clusters/server/routes/api/add_route.test.ts b/x-pack/plugins/remote_clusters/server/routes/api/add_route.test.ts index 3fe04be97abfc..a1f256802fb57 100644 --- a/x-pack/plugins/remote_clusters/server/routes/api/add_route.test.ts +++ b/x-pack/plugins/remote_clusters/server/routes/api/add_route.test.ts @@ -104,7 +104,11 @@ describe('ADD remote clusters', () => { const mockRequest = createMockRequest(); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual({ acknowledged: true }); @@ -161,7 +165,11 @@ describe('ADD remote clusters', () => { serverName: 'foobar', }); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual({ acknowledged: true }); @@ -205,7 +213,11 @@ describe('ADD remote clusters', () => { const mockRequest = createMockRequest(); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(409); expect(response.payload).toEqual({ @@ -222,7 +234,11 @@ describe('ADD remote clusters', () => { const mockRequest = createMockRequest(); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(400); expect(response.payload).toEqual({ diff --git a/x-pack/plugins/remote_clusters/server/routes/api/add_route.ts b/x-pack/plugins/remote_clusters/server/routes/api/add_route.ts index 85e8193a0eb2e..50fb15ef32829 100644 --- a/x-pack/plugins/remote_clusters/server/routes/api/add_route.ts +++ b/x-pack/plugins/remote_clusters/server/routes/api/add_route.ts @@ -41,7 +41,7 @@ export const register = (deps: RouteDependencies): void => { response ) => { try { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = request.body; diff --git a/x-pack/plugins/remote_clusters/server/routes/api/delete_route.test.ts b/x-pack/plugins/remote_clusters/server/routes/api/delete_route.test.ts index 0dc48d82cdb09..ed92c78f9d09d 100644 --- a/x-pack/plugins/remote_clusters/server/routes/api/delete_route.test.ts +++ b/x-pack/plugins/remote_clusters/server/routes/api/delete_route.test.ts @@ -117,7 +117,11 @@ describe('DELETE remote clusters', () => { const mockRequest = createMockRequest(); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual({ @@ -163,7 +167,11 @@ describe('DELETE remote clusters', () => { const mockRequest = createMockRequest(); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual({ @@ -240,7 +248,11 @@ describe('DELETE remote clusters', () => { const mockRequest = createMockRequest(); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual({ diff --git a/x-pack/plugins/remote_clusters/server/routes/api/delete_route.ts b/x-pack/plugins/remote_clusters/server/routes/api/delete_route.ts index 9d24efc1a554c..8e11a0cbe2461 100644 --- a/x-pack/plugins/remote_clusters/server/routes/api/delete_route.ts +++ b/x-pack/plugins/remote_clusters/server/routes/api/delete_route.ts @@ -34,7 +34,7 @@ export const register = (deps: RouteDependencies): void => { response ) => { try { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { nameOrNames } = request.params; const names = nameOrNames.split(','); diff --git a/x-pack/plugins/remote_clusters/server/routes/api/get_route.test.ts b/x-pack/plugins/remote_clusters/server/routes/api/get_route.test.ts index 9bb877b8bff1b..c3628af8c2efc 100644 --- a/x-pack/plugins/remote_clusters/server/routes/api/get_route.test.ts +++ b/x-pack/plugins/remote_clusters/server/routes/api/get_route.test.ts @@ -101,7 +101,11 @@ describe('GET remote clusters', () => { const mockRequest = createMockRequest(); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual([ @@ -128,7 +132,11 @@ describe('GET remote clusters', () => { const mockRequest = createMockRequest(); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual([]); @@ -152,7 +160,11 @@ describe('GET remote clusters', () => { const mockRequest = createMockRequest(); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(406); expect(response.payload).toEqual({ @@ -191,7 +203,11 @@ describe('GET remote clusters', () => { headers: { authorization: 'foo' }, }); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(406); diff --git a/x-pack/plugins/remote_clusters/server/routes/api/get_route.ts b/x-pack/plugins/remote_clusters/server/routes/api/get_route.ts index 7b12ad8d4418c..8923e9be7d9fd 100644 --- a/x-pack/plugins/remote_clusters/server/routes/api/get_route.ts +++ b/x-pack/plugins/remote_clusters/server/routes/api/get_route.ts @@ -21,7 +21,7 @@ export const register = (deps: RouteDependencies): void => { const allHandler: RequestHandler = async (ctx, request, response) => { try { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const clusterSettings = await clusterClient.asCurrentUser.cluster.getSettings(); const transientClusterNames = Object.keys( diff --git a/x-pack/plugins/remote_clusters/server/routes/api/update_route.test.ts b/x-pack/plugins/remote_clusters/server/routes/api/update_route.test.ts index 65939be965c15..951d8c5d806e4 100644 --- a/x-pack/plugins/remote_clusters/server/routes/api/update_route.test.ts +++ b/x-pack/plugins/remote_clusters/server/routes/api/update_route.test.ts @@ -110,7 +110,11 @@ describe('UPDATE remote clusters', () => { const mockRequest = createMockRequest(); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual({ @@ -187,7 +191,11 @@ describe('UPDATE remote clusters', () => { proxySocketConnections: 18, }); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual({ @@ -234,7 +242,11 @@ describe('UPDATE remote clusters', () => { mode: 'sniff', }); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(404); expect(response.payload).toEqual({ @@ -265,7 +277,11 @@ describe('UPDATE remote clusters', () => { mode: 'sniff', }); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(400); expect(response.payload).toEqual({ diff --git a/x-pack/plugins/remote_clusters/server/routes/api/update_route.ts b/x-pack/plugins/remote_clusters/server/routes/api/update_route.ts index db9b3184ac1e7..e186262ade21c 100644 --- a/x-pack/plugins/remote_clusters/server/routes/api/update_route.ts +++ b/x-pack/plugins/remote_clusters/server/routes/api/update_route.ts @@ -47,7 +47,7 @@ export const register = (deps: RouteDependencies): void => { response ) => { try { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = request.params; diff --git a/x-pack/plugins/reporting/common/errors/errors.test.ts b/x-pack/plugins/reporting/common/errors/errors.test.ts index 37210373f4d68..d687d8b4adce6 100644 --- a/x-pack/plugins/reporting/common/errors/errors.test.ts +++ b/x-pack/plugins/reporting/common/errors/errors.test.ts @@ -7,7 +7,9 @@ import * as errors from '.'; -describe('ReportingError', () => { +const { ReportingError: _, ...nonAbstractErrors } = errors; + +describe('Reporting error', () => { it('provides error code when stringified', () => { expect(new errors.AuthenticationExpiredError() + '').toBe( `ReportingError(code: authentication_expired_error)` @@ -18,10 +20,14 @@ describe('ReportingError', () => { `ReportingError(code: authentication_expired_error) "some details"` ); }); - it('has the expected code structure', () => { - const { ReportingError: _, ...nonAbstractErrors } = errors; + it('has the expected error code structure', () => { + Object.values(nonAbstractErrors).forEach((Ctor) => { + expect(Ctor.code).toMatch(/^[a-z_]+_error$/); + }); + }); + it('has the same error code values on static "code" and instance "code" properties', () => { Object.values(nonAbstractErrors).forEach((Ctor) => { - expect(new Ctor().code).toMatch(/^[a-z_]+_error$/); + expect(Ctor.code).toBe(new Ctor().code); }); }); }); diff --git a/x-pack/plugins/reporting/common/errors/index.ts b/x-pack/plugins/reporting/common/errors/index.ts index d5032c206a186..d2c5f0181df86 100644 --- a/x-pack/plugins/reporting/common/errors/index.ts +++ b/x-pack/plugins/reporting/common/errors/index.ts @@ -15,7 +15,7 @@ export abstract class ReportingError extends Error { * * @note Convention for codes: lower-case, snake-case and end in `_error`. */ - public abstract code: string; + public abstract get code(): string; constructor(public details?: string) { super(); @@ -38,22 +38,34 @@ export abstract class ReportingError extends Error { * access token expired. */ export class AuthenticationExpiredError extends ReportingError { - code = 'authentication_expired_error'; + static code = 'authentication_expired_error' as const; + public get code(): string { + return AuthenticationExpiredError.code; + } } export class QueueTimeoutError extends ReportingError { - code = 'queue_timeout_error'; + static code = 'queue_timeout_error' as const; + public get code(): string { + return QueueTimeoutError.code; + } } /** * An unknown error has occurred. See details. */ export class UnknownError extends ReportingError { - code = 'unknown_error'; + static code = 'unknown_error' as const; + public get code(): string { + return UnknownError.code; + } } export class PdfWorkerOutOfMemoryError extends ReportingError { - code = 'pdf_worker_out_of_memory_error'; + static code = 'pdf_worker_out_of_memory_error' as const; + public get code(): string { + return PdfWorkerOutOfMemoryError.code; + } details = i18n.translate('xpack.reporting.common.pdfWorkerOutOfMemoryErrorMessage', { defaultMessage: @@ -70,7 +82,10 @@ export class PdfWorkerOutOfMemoryError extends ReportingError { } export class BrowserCouldNotLaunchError extends ReportingError { - code = 'browser_could_not_launch_error'; + static code = 'browser_could_not_launch_error' as const; + public get code(): string { + return BrowserCouldNotLaunchError.code; + } details = i18n.translate('xpack.reporting.common.browserCouldNotLaunchErrorMessage', { defaultMessage: 'Cannot generate screenshots because the browser did not launch.', @@ -86,13 +101,42 @@ export class BrowserCouldNotLaunchError extends ReportingError { } export class BrowserUnexpectedlyClosedError extends ReportingError { - code = 'browser_unexpectedly_closed_error'; + static code = 'browser_unexpectedly_closed_error' as const; + public get code(): string { + return BrowserUnexpectedlyClosedError.code; + } } export class BrowserScreenshotError extends ReportingError { - code = 'browser_screenshot_error'; + static code = 'browser_screenshot_error' as const; + public get code(): string { + return BrowserScreenshotError.code; + } } export class KibanaShuttingDownError extends ReportingError { - code = 'kibana_shutting_down_error'; + static code = 'kibana_shutting_down_error' as const; + public get code(): string { + return KibanaShuttingDownError.code; + } +} + +/** + * Special error case that should only occur on Cloud when trying to generate + * a report on a Kibana instance that is too small to be running Chromium. + */ +export class VisualReportingSoftDisabledError extends ReportingError { + static code = 'visual_reporting_soft_disabled_error' as const; + public get code(): string { + return VisualReportingSoftDisabledError.code; + } + + details = i18n.translate('xpack.reporting.common.cloud.insufficientSystemMemoryError', { + defaultMessage: + 'This report cannot be generated because Kibana does not have sufficient memory.', + }); + + public override get message() { + return this.details; + } } diff --git a/x-pack/plugins/reporting/common/errors/map_to_reporting_error.ts b/x-pack/plugins/reporting/common/errors/map_to_reporting_error.ts index eafd4ed683627..1244737deee2e 100644 --- a/x-pack/plugins/reporting/common/errors/map_to_reporting_error.ts +++ b/x-pack/plugins/reporting/common/errors/map_to_reporting_error.ts @@ -13,6 +13,7 @@ import { BrowserUnexpectedlyClosedError, BrowserScreenshotError, PdfWorkerOutOfMemoryError, + VisualReportingSoftDisabledError, } from '.'; export function mapToReportingError(error: unknown): ReportingError { @@ -28,6 +29,8 @@ export function mapToReportingError(error: unknown): ReportingError { return new BrowserCouldNotLaunchError(); case error instanceof errors.PdfWorkerOutOfMemoryError: return new PdfWorkerOutOfMemoryError(); + case error instanceof errors.InsufficientMemoryAvailableOnCloudError: + return new VisualReportingSoftDisabledError(); } return new UnknownError(); } diff --git a/x-pack/plugins/reporting/common/types/index.ts b/x-pack/plugins/reporting/common/types/index.ts index 8b95fdb54b1e0..c8743fcf467a1 100644 --- a/x-pack/plugins/reporting/common/types/index.ts +++ b/x-pack/plugins/reporting/common/types/index.ts @@ -156,6 +156,7 @@ export interface JobSummary { status: JobStatus; jobtype: ReportSource['jobtype']; title: ReportSource['payload']['title']; + errorCode?: ReportOutput['error_code']; maxSizeReached: TaskRunResult['max_size_reached']; csvContainsFormulas: TaskRunResult['csv_contains_formulas']; } diff --git a/x-pack/plugins/reporting/public/lib/__snapshots__/stream_handler.test.ts.snap b/x-pack/plugins/reporting/public/lib/__snapshots__/stream_handler.test.ts.snap index 50c8672733168..4187db5b20641 100644 --- a/x-pack/plugins/reporting/public/lib/__snapshots__/stream_handler.test.ts.snap +++ b/x-pack/plugins/reporting/public/lib/__snapshots__/stream_handler.test.ts.snap @@ -5,6 +5,7 @@ Object { "completed": Array [ Object { "csvContainsFormulas": false, + "errorCode": undefined, "id": "job-source-mock1", "jobtype": undefined, "maxSizeReached": false, @@ -13,6 +14,7 @@ Object { }, Object { "csvContainsFormulas": true, + "errorCode": undefined, "id": "job-source-mock4", "jobtype": undefined, "maxSizeReached": false, @@ -23,6 +25,7 @@ Object { "failed": Array [ Object { "csvContainsFormulas": false, + "errorCode": undefined, "id": "job-source-mock2", "jobtype": undefined, "maxSizeReached": false, @@ -94,9 +97,7 @@ Array [ this is the failed report error diff --git a/x-pack/plugins/reporting/public/lib/job.tsx b/x-pack/plugins/reporting/public/lib/job.tsx index e875d00cabab8..59a0446590dd8 100644 --- a/x-pack/plugins/reporting/public/lib/job.tsx +++ b/x-pack/plugins/reporting/public/lib/job.tsx @@ -61,6 +61,8 @@ export class Job { public locatorParams?: BaseParamsV2['locatorParams']; + public error_code?: ReportOutput['error_code']; + constructor(report: ReportApiJSON) { this.id = report.id; this.index = report.index; @@ -90,6 +92,7 @@ export class Job { this.csv_contains_formulas = report.output?.csv_contains_formulas; this.max_size_reached = report.output?.max_size_reached; this.warnings = report.output?.warnings; + this.error_code = report.output?.error_code; this.locatorParams = (report.payload as BaseParamsV2).locatorParams; this.metrics = report.metrics; } diff --git a/x-pack/plugins/reporting/public/lib/stream_handler.test.ts b/x-pack/plugins/reporting/public/lib/stream_handler.test.ts index 895266bdd568b..6f575652450c1 100644 --- a/x-pack/plugins/reporting/public/lib/stream_handler.test.ts +++ b/x-pack/plugins/reporting/public/lib/stream_handler.test.ts @@ -7,7 +7,7 @@ import sinon, { stub } from 'sinon'; import { NotificationsStart } from '@kbn/core/public'; -import { coreMock, themeServiceMock } from '@kbn/core/public/mocks'; +import { coreMock, themeServiceMock, docLinksServiceMock } from '@kbn/core/public/mocks'; import { JobSummary, ReportApiJSON } from '../../common/types'; import { Job } from './job'; import { ReportingAPIClient } from './reporting_api_client'; @@ -48,6 +48,7 @@ const notificationsMock = { } as unknown as NotificationsStart; const theme = themeServiceMock.createStartContract(); +const docLink = docLinksServiceMock.createStartContract(); describe('stream handler', () => { afterEach(() => { @@ -55,13 +56,23 @@ describe('stream handler', () => { }); it('constructs', () => { - const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock, theme); + const sh = new ReportingNotifierStreamHandler( + notificationsMock, + jobQueueClientMock, + theme, + docLink + ); expect(sh).not.toBe(null); }); describe('findChangedStatusJobs', () => { it('finds no changed status jobs from empty', (done) => { - const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock, theme); + const sh = new ReportingNotifierStreamHandler( + notificationsMock, + jobQueueClientMock, + theme, + docLink + ); const findJobs = sh.findChangedStatusJobs([]); findJobs.subscribe((data) => { expect(data).toEqual({ completed: [], failed: [] }); @@ -70,7 +81,12 @@ describe('stream handler', () => { }); it('finds changed status jobs', (done) => { - const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock, theme); + const sh = new ReportingNotifierStreamHandler( + notificationsMock, + jobQueueClientMock, + theme, + docLink + ); const findJobs = sh.findChangedStatusJobs([ 'job-source-mock1', 'job-source-mock2', @@ -87,7 +103,12 @@ describe('stream handler', () => { describe('showNotifications', () => { it('show success', (done) => { - const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock, theme); + const sh = new ReportingNotifierStreamHandler( + notificationsMock, + jobQueueClientMock, + theme, + docLink + ); sh.showNotifications({ completed: [ { @@ -108,7 +129,12 @@ describe('stream handler', () => { }); it('show max length warning', (done) => { - const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock, theme); + const sh = new ReportingNotifierStreamHandler( + notificationsMock, + jobQueueClientMock, + theme, + docLink + ); sh.showNotifications({ completed: [ { @@ -130,7 +156,12 @@ describe('stream handler', () => { }); it('show csv formulas warning', (done) => { - const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock, theme); + const sh = new ReportingNotifierStreamHandler( + notificationsMock, + jobQueueClientMock, + theme, + docLink + ); sh.showNotifications({ completed: [ { @@ -152,7 +183,12 @@ describe('stream handler', () => { }); it('show failed job toast', (done) => { - const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock, theme); + const sh = new ReportingNotifierStreamHandler( + notificationsMock, + jobQueueClientMock, + theme, + docLink + ); sh.showNotifications({ completed: [], failed: [ @@ -173,7 +209,12 @@ describe('stream handler', () => { }); it('show multiple toast', (done) => { - const sh = new ReportingNotifierStreamHandler(notificationsMock, jobQueueClientMock, theme); + const sh = new ReportingNotifierStreamHandler( + notificationsMock, + jobQueueClientMock, + theme, + docLink + ); sh.showNotifications({ completed: [ { diff --git a/x-pack/plugins/reporting/public/lib/stream_handler.ts b/x-pack/plugins/reporting/public/lib/stream_handler.ts index 2ff8b8bd4ebda..ba2c32de49f64 100644 --- a/x-pack/plugins/reporting/public/lib/stream_handler.ts +++ b/x-pack/plugins/reporting/public/lib/stream_handler.ts @@ -8,7 +8,7 @@ import { i18n } from '@kbn/i18n'; import * as Rx from 'rxjs'; import { catchError, map } from 'rxjs/operators'; -import { NotificationsSetup, ThemeServiceStart } from '@kbn/core/public'; +import { NotificationsSetup, ThemeServiceStart, DocLinksStart } from '@kbn/core/public'; import { JOB_COMPLETION_NOTIFICATIONS_SESSION_KEY, JOB_STATUSES } from '../../common/constants'; import { JobId, JobSummary, JobSummarySet } from '../../common/types'; import { @@ -34,6 +34,7 @@ function getReportStatus(src: Job): JobSummary { jobtype: src.prettyJobTypeName ?? src.jobtype, maxSizeReached: src.max_size_reached, csvContainsFormulas: src.csv_contains_formulas, + errorCode: src.error_code, }; } @@ -41,7 +42,8 @@ export class ReportingNotifierStreamHandler { constructor( private notifications: NotificationsSetup, private apiClient: ReportingAPIClient, - private theme: ThemeServiceStart + private theme: ThemeServiceStart, + private docLinks: DocLinksStart ) {} /* @@ -97,7 +99,13 @@ export class ReportingNotifierStreamHandler { for (const job of failedJobs) { const errorText = await this.apiClient.getError(job.id); this.notifications.toasts.addDanger( - getFailureToast(errorText, job, this.apiClient.getManagementLink, this.theme) + getFailureToast( + errorText, + job, + this.apiClient.getManagementLink, + this.theme, + this.docLinks + ) ); } return { completed: completedJobs, failed: failedJobs }; diff --git a/x-pack/plugins/reporting/public/management/components/report_info_flyout_content.tsx b/x-pack/plugins/reporting/public/management/components/report_info_flyout_content.tsx index 92b38d99cedd1..780ea53d885a9 100644 --- a/x-pack/plugins/reporting/public/management/components/report_info_flyout_content.tsx +++ b/x-pack/plugins/reporting/public/management/components/report_info_flyout_content.tsx @@ -17,10 +17,14 @@ import { import moment from 'moment'; import { USES_HEADLESS_JOB_TYPES } from '../../../common/constants'; +import { VisualReportingSoftDisabledError } from '../../../common/errors'; import type { Job } from '../../lib/job'; import { useKibana } from '../../shared_imports'; +import { sharedI18nTexts } from '../../shared_i18n_texts'; + +// TODO: Move all of these i18n texts to ./i18n_texts.tsx const NA = i18n.translate('xpack.reporting.listing.infoPanel.notApplicableLabel', { defaultMessage: 'N/A', }); @@ -40,7 +44,7 @@ const createDateFormatter = (format: string, tz: string) => (date: string) => { export const ReportInfoFlyoutContent: FunctionComponent = ({ info }) => { const { - services: { uiSettings }, + services: { uiSettings, docLinks }, } = useKibana(); const timezone = @@ -186,19 +190,31 @@ export const ReportInfoFlyoutContent: FunctionComponent = ({ info }) => { ]; const warnings = info.getWarnings(); - const errored = info.getError(); + const errored = + /* + * We link the user to documentation if they hit this error case. Note: this + * should only occur on cloud. + */ + info.error_code === VisualReportingSoftDisabledError.code + ? sharedI18nTexts.cloud.insufficientMemoryError( + docLinks.links.reporting.cloudMinimumRequirements + ) + : info.getError(); return ( <> {Boolean(errored) && ( - - {errored} - + <> + + {errored} + + + )} {Boolean(warnings) && ( <> diff --git a/x-pack/plugins/reporting/public/management/mount_management_section.tsx b/x-pack/plugins/reporting/public/management/mount_management_section.tsx index 9e709f317b7f0..a3f238052f66d 100644 --- a/x-pack/plugins/reporting/public/management/mount_management_section.tsx +++ b/x-pack/plugins/reporting/public/management/mount_management_section.tsx @@ -34,6 +34,7 @@ export async function mountManagementSection( http: coreSetup.http, application: coreStart.application, uiSettings: coreStart.uiSettings, + docLinks: coreStart.docLinks, }} > diff --git a/x-pack/plugins/reporting/public/notifier/job_failure.tsx b/x-pack/plugins/reporting/public/notifier/job_failure.tsx index e653c974861ab..e7a6191c30834 100644 --- a/x-pack/plugins/reporting/public/notifier/job_failure.tsx +++ b/x-pack/plugins/reporting/public/notifier/job_failure.tsx @@ -6,18 +6,20 @@ */ import { EuiCallOut, EuiSpacer } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import React from 'react'; -import { ThemeServiceStart, ToastInput } from '@kbn/core/public'; +import { DocLinksStart, ThemeServiceStart, ToastInput } from '@kbn/core/public'; import { toMountPoint } from '@kbn/kibana-react-plugin/public'; import type { JobSummary, ManagementLinkFn } from '../../common/types'; +import * as errors from '../../common/errors'; +import { sharedI18nTexts } from '../shared_i18n_texts'; export const getFailureToast = ( errorText: string, job: JobSummary, getManagmenetLink: ManagementLinkFn, - theme: ThemeServiceStart + theme: ThemeServiceStart, + docLinks: DocLinksStart ): ToastInput => { return { title: toMountPoint( @@ -30,16 +32,12 @@ export const getFailureToast = ( ), text: toMountPoint( <> - - {errorText} + + {job.errorCode === errors.VisualReportingSoftDisabledError.code + ? sharedI18nTexts.cloud.insufficientMemoryError( + docLinks.links.reporting.cloudMinimumRequirements + ) + : errorText} diff --git a/x-pack/plugins/reporting/public/plugin.ts b/x-pack/plugins/reporting/public/plugin.ts index 252745c0cec1f..df47c6f28a6e3 100644 --- a/x-pack/plugins/reporting/public/plugin.ts +++ b/x-pack/plugins/reporting/public/plugin.ts @@ -254,9 +254,9 @@ export class ReportingPublicPlugin } public start(core: CoreStart) { - const { notifications } = core; + const { notifications, docLinks } = core; const apiClient = this.getApiClient(core.http, core.uiSettings); - const streamHandler = new StreamHandler(notifications, apiClient, core.theme); + const streamHandler = new StreamHandler(notifications, apiClient, core.theme, docLinks); const interval = durationToNumber(this.config.poll.jobsRefresh.interval); Rx.timer(0, interval) .pipe( diff --git a/x-pack/plugins/reporting/public/shared_i18n_texts.tsx b/x-pack/plugins/reporting/public/shared_i18n_texts.tsx new file mode 100644 index 0000000000000..344fe5360fc35 --- /dev/null +++ b/x-pack/plugins/reporting/public/shared_i18n_texts.tsx @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { EuiLink } from '@elastic/eui'; + +export const sharedI18nTexts = { + cloud: { + insufficientMemoryError: (helpUrl: string) => ( + + {i18n.translate( + 'xpack.reporting.listing.infoPanel.callout.cloud.insufficientMemoryError.urlLink', + { defaultMessage: 'RAM requirements' } + )} + + ), + }} + /> + ), + }, +}; diff --git a/x-pack/plugins/reporting/public/types.ts b/x-pack/plugins/reporting/public/types.ts index 8a745a237ee57..3be354bada72e 100644 --- a/x-pack/plugins/reporting/public/types.ts +++ b/x-pack/plugins/reporting/public/types.ts @@ -5,10 +5,11 @@ * 2.0. */ -import type { HttpSetup, ApplicationStart, CoreSetup } from '@kbn/core/public'; +import type { CoreSetup, CoreStart } from '@kbn/core/public'; export interface KibanaContext { - http: HttpSetup; - application: ApplicationStart; - uiSettings: CoreSetup['uiSettings']; + http: CoreSetup['http']; + application: CoreStart['application']; + uiSettings: CoreStart['uiSettings']; + docLinks: CoreStart['docLinks']; } diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/execute_job.ts b/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/execute_job.ts index efe905eedd9ae..31924d0d89cf5 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/execute_job.ts +++ b/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/execute_job.ts @@ -39,7 +39,7 @@ export const runTaskFnFactory: RunTaskFnFactory = function e ...immediateJobParams, }; - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; const uiSettings = await reporting.getUiSettingsServiceFactory(savedObjectsClient); const dataPluginStart = await reporting.getDataService(); const fieldFormatsRegistry = await getFieldFormats().fieldFormatServiceFactory(uiSettings); diff --git a/x-pack/plugins/reporting/server/routes/deprecations/deprecations.ts b/x-pack/plugins/reporting/server/routes/deprecations/deprecations.ts index ecb8dc16435f3..dd04cd20ddac2 100644 --- a/x-pack/plugins/reporting/server/routes/deprecations/deprecations.ts +++ b/x-pack/plugins/reporting/server/routes/deprecations/deprecations.ts @@ -27,9 +27,7 @@ export const registerDeprecationsRoutes = (reporting: ReportingCore, logger: Log return handler(ctx, req, res); } - const { - core: { elasticsearch }, - } = ctx; + const { elasticsearch } = await ctx.core; const store = await reporting.getStore(); @@ -63,47 +61,40 @@ export const registerDeprecationsRoutes = (reporting: ReportingCore, logger: Log path: API_GET_ILM_POLICY_STATUS, validate: false, }, - authzWrapper( - async ( - { - core: { - elasticsearch: { client: scopedClient }, - }, - }, - _req, - res - ) => { - const checkIlmMigrationStatus = () => { - return deprecations.checkIlmMigrationStatus({ - reportingCore: reporting, - // We want to make the current status visible to all reporting users - elasticsearchClient: scopedClient.asInternalUser, - }); - }; + authzWrapper(async ({ core }, _req, res) => { + const { + elasticsearch: { client: scopedClient }, + } = await core; + const checkIlmMigrationStatus = () => { + return deprecations.checkIlmMigrationStatus({ + reportingCore: reporting, + // We want to make the current status visible to all reporting users + elasticsearchClient: scopedClient.asInternalUser, + }); + }; - try { - const response: IlmPolicyStatusResponse = { - status: await checkIlmMigrationStatus(), - }; - return res.ok({ body: response }); - } catch (e) { - logger.error(e); - return res.customError({ - statusCode: e?.statusCode ?? 500, - body: { message: e.message }, - }); - } + try { + const response: IlmPolicyStatusResponse = { + status: await checkIlmMigrationStatus(), + }; + return res.ok({ body: response }); + } catch (e) { + logger.error(e); + return res.customError({ + statusCode: e?.statusCode ?? 500, + body: { message: e.message }, + }); } - ) + }) ); router.put( { path: API_MIGRATE_ILM_POLICY_URL, validate: false }, - authzWrapper(async ({ core: { elasticsearch } }, _req, res) => { + authzWrapper(async ({ core }, _req, res) => { const store = await reporting.getStore(); const { client: { asCurrentUser: client }, - } = elasticsearch; + } = (await core).elasticsearch; const scopedIlmPolicyManager = IlmPolicyManager.create({ client, diff --git a/x-pack/plugins/reporting/server/routes/lib/request_handler.test.ts b/x-pack/plugins/reporting/server/routes/lib/request_handler.test.ts index 97b85f8d2d5cd..f3e771555c5a3 100644 --- a/x-pack/plugins/reporting/server/routes/lib/request_handler.test.ts +++ b/x-pack/plugins/reporting/server/routes/lib/request_handler.test.ts @@ -76,7 +76,7 @@ describe('Handle request to generate', () => { (mockResponseFactory.badRequest as jest.Mock) = jest.fn((args: unknown) => args); mockContext = getMockContext(); - mockContext.reporting = {} as ReportingSetup; + mockContext.reporting = Promise.resolve({} as ReportingSetup); requestHandler = new RequestHandler( reportingCore, diff --git a/x-pack/plugins/reporting/server/types.ts b/x-pack/plugins/reporting/server/types.ts index b272f9687c14b..f660690c6a755 100644 --- a/x-pack/plugins/reporting/server/types.ts +++ b/x-pack/plugins/reporting/server/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { IRouter, Logger, RequestHandlerContext } from '@kbn/core/server'; +import type { IRouter, Logger, CustomRequestHandlerContext } from '@kbn/core/server'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import type { DataPluginStart } from '@kbn/data-plugin/server/plugin'; import { FieldFormatsStart } from '@kbn/field-formats-plugin/server'; @@ -113,10 +113,9 @@ export interface ReportingStartDeps { taskManager: TaskManagerStartContract; } -export interface ReportingRequestHandlerContext { +export type ReportingRequestHandlerContext = CustomRequestHandlerContext<{ reporting: ReportingStart | null; - core: RequestHandlerContext['core']; -} +}>; export type ReportingPluginRouter = IRouter; diff --git a/x-pack/plugins/reporting/server/usage/__snapshots__/reporting_usage_collector.test.ts.snap b/x-pack/plugins/reporting/server/usage/__snapshots__/reporting_usage_collector.test.ts.snap index 0bfc8cb0df966..937fb0217f4bf 100644 --- a/x-pack/plugins/reporting/server/usage/__snapshots__/reporting_usage_collector.test.ts.snap +++ b/x-pack/plugins/reporting/server/usage/__snapshots__/reporting_usage_collector.test.ts.snap @@ -48,6 +48,9 @@ Object { "unknown_error": Object { "type": "long", }, + "visual_reporting_soft_disabled_error": Object { + "type": "long", + }, }, "metrics": Object { "png_cpu": Object { @@ -149,6 +152,9 @@ Object { "unknown_error": Object { "type": "long", }, + "visual_reporting_soft_disabled_error": Object { + "type": "long", + }, }, "metrics": Object { "png_cpu": Object { @@ -416,6 +422,9 @@ Object { "unknown_error": Object { "type": "long", }, + "visual_reporting_soft_disabled_error": Object { + "type": "long", + }, }, "metrics": Object { "png_cpu": Object { @@ -517,6 +526,9 @@ Object { "unknown_error": Object { "type": "long", }, + "visual_reporting_soft_disabled_error": Object { + "type": "long", + }, }, "metrics": Object { "png_cpu": Object { @@ -803,6 +815,9 @@ Object { "unknown_error": Object { "type": "long", }, + "visual_reporting_soft_disabled_error": Object { + "type": "long", + }, }, "layout": Object { "canvas": Object { @@ -932,6 +947,9 @@ Object { "unknown_error": Object { "type": "long", }, + "visual_reporting_soft_disabled_error": Object { + "type": "long", + }, }, "layout": Object { "canvas": Object { @@ -1534,6 +1552,9 @@ Object { "unknown_error": Object { "type": "long", }, + "visual_reporting_soft_disabled_error": Object { + "type": "long", + }, }, "layout": Object { "canvas": Object { @@ -1663,6 +1684,9 @@ Object { "unknown_error": Object { "type": "long", }, + "visual_reporting_soft_disabled_error": Object { + "type": "long", + }, }, "layout": Object { "canvas": Object { diff --git a/x-pack/plugins/reporting/server/usage/get_export_stats.test.ts b/x-pack/plugins/reporting/server/usage/get_export_stats.test.ts index 069d5eb42d7f8..f99c81ea39e29 100644 --- a/x-pack/plugins/reporting/server/usage/get_export_stats.test.ts +++ b/x-pack/plugins/reporting/server/usage/get_export_stats.test.ts @@ -331,6 +331,7 @@ test('Incorporate error code stats', () => { browser_could_not_launch_error: 2, browser_unexpectedly_closed_error: 8, browser_screenshot_error: 27, + visual_reporting_soft_disabled_error: 1, }, }, printable_pdf_v2: { @@ -349,6 +350,7 @@ test('Incorporate error code stats', () => { browser_could_not_launch_error: 2, browser_unexpectedly_closed_error: 8, browser_screenshot_error: 27, + visual_reporting_soft_disabled_error: 1, }, }, csv_searchsource_immediate: { @@ -378,6 +380,7 @@ test('Incorporate error code stats', () => { "kibana_shutting_down_error": 1, "queue_timeout_error": 1, "unknown_error": 0, + "visual_reporting_soft_disabled_error": 1, } `); expect(result.printable_pdf_v2.error_codes).toMatchInlineSnapshot(` @@ -390,6 +393,7 @@ test('Incorporate error code stats', () => { "pdf_worker_out_of_memory_error": 99, "queue_timeout_error": 1, "unknown_error": 0, + "visual_reporting_soft_disabled_error": 1, } `); diff --git a/x-pack/plugins/reporting/server/usage/schema.test.ts b/x-pack/plugins/reporting/server/usage/schema.test.ts index d188d6eb373dd..f877b6251378e 100644 --- a/x-pack/plugins/reporting/server/usage/schema.test.ts +++ b/x-pack/plugins/reporting/server/usage/schema.test.ts @@ -39,6 +39,7 @@ describe('Reporting telemetry schema', () => { "PNG.error_codes.kibana_shutting_down_error.type": "long", "PNG.error_codes.queue_timeout_error.type": "long", "PNG.error_codes.unknown_error.type": "long", + "PNG.error_codes.visual_reporting_soft_disabled_error.type": "long", "PNG.metrics.png_cpu.50.0.type": "long", "PNG.metrics.png_cpu.75.0.type": "long", "PNG.metrics.png_cpu.95.0.type": "long", @@ -68,6 +69,7 @@ describe('Reporting telemetry schema', () => { "PNGV2.error_codes.kibana_shutting_down_error.type": "long", "PNGV2.error_codes.queue_timeout_error.type": "long", "PNGV2.error_codes.unknown_error.type": "long", + "PNGV2.error_codes.visual_reporting_soft_disabled_error.type": "long", "PNGV2.metrics.png_cpu.50.0.type": "long", "PNGV2.metrics.png_cpu.75.0.type": "long", "PNGV2.metrics.png_cpu.95.0.type": "long", @@ -144,6 +146,7 @@ describe('Reporting telemetry schema', () => { "last7Days.PNG.error_codes.kibana_shutting_down_error.type": "long", "last7Days.PNG.error_codes.queue_timeout_error.type": "long", "last7Days.PNG.error_codes.unknown_error.type": "long", + "last7Days.PNG.error_codes.visual_reporting_soft_disabled_error.type": "long", "last7Days.PNG.metrics.png_cpu.50.0.type": "long", "last7Days.PNG.metrics.png_cpu.75.0.type": "long", "last7Days.PNG.metrics.png_cpu.95.0.type": "long", @@ -173,6 +176,7 @@ describe('Reporting telemetry schema', () => { "last7Days.PNGV2.error_codes.kibana_shutting_down_error.type": "long", "last7Days.PNGV2.error_codes.queue_timeout_error.type": "long", "last7Days.PNGV2.error_codes.unknown_error.type": "long", + "last7Days.PNGV2.error_codes.visual_reporting_soft_disabled_error.type": "long", "last7Days.PNGV2.metrics.png_cpu.50.0.type": "long", "last7Days.PNGV2.metrics.png_cpu.75.0.type": "long", "last7Days.PNGV2.metrics.png_cpu.95.0.type": "long", @@ -255,6 +259,7 @@ describe('Reporting telemetry schema', () => { "last7Days.printable_pdf.error_codes.pdf_worker_out_of_memory_error.type": "long", "last7Days.printable_pdf.error_codes.queue_timeout_error.type": "long", "last7Days.printable_pdf.error_codes.unknown_error.type": "long", + "last7Days.printable_pdf.error_codes.visual_reporting_soft_disabled_error.type": "long", "last7Days.printable_pdf.layout.canvas.type": "long", "last7Days.printable_pdf.layout.preserve_layout.type": "long", "last7Days.printable_pdf.layout.print.type": "long", @@ -292,6 +297,7 @@ describe('Reporting telemetry schema', () => { "last7Days.printable_pdf_v2.error_codes.pdf_worker_out_of_memory_error.type": "long", "last7Days.printable_pdf_v2.error_codes.queue_timeout_error.type": "long", "last7Days.printable_pdf_v2.error_codes.unknown_error.type": "long", + "last7Days.printable_pdf_v2.error_codes.visual_reporting_soft_disabled_error.type": "long", "last7Days.printable_pdf_v2.layout.canvas.type": "long", "last7Days.printable_pdf_v2.layout.preserve_layout.type": "long", "last7Days.printable_pdf_v2.layout.print.type": "long", @@ -461,6 +467,7 @@ describe('Reporting telemetry schema', () => { "printable_pdf.error_codes.pdf_worker_out_of_memory_error.type": "long", "printable_pdf.error_codes.queue_timeout_error.type": "long", "printable_pdf.error_codes.unknown_error.type": "long", + "printable_pdf.error_codes.visual_reporting_soft_disabled_error.type": "long", "printable_pdf.layout.canvas.type": "long", "printable_pdf.layout.preserve_layout.type": "long", "printable_pdf.layout.print.type": "long", @@ -498,6 +505,7 @@ describe('Reporting telemetry schema', () => { "printable_pdf_v2.error_codes.pdf_worker_out_of_memory_error.type": "long", "printable_pdf_v2.error_codes.queue_timeout_error.type": "long", "printable_pdf_v2.error_codes.unknown_error.type": "long", + "printable_pdf_v2.error_codes.visual_reporting_soft_disabled_error.type": "long", "printable_pdf_v2.layout.canvas.type": "long", "printable_pdf_v2.layout.preserve_layout.type": "long", "printable_pdf_v2.layout.print.type": "long", diff --git a/x-pack/plugins/reporting/server/usage/schema.ts b/x-pack/plugins/reporting/server/usage/schema.ts index a4cd8a3e51bfa..f89d89d35503d 100644 --- a/x-pack/plugins/reporting/server/usage/schema.ts +++ b/x-pack/plugins/reporting/server/usage/schema.ts @@ -88,6 +88,7 @@ const errorCodesSchemaPng: MakeSchemaFrom = { browser_could_not_launch_error: { type: 'long' }, browser_unexpectedly_closed_error: { type: 'long' }, browser_screenshot_error: { type: 'long' }, + visual_reporting_soft_disabled_error: { type: 'long' }, }; const errorCodesSchemaPdf: MakeSchemaFrom = { pdf_worker_out_of_memory_error: { type: 'long' }, @@ -98,6 +99,7 @@ const errorCodesSchemaPdf: MakeSchemaFrom = { diff --git a/x-pack/plugins/reporting/server/usage/types.ts b/x-pack/plugins/reporting/server/usage/types.ts index cf0acee312ae4..9d7e08932cc1c 100644 --- a/x-pack/plugins/reporting/server/usage/types.ts +++ b/x-pack/plugins/reporting/server/usage/types.ts @@ -203,6 +203,7 @@ export interface ErrorCodeStats { browser_unexpectedly_closed_error: number | null; browser_screenshot_error: number | null; kibana_shutting_down_error: number | null; + visual_reporting_soft_disabled_error: number | null; } export interface MetricsStats { diff --git a/x-pack/plugins/rollup/server/routes/api/indices/register_get_route.ts b/x-pack/plugins/rollup/server/routes/api/indices/register_get_route.ts index 485c1301b4d9b..99312936adba4 100644 --- a/x-pack/plugins/rollup/server/routes/api/indices/register_get_route.ts +++ b/x-pack/plugins/rollup/server/routes/api/indices/register_get_route.ts @@ -23,7 +23,7 @@ export const registerGetRoute = ({ }, license.guardApiRoute(async (context, request, response) => { try { - const { client: clusterClient } = context.core.elasticsearch; + const { client: clusterClient } = (await context.core).elasticsearch; const data = await clusterClient.asCurrentUser.rollup.getRollupIndexCaps({ index: '_all', }); diff --git a/x-pack/plugins/rollup/server/routes/api/indices/register_validate_index_pattern_route.ts b/x-pack/plugins/rollup/server/routes/api/indices/register_validate_index_pattern_route.ts index dec51870f2f57..8eaea73e42b37 100644 --- a/x-pack/plugins/rollup/server/routes/api/indices/register_validate_index_pattern_route.ts +++ b/x-pack/plugins/rollup/server/routes/api/indices/register_validate_index_pattern_route.ts @@ -67,7 +67,7 @@ export const registerValidateIndexPatternRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client: clusterClient } = context.core.elasticsearch; + const { client: clusterClient } = (await context.core).elasticsearch; try { const { indexPattern } = request.params; const [fieldCapabilities, rollupIndexCapabilities] = await Promise.all([ diff --git a/x-pack/plugins/rollup/server/routes/api/jobs/register_create_route.ts b/x-pack/plugins/rollup/server/routes/api/jobs/register_create_route.ts index ca067d0833981..21c0681f8458c 100644 --- a/x-pack/plugins/rollup/server/routes/api/jobs/register_create_route.ts +++ b/x-pack/plugins/rollup/server/routes/api/jobs/register_create_route.ts @@ -29,7 +29,7 @@ export const registerCreateRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client: clusterClient } = context.core.elasticsearch; + const { client: clusterClient } = (await context.core).elasticsearch; try { const { id, ...rest } = request.body.job; // Create job. diff --git a/x-pack/plugins/rollup/server/routes/api/jobs/register_delete_route.ts b/x-pack/plugins/rollup/server/routes/api/jobs/register_delete_route.ts index 7e22b5c4ead10..f6b530ef2fc0e 100644 --- a/x-pack/plugins/rollup/server/routes/api/jobs/register_delete_route.ts +++ b/x-pack/plugins/rollup/server/routes/api/jobs/register_delete_route.ts @@ -24,7 +24,7 @@ export const registerDeleteRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client: clusterClient } = context.core.elasticsearch; + const { client: clusterClient } = (await context.core).elasticsearch; try { const { jobIds } = request.body; const data = await Promise.all( diff --git a/x-pack/plugins/rollup/server/routes/api/jobs/register_get_route.ts b/x-pack/plugins/rollup/server/routes/api/jobs/register_get_route.ts index cc0b138aeb835..d74a2907254d7 100644 --- a/x-pack/plugins/rollup/server/routes/api/jobs/register_get_route.ts +++ b/x-pack/plugins/rollup/server/routes/api/jobs/register_get_route.ts @@ -19,7 +19,7 @@ export const registerGetRoute = ({ validate: false, }, license.guardApiRoute(async (context, request, response) => { - const { client: clusterClient } = context.core.elasticsearch; + const { client: clusterClient } = (await context.core).elasticsearch; try { const data = await clusterClient.asCurrentUser.rollup.getJobs({ id: '_all' }); return response.ok({ body: data }); diff --git a/x-pack/plugins/rollup/server/routes/api/jobs/register_start_route.ts b/x-pack/plugins/rollup/server/routes/api/jobs/register_start_route.ts index 133c0cb34c9f5..85e2a508f04a9 100644 --- a/x-pack/plugins/rollup/server/routes/api/jobs/register_start_route.ts +++ b/x-pack/plugins/rollup/server/routes/api/jobs/register_start_route.ts @@ -29,7 +29,7 @@ export const registerStartRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client: clusterClient } = context.core.elasticsearch; + const { client: clusterClient } = (await context.core).elasticsearch; try { const { jobIds } = request.body; diff --git a/x-pack/plugins/rollup/server/routes/api/jobs/register_stop_route.ts b/x-pack/plugins/rollup/server/routes/api/jobs/register_stop_route.ts index 164273f604b43..617023413eea3 100644 --- a/x-pack/plugins/rollup/server/routes/api/jobs/register_stop_route.ts +++ b/x-pack/plugins/rollup/server/routes/api/jobs/register_stop_route.ts @@ -27,7 +27,7 @@ export const registerStopRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client: clusterClient } = context.core.elasticsearch; + const { client: clusterClient } = (await context.core).elasticsearch; try { const { jobIds } = request.body; // For our API integration tests we need to wait for the jobs to be stopped diff --git a/x-pack/plugins/rollup/server/routes/api/search/register_search_route.ts b/x-pack/plugins/rollup/server/routes/api/search/register_search_route.ts index ab144c1f42440..98116e8288866 100644 --- a/x-pack/plugins/rollup/server/routes/api/search/register_search_route.ts +++ b/x-pack/plugins/rollup/server/routes/api/search/register_search_route.ts @@ -27,7 +27,7 @@ export const registerSearchRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client: clusterClient } = context.core.elasticsearch; + const { client: clusterClient } = (await context.core).elasticsearch; try { const requests = request.body.map(({ index, query }: { index: string; query?: any }) => clusterClient.asCurrentUser.rollup.rollupSearch({ diff --git a/x-pack/plugins/rule_registry/server/routes/bulk_update_alerts.ts b/x-pack/plugins/rule_registry/server/routes/bulk_update_alerts.ts index 4d297c56fe28b..a1a316200e5ee 100644 --- a/x-pack/plugins/rule_registry/server/routes/bulk_update_alerts.ts +++ b/x-pack/plugins/rule_registry/server/routes/bulk_update_alerts.ts @@ -52,7 +52,8 @@ export const bulkUpdateAlertsRoute = (router: IRouter) }, async (context, req, response) => { try { - const alertsClient = await context.rac.getAlertsClient(); + const racContext = await context.rac; + const alertsClient = await racContext.getAlertsClient(); const { status, ids, index, query } = req.body; if (ids != null && ids.length > 1000) { diff --git a/x-pack/plugins/rule_registry/server/routes/find.ts b/x-pack/plugins/rule_registry/server/routes/find.ts index abf465fc5238d..eca0a6c2a0551 100644 --- a/x-pack/plugins/rule_registry/server/routes/find.ts +++ b/x-pack/plugins/rule_registry/server/routes/find.ts @@ -43,7 +43,8 @@ export const findAlertsByQueryRoute = (router: IRouter // eslint-disable-next-line @typescript-eslint/naming-convention const { query, aggs, _source, track_total_hits, size, index } = request.body; - const alertsClient = await context.rac.getAlertsClient(); + const racContext = await context.rac; + const alertsClient = await racContext.getAlertsClient(); const alerts = await alertsClient.find({ query, diff --git a/x-pack/plugins/rule_registry/server/routes/get_alert_by_id.ts b/x-pack/plugins/rule_registry/server/routes/get_alert_by_id.ts index 86e2b25850aaf..2dc2d1ec2db7d 100644 --- a/x-pack/plugins/rule_registry/server/routes/get_alert_by_id.ts +++ b/x-pack/plugins/rule_registry/server/routes/get_alert_by_id.ts @@ -40,7 +40,8 @@ export const getAlertByIdRoute = (router: IRouter) => }, async (context, request, response) => { try { - const alertsClient = await context.rac.getAlertsClient(); + const racContext = await context.rac; + const alertsClient = await racContext.getAlertsClient(); const { id, index } = request.query; const alert = await alertsClient.get({ id, index }); if (alert == null) { diff --git a/x-pack/plugins/rule_registry/server/routes/get_alert_index.ts b/x-pack/plugins/rule_registry/server/routes/get_alert_index.ts index 650c47f53f692..3da040de66963 100644 --- a/x-pack/plugins/rule_registry/server/routes/get_alert_index.ts +++ b/x-pack/plugins/rule_registry/server/routes/get_alert_index.ts @@ -34,7 +34,8 @@ export const getAlertsIndexRoute = (router: IRouter) = }, async (context, request, response) => { try { - const alertsClient = await context.rac.getAlertsClient(); + const racContext = await context.rac; + const alertsClient = await racContext.getAlertsClient(); const { features } = request.query; const indexName = await alertsClient.getAuthorizedAlertsIndices( features?.split(',') ?? validFeatureIds diff --git a/x-pack/plugins/rule_registry/server/routes/update_alert_by_id.ts b/x-pack/plugins/rule_registry/server/routes/update_alert_by_id.ts index 1dcf7d28380dd..69f6b338bfda8 100644 --- a/x-pack/plugins/rule_registry/server/routes/update_alert_by_id.ts +++ b/x-pack/plugins/rule_registry/server/routes/update_alert_by_id.ts @@ -42,7 +42,8 @@ export const updateAlertByIdRoute = (router: IRouter) }, async (context, req, response) => { try { - const alertsClient = await context.rac.getAlertsClient(); + const racContext = await context.rac; + const alertsClient = await racContext.getAlertsClient(); const { status, ids, index, _version } = req.body; const updatedAlert = await alertsClient.update({ diff --git a/x-pack/plugins/rule_registry/server/types.ts b/x-pack/plugins/rule_registry/server/types.ts index b634d352aaf8e..6a7d5b849c771 100644 --- a/x-pack/plugins/rule_registry/server/types.ts +++ b/x-pack/plugins/rule_registry/server/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { RequestHandlerContext } from '@kbn/core/server'; +import { CustomRequestHandlerContext } from '@kbn/core/server'; import { AlertInstanceContext, AlertInstanceState, @@ -68,6 +68,6 @@ export interface RacApiRequestHandlerContext { /** * @internal */ -export interface RacRequestHandlerContext extends RequestHandlerContext { +export type RacRequestHandlerContext = CustomRequestHandlerContext<{ rac: RacApiRequestHandlerContext; -} +}>; diff --git a/x-pack/plugins/runtime_fields/public/types.ts b/x-pack/plugins/runtime_fields/public/types.ts index 3cd8506c01b10..b39e5e2ee5e6d 100644 --- a/x-pack/plugins/runtime_fields/public/types.ts +++ b/x-pack/plugins/runtime_fields/public/types.ts @@ -5,8 +5,6 @@ * 2.0. */ -import { DataPublicPluginStart } from '@kbn/data-plugin/public'; - import { RUNTIME_FIELD_TYPES } from './constants'; import { OpenRuntimeFieldEditorProps } from './load_editor'; @@ -24,9 +22,8 @@ export interface PluginStart {} // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface SetupPlugins {} -export interface StartPlugins { - data: DataPublicPluginStart; -} +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface StartPlugins {} export type RuntimeType = typeof RUNTIME_FIELD_TYPES[number]; diff --git a/x-pack/plugins/saved_objects_tagging/server/index.ts b/x-pack/plugins/saved_objects_tagging/server/index.ts index 5f731c77caac7..b9fcdcdbb7b4e 100644 --- a/x-pack/plugins/saved_objects_tagging/server/index.ts +++ b/x-pack/plugins/saved_objects_tagging/server/index.ts @@ -9,6 +9,13 @@ import { PluginInitializerContext } from '@kbn/core/server'; import { SavedObjectTaggingPlugin } from './plugin'; export { config } from './config'; +export type { + SavedObjectTaggingStart, + CreateTagAssignmentServiceOptions, + CreateTagClientOptions, +} from './types'; +export type { IAssignmentService } from './services'; +export type { ITagsClient } from '../common'; export const plugin = (initializerContext: PluginInitializerContext) => new SavedObjectTaggingPlugin(); diff --git a/x-pack/plugins/saved_objects_tagging/server/mocks.ts b/x-pack/plugins/saved_objects_tagging/server/mocks.ts new file mode 100644 index 0000000000000..6e1b456090dd4 --- /dev/null +++ b/x-pack/plugins/saved_objects_tagging/server/mocks.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { SavedObjectTaggingStart } from './types'; +import { tagsClientMock } from './services/tags/tags_client.mock'; +import { assigmentServiceMock } from './services/assignments/assignment_service.mock'; + +const createStartMock = () => { + const start: jest.Mocked = { + createTagClient: jest.fn(), + createInternalAssignmentService: jest.fn(), + }; + + start.createTagClient.mockImplementation(() => tagsClientMock.create()); + start.createInternalAssignmentService.mockImplementation(() => assigmentServiceMock.create()); + + return start; +}; + +export const savedObjectsTaggingMock = { + createStartContract: createStartMock, + createTagClient: tagsClientMock.create, + createAssignmentService: assigmentServiceMock.create, +}; diff --git a/x-pack/plugins/saved_objects_tagging/server/plugin.test.ts b/x-pack/plugins/saved_objects_tagging/server/plugin.test.ts index a62952937bc21..78cd2cd1f1f95 100644 --- a/x-pack/plugins/saved_objects_tagging/server/plugin.test.ts +++ b/x-pack/plugins/saved_objects_tagging/server/plugin.test.ts @@ -41,7 +41,7 @@ describe('SavedObjectTaggingPlugin', () => { it('registers the globalSearch route handler context', async () => { const coreSetup = coreMock.createSetup(); - await plugin.setup(coreSetup, { features: featuresPluginSetup }); + plugin.setup(coreSetup, { features: featuresPluginSetup }); expect(coreSetup.http.registerRouteHandlerContext).toHaveBeenCalledTimes(1); expect(coreSetup.http.registerRouteHandlerContext).toHaveBeenCalledWith( 'tags', @@ -50,7 +50,7 @@ describe('SavedObjectTaggingPlugin', () => { }); it('registers the `savedObjectsTagging` feature', async () => { - await plugin.setup(coreMock.createSetup(), { features: featuresPluginSetup }); + plugin.setup(coreMock.createSetup(), { features: featuresPluginSetup }); expect(featuresPluginSetup.registerKibanaFeature).toHaveBeenCalledTimes(1); expect(featuresPluginSetup.registerKibanaFeature).toHaveBeenCalledWith( savedObjectsTaggingFeature @@ -61,7 +61,7 @@ describe('SavedObjectTaggingPlugin', () => { const tagUsageCollector = Symbol('saved_objects_tagging'); createTagUsageCollectorMock.mockReturnValue(tagUsageCollector); - await plugin.setup(coreMock.createSetup(), { + plugin.setup(coreMock.createSetup(), { features: featuresPluginSetup, usageCollection: usageCollectionSetup, }); @@ -70,4 +70,16 @@ describe('SavedObjectTaggingPlugin', () => { expect(usageCollectionSetup.registerCollector).toHaveBeenCalledWith(tagUsageCollector); }); }); + + describe('#start', () => { + it('returns the expected contract', () => { + plugin.setup(coreMock.createSetup(), { features: featuresPluginSetup }); + const contract = plugin.start(coreMock.createStart(), {}); + + expect(contract).toEqual({ + createTagClient: expect.any(Function), + createInternalAssignmentService: expect.any(Function), + }); + }); + }); }); diff --git a/x-pack/plugins/saved_objects_tagging/server/plugin.ts b/x-pack/plugins/saved_objects_tagging/server/plugin.ts index bc43d4d65c828..59c40ab4f124b 100644 --- a/x-pack/plugins/saved_objects_tagging/server/plugin.ts +++ b/x-pack/plugins/saved_objects_tagging/server/plugin.ts @@ -8,13 +8,19 @@ import { CoreSetup, CoreStart, Plugin } from '@kbn/core/server'; import { PluginSetupContract as FeaturesPluginSetup } from '@kbn/features-plugin/server'; import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server'; -import { SecurityPluginSetup } from '@kbn/security-plugin/server'; +import { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server'; import { savedObjectsTaggingFeature } from './features'; import { tagType } from './saved_objects'; -import type { TagsHandlerContext } from './types'; +import type { + TagsHandlerContext, + SavedObjectTaggingStart, + CreateTagClientOptions, + CreateTagAssignmentServiceOptions, +} from './types'; import { TagsRequestHandlerContext } from './request_handler_context'; import { registerRoutes } from './routes'; import { createTagUsageCollector } from './usage'; +import { TagsClient, AssignmentService } from './services'; interface SetupDeps { features: FeaturesPluginSetup; @@ -22,7 +28,13 @@ interface SetupDeps { security?: SecurityPluginSetup; } -export class SavedObjectTaggingPlugin implements Plugin<{}, {}, SetupDeps, {}> { +interface StartDeps { + security?: SecurityPluginStart; +} + +export class SavedObjectTaggingPlugin + implements Plugin<{}, SavedObjectTaggingStart, SetupDeps, StartDeps> +{ public setup( { savedObjects, http }: CoreSetup, { features, usageCollection, security }: SetupDeps @@ -35,7 +47,7 @@ export class SavedObjectTaggingPlugin implements Plugin<{}, {}, SetupDeps, {}> { http.registerRouteHandlerContext( 'tags', async (context, req, res) => { - return new TagsRequestHandlerContext(req, context.core, security); + return new TagsRequestHandlerContext(req, await context.core, security); } ); @@ -53,7 +65,19 @@ export class SavedObjectTaggingPlugin implements Plugin<{}, {}, SetupDeps, {}> { return {}; } - public start(core: CoreStart) { - return {}; + public start(core: CoreStart, { security }: StartDeps) { + return { + createTagClient: ({ client }: CreateTagClientOptions) => { + return new TagsClient({ client }); + }, + createInternalAssignmentService: ({ client }: CreateTagAssignmentServiceOptions) => { + return new AssignmentService({ + client, + authorization: security?.authz, + typeRegistry: core.savedObjects.getTypeRegistry(), + internal: true, + }); + }, + }; } } diff --git a/x-pack/plugins/saved_objects_tagging/server/request_handler_context.ts b/x-pack/plugins/saved_objects_tagging/server/request_handler_context.ts index 09c9f77d69572..00f0de038851c 100644 --- a/x-pack/plugins/saved_objects_tagging/server/request_handler_context.ts +++ b/x-pack/plugins/saved_objects_tagging/server/request_handler_context.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { RequestHandlerContext, KibanaRequest } from '@kbn/core/server'; +import type { CoreRequestHandlerContext, KibanaRequest } from '@kbn/core/server'; import { SecurityPluginSetup } from '@kbn/security-plugin/server'; import { ITagsClient } from '../common/types'; import { ITagsRequestHandlerContext } from './types'; @@ -17,7 +17,7 @@ export class TagsRequestHandlerContext implements ITagsRequestHandlerContext { constructor( private readonly request: KibanaRequest, - private readonly coreContext: RequestHandlerContext['core'], + private readonly coreContext: CoreRequestHandlerContext, private readonly security?: SecurityPluginSetup ) {} diff --git a/x-pack/plugins/saved_objects_tagging/server/routes/assignments/find_assignable_objects.ts b/x-pack/plugins/saved_objects_tagging/server/routes/assignments/find_assignable_objects.ts index 8bda50940cc21..2fd6dfe56b33e 100644 --- a/x-pack/plugins/saved_objects_tagging/server/routes/assignments/find_assignable_objects.ts +++ b/x-pack/plugins/saved_objects_tagging/server/routes/assignments/find_assignable_objects.ts @@ -22,7 +22,7 @@ export const registerFindAssignableObjectsRoute = (router: TagsPluginRouter) => }, }, router.handleLegacyErrors(async (ctx, req, res) => { - const { assignmentService } = ctx.tags!; + const { assignmentService } = await ctx.tags; const { query } = req; const results = await assignmentService.findAssignableObjects({ diff --git a/x-pack/plugins/saved_objects_tagging/server/routes/assignments/get_assignable_types.ts b/x-pack/plugins/saved_objects_tagging/server/routes/assignments/get_assignable_types.ts index 385de4eb9fb64..bd82e7d31bc7f 100644 --- a/x-pack/plugins/saved_objects_tagging/server/routes/assignments/get_assignable_types.ts +++ b/x-pack/plugins/saved_objects_tagging/server/routes/assignments/get_assignable_types.ts @@ -15,7 +15,7 @@ export const registerGetAssignableTypesRoute = (router: TagsPluginRouter) => { validate: {}, }, router.handleLegacyErrors(async (ctx, req, res) => { - const { assignmentService } = ctx.tags!; + const { assignmentService } = await ctx.tags; const types = await assignmentService.getAssignableTypes(); return res.ok({ diff --git a/x-pack/plugins/saved_objects_tagging/server/routes/assignments/update_tags_assignments.ts b/x-pack/plugins/saved_objects_tagging/server/routes/assignments/update_tags_assignments.ts index c6c98ebd7b686..5bc1f844c4d36 100644 --- a/x-pack/plugins/saved_objects_tagging/server/routes/assignments/update_tags_assignments.ts +++ b/x-pack/plugins/saved_objects_tagging/server/routes/assignments/update_tags_assignments.ts @@ -37,7 +37,7 @@ export const registerUpdateTagsAssignmentsRoute = (router: TagsPluginRouter) => }, router.handleLegacyErrors(async (ctx, req, res) => { try { - const { assignmentService } = ctx.tags!; + const { assignmentService } = await ctx.tags; const { tags, assign, unassign } = req.body; await assignmentService.updateTagAssignments({ diff --git a/x-pack/plugins/saved_objects_tagging/server/routes/internal/bulk_delete.ts b/x-pack/plugins/saved_objects_tagging/server/routes/internal/bulk_delete.ts index e708193466810..ea4471f7d1243 100644 --- a/x-pack/plugins/saved_objects_tagging/server/routes/internal/bulk_delete.ts +++ b/x-pack/plugins/saved_objects_tagging/server/routes/internal/bulk_delete.ts @@ -20,7 +20,7 @@ export const registerInternalBulkDeleteRoute = (router: TagsPluginRouter) => { }, router.handleLegacyErrors(async (ctx, req, res) => { const { ids: tagIds } = req.body; - const client = ctx.tags!.tagsClient; + const client = (await ctx.tags).tagsClient; for (const tagId of tagIds) { await client.delete(tagId); diff --git a/x-pack/plugins/saved_objects_tagging/server/routes/internal/find_tags.ts b/x-pack/plugins/saved_objects_tagging/server/routes/internal/find_tags.ts index 0506b9051e467..32318f39b5a0c 100644 --- a/x-pack/plugins/saved_objects_tagging/server/routes/internal/find_tags.ts +++ b/x-pack/plugins/saved_objects_tagging/server/routes/internal/find_tags.ts @@ -26,7 +26,7 @@ export const registerInternalFindTagsRoute = (router: TagsPluginRouter) => { }, router.handleLegacyErrors(async (ctx, req, res) => { const { query } = req; - const { client, typeRegistry } = ctx.core.savedObjects; + const { client, typeRegistry } = (await ctx.core).savedObjects; const findResponse = await client.find({ page: query.page, diff --git a/x-pack/plugins/saved_objects_tagging/server/routes/tags/create_tag.ts b/x-pack/plugins/saved_objects_tagging/server/routes/tags/create_tag.ts index 0001ff422a2bc..7b9e6a32d3aea 100644 --- a/x-pack/plugins/saved_objects_tagging/server/routes/tags/create_tag.ts +++ b/x-pack/plugins/saved_objects_tagging/server/routes/tags/create_tag.ts @@ -23,7 +23,8 @@ export const registerCreateTagRoute = (router: TagsPluginRouter) => { }, router.handleLegacyErrors(async (ctx, req, res) => { try { - const tag = await ctx.tags!.tagsClient.create(req.body); + const { tagsClient } = await ctx.tags; + const tag = await tagsClient.create(req.body); return res.ok({ body: { tag, diff --git a/x-pack/plugins/saved_objects_tagging/server/routes/tags/delete_tag.ts b/x-pack/plugins/saved_objects_tagging/server/routes/tags/delete_tag.ts index 42077eb05d13e..505ecfd4974a0 100644 --- a/x-pack/plugins/saved_objects_tagging/server/routes/tags/delete_tag.ts +++ b/x-pack/plugins/saved_objects_tagging/server/routes/tags/delete_tag.ts @@ -20,7 +20,8 @@ export const registerDeleteTagRoute = (router: TagsPluginRouter) => { }, router.handleLegacyErrors(async (ctx, req, res) => { const { id } = req.params; - await ctx.tags!.tagsClient.delete(id); + const { tagsClient } = await ctx.tags; + await tagsClient.delete(id); return res.ok(); }) ); diff --git a/x-pack/plugins/saved_objects_tagging/server/routes/tags/get_all_tags.ts b/x-pack/plugins/saved_objects_tagging/server/routes/tags/get_all_tags.ts index af3b39f26f2a9..011d764983faf 100644 --- a/x-pack/plugins/saved_objects_tagging/server/routes/tags/get_all_tags.ts +++ b/x-pack/plugins/saved_objects_tagging/server/routes/tags/get_all_tags.ts @@ -14,7 +14,8 @@ export const registerGetAllTagsRoute = (router: TagsPluginRouter) => { validate: {}, }, router.handleLegacyErrors(async (ctx, req, res) => { - const tags = await ctx.tags!.tagsClient.getAll(); + const { tagsClient } = await ctx.tags; + const tags = await tagsClient.getAll(); return res.ok({ body: { tags, diff --git a/x-pack/plugins/saved_objects_tagging/server/routes/tags/get_tag.ts b/x-pack/plugins/saved_objects_tagging/server/routes/tags/get_tag.ts index 8080b6ea22a6f..4488d4dae6e2b 100644 --- a/x-pack/plugins/saved_objects_tagging/server/routes/tags/get_tag.ts +++ b/x-pack/plugins/saved_objects_tagging/server/routes/tags/get_tag.ts @@ -20,7 +20,8 @@ export const registerGetTagRoute = (router: TagsPluginRouter) => { }, router.handleLegacyErrors(async (ctx, req, res) => { const { id } = req.params; - const tag = await ctx.tags!.tagsClient.get(id); + const { tagsClient } = await ctx.tags; + const tag = await tagsClient.get(id); return res.ok({ body: { tag, diff --git a/x-pack/plugins/saved_objects_tagging/server/routes/tags/update_tag.ts b/x-pack/plugins/saved_objects_tagging/server/routes/tags/update_tag.ts index d357c42d1924f..67b7d7a6acbda 100644 --- a/x-pack/plugins/saved_objects_tagging/server/routes/tags/update_tag.ts +++ b/x-pack/plugins/saved_objects_tagging/server/routes/tags/update_tag.ts @@ -27,7 +27,8 @@ export const registerUpdateTagRoute = (router: TagsPluginRouter) => { router.handleLegacyErrors(async (ctx, req, res) => { const { id } = req.params; try { - const tag = await ctx.tags!.tagsClient.update(id, req.body); + const { tagsClient } = await ctx.tags; + const tag = await tagsClient.update(id, req.body); return res.ok({ body: { tag, diff --git a/x-pack/plugins/saved_objects_tagging/server/services/assignments/assignment_service.test.ts b/x-pack/plugins/saved_objects_tagging/server/services/assignments/assignment_service.test.ts index 3cc4c00da5b30..61e4fbc2fb651 100644 --- a/x-pack/plugins/saved_objects_tagging/server/services/assignments/assignment_service.test.ts +++ b/x-pack/plugins/saved_objects_tagging/server/services/assignments/assignment_service.test.ts @@ -28,245 +28,350 @@ describe('AssignmentService', () => { authorization = securityMock.createSetup().authz; savedObjectClient = savedObjectsClientMock.create(); typeRegistry = savedObjectsTypeRegistryMock.create(); - - service = new AssignmentService({ - request, - typeRegistry, - authorization, - client: savedObjectClient, - }); }); afterEach(() => { getUpdatableSavedObjectTypesMock.mockReset(); }); - describe('#updateTagAssignments', () => { + describe('scoped service', () => { beforeEach(() => { - getUpdatableSavedObjectTypesMock.mockImplementation(({ types }) => Promise.resolve(types)); - - savedObjectClient.bulkGet.mockResolvedValue({ - saved_objects: [], + service = new AssignmentService({ + request, + typeRegistry, + authorization, + client: savedObjectClient, }); }); - it('throws an error if trying to assign non-taggable types', async () => { - await expect( - service.updateTagAssignments({ - tags: ['tag-1', 'tag-2'], - assign: [ - { type: 'dashboard', id: 'dash-1' }, - { type: 'not-supported', id: 'foo' }, - ], - unassign: [], - }) - ).rejects.toThrowErrorMatchingInlineSnapshot(`"Unsupported type [not-supported]"`); + it('throws when instantiated with `internal: false` if no request is provided', () => { + expect(() => { + new AssignmentService({ + internal: false, + typeRegistry, + authorization, + client: savedObjectClient, + }); + }).toThrowErrorMatchingInlineSnapshot(`"request required for non-internal usages"`); }); - it('throws an error if trying to assign non-assignable types', async () => { - getUpdatableSavedObjectTypesMock.mockResolvedValue(['dashboard']); + describe('#updateTagAssignments', () => { + beforeEach(() => { + getUpdatableSavedObjectTypesMock.mockImplementation(({ types }) => Promise.resolve(types)); + + savedObjectClient.bulkGet.mockResolvedValue({ + saved_objects: [], + }); + }); + + it('throws an error if trying to assign non-taggable types', async () => { + await expect( + service.updateTagAssignments({ + tags: ['tag-1', 'tag-2'], + assign: [ + { type: 'dashboard', id: 'dash-1' }, + { type: 'not-supported', id: 'foo' }, + ], + unassign: [], + }) + ).rejects.toThrowErrorMatchingInlineSnapshot(`"Unsupported type [not-supported]"`); + }); - await expect( - service.updateTagAssignments({ + it('throws an error if trying to assign non-assignable types', async () => { + getUpdatableSavedObjectTypesMock.mockResolvedValue(['dashboard']); + + await expect( + service.updateTagAssignments({ + tags: ['tag-1', 'tag-2'], + assign: [ + { type: 'dashboard', id: 'dash-1' }, + { type: 'map', id: 'map-1' }, + ], + unassign: [], + }) + ).rejects.toThrowErrorMatchingInlineSnapshot(`"Forbidden type [map]"`); + }); + + it('calls `soClient.bulkGet` with the correct parameters', async () => { + await service.updateTagAssignments({ tags: ['tag-1', 'tag-2'], - assign: [ - { type: 'dashboard', id: 'dash-1' }, - { type: 'map', id: 'map-1' }, - ], - unassign: [], - }) - ).rejects.toThrowErrorMatchingInlineSnapshot(`"Forbidden type [map]"`); - }); + assign: [{ type: 'dashboard', id: 'dash-1' }], + unassign: [{ type: 'map', id: 'map-1' }], + }); - it('calls `soClient.bulkGet` with the correct parameters', async () => { - await service.updateTagAssignments({ - tags: ['tag-1', 'tag-2'], - assign: [{ type: 'dashboard', id: 'dash-1' }], - unassign: [{ type: 'map', id: 'map-1' }], + expect(savedObjectClient.bulkGet).toHaveBeenCalledTimes(1); + expect(savedObjectClient.bulkGet).toHaveBeenCalledWith([ + { type: 'dashboard', id: 'dash-1', fields: [] }, + { type: 'map', id: 'map-1', fields: [] }, + ]); }); - expect(savedObjectClient.bulkGet).toHaveBeenCalledTimes(1); - expect(savedObjectClient.bulkGet).toHaveBeenCalledWith([ - { type: 'dashboard', id: 'dash-1', fields: [] }, - { type: 'map', id: 'map-1', fields: [] }, - ]); - }); + it('throws an error if any result from `soClient.bulkGet` has an error', async () => { + savedObjectClient.bulkGet.mockResolvedValue({ + saved_objects: [ + createSavedObject({ type: 'dashboard', id: 'dash-1' }), + createSavedObject({ + type: 'map', + id: 'map-1', + error: { + statusCode: 404, + message: 'not found', + error: 'object was not found', + }, + }), + ], + }); - it('throws an error if any result from `soClient.bulkGet` has an error', async () => { - savedObjectClient.bulkGet.mockResolvedValue({ - saved_objects: [ - createSavedObject({ type: 'dashboard', id: 'dash-1' }), - createSavedObject({ - type: 'map', - id: 'map-1', - error: { - statusCode: 404, - message: 'not found', - error: 'object was not found', - }, - }), - ], + await expect( + service.updateTagAssignments({ + tags: ['tag-1', 'tag-2'], + assign: [{ type: 'dashboard', id: 'dash-1' }], + unassign: [{ type: 'map', id: 'map-1' }], + }) + ).rejects.toThrowErrorMatchingInlineSnapshot(`"not found"`); }); - await expect( - service.updateTagAssignments({ + it('calls `soClient.bulkUpdate` to update the references', async () => { + savedObjectClient.bulkGet.mockResolvedValue({ + saved_objects: [ + createSavedObject({ + type: 'dashboard', + id: 'dash-1', + references: [], + }), + createSavedObject({ + type: 'map', + id: 'map-1', + references: [createReference('dashboard', 'dash-1'), createReference('tag', 'tag-1')], + }), + ], + }); + + await service.updateTagAssignments({ tags: ['tag-1', 'tag-2'], assign: [{ type: 'dashboard', id: 'dash-1' }], unassign: [{ type: 'map', id: 'map-1' }], - }) - ).rejects.toThrowErrorMatchingInlineSnapshot(`"not found"`); - }); + }); - it('calls `soClient.bulkUpdate` to update the references', async () => { - savedObjectClient.bulkGet.mockResolvedValue({ - saved_objects: [ - createSavedObject({ + expect(savedObjectClient.bulkUpdate).toHaveBeenCalledTimes(1); + expect(savedObjectClient.bulkUpdate).toHaveBeenCalledWith([ + { type: 'dashboard', id: 'dash-1', - references: [], - }), - createSavedObject({ + attributes: {}, + references: [createReference('tag', 'tag-1'), createReference('tag', 'tag-2')], + }, + { type: 'map', id: 'map-1', - references: [createReference('dashboard', 'dash-1'), createReference('tag', 'tag-1')], - }), - ], + attributes: {}, + references: [createReference('dashboard', 'dash-1')], + }, + ]); }); + }); - await service.updateTagAssignments({ - tags: ['tag-1', 'tag-2'], - assign: [{ type: 'dashboard', id: 'dash-1' }], - unassign: [{ type: 'map', id: 'map-1' }], + describe('#findAssignableObjects', () => { + beforeEach(() => { + getUpdatableSavedObjectTypesMock.mockImplementation(({ types }) => Promise.resolve(types)); + typeRegistry.getType.mockImplementation( + (name) => + ({ + management: { + defaultSearchField: `${name}-search-field`, + }, + } as any) + ); + savedObjectClient.find.mockResolvedValue({ + saved_objects: [], + total: 0, + page: 1, + per_page: 20, + }); }); - expect(savedObjectClient.bulkUpdate).toHaveBeenCalledTimes(1); - expect(savedObjectClient.bulkUpdate).toHaveBeenCalledWith([ - { - type: 'dashboard', - id: 'dash-1', - attributes: {}, - references: [createReference('tag', 'tag-1'), createReference('tag', 'tag-2')], - }, - { - type: 'map', - id: 'map-1', - attributes: {}, - references: [createReference('dashboard', 'dash-1')], - }, - ]); - }); - }); + it('calls `soClient.find` with the correct parameters', async () => { + await service.findAssignableObjects({ + types: ['dashboard', 'map'], + search: 'term', + maxResults: 20, + }); - describe('#findAssignableObjects', () => { - beforeEach(() => { - getUpdatableSavedObjectTypesMock.mockImplementation(({ types }) => Promise.resolve(types)); - typeRegistry.getType.mockImplementation( - (name) => - ({ - management: { - defaultSearchField: `${name}-search-field`, - }, - } as any) - ); - savedObjectClient.find.mockResolvedValue({ - saved_objects: [], - total: 0, - page: 1, - per_page: 20, + expect(savedObjectClient.find).toHaveBeenCalledTimes(1); + expect(savedObjectClient.find).toHaveBeenCalledWith({ + page: 1, + perPage: 20, + search: 'term', + type: ['dashboard', 'map'], + searchFields: ['dashboard-search-field', 'map-search-field'], + }); }); - }); - it('calls `soClient.find` with the correct parameters', async () => { - await service.findAssignableObjects({ - types: ['dashboard', 'map'], - search: 'term', - maxResults: 20, + it('filters the non-assignable types', async () => { + getUpdatableSavedObjectTypesMock.mockResolvedValue(['dashboard']); + + await service.findAssignableObjects({ + types: ['dashboard', 'map'], + search: 'term', + maxResults: 20, + }); + + expect(savedObjectClient.find).toHaveBeenCalledTimes(1); + expect(savedObjectClient.find).toHaveBeenCalledWith( + expect.objectContaining({ + type: ['dashboard'], + }) + ); }); - expect(savedObjectClient.find).toHaveBeenCalledTimes(1); - expect(savedObjectClient.find).toHaveBeenCalledWith({ - page: 1, - perPage: 20, - search: 'term', - type: ['dashboard', 'map'], - searchFields: ['dashboard-search-field', 'map-search-field'], + it('converts the results returned from `soClient.find`', async () => { + savedObjectClient.find.mockResolvedValue({ + saved_objects: [ + createSavedObject({ + type: 'dashboard', + id: 'dash-1', + }), + createSavedObject({ + type: 'map', + id: 'dash-2', + }), + ] as any[], + total: 2, + page: 1, + per_page: 20, + }); + + const results = await service.findAssignableObjects({ + types: ['dashboard', 'map'], + search: 'term', + maxResults: 20, + }); + + expect(results.map(({ type, id }) => ({ type, id }))).toEqual([ + { type: 'dashboard', id: 'dash-1' }, + { type: 'map', id: 'dash-2' }, + ]); }); }); - it('filters the non-assignable types', async () => { - getUpdatableSavedObjectTypesMock.mockResolvedValue(['dashboard']); + describe('#getAssignableTypes', () => { + it('calls `getUpdatableSavedObjectTypes` with the correct parameters', async () => { + await service.getAssignableTypes(['type-a', 'type-b']); - await service.findAssignableObjects({ - types: ['dashboard', 'map'], - search: 'term', - maxResults: 20, + expect(getUpdatableSavedObjectTypesMock).toHaveBeenCalledTimes(1); + expect(getUpdatableSavedObjectTypesMock).toHaveBeenCalledWith({ + request, + authorization, + types: ['type-a', 'type-b'], + }); }); + it('calls `getUpdatableSavedObjectTypes` with `taggableTypes` when `types` is not specified ', async () => { + await service.getAssignableTypes(); - expect(savedObjectClient.find).toHaveBeenCalledTimes(1); - expect(savedObjectClient.find).toHaveBeenCalledWith( - expect.objectContaining({ - type: ['dashboard'], - }) - ); + expect(getUpdatableSavedObjectTypesMock).toHaveBeenCalledTimes(1); + expect(getUpdatableSavedObjectTypesMock).toHaveBeenCalledWith({ + request, + authorization, + types: taggableTypes, + }); + }); + it('forward the result of `getUpdatableSavedObjectTypes`', async () => { + getUpdatableSavedObjectTypesMock.mockReturnValue(['updatable-a', 'updatable-b']); + + const assignableTypes = await service.getAssignableTypes(); + + expect(assignableTypes).toEqual(['updatable-a', 'updatable-b']); + }); }); + }); - it('converts the results returned from `soClient.find`', async () => { - savedObjectClient.find.mockResolvedValue({ - saved_objects: [ - createSavedObject({ - type: 'dashboard', - id: 'dash-1', - }), - createSavedObject({ - type: 'map', - id: 'dash-2', - }), - ] as any[], - total: 2, - page: 1, - per_page: 20, + describe('internal service', () => { + beforeEach(() => { + service = new AssignmentService({ + internal: true, + typeRegistry, + authorization, + client: savedObjectClient, }); + }); - const results = await service.findAssignableObjects({ - types: ['dashboard', 'map'], - search: 'term', - maxResults: 20, + describe('#updateTagAssignments', () => { + beforeEach(() => { + getUpdatableSavedObjectTypesMock.mockImplementation(({ types }) => Promise.resolve(types)); + + savedObjectClient.bulkGet.mockResolvedValue({ + saved_objects: [], + }); }); - expect(results.map(({ type, id }) => ({ type, id }))).toEqual([ - { type: 'dashboard', id: 'dash-1' }, - { type: 'map', id: 'dash-2' }, - ]); - }); - }); + it('does not calls `getUpdatableSavedObjectTypes`', async () => { + getUpdatableSavedObjectTypesMock.mockResolvedValue(['dashboard']); - describe('#getAssignableTypes', () => { - it('calls `getUpdatableSavedObjectTypes` with the correct parameters', async () => { - await service.getAssignableTypes(['type-a', 'type-b']); + await service.updateTagAssignments({ + tags: ['tag-1', 'tag-2'], + assign: [ + { type: 'dashboard', id: 'dash-1' }, + { type: 'map', id: 'map-1' }, + ], + unassign: [], + }); - expect(getUpdatableSavedObjectTypesMock).toHaveBeenCalledTimes(1); - expect(getUpdatableSavedObjectTypesMock).toHaveBeenCalledWith({ - request, - authorization, - types: ['type-a', 'type-b'], + expect(getUpdatableSavedObjectTypesMock).not.toHaveBeenCalled(); + expect(savedObjectClient.bulkGet).toHaveBeenCalledTimes(1); + expect(savedObjectClient.bulkGet).toHaveBeenCalledWith([ + { type: 'dashboard', id: 'dash-1', fields: [] }, + { type: 'map', id: 'map-1', fields: [] }, + ]); }); }); - it('calls `getUpdatableSavedObjectTypes` with `taggableTypes` when `types` is not specified ', async () => { - await service.getAssignableTypes(); - expect(getUpdatableSavedObjectTypesMock).toHaveBeenCalledTimes(1); - expect(getUpdatableSavedObjectTypesMock).toHaveBeenCalledWith({ - request, - authorization, - types: taggableTypes, + describe('#findAssignableObjects', () => { + beforeEach(() => { + typeRegistry.getType.mockImplementation( + (name) => + ({ + management: { + defaultSearchField: `${name}-search-field`, + }, + } as any) + ); + savedObjectClient.find.mockResolvedValue({ + saved_objects: [], + total: 0, + page: 1, + per_page: 20, + }); + }); + + it('does not calls `getUpdatableSavedObjectTypes`', async () => { + getUpdatableSavedObjectTypesMock.mockResolvedValue(['dashboard']); + + await service.findAssignableObjects({ + types: ['dashboard', 'map'], + search: 'term', + maxResults: 20, + }); + + expect(getUpdatableSavedObjectTypesMock).not.toHaveBeenCalled(); + expect(savedObjectClient.find).toHaveBeenCalledTimes(1); + expect(savedObjectClient.find).toHaveBeenCalledWith( + expect.objectContaining({ + type: ['dashboard', 'map'], + }) + ); }); }); - it('forward the result of `getUpdatableSavedObjectTypes`', async () => { - getUpdatableSavedObjectTypesMock.mockReturnValue(['updatable-a', 'updatable-b']); - const assignableTypes = await service.getAssignableTypes(); + describe('#getAssignableTypes', () => { + it('does not calls `getUpdatableSavedObjectTypes`', async () => { + await service.getAssignableTypes(['type-a', 'type-b']); - expect(assignableTypes).toEqual(['updatable-a', 'updatable-b']); + expect(getUpdatableSavedObjectTypesMock).not.toHaveBeenCalled(); + }); + it('returns the list of all taggable types', async () => { + const assignableTypes = await service.getAssignableTypes(); + expect(assignableTypes).toEqual(taggableTypes); + }); }); }); }); diff --git a/x-pack/plugins/saved_objects_tagging/server/services/assignments/assignment_service.ts b/x-pack/plugins/saved_objects_tagging/server/services/assignments/assignment_service.ts index d6d14f68357be..09a726db856c2 100644 --- a/x-pack/plugins/saved_objects_tagging/server/services/assignments/assignment_service.ts +++ b/x-pack/plugins/saved_objects_tagging/server/services/assignments/assignment_service.ts @@ -28,10 +28,11 @@ import { AssignmentError } from './errors'; import { toAssignableObject } from './utils'; interface AssignmentServiceOptions { - request: KibanaRequest; + request?: KibanaRequest; client: SavedObjectsClientContract; typeRegistry: ISavedObjectTypeRegistry; authorization?: SecurityPluginSetup['authz']; + internal?: boolean; } export type IAssignmentService = PublicMethodsOf; @@ -40,9 +41,20 @@ export class AssignmentService { private readonly soClient: SavedObjectsClientContract; private readonly typeRegistry: ISavedObjectTypeRegistry; private readonly authorization?: SecurityPluginSetup['authz']; - private readonly request: KibanaRequest; - - constructor({ client, typeRegistry, authorization, request }: AssignmentServiceOptions) { + private readonly request?: KibanaRequest; + private readonly internal: boolean; + + constructor({ + client, + typeRegistry, + authorization, + request, + internal = false, + }: AssignmentServiceOptions) { + if (!internal && !request) { + throw new Error('request required for non-internal usages'); + } + this.internal = internal; this.soClient = client; this.typeRegistry = typeRegistry; this.authorization = authorization; @@ -84,8 +96,11 @@ export class AssignmentService { } public async getAssignableTypes(types?: string[]) { + if (this.internal) { + return types ?? taggableTypes; + } return getUpdatableSavedObjectTypes({ - request: this.request, + request: this.request!, types: types ?? taggableTypes, authorization: this.authorization, }); diff --git a/x-pack/plugins/saved_objects_tagging/server/types.ts b/x-pack/plugins/saved_objects_tagging/server/types.ts index 92618c7d3fb53..0bc023214151d 100644 --- a/x-pack/plugins/saved_objects_tagging/server/types.ts +++ b/x-pack/plugins/saved_objects_tagging/server/types.ts @@ -5,7 +5,11 @@ * 2.0. */ -import type { IRouter, RequestHandlerContext } from '@kbn/core/server'; +import type { + IRouter, + CustomRequestHandlerContext, + SavedObjectsClientContract, +} from '@kbn/core/server'; import { ITagsClient } from '../common/types'; import { IAssignmentService } from './services'; @@ -14,12 +18,43 @@ export interface ITagsRequestHandlerContext { assignmentService: IAssignmentService; } +/** @public */ +export interface CreateTagClientOptions { + client: SavedObjectsClientContract; +} + +/** @public */ +export interface CreateTagAssignmentServiceOptions { + client: SavedObjectsClientContract; +} + +/** @public */ +export interface SavedObjectTaggingStart { + /** + * Creates a TagClient bound to the provided SavedObject client. + */ + createTagClient: (options: CreateTagClientOptions) => ITagsClient; + + /** + * Creates an internal AssignmentService bound to the provided SavedObject client. + * + * @remark: As assignment services created via this API will not be performing authz check to ensure + * that the current user is allowed to update the assigned/unassigned objects. + * This API is only meant to be used to perform operations on behalf of the 'internal' Kibana user. + * When trying to assign or unassign tags on behalf of a user, use the `tags` request handler context + * instead. + */ + createInternalAssignmentService: ( + options: CreateTagAssignmentServiceOptions + ) => IAssignmentService; +} + /** * @internal */ -export interface TagsHandlerContext extends RequestHandlerContext { +export type TagsHandlerContext = CustomRequestHandlerContext<{ tags: ITagsRequestHandlerContext; -} +}>; /** * @internal diff --git a/x-pack/plugins/screenshotting/common/errors.ts b/x-pack/plugins/screenshotting/common/errors.ts index 50effb03ee1da..5284e808c7993 100644 --- a/x-pack/plugins/screenshotting/common/errors.ts +++ b/x-pack/plugins/screenshotting/common/errors.ts @@ -13,3 +13,5 @@ export class FailedToSpawnBrowserError extends Error {} export class BrowserClosedUnexpectedly extends Error {} export class FailedToCaptureScreenshot extends Error {} + +export class InsufficientMemoryAvailableOnCloudError extends Error {} diff --git a/x-pack/plugins/screenshotting/kibana.json b/x-pack/plugins/screenshotting/kibana.json index f376409687311..37f962539446b 100644 --- a/x-pack/plugins/screenshotting/kibana.json +++ b/x-pack/plugins/screenshotting/kibana.json @@ -7,6 +7,7 @@ "githubTeam": "kibana-reporting-services" }, "description": "Kibana Screenshotting Plugin", + "optionalPlugins": ["cloud"], "requiredPlugins": ["expressions", "screenshotMode"], "configPath": ["xpack", "screenshotting"], "server": true, diff --git a/x-pack/plugins/screenshotting/server/cloud/index.ts b/x-pack/plugins/screenshotting/server/cloud/index.ts new file mode 100644 index 0000000000000..9ce60bf13c4bb --- /dev/null +++ b/x-pack/plugins/screenshotting/server/cloud/index.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Logger } from '@kbn/core/server'; +import type { CloudSetup } from '@kbn/cloud-plugin/server'; + +const MIN_CLOUD_MEM_GB: number = 2; +const MIN_CLOUD_MEM_MB: number = MIN_CLOUD_MEM_GB * 1024; + +/** + * If we are on Cloud we need to ensure that we have sufficient memory available, + * if we do not Chromium cannot start. See {@link MIN_CLOUD_MEM_MB}. + * + */ +export function systemHasInsufficientMemory( + cloud: undefined | CloudSetup, + logger: Logger +): boolean { + if (cloud?.isCloudEnabled && typeof cloud?.instanceSizeMb === 'number') { + const instanceSizeMb = cloud.instanceSizeMb; + logger.info(`Memory limit read from cloud (in MB): ${instanceSizeMb}`); + return instanceSizeMb < MIN_CLOUD_MEM_MB; + } + return false; +} diff --git a/x-pack/plugins/screenshotting/server/plugin.ts b/x-pack/plugins/screenshotting/server/plugin.ts index 23f688206d394..27da8b3430e6d 100755 --- a/x-pack/plugins/screenshotting/server/plugin.ts +++ b/x-pack/plugins/screenshotting/server/plugin.ts @@ -16,6 +16,7 @@ import type { PluginInitializerContext, } from '@kbn/core/server'; import type { ScreenshotModePluginSetup } from '@kbn/screenshot-mode-plugin/server'; +import type { CloudSetup } from '@kbn/cloud-plugin/server'; import { ChromiumArchivePaths, HeadlessChromiumDriverFactory, install } from './browsers'; import { ConfigType, createConfig } from './config'; import { Screenshots } from './screenshots'; @@ -23,6 +24,7 @@ import { getChromiumPackage } from './utils'; interface SetupDeps { screenshotMode: ScreenshotModePluginSetup; + cloud?: CloudSetup; } /** @@ -57,7 +59,7 @@ export class ScreenshottingPlugin implements Plugin { const paths = new ChromiumArchivePaths(); @@ -85,7 +87,14 @@ export class ScreenshottingPlugin implements Plugin {}); diff --git a/x-pack/plugins/screenshotting/server/screenshots/index.test.ts b/x-pack/plugins/screenshotting/server/screenshots/index.test.ts index 3833cfcc45932..1cc328509ab72 100644 --- a/x-pack/plugins/screenshotting/server/screenshots/index.test.ts +++ b/x-pack/plugins/screenshotting/server/screenshots/index.test.ts @@ -14,10 +14,12 @@ import { SCREENSHOTTING_EXPRESSION, SCREENSHOTTING_EXPRESSION_INPUT, } from '../../common'; +import type { CloudSetup } from '@kbn/cloud-plugin/server'; import type { HeadlessChromiumDriverFactory } from '../browsers'; import { createMockBrowserDriver, createMockBrowserDriverFactory } from '../browsers/mock'; import type { ConfigType } from '../config'; import type { PngScreenshotOptions } from '../formats'; +import * as errors from '../../common/errors'; import * as Layouts from '../layouts/create_layout'; import { createMockLayout } from '../layouts/mock'; import { CONTEXT_ELEMENTATTRIBUTES } from './constants'; @@ -34,9 +36,15 @@ describe('Screenshot Observable Pipeline', () => { let packageInfo: Readonly; let options: ScreenshotOptions; let screenshots: Screenshots; + let cloud: CloudSetup; let config: ConfigType; beforeEach(async () => { + cloud = { + isCloudEnabled: false, + instanceSizeMb: 1024, // 1GB + apm: {}, + } as CloudSetup; driver = createMockBrowserDriver(); driverFactory = createMockBrowserDriverFactory(driver); http = httpServiceMock.createSetupContract(); @@ -71,7 +79,7 @@ describe('Screenshot Observable Pipeline', () => { browser: {} as ConfigType['browser'], }; - screenshots = new Screenshots(driverFactory, logger, packageInfo, http, config); + screenshots = new Screenshots(driverFactory, logger, packageInfo, http, config, cloud); jest.spyOn(Layouts, 'createLayout').mockReturnValue(layout); @@ -185,4 +193,41 @@ describe('Screenshot Observable Pipeline', () => { expect(result.results).toMatchSnapshot(); }); }); + + describe('cloud', () => { + beforeEach(() => { + cloud.isCloudEnabled = true; + }); + + afterEach(() => { + jest.resetAllMocks(); + }); + + it('throws an error when OS memory is under 1GB on cloud', async () => { + await expect( + lastValueFrom( + screenshots.getScreenshots({ + ...options, + expression: 'kibana', + input: 'something', + } as PngScreenshotOptions) + ) + ).rejects.toEqual(new errors.InsufficientMemoryAvailableOnCloudError()); + + expect(driver.open).toHaveBeenCalledTimes(0); + }); + + it('generates a report when OS memory is 2GB on cloud', async () => { + cloud.instanceSizeMb = 2048; + await lastValueFrom( + screenshots.getScreenshots({ + ...options, + expression: 'kibana', + input: 'something', + } as PngScreenshotOptions) + ); + + expect(driver.open).toHaveBeenCalledTimes(1); + }); + }); }); diff --git a/x-pack/plugins/screenshotting/server/screenshots/index.ts b/x-pack/plugins/screenshotting/server/screenshots/index.ts index 3fa0f1d222c3d..b98270547dbec 100644 --- a/x-pack/plugins/screenshotting/server/screenshots/index.ts +++ b/x-pack/plugins/screenshotting/server/screenshots/index.ts @@ -12,7 +12,7 @@ import type { Transaction } from 'elastic-apm-node'; import apm from 'elastic-apm-node'; import ipaddr from 'ipaddr.js'; import { defaultsDeep, sum } from 'lodash'; -import { from, Observable, of } from 'rxjs'; +import { from, Observable, of, throwError } from 'rxjs'; import { catchError, concatMap, @@ -24,12 +24,15 @@ import { tap, toArray, } from 'rxjs/operators'; +import type { CloudSetup } from '@kbn/cloud-plugin/server'; import { LayoutParams, SCREENSHOTTING_APP_ID, SCREENSHOTTING_EXPRESSION, SCREENSHOTTING_EXPRESSION_INPUT, + errors, } from '../../common'; +import { systemHasInsufficientMemory } from '../cloud'; import type { HeadlessChromiumDriverFactory, PerformanceMetrics } from '../browsers'; import type { ConfigType } from '../config'; import { durationToNumber } from '../config'; @@ -101,7 +104,8 @@ export class Screenshots { private readonly logger: Logger, private readonly packageInfo: PackageInfo, private readonly http: HttpServiceSetup, - private readonly config: ConfigType + private readonly config: ConfigType, + private readonly cloud?: CloudSetup ) { this.semaphore = new Semaphore(config.poolSize); } @@ -228,10 +232,17 @@ export class Screenshots { ); } + systemHasInsufficientMemory(): boolean { + return systemHasInsufficientMemory(this.cloud, this.logger.get('cloud')); + } + getScreenshots(options: PngScreenshotOptions): Observable; getScreenshots(options: PdfScreenshotOptions): Observable; getScreenshots(options: ScreenshotOptions): Observable; getScreenshots(options: ScreenshotOptions): Observable { + if (this.systemHasInsufficientMemory()) { + return throwError(() => new errors.InsufficientMemoryAvailableOnCloudError()); + } const transaction = apm.startTransaction('screenshot-pipeline', 'screenshotting'); const layout = this.createLayout(transaction, options); const captureOptions = this.getCaptureOptions(options); diff --git a/x-pack/plugins/screenshotting/tsconfig.json b/x-pack/plugins/screenshotting/tsconfig.json index d385f72809ce2..af98e0fcc3244 100644 --- a/x-pack/plugins/screenshotting/tsconfig.json +++ b/x-pack/plugins/screenshotting/tsconfig.json @@ -16,5 +16,6 @@ { "path": "../../../src/core/tsconfig.json" }, { "path": "../../../src/plugins/expressions/tsconfig.json" }, { "path": "../../../src/plugins/screenshot_mode/tsconfig.json" }, + { "path": "../cloud/tsconfig.json" }, ] } diff --git a/x-pack/plugins/searchprofiler/server/routes/profile.ts b/x-pack/plugins/searchprofiler/server/routes/profile.ts index 22c97e240a3b9..9e76bf0df96a1 100644 --- a/x-pack/plugins/searchprofiler/server/routes/profile.ts +++ b/x-pack/plugins/searchprofiler/server/routes/profile.ts @@ -43,7 +43,7 @@ export const register = ({ router, getLicenseStatus, log }: RouteDependencies) = }; try { - const client = ctx.core.elasticsearch.client.asCurrentUser; + const client = (await ctx.core).elasticsearch.client.asCurrentUser; const resp = await client.search(body); return response.ok({ diff --git a/x-pack/plugins/security/public/management/roles/edit_role/edit_role_page.test.tsx b/x-pack/plugins/security/public/management/roles/edit_role/edit_role_page.test.tsx index ae64ad4655ba5..72612904f1c08 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/edit_role_page.test.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/edit_role_page.test.tsx @@ -11,7 +11,7 @@ import React from 'react'; import type { Capabilities } from '@kbn/core/public'; import { coreMock, scopedHistoryMock } from '@kbn/core/public/mocks'; -import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; +import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; import { KibanaFeature } from '@kbn/features-plugin/public'; import type { Space } from '@kbn/spaces-plugin/public'; import { mountWithIntl, nextTick } from '@kbn/test-jest-helpers'; @@ -139,7 +139,7 @@ function getProps({ const rolesAPIClient = rolesAPIClientMock.create(); rolesAPIClient.getRole.mockResolvedValue(role); - const dataViews = dataPluginMock.createStartContract().dataViews; + const dataViews = dataViewPluginMocks.createStartContract(); // `undefined` titles can technically happen via import/export or other manual manipulation dataViews.getTitles = jest.fn().mockResolvedValue(['foo*', 'bar*', undefined]); @@ -352,7 +352,7 @@ describe('', () => { }); it('can render if index patterns are not available', async () => { - const dataViews = dataPluginMock.createStartContract().dataViews; + const dataViews = dataViewPluginMocks.createStartContract(); dataViews.getTitles = jest.fn().mockRejectedValue({ response: { status: 403 } }); const wrapper = mountWithIntl( diff --git a/x-pack/plugins/security/public/management/roles/edit_role/edit_role_page.tsx b/x-pack/plugins/security/public/management/roles/edit_role/edit_role_page.tsx index 1cda335ace204..cc9803063b860 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/edit_role_page.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/edit_role_page.tsx @@ -31,7 +31,7 @@ import type { NotificationsStart, ScopedHistory, } from '@kbn/core/public'; -import type { DataViewsContract } from '@kbn/data-plugin/public'; +import type { DataViewsContract } from '@kbn/data-views-plugin/public'; import type { KibanaFeature } from '@kbn/features-plugin/common'; import type { FeaturesPluginStart } from '@kbn/features-plugin/public'; import { i18n } from '@kbn/i18n'; diff --git a/x-pack/plugins/security/public/management/roles/edit_role/spaces_popover_list/spaces_popover_list.tsx b/x-pack/plugins/security/public/management/roles/edit_role/spaces_popover_list/spaces_popover_list.tsx index 20c2d3f4c4bc8..7e1c5eb545a28 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/spaces_popover_list/spaces_popover_list.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/spaces_popover_list/spaces_popover_list.tsx @@ -136,7 +136,6 @@ export class SpacesPopoverList extends Component { key={`spcMenuList`} data-search-term={searchTerm} className="spcMenu__spacesList" - hasFocus={this.state.allowSpacesListFocus} initialFocusedItemIndex={this.state.allowSpacesListFocus ? 0 : undefined} items={items} /> diff --git a/x-pack/plugins/security/public/nav_control/nav_control_service.test.ts b/x-pack/plugins/security/public/nav_control/nav_control_service.test.ts index 3e871c4979804..c801a1f8f4e1b 100644 --- a/x-pack/plugins/security/public/nav_control/nav_control_service.test.ts +++ b/x-pack/plugins/security/public/nav_control/nav_control_service.test.ts @@ -85,7 +85,7 @@ describe('SecurityNavControlService', () => { >
} - handleClick={onClose} - data-test-subj="flyout-header-osquery" - /> + + +

{ACTION_OSQUERY}

+
- + @@ -55,4 +96,4 @@ export const OsqueryFlyout: React.FC = ({ agentId, onClose } ); }; -OsqueryFlyout.displayName = 'OsqueryFlyout'; +export const OsqueryFlyout = React.memo(OsqueryFlyoutComponent); diff --git a/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_flyout_header.tsx b/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_flyout_header.tsx deleted file mode 100644 index 7a0f7f15f3e74..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_flyout_header.tsx +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { EuiButtonEmpty, EuiText, EuiTitle } from '@elastic/eui'; -import { BACK_TO_ALERT_DETAILS } from './translations'; - -interface IProps { - primaryText: React.ReactElement; - handleClick: () => void; -} - -const OsqueryEventDetailsHeaderComponent: React.FC = ({ primaryText, handleClick }) => { - return ( - <> - - -

{BACK_TO_ALERT_DETAILS}

-
-
- {primaryText} - - ); -}; - -export const OsqueryEventDetailsHeader = React.memo(OsqueryEventDetailsHeaderComponent); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/__snapshots__/index.test.tsx.snap index 1945562cb5b3d..e87b05a0cc8f8 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/__snapshots__/index.test.tsx.snap @@ -32,7 +32,6 @@ exports[`RuleActionsOverflow snapshots renders correctly against snapshot 1`] = > = { query: 'host.name : *', references: ['https://google.com'], severity: 'high', - tags: [ - 'host.name exists', - 'for testing', - '__internal_rule_id:82b2b065-a2ee-49fc-9d6d-781a75c3d280', - '__internal_immutable:false', - ], + tags: ['host.name exists', 'for testing'], type: 'query', to: 'now', enabled: true, @@ -428,12 +423,7 @@ export const alertsMock: AlertSearchResponse = { query: 'host.name : *', references: ['https://google.com'], severity: 'high', - tags: [ - 'host.name exists', - 'for testing', - '__internal_rule_id:82b2b065-a2ee-49fc-9d6d-781a75c3d280', - '__internal_immutable:false', - ], + tags: ['host.name exists', 'for testing'], type: 'query', to: 'now', enabled: true, @@ -634,12 +624,7 @@ export const alertsMock: AlertSearchResponse = { query: 'host.name : *', references: ['https://google.com'], severity: 'high', - tags: [ - 'host.name exists', - 'for testing', - '__internal_rule_id:82b2b065-a2ee-49fc-9d6d-781a75c3d280', - '__internal_immutable:false', - ], + tags: ['host.name exists', 'for testing'], type: 'query', to: 'now', enabled: true, @@ -838,12 +823,7 @@ export const alertsMock: AlertSearchResponse = { query: 'host.name : *', references: ['https://google.com'], severity: 'high', - tags: [ - 'host.name exists', - 'for testing', - '__internal_rule_id:82b2b065-a2ee-49fc-9d6d-781a75c3d280', - '__internal_immutable:false', - ], + tags: ['host.name exists', 'for testing'], type: 'query', to: 'now', enabled: true, diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_signal_index.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_signal_index.tsx index 12d93bc0fc5c2..594a07f20e4cb 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_signal_index.tsx +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_signal_index.tsx @@ -9,7 +9,6 @@ import { useEffect, useState } from 'react'; import { isSecurityAppError } from '@kbn/securitysolution-t-grid'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; -import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; import { createSignalIndex, getSignalIndex } from './api'; import * as i18n from './translations'; import { useAlertsPrivileges } from './use_alerts_privileges'; @@ -39,8 +38,6 @@ export const useSignalIndex = (): ReturnSignalIndex => { }); const { addError } = useAppToasts(); const { hasIndexRead } = useAlertsPrivileges(); - // TODO: Once we are past experimental phase this code should be removed - const ruleRegistryEnabled = useIsExperimentalFeatureEnabled('ruleRegistryEnabled'); useEffect(() => { let isSubscribed = true; @@ -118,7 +115,7 @@ export const useSignalIndex = (): ReturnSignalIndex => { isSubscribed = false; abortCtrl.abort(); }; - }, [addError, hasIndexRead, ruleRegistryEnabled]); + }, [addError, hasIndexRead]); return { loading, ...signalIndex }; }; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/api.test.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/api.test.ts index 3c534ca7294a5..b999040674a91 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/api.test.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/api.test.ts @@ -200,7 +200,7 @@ describe('Detections Rules API', () => { expect(fetchMock).toHaveBeenCalledWith('/api/detection_engine/rules/_find', { method: 'GET', query: { - filter: 'alert.attributes.tags: "__internal_immutable:false"', + filter: 'alert.attributes.params.immutable: false', page: 1, per_page: 20, sort_field: 'enabled', @@ -228,7 +228,7 @@ describe('Detections Rules API', () => { expect(fetchMock).toHaveBeenCalledWith('/api/detection_engine/rules/_find', { method: 'GET', query: { - filter: 'alert.attributes.tags: "__internal_immutable:true"', + filter: 'alert.attributes.params.immutable: true', page: 1, per_page: 20, sort_field: 'enabled', @@ -383,7 +383,7 @@ describe('Detections Rules API', () => { method: 'GET', query: { filter: - 'alert.attributes.tags: "__internal_immutable:false" AND alert.attributes.tags: "__internal_immutable:true" AND alert.attributes.tags:("hello" AND "world") AND (alert.attributes.name: "ruleName" OR alert.attributes.params.index: "ruleName" OR alert.attributes.params.threat.tactic.id: "ruleName" OR alert.attributes.params.threat.tactic.name: "ruleName" OR alert.attributes.params.threat.technique.id: "ruleName" OR alert.attributes.params.threat.technique.name: "ruleName" OR alert.attributes.params.threat.technique.subtechnique.id: "ruleName" OR alert.attributes.params.threat.technique.subtechnique.name: "ruleName")', + 'alert.attributes.tags:("hello" AND "world") AND (alert.attributes.name: "ruleName" OR alert.attributes.params.index: "ruleName" OR alert.attributes.params.threat.tactic.id: "ruleName" OR alert.attributes.params.threat.tactic.name: "ruleName" OR alert.attributes.params.threat.technique.id: "ruleName" OR alert.attributes.params.threat.technique.name: "ruleName" OR alert.attributes.params.threat.technique.subtechnique.id: "ruleName" OR alert.attributes.params.threat.technique.subtechnique.name: "ruleName")', page: 1, per_page: 20, sort_field: 'enabled', diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_with_fallback.test.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_with_fallback.test.tsx index 40d2e8663b618..d7c4ad8772bd2 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_with_fallback.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_with_fallback.test.tsx @@ -154,8 +154,6 @@ describe('useRuleWithFallback', () => { "tags": Array [ "host.name exists", "for testing", - "__internal_rule_id:82b2b065-a2ee-49fc-9d6d-781a75c3d280", - "__internal_immutable:false", ], "threat": Array [ Object { diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/utils.test.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/utils.test.ts index a26a4aec3ec02..dff02aa3d3a75 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/utils.test.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/utils.test.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { INTERNAL_IMMUTABLE_KEY } from '../../../../../common/constants'; import { FilterOptions } from './types'; import { convertRulesFilterToKQL } from './utils'; @@ -42,13 +41,23 @@ describe('convertRulesFilterToKQL', () => { it('handles presence of "showCustomRules" properly', () => { const kql = convertRulesFilterToKQL({ ...filterOptions, showCustomRules: true }); - expect(kql).toBe(`alert.attributes.tags: "${INTERNAL_IMMUTABLE_KEY}:false"`); + expect(kql).toBe(`alert.attributes.params.immutable: false`); }); it('handles presence of "showElasticRules" properly', () => { const kql = convertRulesFilterToKQL({ ...filterOptions, showElasticRules: true }); - expect(kql).toBe(`alert.attributes.tags: "${INTERNAL_IMMUTABLE_KEY}:true"`); + expect(kql).toBe(`alert.attributes.params.immutable: true`); + }); + + it('handles presence of "showElasticRules" and "showCustomRules" at the same time properly', () => { + const kql = convertRulesFilterToKQL({ + ...filterOptions, + showElasticRules: true, + showCustomRules: true, + }); + + expect(kql).toBe(''); }); it('handles presence of "tags" properly', () => { @@ -66,7 +75,7 @@ describe('convertRulesFilterToKQL', () => { }); expect(kql).toBe( - `alert.attributes.tags: "${INTERNAL_IMMUTABLE_KEY}:true" AND alert.attributes.tags:("tag1" AND "tag2") AND (alert.attributes.name: "foo" OR alert.attributes.params.index: "foo" OR alert.attributes.params.threat.tactic.id: "foo" OR alert.attributes.params.threat.tactic.name: "foo" OR alert.attributes.params.threat.technique.id: "foo" OR alert.attributes.params.threat.technique.name: "foo" OR alert.attributes.params.threat.technique.subtechnique.id: "foo" OR alert.attributes.params.threat.technique.subtechnique.name: "foo")` + `alert.attributes.params.immutable: true AND alert.attributes.tags:("tag1" AND "tag2") AND (alert.attributes.name: "foo" OR alert.attributes.params.index: "foo" OR alert.attributes.params.threat.tactic.id: "foo" OR alert.attributes.params.threat.tactic.name: "foo" OR alert.attributes.params.threat.technique.id: "foo" OR alert.attributes.params.threat.technique.name: "foo" OR alert.attributes.params.threat.technique.subtechnique.id: "foo" OR alert.attributes.params.threat.technique.subtechnique.name: "foo")` ); }); }); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/utils.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/utils.ts index 069746223731c..8c576979a15c0 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/utils.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/utils.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { INTERNAL_IMMUTABLE_KEY } from '../../../../../common/constants'; import { escapeKuery } from '../../../../common/lib/keury'; import { FilterOptions } from './types'; @@ -35,12 +34,12 @@ export const convertRulesFilterToKQL = ({ }: FilterOptions): string => { const filters: string[] = []; - if (showCustomRules) { - filters.push(`alert.attributes.tags: "${INTERNAL_IMMUTABLE_KEY}:false"`); - } - - if (showElasticRules) { - filters.push(`alert.attributes.tags: "${INTERNAL_IMMUTABLE_KEY}:true"`); + if (showCustomRules && showElasticRules) { + // if both showCustomRules && showElasticRules selected we omit filter, as it includes all existing rules + } else if (showElasticRules) { + filters.push('alert.attributes.params.immutable: true'); + } else if (showCustomRules) { + filters.push('alert.attributes.params.immutable: false'); } if (tags.length > 0) { diff --git a/x-pack/plugins/security_solution/public/landing_pages/components/landing_links_images.test.tsx b/x-pack/plugins/security_solution/public/landing_pages/components/landing_links_images.test.tsx new file mode 100644 index 0000000000000..d326fff1a9262 --- /dev/null +++ b/x-pack/plugins/security_solution/public/landing_pages/components/landing_links_images.test.tsx @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { render } from '@testing-library/react'; +import React from 'react'; +import { SecurityPageName } from '../../app/types'; +import { TestProviders } from '../../common/mock'; +import { LandingLinksImages, NavItem } from './landing_links_images'; +import { SCREENSHOT_IMAGE_ALT } from './translations'; + +const DEFAULT_NAV_ITEM: NavItem = { + id: SecurityPageName.overview, + label: 'TEST LABEL', + description: 'TEST DESCRIPTION', + image: 'TEST_IMAGE.png', +}; + +jest.mock('../../common/lib/kibana/kibana_react', () => { + return { + useKibana: jest.fn().mockReturnValue({ + services: { + application: { + getUrlForApp: jest.fn(), + }, + }, + }), + }; +}); + +describe('LandingLinksImages', () => { + test('renders', () => { + const label = 'test label'; + + const { queryByText } = render( + + + + ); + + expect(queryByText(label)).toBeInTheDocument(); + }); + + test('renders image', () => { + const image = 'test_image.jpeg'; + const label = 'TEST_LABEL'; + + const { getByAltText } = render( + + + + ); + + expect(getByAltText(SCREENSHOT_IMAGE_ALT(label))).toHaveAttribute('src', image); + }); +}); diff --git a/x-pack/plugins/security_solution/public/landing_pages/components/landing_links_images.tsx b/x-pack/plugins/security_solution/public/landing_pages/components/landing_links_images.tsx new file mode 100644 index 0000000000000..93366b413e0bc --- /dev/null +++ b/x-pack/plugins/security_solution/public/landing_pages/components/landing_links_images.tsx @@ -0,0 +1,74 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { EuiFlexGroup, EuiFlexItem, EuiImage, EuiPanel, EuiText, EuiTitle } from '@elastic/eui'; +import React from 'react'; +import styled from 'styled-components'; +import { SecurityPageName } from '../../app/types'; +import { withSecuritySolutionLink } from '../../common/components/links'; +import * as i18n from './translations'; + +interface LandingLinksImagesProps { + items: NavItem[]; +} + +export interface NavItem { + id: SecurityPageName; + label: string; + image: string; + description: string; + path?: string; +} + +const PrimatyEuiTitle = styled(EuiTitle)` + color: ${(props) => props.theme.eui.euiColorPrimary}; +`; + +const LandingLinksDescripton = styled(EuiText)` + padding-top: ${({ theme }) => theme.eui.paddingSizes.xs}; + max-width: 550px; +`; + +const Link = styled.a` + color: inherit; +`; + +const StyledFlexItem = styled(EuiFlexItem)` + align-items: center; +`; + +const SecuritySolutionLink = withSecuritySolutionLink(Link); + +const Content = styled(EuiFlexItem)` + padding-left: ${({ theme }) => theme.eui.paddingSizes.s}; +`; + +export const LandingLinksImages: React.FC = ({ items }) => ( + + {items.map(({ label, description, path, image, id }) => ( + + + {/* Empty onClick is to force hover style on `EuiPanel` */} + {}}> + + + + + + +

{label}

+
+ + {description} + +
+
+
+
+
+ ))} +
+); diff --git a/x-pack/plugins/security_solution/public/landing_pages/components/translations.ts b/x-pack/plugins/security_solution/public/landing_pages/components/translations.ts new file mode 100644 index 0000000000000..6f27c3e58cbbc --- /dev/null +++ b/x-pack/plugins/security_solution/public/landing_pages/components/translations.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const SCREENSHOT_IMAGE_ALT = (pageName: string) => + i18n.translate('xpack.securitySolution.landing.threatHunting.pageImageAlt', { + values: { pageName }, + defaultMessage: '{pageName} page screenshot', + }); diff --git a/x-pack/plugins/security_solution/public/landing_pages/index.ts b/x-pack/plugins/security_solution/public/landing_pages/index.ts new file mode 100644 index 0000000000000..cac375cce6b2e --- /dev/null +++ b/x-pack/plugins/security_solution/public/landing_pages/index.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { SecuritySubPlugin } from '../app/types'; +import { routes } from './routes'; + +export class LandingPages { + public setup() {} + + public start(): SecuritySubPlugin { + return { + routes, + }; + } +} diff --git a/x-pack/plugins/security_solution/public/landing_pages/jest.config.js b/x-pack/plugins/security_solution/public/landing_pages/jest.config.js new file mode 100644 index 0000000000000..41b8d41269263 --- /dev/null +++ b/x-pack/plugins/security_solution/public/landing_pages/jest.config.js @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../../..', + roots: ['/x-pack/plugins/security_solution/public/landing_pages'], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/security_solution/public/landing_pages', + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/security_solution/public/landing_pages/**/*.{ts,tsx}', + ], + // See: https://github.com/elastic/kibana/issues/117255, the moduleNameMapper creates mocks to avoid memory leaks from kibana core. + moduleNameMapper: { + 'core/server$': '/x-pack/plugins/security_solution/server/__mocks__/core.mock.ts', + 'task_manager/server$': + '/x-pack/plugins/security_solution/server/__mocks__/task_manager.mock.ts', + 'alerting/server$': '/x-pack/plugins/security_solution/server/__mocks__/alert.mock.ts', + 'actions/server$': '/x-pack/plugins/security_solution/server/__mocks__/action.mock.ts', + }, +}; diff --git a/x-pack/plugins/security_solution/public/landing_pages/pages/dashboards.tsx b/x-pack/plugins/security_solution/public/landing_pages/pages/dashboards.tsx new file mode 100644 index 0000000000000..8c49fda169ad3 --- /dev/null +++ b/x-pack/plugins/security_solution/public/landing_pages/pages/dashboards.tsx @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { SecurityPageName } from '../../app/types'; +import { HeaderPage } from '../../common/components/header_page'; +import { SecuritySolutionPageWrapper } from '../../common/components/page_wrapper'; +import { SpyRoute } from '../../common/utils/route/spy_routes'; +import { LandingLinksImages, NavItem } from '../components/landing_links_images'; +import { DASHBOARDS_PAGE_TITLE } from './translations'; +import overviewPageImg from '../../common/images/overview_page.png'; +import { OVERVIEW } from '../../app/translations'; + +const items: NavItem[] = [ + { + id: SecurityPageName.overview, + label: OVERVIEW, + description: i18n.translate('xpack.securitySolution.landing.dashboards.overviewDescription', { + defaultMessage: 'What is going in your secuity environment', + }), + image: overviewPageImg, + }, +]; + +export const DashboardsLandingPage = () => ( + + + + + +); diff --git a/x-pack/plugins/security_solution/public/landing_pages/pages/threat_hunting.tsx b/x-pack/plugins/security_solution/public/landing_pages/pages/threat_hunting.tsx new file mode 100644 index 0000000000000..2a0f4e471a75d --- /dev/null +++ b/x-pack/plugins/security_solution/public/landing_pages/pages/threat_hunting.tsx @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { SecurityPageName } from '../../app/types'; +import { HeaderPage } from '../../common/components/header_page'; +import { SecuritySolutionPageWrapper } from '../../common/components/page_wrapper'; +import { SpyRoute } from '../../common/utils/route/spy_routes'; +import { LandingLinksImages, NavItem } from '../components/landing_links_images'; +import { THREAT_HUNTING_PAGE_TITLE } from './translations'; +import userPageImg from '../../common/images/users_page.png'; +import hostsPageImg from '../../common/images/hosts_page.png'; +import networkPageImg from '../../common/images/network_page.png'; +import { HOSTS, NETWORK, USERS } from '../../app/translations'; + +const items: NavItem[] = [ + { + id: SecurityPageName.hosts, + label: HOSTS, + description: i18n.translate('xpack.securitySolution.landing.threatHunting.hostsDescription', { + defaultMessage: + 'Computer or other device that communicates with other hosts on a network. Hosts on a network include clients and servers -- that send or receive data, services or applications.', + }), + image: hostsPageImg, + }, + { + id: SecurityPageName.network, + label: NETWORK, + description: i18n.translate('xpack.securitySolution.landing.threatHunting.networkDescription', { + defaultMessage: + 'The action or process of interacting with others to exchange information and develop professional or social contacts.', + }), + image: networkPageImg, + }, + { + id: SecurityPageName.users, + label: USERS, + description: i18n.translate('xpack.securitySolution.landing.threatHunting.usersDescription', { + defaultMessage: 'Sudo commands dashboard from the Logs System integration.', + }), + image: userPageImg, + }, +]; + +export const ThreatHuntingLandingPage = () => ( + + + + + +); diff --git a/x-pack/plugins/security_solution/public/landing_pages/pages/translations.ts b/x-pack/plugins/security_solution/public/landing_pages/pages/translations.ts new file mode 100644 index 0000000000000..398bc3fc89fd8 --- /dev/null +++ b/x-pack/plugins/security_solution/public/landing_pages/pages/translations.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const THREAT_HUNTING_PAGE_TITLE = i18n.translate( + 'xpack.securitySolution.landing.threatHunting.pageTitle', + { + defaultMessage: 'Threat hunting', + } +); + +export const DASHBOARDS_PAGE_TITLE = i18n.translate( + 'xpack.securitySolution.landing.dashboards.pageTitle', + { + defaultMessage: 'Dashboards', + } +); diff --git a/x-pack/plugins/security_solution/public/landing_pages/routes.tsx b/x-pack/plugins/security_solution/public/landing_pages/routes.tsx new file mode 100644 index 0000000000000..d849b4c22cf7e --- /dev/null +++ b/x-pack/plugins/security_solution/public/landing_pages/routes.tsx @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { TrackApplicationView } from '@kbn/usage-collection-plugin/public'; + +import { SecurityPageName, SecuritySubPluginRoutes } from '../app/types'; +import { DASHBOARDS_PATH, THREAT_HUNTING_PATH } from '../../common/constants'; +import { ThreatHuntingLandingPage } from './pages/threat_hunting'; +import { DashboardsLandingPage } from './pages/dashboards'; + +export const ThreatHuntingRoutes = () => ( + + + +); + +export const DashboardRoutes = () => ( + + + +); + +export const routes: SecuritySubPluginRoutes = [ + { + path: THREAT_HUNTING_PATH, + render: ThreatHuntingRoutes, + }, + { + path: DASHBOARDS_PATH, + render: DashboardRoutes, + }, +]; diff --git a/x-pack/plugins/security_solution/public/lazy_sub_plugins.tsx b/x-pack/plugins/security_solution/public/lazy_sub_plugins.tsx index bdf70a995aea1..a9562207f9eaa 100644 --- a/x-pack/plugins/security_solution/public/lazy_sub_plugins.tsx +++ b/x-pack/plugins/security_solution/public/lazy_sub_plugins.tsx @@ -22,6 +22,7 @@ import { Rules } from './rules'; import { Timelines } from './timelines'; import { Management } from './management'; +import { LandingPages } from './landing_pages'; /** * The classes used to instantiate the sub plugins. These are grouped into a single object for the sake of bundling them in a single dynamic import. @@ -38,5 +39,6 @@ const subPluginClasses = { Rules, Timelines, Management, + LandingPages, }; export { subPluginClasses }; diff --git a/x-pack/plugins/security_solution/public/management/common/routing.test.ts b/x-pack/plugins/security_solution/public/management/common/routing.test.ts deleted file mode 100644 index 99afd30688983..0000000000000 --- a/x-pack/plugins/security_solution/public/management/common/routing.test.ts +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { extractTrustedAppsListPageLocation, getTrustedAppsListPath } from './routing'; -import { MANAGEMENT_DEFAULT_PAGE, MANAGEMENT_DEFAULT_PAGE_SIZE } from './constants'; -import { TrustedAppsListPageLocation } from '../pages/trusted_apps/state'; - -describe('routing', () => { - describe('extractListPaginationParams()', () => { - it('extracts default page index when not provided', () => { - expect(extractTrustedAppsListPageLocation({}).page_index).toBe(MANAGEMENT_DEFAULT_PAGE); - }); - - it('extracts default page index when too small value provided', () => { - expect(extractTrustedAppsListPageLocation({ page_index: '-1' }).page_index).toBe( - MANAGEMENT_DEFAULT_PAGE - ); - }); - - it('extracts default page index when not a number provided', () => { - expect(extractTrustedAppsListPageLocation({ page_index: 'a' }).page_index).toBe( - MANAGEMENT_DEFAULT_PAGE - ); - }); - - it('extracts only last page index when multiple values provided', () => { - expect(extractTrustedAppsListPageLocation({ page_index: ['1', '2'] }).page_index).toBe(2); - }); - - it('extracts proper page index when single valid value provided', () => { - expect(extractTrustedAppsListPageLocation({ page_index: '2' }).page_index).toBe(2); - }); - - it('extracts default page size when not provided', () => { - expect(extractTrustedAppsListPageLocation({}).page_size).toBe(MANAGEMENT_DEFAULT_PAGE_SIZE); - }); - - it('extracts default page size when invalid option provided', () => { - expect(extractTrustedAppsListPageLocation({ page_size: '25' }).page_size).toBe( - MANAGEMENT_DEFAULT_PAGE_SIZE - ); - }); - - it('extracts default page size when not a number provided', () => { - expect(extractTrustedAppsListPageLocation({ page_size: 'a' }).page_size).toBe( - MANAGEMENT_DEFAULT_PAGE_SIZE - ); - }); - - it('extracts only last page size when multiple values provided', () => { - expect(extractTrustedAppsListPageLocation({ page_size: ['10', '20'] }).page_size).toBe(20); - }); - - it('extracts proper page size when single valid value provided', () => { - expect(extractTrustedAppsListPageLocation({ page_size: '20' }).page_size).toBe(20); - }); - - it('extracts proper "show" when single valid value provided', () => { - expect(extractTrustedAppsListPageLocation({ show: 'create' }).show).toBe('create'); - }); - - it('extracts only last "show" when multiple values provided', () => { - expect(extractTrustedAppsListPageLocation({ show: ['invalid', 'create'] }).show).toBe( - 'create' - ); - }); - - it('extracts default "show" when no value provided', () => { - expect(extractTrustedAppsListPageLocation({}).show).toBeUndefined(); - }); - - it('extracts default "show" when single invalid value provided', () => { - expect(extractTrustedAppsListPageLocation({ show: 'invalid' }).show).toBeUndefined(); - }); - - it('extracts proper view type when single valid value provided', () => { - expect(extractTrustedAppsListPageLocation({ view_type: 'list' }).view_type).toBe('list'); - }); - - it('extracts only last view type when multiple values provided', () => { - expect(extractTrustedAppsListPageLocation({ view_type: ['grid', 'list'] }).view_type).toBe( - 'list' - ); - }); - - it('extracts default view type when no value provided', () => { - expect(extractTrustedAppsListPageLocation({}).view_type).toBe('grid'); - }); - - it('extracts default view type when single invalid value provided', () => { - expect(extractTrustedAppsListPageLocation({ view_type: 'invalid' }).view_type).toBe('grid'); - }); - }); - - describe('getTrustedAppsListPath()', () => { - it('builds proper path when no parameters provided', () => { - expect(getTrustedAppsListPath()).toEqual('/administration/trusted_apps'); - }); - - it('builds proper path when empty parameters provided', () => { - expect(getTrustedAppsListPath({})).toEqual('/administration/trusted_apps'); - }); - - it('builds proper path when only page size provided', () => { - const pageSize = 20; - expect(getTrustedAppsListPath({ page_size: pageSize })).toEqual( - `/administration/trusted_apps?page_size=${pageSize}` - ); - }); - - it('builds proper path when only page index provided', () => { - const pageIndex = 2; - expect(getTrustedAppsListPath({ page_index: pageIndex })).toEqual( - `/administration/trusted_apps?page_index=${pageIndex}` - ); - }); - - it('builds proper path when only "show" provided', () => { - const show = 'create'; - expect(getTrustedAppsListPath({ show })).toEqual(`/administration/trusted_apps?show=${show}`); - }); - - it('builds proper path when only view type provided', () => { - const viewType = 'list'; - expect(getTrustedAppsListPath({ view_type: viewType })).toEqual( - `/administration/trusted_apps?view_type=${viewType}` - ); - }); - - it('builds proper path when all params provided', () => { - const location: TrustedAppsListPageLocation = { - page_index: 2, - page_size: 20, - show: 'create', - view_type: 'list', - filter: 'test', - included_policies: 'globally', - }; - - expect(getTrustedAppsListPath(location)).toEqual( - `/administration/trusted_apps?page_index=${location.page_index}&page_size=${location.page_size}&view_type=${location.view_type}&show=${location.show}&filter=${location.filter}&included_policies=${location.included_policies}` - ); - }); - - it('builds proper path when page index is equal to default', () => { - const location: TrustedAppsListPageLocation = { - page_index: MANAGEMENT_DEFAULT_PAGE, - page_size: 20, - show: 'create', - view_type: 'list', - filter: '', - included_policies: '', - }; - const path = getTrustedAppsListPath(location); - - expect(path).toEqual( - `/administration/trusted_apps?page_size=${location.page_size}&view_type=${location.view_type}&show=${location.show}` - ); - }); - - it('builds proper path when page size is equal to default', () => { - const location: TrustedAppsListPageLocation = { - page_index: 2, - page_size: MANAGEMENT_DEFAULT_PAGE_SIZE, - show: 'create', - view_type: 'list', - filter: '', - included_policies: '', - }; - const path = getTrustedAppsListPath(location); - - expect(path).toEqual( - `/administration/trusted_apps?page_index=${location.page_index}&view_type=${location.view_type}&show=${location.show}` - ); - }); - - it('builds proper path when "show" is equal to default', () => { - const location: TrustedAppsListPageLocation = { - page_index: 2, - page_size: 20, - show: undefined, - view_type: 'list', - filter: '', - included_policies: '', - }; - const path = getTrustedAppsListPath(location); - - expect(path).toEqual( - `/administration/trusted_apps?page_index=${location.page_index}&page_size=${location.page_size}&view_type=${location.view_type}` - ); - }); - - it('builds proper path when view type is equal to default', () => { - const location: TrustedAppsListPageLocation = { - page_index: 2, - page_size: 20, - show: 'create', - view_type: 'grid', - filter: '', - included_policies: '', - }; - const path = getTrustedAppsListPath(location); - - expect(path).toEqual( - `/administration/trusted_apps?page_index=${location.page_index}&page_size=${location.page_size}&show=${location.show}` - ); - }); - - it('builds proper path when params are equal to default', () => { - const path = getTrustedAppsListPath({ - page_index: MANAGEMENT_DEFAULT_PAGE, - page_size: MANAGEMENT_DEFAULT_PAGE_SIZE, - show: undefined, - view_type: 'grid', - }); - - expect(path).toEqual('/administration/trusted_apps'); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/management/common/routing.ts b/x-pack/plugins/security_solution/public/management/common/routing.ts index 40d17dc766690..828be47d9d0dd 100644 --- a/x-pack/plugins/security_solution/public/management/common/routing.ts +++ b/x-pack/plugins/security_solution/public/management/common/routing.ts @@ -16,7 +16,6 @@ import { paginationFromUrlParams } from '../components/hooks/use_url_pagination' import { EndpointIndexUIQueryParams } from '../pages/endpoint_hosts/types'; import { EventFiltersPageLocation } from '../pages/event_filters/types'; import { PolicyDetailsArtifactsPageLocation } from '../pages/policy/types'; -import { TrustedAppsListPageLocation } from '../pages/trusted_apps/state'; import { AdministrationSubTab } from '../types'; import { MANAGEMENT_DEFAULT_PAGE, @@ -150,30 +149,6 @@ export const getPolicyEventFiltersPath = ( )}`; }; -const normalizeTrustedAppsPageLocation = ( - location?: Partial -): Partial => { - if (location) { - return { - ...(!isDefaultOrMissing(location.page_index, MANAGEMENT_DEFAULT_PAGE) - ? { page_index: location.page_index } - : {}), - ...(!isDefaultOrMissing(location.page_size, MANAGEMENT_DEFAULT_PAGE_SIZE) - ? { page_size: location.page_size } - : {}), - ...(!isDefaultOrMissing(location.view_type, 'grid') ? { view_type: location.view_type } : {}), - ...(!isDefaultOrMissing(location.show, undefined) ? { show: location.show } : {}), - ...(!isDefaultOrMissing(location.id, undefined) ? { id: location.id } : {}), - ...(!isDefaultOrMissing(location.filter, '') ? { filter: location.filter } : ''), - ...(!isDefaultOrMissing(location.included_policies, '') - ? { included_policies: location.included_policies } - : ''), - }; - } else { - return {}; - } -}; - const normalizePolicyDetailsArtifactsListPageLocation = ( location?: Partial ): Partial => { @@ -266,31 +241,12 @@ export const extractArtifactsListPaginationParams = (query: querystring.ParsedUr included_policies: extractIncludedPolicies(query), }); -export const extractTrustedAppsListPageLocation = ( - query: querystring.ParsedUrlQuery -): TrustedAppsListPageLocation => { - const showParamValue = extractFirstParamValue( - query, - 'show' - ) as TrustedAppsListPageLocation['show']; - - return { - ...extractTrustedAppsListPaginationParams(query), - view_type: extractFirstParamValue(query, 'view_type') === 'list' ? 'list' : 'grid', - show: - showParamValue && ['edit', 'create'].includes(showParamValue) ? showParamValue : undefined, - id: extractFirstParamValue(query, 'id'), - }; -}; - -export const getTrustedAppsListPath = (location?: Partial): string => { +export const getTrustedAppsListPath = (location?: Partial): string => { const path = generatePath(MANAGEMENT_ROUTING_TRUSTED_APPS_PATH, { tabName: AdministrationSubTab.trustedApps, }); - return `${path}${appendSearch( - querystring.stringify(normalizeTrustedAppsPageLocation(location)) - )}`; + return getArtifactListPageUrlPath(path, location); }; export const extractPolicyDetailsArtifactsListPageLocation = ( diff --git a/x-pack/plugins/security_solution/public/management/common/url_routing/artifact_list_page_routing.test.ts b/x-pack/plugins/security_solution/public/management/common/url_routing/artifact_list_page_routing.test.ts new file mode 100644 index 0000000000000..efbed1e2e14fc --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/common/url_routing/artifact_list_page_routing.test.ts @@ -0,0 +1,232 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ArtifactListPageUrlParams } from '../../components/artifact_list_page'; +import { MANAGEMENT_DEFAULT_PAGE, MANAGEMENT_DEFAULT_PAGE_SIZE } from '../constants'; +import { + getArtifactListPageUrlPath, + extractArtifactListPageUrlSearchParams, +} from './artifact_list_page_routing'; +import { + getTrustedAppsListPath, + getBlocklistsListPath, + getHostIsolationExceptionsListPath, +} from '../routing'; + +describe('routing', () => { + describe('extractListPaginationParams()', () => { + it('extracts default page when not provided', () => { + expect(extractArtifactListPageUrlSearchParams({}).page).toBe(1); + }); + + it('extracts default page when too small value provided', () => { + expect(extractArtifactListPageUrlSearchParams({ page: '-1' }).page).toBe(1); + }); + + it('extracts default page when not a number provided', () => { + expect(extractArtifactListPageUrlSearchParams({ page: 'a' }).page).toBe(1); + }); + + it('extracts only last page when multiple values provided', () => { + expect(extractArtifactListPageUrlSearchParams({ page: ['1', '2'] }).page).toBe(2); + }); + + it('extracts proper page when single valid value provided', () => { + expect(extractArtifactListPageUrlSearchParams({ page: '2' }).page).toBe(2); + }); + + it('extracts default page size when not provided', () => { + expect(extractArtifactListPageUrlSearchParams({}).pageSize).toBe( + MANAGEMENT_DEFAULT_PAGE_SIZE + ); + }); + + it('extracts default page size when invalid option provided', () => { + expect(extractArtifactListPageUrlSearchParams({ pageSize: '25' }).pageSize).toBe( + MANAGEMENT_DEFAULT_PAGE_SIZE + ); + }); + + it('extracts default page size when not a number provided', () => { + expect(extractArtifactListPageUrlSearchParams({ pageSize: 'a' }).pageSize).toBe( + MANAGEMENT_DEFAULT_PAGE_SIZE + ); + }); + + it('extracts only last page size when multiple values provided', () => { + expect(extractArtifactListPageUrlSearchParams({ pageSize: ['10', '20'] }).pageSize).toBe(20); + }); + + it('extracts proper page size when single valid value provided', () => { + expect(extractArtifactListPageUrlSearchParams({ pageSize: '20' }).pageSize).toBe(20); + }); + + it('extracts proper "show" when single valid value provided', () => { + expect(extractArtifactListPageUrlSearchParams({ show: 'create' }).show).toBe('create'); + }); + + it('extracts only last "show" when multiple values provided', () => { + expect(extractArtifactListPageUrlSearchParams({ show: ['invalid', 'create'] }).show).toBe( + 'create' + ); + }); + + it('extracts default "show" when no value provided', () => { + expect(extractArtifactListPageUrlSearchParams({}).show).toBeUndefined(); + }); + + it('extracts default "show" when single invalid value provided', () => { + expect(extractArtifactListPageUrlSearchParams({ show: 'invalid' }).show).toBeUndefined(); + }); + }); + + describe('getArtifactListPageUrlPath()', () => { + it.each([ + ['trusted_apps', getTrustedAppsListPath], + ['blocklist', getBlocklistsListPath], + ['host_isolation_exceptions', getHostIsolationExceptionsListPath], + ])('builds proper path for %s when no parameters provided', (path, getPath) => { + expect(getArtifactListPageUrlPath(getPath())).toEqual(`/administration/${path}`); + }); + + it.each([ + ['trusted_apps', getTrustedAppsListPath], + ['blocklist', getBlocklistsListPath], + ['host_isolation_exceptions', getHostIsolationExceptionsListPath], + ])('builds proper path for %s when only page size provided', (path, getPath) => { + const pageSize = 20; + expect(getArtifactListPageUrlPath(getPath({ pageSize }))).toEqual( + `/administration/${path}?pageSize=${pageSize}` + ); + }); + + it.each([ + ['trusted_apps', getTrustedAppsListPath], + ['blocklist', getBlocklistsListPath], + ['host_isolation_exceptions', getHostIsolationExceptionsListPath], + ])('builds proper path for %s when only page index provided', (path, getPath) => { + const pageIndex = 2; + expect(getArtifactListPageUrlPath(getPath({ page: pageIndex }))).toEqual( + `/administration/${path}?page=${pageIndex}` + ); + }); + + it.each([ + ['trusted_apps', getTrustedAppsListPath], + ['blocklist', getBlocklistsListPath], + ['host_isolation_exceptions', getHostIsolationExceptionsListPath], + ])('builds proper path for %s when only "show" provided', (path, getPath) => { + const show = 'create'; + expect(getArtifactListPageUrlPath(getPath({ show }))).toEqual( + `/administration/${path}?show=${show}` + ); + }); + + it.each([ + ['trusted_apps', getTrustedAppsListPath], + ['blocklist', getBlocklistsListPath], + ['host_isolation_exceptions', getHostIsolationExceptionsListPath], + ])('builds proper path for %s when all params provided', (path, getPath) => { + const location: ArtifactListPageUrlParams = { + page: 2, + pageSize: 20, + show: 'create', + filter: 'test', + includedPolicies: 'globally', + }; + + expect(getPath(location)).toEqual( + `/administration/${path}?page=${location.page}&pageSize=${location.pageSize}&show=${location.show}&filter=${location.filter}&includedPolicies=${location.includedPolicies}` + ); + }); + + it.each([ + ['trusted_apps', getTrustedAppsListPath], + ['blocklist', getBlocklistsListPath], + ['host_isolation_exceptions', getHostIsolationExceptionsListPath], + ])('builds proper path for %s when page index is equal to default', (path, getPath) => { + const location: ArtifactListPageUrlParams = { + page: MANAGEMENT_DEFAULT_PAGE, + pageSize: 20, + show: 'create', + filter: '', + includedPolicies: '', + }; + + expect(getPath(location)).toEqual( + `/administration/${path}?pageSize=${location.pageSize}&show=${location.show}` + ); + }); + + it.each([ + ['trusted_apps', getTrustedAppsListPath], + ['blocklist', getBlocklistsListPath], + ['host_isolation_exceptions', getHostIsolationExceptionsListPath], + ])('builds proper path for %s when page size is equal to default', (path, getPath) => { + const location: ArtifactListPageUrlParams = { + page: 2, + pageSize: MANAGEMENT_DEFAULT_PAGE_SIZE, + show: 'create', + filter: '', + includedPolicies: '', + }; + + expect(getPath(location)).toEqual( + `/administration/${path}?page=${location.page}&show=${location.show}` + ); + }); + + it.each([ + ['trusted_apps', getTrustedAppsListPath], + ['blocklist', getBlocklistsListPath], + ['host_isolation_exceptions', getHostIsolationExceptionsListPath], + ])('builds proper path for %s when "show" is equal to default', (path, getPath) => { + const location: ArtifactListPageUrlParams = { + page: 2, + pageSize: 20, + show: undefined, + filter: '', + includedPolicies: '', + }; + + expect(getPath(location)).toEqual( + `/administration/${path}?page=${location.page}&pageSize=${location.pageSize}` + ); + }); + + it.each([ + ['trusted_apps', getTrustedAppsListPath], + ['blocklist', getBlocklistsListPath], + ['host_isolation_exceptions', getHostIsolationExceptionsListPath], + ])('builds proper path for %s when view type is equal to default', (path, getPath) => { + const location: ArtifactListPageUrlParams = { + page: 2, + pageSize: 20, + show: 'create', + filter: '', + includedPolicies: '', + }; + + expect(getPath(location)).toEqual( + `/administration/${path}?page=${location.page}&pageSize=${location.pageSize}&show=${location.show}` + ); + }); + + it.each([ + ['trusted_apps', getTrustedAppsListPath], + ['blocklist', getBlocklistsListPath], + ['host_isolation_exceptions', getHostIsolationExceptionsListPath], + ])('builds proper path for %s when params are equal to default', (path, getPath) => { + const location: ArtifactListPageUrlParams = { + page: MANAGEMENT_DEFAULT_PAGE, + pageSize: MANAGEMENT_DEFAULT_PAGE_SIZE, + }; + + expect(getPath(location)).toEqual(`/administration/${path}`); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/management/common/url_routing/utils.ts b/x-pack/plugins/security_solution/public/management/common/url_routing/utils.ts index b9ec8b2fb7a82..afff61e94b06d 100644 --- a/x-pack/plugins/security_solution/public/management/common/url_routing/utils.ts +++ b/x-pack/plugins/security_solution/public/management/common/url_routing/utils.ts @@ -14,8 +14,8 @@ import { MANAGEMENT_DEFAULT_PAGE_SIZE, MANAGEMENT_PAGE_SIZE_OPTIONS } from '../c * @param value * @param defaultValue */ -export const isDefaultOrMissing = (value: T | undefined, defaultValue: T) => { - return value === undefined || value === defaultValue; +export const isDefaultOrMissing = (value: T | undefined | 0, defaultValue: T) => { + return value === undefined || value === defaultValue || value === 0; }; /** diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.test.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.test.tsx index 81dc91dbae32c..b21579d25dedb 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.test.tsx @@ -16,6 +16,8 @@ import { getEndpointPrivilegesInitialStateMock } from '../../../../common/compon import { AppContextTestRender } from '../../../../common/mock/endpoint'; import { trustedAppsAllHttpMocks } from '../../../pages/mocks'; import { useUserPrivileges as _useUserPrivileges } from '../../../../common/components/user_privileges'; +import { entriesToConditionEntries } from '../../../../common/utils/exception_list_items/mappers'; +import { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; jest.mock('../../../../common/components/user_privileges'); const useUserPrivileges = _useUserPrivileges as jest.Mock; @@ -357,12 +359,19 @@ describe('When the flyout is opened in the ArtifactListPage component', () => { }); }); - expect(getLastFormComponentProps().item).toEqual({ + const expectedProps = { ...mockedApi.responseProvider.trustedApp({ query: { item_id: '123' }, } as unknown as HttpFetchOptionsWithPath), created_at: expect.any(String), - }); + }; + + // map process.hash entries to have * as suffix + expectedProps.entries = entriesToConditionEntries( + expectedProps.entries + ) as ExceptionListItemSchema['entries']; + + expect(getLastFormComponentProps().item).toEqual(expectedProps); }); it('should show error toast and close flyout if item for edit does not exist', async () => { diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/mocks.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/mocks.tsx index d4f92bd2717f2..ebf98c64d7dc4 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/mocks.tsx +++ b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/mocks.tsx @@ -14,7 +14,7 @@ import { ArtifactFormComponentProps } from './types'; import { ArtifactListPage, ArtifactListPageProps } from './artifact_list_page'; import { AppContextTestRender, createAppRootMockRenderer } from '../../../common/mock/endpoint'; import { trustedAppsAllHttpMocks } from '../../pages/mocks'; -import { TrustedAppsApiClient } from '../../pages/trusted_apps/service/trusted_apps_api_client'; +import { TrustedAppsApiClient } from '../../pages/trusted_apps/service/api_client'; import { artifactListPageLabels } from './translations'; export const getFormComponentMock = (): { diff --git a/x-pack/plugins/security_solution/public/management/components/context_menu_with_router_support/context_menu_with_router_support.tsx b/x-pack/plugins/security_solution/public/management/components/context_menu_with_router_support/context_menu_with_router_support.tsx index 85013b82fb2db..a78375d4cbf49 100644 --- a/x-pack/plugins/security_solution/public/management/components/context_menu_with_router_support/context_menu_with_router_support.tsx +++ b/x-pack/plugins/security_solution/public/management/components/context_menu_with_router_support/context_menu_with_router_support.tsx @@ -153,11 +153,7 @@ export const ContextMenuWithRouterSupport = memo {title ? {title} : null} - + ); } diff --git a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_bulk_delete_artifact.tsx b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_bulk_delete_artifact.tsx index 994ed4f466d00..f534cc01e62ee 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_bulk_delete_artifact.tsx +++ b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_bulk_delete_artifact.tsx @@ -7,14 +7,19 @@ import pMap from 'p-map'; import { HttpFetchError } from '@kbn/core/public'; import { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; -import { useMutation, UseMutationResult, UseQueryOptions } from 'react-query'; +import { useMutation, UseMutationOptions, UseMutationResult } from 'react-query'; import { ExceptionsListApiClient } from '../../services/exceptions_list/exceptions_list_api_client'; const DEFAULT_OPTIONS = Object.freeze({}); export function useBulkDeleteArtifact( exceptionListApiClient: ExceptionsListApiClient, - customOptions: UseQueryOptions = DEFAULT_OPTIONS, + customOptions: UseMutationOptions< + ExceptionListItemSchema[], + HttpFetchError, + Array<{ itemId?: string; id?: string }>, + () => void + > = DEFAULT_OPTIONS, options: { concurrency: number; } = { diff --git a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_bulk_update_artifact.tsx b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_bulk_update_artifact.tsx index 3389b3563577a..68090e2aabc90 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_bulk_update_artifact.tsx +++ b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_bulk_update_artifact.tsx @@ -10,14 +10,19 @@ import { UpdateExceptionListItemSchema, ExceptionListItemSchema, } from '@kbn/securitysolution-io-ts-list-types'; -import { useMutation, UseMutationResult, UseQueryOptions } from 'react-query'; +import { useMutation, UseMutationOptions, UseMutationResult } from 'react-query'; import { ExceptionsListApiClient } from '../../services/exceptions_list/exceptions_list_api_client'; const DEFAULT_OPTIONS = Object.freeze({}); export function useBulkUpdateArtifact( exceptionListApiClient: ExceptionsListApiClient, - customOptions: UseQueryOptions = DEFAULT_OPTIONS, + customOptions: UseMutationOptions< + ExceptionListItemSchema[], + HttpFetchError, + UpdateExceptionListItemSchema[], + () => void + > = DEFAULT_OPTIONS, options: { concurrency: number; } = { diff --git a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_create_artifact.tsx b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_create_artifact.tsx index c1aed4be8005b..79dd59d744e7f 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_create_artifact.tsx +++ b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_create_artifact.tsx @@ -9,14 +9,19 @@ import { ExceptionListItemSchema, } from '@kbn/securitysolution-io-ts-list-types'; import { HttpFetchError } from '@kbn/core/public'; -import { useMutation, UseMutationResult, UseQueryOptions } from 'react-query'; +import { useMutation, UseMutationOptions, UseMutationResult } from 'react-query'; import { ExceptionsListApiClient } from '../../services/exceptions_list/exceptions_list_api_client'; const DEFAULT_OPTIONS = Object.freeze({}); export function useCreateArtifact( exceptionListApiClient: ExceptionsListApiClient, - customOptions: UseQueryOptions = DEFAULT_OPTIONS + customOptions: UseMutationOptions< + ExceptionListItemSchema, + HttpFetchError, + CreateExceptionListItemSchema, + () => void + > = DEFAULT_OPTIONS ): UseMutationResult< ExceptionListItemSchema, HttpFetchError, diff --git a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_delete_artifact.tsx b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_delete_artifact.tsx index 16568a0766444..a12b3aaa9ba40 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_delete_artifact.tsx +++ b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_delete_artifact.tsx @@ -6,14 +6,19 @@ */ import { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; import { HttpFetchError } from '@kbn/core/public'; -import { useMutation, UseMutationResult, UseQueryOptions } from 'react-query'; +import { useMutation, UseMutationOptions, UseMutationResult } from 'react-query'; import { ExceptionsListApiClient } from '../../services/exceptions_list/exceptions_list_api_client'; const DEFAULT_OPTIONS = Object.freeze({}); export function useDeleteArtifact( exceptionListApiClient: ExceptionsListApiClient, - customOptions: UseQueryOptions = DEFAULT_OPTIONS + customOptions: UseMutationOptions< + ExceptionListItemSchema, + HttpFetchError, + { itemId?: string; id?: string }, + () => void + > = DEFAULT_OPTIONS ): UseMutationResult< ExceptionListItemSchema, HttpFetchError, diff --git a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_get_artifact.tsx b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_get_artifact.tsx index eb80a689e5a0d..36ae203707c28 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_get_artifact.tsx +++ b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_get_artifact.tsx @@ -9,24 +9,17 @@ import { HttpFetchError } from '@kbn/core/public'; import { QueryObserverResult, useQuery, UseQueryOptions } from 'react-query'; import { ExceptionsListApiClient } from '../../services/exceptions_list/exceptions_list_api_client'; -const DEFAULT_OPTIONS = Object.freeze({}); - export function useGetArtifact( exceptionListApiClient: ExceptionsListApiClient, itemId?: string, id?: string, - customQueryOptions: UseQueryOptions = DEFAULT_OPTIONS + customQueryOptions?: UseQueryOptions ): QueryObserverResult { return useQuery( ['get', exceptionListApiClient, itemId, id], () => { return exceptionListApiClient.get(itemId, id); }, - { - refetchIntervalInBackground: false, - refetchOnWindowFocus: false, - refetchOnMount: true, - ...customQueryOptions, - } + customQueryOptions ); } diff --git a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_list_artifact.tsx b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_list_artifact.tsx index 68bee6de0113a..64a5b908e2d9e 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_list_artifact.tsx +++ b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_list_artifact.tsx @@ -31,9 +31,7 @@ export function useListArtifact( excludedPolicies: string[]; }> = DEFAULT_OPTIONS, searchableFields: MaybeImmutable = DEFAULT_EXCEPTION_LIST_ITEM_SEARCHABLE_FIELDS, - customQueryOptions: Partial< - UseQueryOptions - > = DEFAULT_OPTIONS, + customQueryOptions?: Partial>, customQueryIds: string[] = [] ): QueryObserverResult { const { @@ -64,12 +62,6 @@ export function useListArtifact( return result; }, - { - refetchIntervalInBackground: false, - refetchOnWindowFocus: false, - refetchOnMount: true, - keepPreviousData: true, - ...customQueryOptions, - } + customQueryOptions ); } diff --git a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_summary_artifact.tsx b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_summary_artifact.tsx index 62e5372dc39aa..111fdb4565785 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_summary_artifact.tsx +++ b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_summary_artifact.tsx @@ -21,9 +21,7 @@ export function useSummaryArtifact( policies: string[]; }> = DEFAULT_OPTIONS, searchableFields: MaybeImmutable = DEFAULT_EXCEPTION_LIST_ITEM_SEARCHABLE_FIELDS, - customQueryOptions: Partial< - UseQueryOptions - > = DEFAULT_OPTIONS + customQueryOptions: Partial> ): QueryObserverResult { const { filter = '', policies = [] } = options; @@ -37,12 +35,6 @@ export function useSummaryArtifact( }) ); }, - { - refetchIntervalInBackground: false, - refetchOnWindowFocus: false, - refetchOnMount: true, - keepPreviousData: true, - ...customQueryOptions, - } + customQueryOptions ); } diff --git a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_update_artifact.tsx b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_update_artifact.tsx index 92da096f71e66..e3a7e37eebf56 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_update_artifact.tsx +++ b/x-pack/plugins/security_solution/public/management/hooks/artifacts/use_update_artifact.tsx @@ -9,14 +9,19 @@ import { ExceptionListItemSchema, } from '@kbn/securitysolution-io-ts-list-types'; import { HttpFetchError } from '@kbn/core/public'; -import { useMutation, UseMutationResult, UseQueryOptions } from 'react-query'; +import { useMutation, UseMutationOptions, UseMutationResult } from 'react-query'; import { ExceptionsListApiClient } from '../../services/exceptions_list/exceptions_list_api_client'; const DEFAULT_OPTIONS = Object.freeze({}); export function useUpdateArtifact( exceptionListApiClient: ExceptionsListApiClient, - customQueryOptions: UseQueryOptions = DEFAULT_OPTIONS + customQueryOptions: UseMutationOptions< + ExceptionListItemSchema, + HttpFetchError, + UpdateExceptionListItemSchema, + () => void + > = DEFAULT_OPTIONS ): UseMutationResult< ExceptionListItemSchema, HttpFetchError, diff --git a/x-pack/plugins/security_solution/public/management/pages/blocklist/view/components/blocklist_form.tsx b/x-pack/plugins/security_solution/public/management/pages/blocklist/view/components/blocklist_form.tsx index 3926d42fb36cf..ccb2ec9055fc8 100644 --- a/x-pack/plugins/security_solution/public/management/pages/blocklist/view/components/blocklist_form.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/blocklist/view/components/blocklist_form.tsx @@ -61,7 +61,7 @@ import { BY_POLICY_ARTIFACT_TAG_PREFIX, } from '../../../../../../common/endpoint/service/artifacts/constants'; import { useLicense } from '../../../../../common/hooks/use_license'; -import { isValidHash } from '../../../../../../common/endpoint/service/trusted_apps/validations'; +import { isValidHash } from '../../../../../../common/endpoint/service/artifacts/validations'; import { isArtifactGlobal } from '../../../../../../common/endpoint/service/artifacts'; import type { PolicyData } from '../../../../../../common/endpoint/types'; import { isGlobalPolicyEffected } from '../../../../components/effected_policy_select/utils'; diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.test.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.test.ts index 57cdaca1f2147..d8dc87885a1fa 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.test.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.test.ts @@ -424,16 +424,16 @@ describe('endpoint list middleware', () => { path: expect.any(String), query: { agent_ids: [ - '6db499e5-4927-4350-abb8-d8318e7d0eec', - 'c082dda9-1847-4997-8eda-f1192d95bec3', - '8aa1cd61-cc25-4783-afb5-0eefc4919c07', - '47fe24c1-7370-419a-9732-3ff38bf41272', - '0d2b2fa7-a9cd-49fc-ad5f-0252c642290e', - 'f480092d-0445-4bf3-9c96-8a3d5cb97824', - '3850e676-0940-4c4b-aaca-571bd1bc66d9', - '46efcc7a-086a-47a3-8f09-c4ecd6d2d917', - 'afa55826-b81b-4440-a2ac-0644d77a3fc6', - '25b49e50-cb5c-43df-824f-67b8cf697d9d', + '0dc3661d-6e67-46b0-af39-6f12b025fcb0', + 'a8e32a61-2685-47f0-83eb-edf157b8e616', + '37e219a8-fe16-4da9-bf34-634c5824b484', + '2484eb13-967e-4491-bf83-dffefdfe607c', + '0bc08ef6-6d6a-4113-92f2-b97811187c63', + 'f4127d87-b567-4a6e-afa6-9a1c7dc95f01', + 'f9ab5b8c-a43e-4e80-99d6-11570845a697', + '406c4b6a-ca57-4bd1-bc66-d9d999df3e70', + '2da1dd51-f7af-4f0e-b64c-e7751c74b0e7', + '89a94ea4-073c-4cb6-90a2-500805837027', ], }, }); diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/index.test.tsx index a9778329ff2f7..f0589099a8077 100644 --- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/index.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/index.test.tsx @@ -87,6 +87,7 @@ describe('Event filter form', () => { services: { http: {}, data: {}, + unifiedSearch: {}, notifications: {}, }, }); diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/index.tsx b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/index.tsx index 0bd785a28eff0..11d1af0a5a2e9 100644 --- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/index.tsx @@ -88,7 +88,7 @@ interface EventFiltersFormProps { } export const EventFiltersForm: React.FC = memo( ({ allowSelectOs = false, policies, arePoliciesLoading }) => { - const { http, data } = useKibana().services; + const { http, unifiedSearch } = useKibana().services; const dispatch = useDispatch>(); const exception = useEventFiltersSelector(getFormEntryStateMutable); @@ -225,7 +225,7 @@ export const EventFiltersForm: React.FC = memo( getExceptionBuilderComponentLazy({ allowLargeValueLists: false, httpService: http, - autocompleteService: data.autocomplete, + autocompleteService: unifiedSearch.autocomplete, exceptionListItems: [exception as ExceptionListItemSchema], listType: EVENT_FILTER_LIST_TYPE, listId: ENDPOINT_EVENT_FILTERS_LIST_ID, @@ -243,7 +243,7 @@ export const EventFiltersForm: React.FC = memo( operatorsList: EVENT_FILTERS_OPERATORS, osTypes: exception?.os_types, }), - [data, handleOnBuilderChange, http, indexPatterns, exception] + [unifiedSearch, handleOnBuilderChange, http, indexPatterns, exception] ); const nameInputMemo = useMemo( diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/test_utils/mocks.ts b/x-pack/plugins/security_solution/public/management/pages/policy/test_utils/mocks.ts index c1b30b6fad10c..e3641ba66e15b 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/test_utils/mocks.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/test_utils/mocks.ts @@ -5,8 +5,61 @@ * 2.0. */ -import { GetTrustedAppsListResponse } from '../../../../../common/endpoint/types'; -import { createSampleTrustedApps } from '../../trusted_apps/test_utils'; +import { OperatingSystem } from '@kbn/securitysolution-utils'; +import { GetTrustedAppsListResponse, TrustedApp } from '../../../../../common/endpoint/types'; +import { + MANAGEMENT_DEFAULT_PAGE, + MANAGEMENT_DEFAULT_PAGE_SIZE, + MANAGEMENT_PAGE_SIZE_OPTIONS, +} from '../../../common/constants'; + +interface Pagination { + pageIndex: number; + pageSize: number; + totalItemCount: number; + pageSizeOptions: number[]; +} + +const OPERATING_SYSTEMS: OperatingSystem[] = [ + OperatingSystem.WINDOWS, + OperatingSystem.MAC, + OperatingSystem.LINUX, +]; + +const generate = (count: number, generator: (i: number) => T) => + [...new Array(count).keys()].map(generator); + +const createSampleTrustedApp = (i: number, longTexts?: boolean): TrustedApp => { + return { + id: String(i), + version: 'abc123', + name: generate(longTexts ? 10 : 1, () => `trusted app ${i}`).join(' '), + description: generate(longTexts ? 10 : 1, () => `Trusted App ${i}`).join(' '), + created_at: '1 minute ago', + created_by: 'someone', + updated_at: '1 minute ago', + updated_by: 'someone', + os: OPERATING_SYSTEMS[i % 3], + entries: [], + effectScope: { type: 'global' }, + }; +}; + +const createDefaultPagination = (): Pagination => ({ + pageIndex: MANAGEMENT_DEFAULT_PAGE, + pageSize: MANAGEMENT_DEFAULT_PAGE_SIZE, + totalItemCount: 200, + pageSizeOptions: [...MANAGEMENT_PAGE_SIZE_OPTIONS], +}); + +const createSampleTrustedApps = ( + pagination: Partial, + longTexts?: boolean +): TrustedApp[] => { + const fullPagination = { ...createDefaultPagination(), ...pagination }; + + return generate(fullPagination.pageSize, (i: number) => createSampleTrustedApp(i, longTexts)); +}; export const getMockListResponse: () => GetTrustedAppsListResponse = () => ({ data: createSampleTrustedApps({}), diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/empty/policy_artifacts_empty_unassigned.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/empty/policy_artifacts_empty_unassigned.tsx index 4809ee53b0d7b..2bee159dc6e4d 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/empty/policy_artifacts_empty_unassigned.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/empty/policy_artifacts_empty_unassigned.tsx @@ -12,7 +12,6 @@ import { useGetLinkTo } from './use_policy_artifacts_empty_hooks'; import { useUserPrivileges } from '../../../../../../common/components/user_privileges'; import { POLICY_ARTIFACT_EMPTY_UNASSIGNED_LABELS } from './translations'; import { EventFiltersPageLocation } from '../../../../event_filters/types'; -import { TrustedAppsListPageLocation } from '../../../../trusted_apps/state'; import { ArtifactListPageUrlParams } from '../../../../../components/artifact_list_page'; interface CommonProps { policyId: string; @@ -21,10 +20,7 @@ interface CommonProps { labels: typeof POLICY_ARTIFACT_EMPTY_UNASSIGNED_LABELS; getPolicyArtifactsPath: (policyId: string) => string; getArtifactPath: ( - location?: - | Partial - | Partial - | Partial + location?: Partial | Partial ) => string; } diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/empty/policy_artifacts_empty_unexisting.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/empty/policy_artifacts_empty_unexisting.tsx index eb0133823ea99..7d12389048753 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/empty/policy_artifacts_empty_unexisting.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/empty/policy_artifacts_empty_unexisting.tsx @@ -10,7 +10,6 @@ import { EuiEmptyPrompt, EuiButton, EuiPageTemplate } from '@elastic/eui'; import { useGetLinkTo } from './use_policy_artifacts_empty_hooks'; import { POLICY_ARTIFACT_EMPTY_UNEXISTING_LABELS } from './translations'; import { EventFiltersPageLocation } from '../../../../event_filters/types'; -import { TrustedAppsListPageLocation } from '../../../../trusted_apps/state'; import { ArtifactListPageUrlParams } from '../../../../../components/artifact_list_page'; interface CommonProps { @@ -19,10 +18,7 @@ interface CommonProps { labels: typeof POLICY_ARTIFACT_EMPTY_UNEXISTING_LABELS; getPolicyArtifactsPath: (policyId: string) => string; getArtifactPath: ( - location?: - | Partial - | Partial - | Partial + location?: Partial | Partial ) => string; } diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/empty/use_policy_artifacts_empty_hooks.ts b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/empty/use_policy_artifacts_empty_hooks.ts index 723988a9de468..b2ee8e7dd17ba 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/empty/use_policy_artifacts_empty_hooks.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/empty/use_policy_artifacts_empty_hooks.ts @@ -11,7 +11,6 @@ import { useNavigateToAppEventHandler } from '../../../../../../common/hooks/end import { useAppUrl } from '../../../../../../common/lib/kibana/hooks'; import { APP_UI_ID } from '../../../../../../../common/constants'; import { EventFiltersPageLocation } from '../../../../event_filters/types'; -import { TrustedAppsListPageLocation } from '../../../../trusted_apps/state'; import { ArtifactListPageUrlParams } from '../../../../../components/artifact_list_page'; export const useGetLinkTo = ( @@ -19,10 +18,7 @@ export const useGetLinkTo = ( policyName: string, getPolicyArtifactsPath: (policyId: string) => string, getArtifactPath: ( - location?: - | Partial - | Partial - | Partial + location?: Partial | Partial ) => string, location?: Partial<{ show: 'create' }> ) => { diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/layout/policy_artifacts_layout.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/layout/policy_artifacts_layout.tsx index 92b0edc690a44..ac3cf9e536b9a 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/layout/policy_artifacts_layout.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/layout/policy_artifacts_layout.tsx @@ -32,7 +32,6 @@ import { PolicyArtifactsFlyout } from '../flyout'; import { PolicyArtifactsPageLabels, policyArtifactsPageLabels } from '../translations'; import { PolicyArtifactsDeleteModal } from '../delete_modal'; import { EventFiltersPageLocation } from '../../../../event_filters/types'; -import { TrustedAppsListPageLocation } from '../../../../trusted_apps/state'; import { ArtifactListPageUrlParams } from '../../../../../components/artifact_list_page'; interface PolicyArtifactsLayoutProps { @@ -42,10 +41,7 @@ interface PolicyArtifactsLayoutProps { getExceptionsListApiClient: () => ExceptionsListApiClient; searchableFields: readonly string[]; getArtifactPath: ( - location?: - | Partial - | Partial - | Partial + location?: Partial | Partial ) => string; getPolicyArtifactsPath: (policyId: string) => string; /** A boolean to check extra privileges for restricted actions, true when it's allowed, false when not */ diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/policy_artifacts_list.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/policy_artifacts_list.tsx index 863b7de4a4815..445725915899b 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/policy_artifacts_list.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/policy_artifacts_list.tsx @@ -29,7 +29,6 @@ import { ExceptionsListApiClient } from '../../../../../services/exceptions_list import { useListArtifact } from '../../../../../hooks/artifacts'; import { POLICY_ARTIFACT_LIST_LABELS } from './translations'; import { EventFiltersPageLocation } from '../../../../event_filters/types'; -import { TrustedAppsListPageLocation } from '../../../../trusted_apps/state'; import { ArtifactListPageUrlParams } from '../../../../../components/artifact_list_page'; interface PolicyArtifactsListProps { @@ -37,10 +36,7 @@ interface PolicyArtifactsListProps { apiClient: ExceptionsListApiClient; searchableFields: string[]; getArtifactPath: ( - location?: - | Partial - | Partial - | Partial + location?: Partial | Partial ) => string; getPolicyArtifactsPath: (policyId: string) => string; labels: typeof POLICY_ARTIFACT_LIST_LABELS; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/endpoint_package_custom_extension.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/endpoint_package_custom_extension.test.tsx index 6aba0483fc945..eff4671fe2fa0 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/endpoint_package_custom_extension.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/endpoint_package_custom_extension.test.tsx @@ -97,4 +97,16 @@ describe('When displaying the EndpointPackageCustomExtension fleet UI extension' expect(renderResult.queryByTestId('hostIsolationExceptions-fleetCard')).toBeNull(); }); }); + + it('should only show loading spinner if loading', () => { + useEndpointPrivilegesMock.mockReturnValue({ + ...getEndpointPrivilegesInitialStateMock(), + loading: true, + }); + render(); + + expect(renderResult.getByTestId('endpointExtensionLoadingSpinner')).toBeInTheDocument(); + expect(renderResult.queryByTestId('fleetEndpointPackageCustomContent')).toBeNull(); + expect(renderResult.queryByTestId('noIngestPermissions')).toBeNull(); + }); }); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/endpoint_package_custom_extension.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/endpoint_package_custom_extension.tsx index e6984087bef5a..72cc9852b0e7d 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/endpoint_package_custom_extension.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/endpoint_package_custom_extension.tsx @@ -6,11 +6,11 @@ */ import React, { memo, useMemo } from 'react'; -import { EuiSpacer } from '@elastic/eui'; +import { EuiSpacer, EuiLoadingSpinner } from '@elastic/eui'; import { PackageCustomExtensionComponentProps } from '@kbn/fleet-plugin/public'; import { useHttp } from '../../../../../../common/lib/kibana'; import { useCanSeeHostIsolationExceptionsMenu } from '../../../../host_isolation_exceptions/view/hooks'; -import { TrustedAppsApiClient } from '../../../../trusted_apps/service/trusted_apps_api_client'; +import { TrustedAppsApiClient } from '../../../../trusted_apps/service/api_client'; import { EventFiltersApiClient } from '../../../../event_filters/service/event_filters_api_client'; import { HostIsolationExceptionsApiClient } from '../../../../host_isolation_exceptions/host_isolation_exceptions_api_client'; import { BlocklistsApiClient } from '../../../../blocklist/services'; @@ -34,7 +34,7 @@ export const EndpointPackageCustomExtension = memo { const http = useHttp(); const canSeeHostIsolationExceptions = useCanSeeHostIsolationExceptionsMenu(); - const { canAccessEndpointManagement } = useEndpointPrivileges(); + const { loading, canAccessEndpointManagement } = useEndpointPrivileges(); const trustedAppsApiClientInstance = useMemo( () => TrustedAppsApiClient.getInstance(http), @@ -106,7 +106,13 @@ export const EndpointPackageCustomExtension = memo; + return loading ? ( + + ) : canAccessEndpointManagement ? ( + artifactCards + ) : ( + + ); } ); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_edit_extension.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_edit_extension.tsx index 87537014e6b0f..dfb2677ecb594 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_edit_extension.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_edit_extension.tsx @@ -36,7 +36,7 @@ import { FleetIntegrationArtifactsCard } from './endpoint_package_custom_extensi import { BlocklistsApiClient } from '../../../blocklist/services'; import { HostIsolationExceptionsApiClient } from '../../../host_isolation_exceptions/host_isolation_exceptions_api_client'; import { EventFiltersApiClient } from '../../../event_filters/service/event_filters_api_client'; -import { TrustedAppsApiClient } from '../../../trusted_apps/service/trusted_apps_api_client'; +import { TrustedAppsApiClient } from '../../../trusted_apps/service/api_client'; import { SEARCHABLE_FIELDS as BLOCKLIST_SEARCHABLE_FIELDS } from '../../../blocklist/constants'; import { SEARCHABLE_FIELDS as HOST_ISOLATION_EXCEPTIONS_SEARCHABLE_FIELDS } from '../../../host_isolation_exceptions/constants'; import { SEARCHABLE_FIELDS as EVENT_FILTERS_SEARCHABLE_FIELDS } from '../../../event_filters/constants'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/mocks.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/mocks.tsx index 908ebc22a19cd..daa44f01dbffd 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/mocks.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/mocks.tsx @@ -13,7 +13,7 @@ import { I18nProvider } from '@kbn/i18n-react'; import type { PackageInfo } from '@kbn/fleet-plugin/common/types'; import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; -import { QueryClient } from 'react-query'; +import { SecuritySolutionQueryClient } from '../../../../../common/containers/query_client/query_client_provider'; import { AppContextTestRender, createAppRootMockRenderer, @@ -85,7 +85,7 @@ export const createFleetContextRendererMock = (): AppContextTestRender => { additionalMiddleware: [mockedContext.middlewareSpy.actionSpyMiddleware], }); - const queryClient = new QueryClient(); + const queryClient = new SecuritySolutionQueryClient(); const Wrapper: RenderOptions['wrapper'] = ({ children }) => { const services = useMemo(() => { diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/with_security_context/render_context_providers.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/with_security_context/render_context_providers.tsx index 9b3472192a718..ec222de1713f0 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/with_security_context/render_context_providers.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/with_security_context/render_context_providers.tsx @@ -8,8 +8,10 @@ import React, { memo, PropsWithChildren } from 'react'; import { Provider as ReduxStoreProvider } from 'react-redux'; import { Store } from 'redux'; -import type { QueryClient } from 'react-query'; -import { ReactQueryClientProvider } from '../../../../../../common/containers/query_client/query_client_provider'; +import { + ReactQueryClientProvider, + SecuritySolutionQueryClient, +} from '../../../../../../common/containers/query_client/query_client_provider'; import { SecuritySolutionStartDependenciesContext } from '../../../../../../common/components/user_privileges/endpoint/security_solution_start_dependencies'; import { CurrentLicense } from '../../../../../../common/components/current_license'; import { StartPlugins } from '../../../../../../types'; @@ -17,7 +19,7 @@ import { StartPlugins } from '../../../../../../types'; export type RenderContextProvidersProps = PropsWithChildren<{ store: Store; depsStart: Pick; - queryClient?: QueryClient; + queryClient?: SecuritySolutionQueryClient; }>; export const RenderContextProviders = memo( diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/tabs/policy_tabs.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/tabs/policy_tabs.tsx index 62778bb164d98..f3a20a1abfd66 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/tabs/policy_tabs.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/tabs/policy_tabs.tsx @@ -41,7 +41,7 @@ import { POLICY_ARTIFACT_EVENT_FILTERS_LABELS } from './event_filters_translatio import { POLICY_ARTIFACT_TRUSTED_APPS_LABELS } from './trusted_apps_translations'; import { POLICY_ARTIFACT_HOST_ISOLATION_EXCEPTIONS_LABELS } from './host_isolation_exceptions_translations'; import { POLICY_ARTIFACT_BLOCKLISTS_LABELS } from './blocklists_translations'; -import { TrustedAppsApiClient } from '../../../trusted_apps/service/trusted_apps_api_client'; +import { TrustedAppsApiClient } from '../../../trusted_apps/service/api_client'; import { EventFiltersApiClient } from '../../../event_filters/service/event_filters_api_client'; import { BlocklistsApiClient } from '../../../blocklist/services/blocklists_api_client'; import { HostIsolationExceptionsApiClient } from '../../../host_isolation_exceptions/host_isolation_exceptions_api_client'; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/index.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/index.tsx index 018987c81b94d..d9edd9986e156 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/index.tsx @@ -6,16 +6,18 @@ */ import { Switch, Route } from 'react-router-dom'; -import React from 'react'; -import { TrustedAppsPage } from './view'; +import React, { memo } from 'react'; +import { TrustedAppsList } from './view/trusted_apps_list'; import { MANAGEMENT_ROUTING_TRUSTED_APPS_PATH } from '../../common/constants'; import { NotFoundPage } from '../../../app/404'; -export function TrustedAppsContainer() { +export const TrustedAppsContainer = memo(() => { return ( - + ); -} +}); + +TrustedAppsContainer.displayName = 'TrustedAppsContainer'; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/api_client.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/api_client.ts new file mode 100644 index 0000000000000..e66c16717e428 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/api_client.ts @@ -0,0 +1,65 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + CreateExceptionListItemSchema, + ExceptionListItemSchema, + UpdateExceptionListItemSchema, +} from '@kbn/securitysolution-io-ts-list-types'; +import { ENDPOINT_TRUSTED_APPS_LIST_ID } from '@kbn/securitysolution-list-constants'; + +import { HttpStart } from '@kbn/core/public'; +import { ConditionEntry } from '../../../../../common/endpoint/types'; +import { + conditionEntriesToEntries, + entriesToConditionEntries, +} from '../../../../common/utils/exception_list_items'; +import { ExceptionsListApiClient } from '../../../services/exceptions_list/exceptions_list_api_client'; +import { TRUSTED_APPS_EXCEPTION_LIST_DEFINITION } from '../constants'; + +function readTransform(item: ExceptionListItemSchema): ExceptionListItemSchema { + return { + ...item, + entries: entriesToConditionEntries(item.entries) as ExceptionListItemSchema['entries'], + }; +} + +function writeTransform( + item: T +): T { + return { + ...item, + entries: conditionEntriesToEntries(item.entries as ConditionEntry[], true), + } as T; +} + +/** + * Trusted Apps exceptions Api client class using ExceptionsListApiClient as base class + * It follows the Singleton pattern. + * Please, use the getInstance method instead of creating a new instance when using this implementation. + */ +export class TrustedAppsApiClient extends ExceptionsListApiClient { + constructor(http: HttpStart) { + super( + http, + ENDPOINT_TRUSTED_APPS_LIST_ID, + TRUSTED_APPS_EXCEPTION_LIST_DEFINITION, + readTransform, + writeTransform + ); + } + + public static getInstance(http: HttpStart): ExceptionsListApiClient { + return super.getInstance( + http, + ENDPOINT_TRUSTED_APPS_LIST_ID, + TRUSTED_APPS_EXCEPTION_LIST_DEFINITION, + readTransform, + writeTransform + ); + } +} diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/index.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/index.ts index 3c0d58043dd02..4b2dee13ce70a 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/index.ts +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/index.ts @@ -5,4 +5,4 @@ * 2.0. */ -export * from './trusted_apps_http_service'; +export { TrustedAppsApiClient } from './api_client'; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/trusted_apps_api_client.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/trusted_apps_api_client.ts deleted file mode 100644 index 574f32dca6b33..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/trusted_apps_api_client.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { ENDPOINT_TRUSTED_APPS_LIST_ID } from '@kbn/securitysolution-list-constants'; -import { HttpStart } from '@kbn/core/public'; -import { ExceptionsListApiClient } from '../../../services/exceptions_list/exceptions_list_api_client'; -import { TRUSTED_APPS_EXCEPTION_LIST_DEFINITION } from '../constants'; - -/** - * Trusted apps Api client class using ExceptionsListApiClient as base class - * It follow the Singleton pattern. - * Please, use the getInstance method instead of creating a new instance when using this implementation. - */ -export class TrustedAppsApiClient extends ExceptionsListApiClient { - constructor(http: HttpStart) { - super(http, ENDPOINT_TRUSTED_APPS_LIST_ID, TRUSTED_APPS_EXCEPTION_LIST_DEFINITION); - } - - public static getInstance(http: HttpStart): ExceptionsListApiClient { - return super.getInstance( - http, - ENDPOINT_TRUSTED_APPS_LIST_ID, - TRUSTED_APPS_EXCEPTION_LIST_DEFINITION - ); - } -} diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/trusted_apps_http_service.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/trusted_apps_http_service.ts deleted file mode 100644 index a16ccd9169dbe..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/trusted_apps_http_service.ts +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - ExceptionListItemSchema, - ExceptionListSchema, - ExceptionListSummarySchema, - FoundExceptionListItemSchema, -} from '@kbn/securitysolution-io-ts-list-types'; -import { - ENDPOINT_TRUSTED_APPS_LIST_ID, - EXCEPTION_LIST_ITEM_URL, - EXCEPTION_LIST_URL, -} from '@kbn/securitysolution-list-constants'; -import { HttpStart } from '@kbn/core/public'; -import pMap from 'p-map'; -import { toUpdateTrustedApp } from '../../../../../common/endpoint/service/trusted_apps/to_update_trusted_app'; -import { - DeleteTrustedAppsRequestParams, - GetOneTrustedAppRequestParams, - GetOneTrustedAppResponse, - GetTrustedAppsListRequest, - GetTrustedAppsListResponse, - MaybeImmutable, - PostTrustedAppCreateRequest, - PostTrustedAppCreateResponse, - PutTrustedAppsRequestParams, - PutTrustedAppUpdateRequest, - PutTrustedAppUpdateResponse, - TrustedApp, -} from '../../../../../common/endpoint/types'; -import { sendGetEndpointSpecificPackagePolicies } from '../../../services/policies/policies'; -import { TRUSTED_APPS_EXCEPTION_LIST_DEFINITION } from '../constants'; -import { isGlobalEffectScope } from '../state/type_guards'; -import { - exceptionListItemToTrustedApp, - newTrustedAppToCreateExceptionListItem, - updatedTrustedAppToUpdateExceptionListItem, -} from './mappers'; -import { validateTrustedAppHttpRequestBody } from './validate_trusted_app_http_request_body'; - -export interface TrustedAppsService { - getTrustedApp(params: GetOneTrustedAppRequestParams): Promise; - - getTrustedAppsList(request: GetTrustedAppsListRequest): Promise; - - deleteTrustedApp(request: DeleteTrustedAppsRequestParams): Promise; - - createTrustedApp(request: PostTrustedAppCreateRequest): Promise; - - updateTrustedApp( - params: PutTrustedAppsRequestParams, - request: PutTrustedAppUpdateRequest - ): Promise; - - getPolicyList( - options?: Parameters[1] - ): ReturnType; - - assignPolicyToTrustedApps( - policyId: string, - trustedApps: MaybeImmutable - ): Promise; - - removePolicyFromTrustedApps( - policyId: string, - trustedApps: MaybeImmutable - ): Promise; -} - -const P_MAP_OPTIONS = Object.freeze({ - concurrency: 5, - /** When set to false, instead of stopping when a promise rejects, it will wait for all the promises to settle - * and then reject with an aggregated error containing all the errors from the rejected promises. */ - stopOnError: false, -}); - -export class TrustedAppsHttpService implements TrustedAppsService { - private readonly getHttpService: () => Promise; - - constructor(http: HttpStart) { - let ensureListExists: Promise; - - this.getHttpService = async () => { - if (!ensureListExists) { - ensureListExists = http - .post(EXCEPTION_LIST_URL, { - body: JSON.stringify(TRUSTED_APPS_EXCEPTION_LIST_DEFINITION), - }) - .then(() => {}) - .catch((err) => { - if (err.response.status !== 409) { - return Promise.reject(err); - } - }); - } - - await ensureListExists; - return http; - }; - } - - private async getExceptionListItem(itemId: string): Promise { - return (await this.getHttpService()).get(EXCEPTION_LIST_ITEM_URL, { - query: { - item_id: itemId, - namespace_type: 'agnostic', - }, - }); - } - - async getTrustedApp(params: GetOneTrustedAppRequestParams) { - const exceptionItem = await this.getExceptionListItem(params.id); - - return { - data: exceptionListItemToTrustedApp(exceptionItem), - }; - } - - async getTrustedAppsList({ - page = 1, - per_page: perPage = 10, - kuery, - }: GetTrustedAppsListRequest): Promise { - const itemListResults = await ( - await this.getHttpService() - ).get(`${EXCEPTION_LIST_ITEM_URL}/_find`, { - query: { - page, - per_page: perPage, - filter: kuery, - sort_field: 'name', - sort_order: 'asc', - list_id: [ENDPOINT_TRUSTED_APPS_LIST_ID], - namespace_type: ['agnostic'], - }, - }); - - return { - ...itemListResults, - data: itemListResults.data.map(exceptionListItemToTrustedApp), - }; - } - - async deleteTrustedApp(request: DeleteTrustedAppsRequestParams): Promise { - await ( - await this.getHttpService() - ).delete(EXCEPTION_LIST_ITEM_URL, { - query: { - item_id: request.id, - namespace_type: 'agnostic', - }, - }); - } - - async createTrustedApp(request: PostTrustedAppCreateRequest) { - await validateTrustedAppHttpRequestBody(await this.getHttpService(), request); - - const newTrustedAppException = newTrustedAppToCreateExceptionListItem(request); - const createdExceptionItem = await ( - await this.getHttpService() - ).post(EXCEPTION_LIST_ITEM_URL, { - body: JSON.stringify(newTrustedAppException), - }); - - return { - data: exceptionListItemToTrustedApp(createdExceptionItem), - }; - } - - async updateTrustedApp( - params: PutTrustedAppsRequestParams, - updatedTrustedApp: PutTrustedAppUpdateRequest - ) { - const [currentExceptionListItem] = await Promise.all([ - await this.getExceptionListItem(params.id), - await validateTrustedAppHttpRequestBody(await this.getHttpService(), updatedTrustedApp), - ]); - - const updatedExceptionListItem = await ( - await this.getHttpService() - ).put(EXCEPTION_LIST_ITEM_URL, { - body: JSON.stringify( - updatedTrustedAppToUpdateExceptionListItem(currentExceptionListItem, updatedTrustedApp) - ), - }); - - return { - data: exceptionListItemToTrustedApp(updatedExceptionListItem), - }; - } - - async getTrustedAppsSummary(filter?: string) { - return (await this.getHttpService()).get( - `${EXCEPTION_LIST_URL}/summary`, - { - query: { - filter, - list_id: ENDPOINT_TRUSTED_APPS_LIST_ID, - namespace_type: 'agnostic', - }, - } - ); - } - - async getPolicyList(options?: Parameters[1]) { - return sendGetEndpointSpecificPackagePolicies(await this.getHttpService(), options); - } - - /** - * Assign a policy to trusted apps. Note that Trusted Apps MUST NOT be global - * - * @param policyId - * @param trustedApps[] - */ - assignPolicyToTrustedApps( - policyId: string, - trustedApps: MaybeImmutable - ): Promise { - return this._handleAssignOrRemovePolicyId('assign', policyId, trustedApps); - } - - /** - * Remove a policy from trusted apps. Note that Trusted Apps MUST NOT be global - * - * @param policyId - * @param trustedApps[] - */ - removePolicyFromTrustedApps( - policyId: string, - trustedApps: MaybeImmutable - ): Promise { - return this._handleAssignOrRemovePolicyId('remove', policyId, trustedApps); - } - - private _handleAssignOrRemovePolicyId( - action: 'assign' | 'remove', - policyId: string, - trustedApps: MaybeImmutable - ): Promise { - if (policyId.trim() === '') { - throw new Error('policy ID is required'); - } - - if (trustedApps.length === 0) { - throw new Error('at least one trusted app is required'); - } - - return pMap( - trustedApps, - async (trustedApp) => { - if (isGlobalEffectScope(trustedApp.effectScope)) { - throw new Error( - `Unable to update trusted app [${trustedApp.id}] policy assignment. It's effectScope is 'global'` - ); - } - - const policies: string[] = !isGlobalEffectScope(trustedApp.effectScope) - ? [...trustedApp.effectScope.policies] - : []; - - const indexOfPolicyId = policies.indexOf(policyId); - - if (action === 'assign' && indexOfPolicyId === -1) { - policies.push(policyId); - } else if (action === 'remove' && indexOfPolicyId !== -1) { - policies.splice(indexOfPolicyId, 1); - } - - return this.updateTrustedApp( - { id: trustedApp.id }, - { - ...toUpdateTrustedApp(trustedApp), - effectScope: { - type: 'policy', - policies, - }, - } - ); - }, - P_MAP_OPTIONS - ); - } -} diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/validate_trusted_app_http_request_body.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/validate_trusted_app_http_request_body.ts deleted file mode 100644 index 69b281e88fc9b..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/validate_trusted_app_http_request_body.ts +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { HttpStart } from '@kbn/core/public'; -import { AGENT_POLICY_SAVED_OBJECT_TYPE } from '@kbn/fleet-plugin/common'; -import { - PostTrustedAppCreateRequest, - PutTrustedAppUpdateRequest, -} from '../../../../../common/endpoint/types'; -import { HttpRequestValidationError } from './errors'; -import { sendGetAgentPolicyList } from '../../../services/policies/ingest'; - -/** - * Validates that the Trusted App is valid for sending to the API (`POST` + 'PUT') - * - * @throws - */ -export const validateTrustedAppHttpRequestBody = async ( - http: HttpStart, - trustedApp: PostTrustedAppCreateRequest | PutTrustedAppUpdateRequest -): Promise => { - const failedValidations: string[] = []; - - // Validate that the Policy IDs are still valid - if (trustedApp.effectScope.type === 'policy' && trustedApp.effectScope.policies.length) { - const policyIds = trustedApp.effectScope.policies; - - // We can't search against the Package Policy API by ID because there is no way to do that. - // So, as a work-around, we use the Agent Policy API and check for those Agent Policies that - // have these package policies in it. For endpoint, these are 1-to-1. - const agentPoliciesFound = await sendGetAgentPolicyList(http, { - query: { - kuery: `${AGENT_POLICY_SAVED_OBJECT_TYPE}.package_policies: (${policyIds.join(' or ')})`, - }, - }); - - if (!agentPoliciesFound.items.length) { - failedValidations.push(`Invalid Policy Id(s) [${policyIds.join(', ')}]`); - } else { - const missingPolicies = policyIds.filter( - (policyId) => - !agentPoliciesFound.items.find(({ package_policies: packagePolicies }) => - (packagePolicies as string[]).includes(policyId) - ) - ); - - if (missingPolicies.length) { - failedValidations.push(`Invalid Policy Id(s) [${missingPolicies.join(', ')}]`); - } - } - } - - if (failedValidations.length) { - throw new HttpRequestValidationError(failedValidations); - } -}; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/state/index.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/state/index.ts deleted file mode 100644 index a06fceab29d4c..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/state/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export * from '../../../state/async_resource_state'; -export * from './trusted_apps_list_page_state'; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/state/trusted_apps_list_page_state.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/state/trusted_apps_list_page_state.ts deleted file mode 100644 index 292b982eebb47..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/state/trusted_apps_list_page_state.ts +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { NewTrustedApp, TrustedApp } from '../../../../../common/endpoint/types/trusted_apps'; -import { AsyncResourceState } from '../../../state/async_resource_state'; -import { GetPolicyListResponse } from '../../policy/types'; - -export interface Pagination { - pageIndex: number; - pageSize: number; - totalItemCount: number; - pageSizeOptions: number[]; -} - -export interface TrustedAppsListData { - items: TrustedApp[]; - pageIndex: number; - pageSize: number; - timestamp: number; - totalItemsCount: number; - filter: string; - includedPolicies: string; -} - -export type ViewType = 'list' | 'grid'; - -export interface TrustedAppsListPageLocation { - page_index: number; - page_size: number; - view_type: ViewType; - show?: 'create' | 'edit'; - /** Used for editing. The ID of the selected trusted app */ - id?: string; - filter: string; - // A string with comma dlimetered list of included policy IDs - included_policies: string; -} - -export interface TrustedAppsListPageState { - /** Represents if trusted apps entries exist, regardless of whether the list is showing results - * or not (which could use filtering in the future) - */ - entriesExist: AsyncResourceState; - listView: { - listResourceState: AsyncResourceState; - freshDataTimestamp: number; - }; - deletionDialog: { - entry?: TrustedApp; - confirmed: boolean; - submissionResourceState: AsyncResourceState; - }; - creationDialog: { - formState?: { - entry: NewTrustedApp; - isValid: boolean; - }; - /** The trusted app to be edited (when in edit mode) */ - editItem?: AsyncResourceState; - confirmed: boolean; - submissionResourceState: AsyncResourceState; - }; - /** A list of all available polices for use in associating TA to policies */ - policies: AsyncResourceState; - location: TrustedAppsListPageLocation; - active: boolean; - forceRefresh: boolean; -} diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/state/type_guards.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/state/type_guards.ts index 1a28e6f3bfecf..239255b641bf4 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/state/type_guards.ts +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/state/type_guards.ts @@ -8,11 +8,7 @@ import { ConditionEntryField } from '@kbn/securitysolution-utils'; import { TrustedAppConditionEntry, - EffectScope, - GlobalEffectScope, MacosLinuxConditionEntry, - MaybeImmutable, - PolicyEffectScope, WindowsConditionEntry, } from '../../../../../common/endpoint/types'; @@ -27,15 +23,3 @@ export const isMacosLinuxTrustedAppCondition = ( ): condition is MacosLinuxConditionEntry => { return condition.field !== ConditionEntryField.SIGNER; }; - -export const isGlobalEffectScope = ( - effectedScope: MaybeImmutable -): effectedScope is GlobalEffectScope => { - return effectedScope.type === 'global'; -}; - -export const isPolicyEffectScope = ( - effectedScope: MaybeImmutable -): effectedScope is PolicyEffectScope => { - return effectedScope.type === 'policy'; -}; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/action.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/action.ts deleted file mode 100644 index f9965da4a2256..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/action.ts +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { Action } from 'redux'; - -import { NewTrustedApp, TrustedApp } from '../../../../../common/endpoint/types'; -import { AsyncResourceState, TrustedAppsListData } from '../state'; -import { GetPolicyListResponse } from '../../policy/types'; - -export type TrustedAppsListDataOutdated = Action<'trustedAppsListDataOutdated'>; - -interface ResourceStateChanged extends Action { - payload: { newState: AsyncResourceState }; -} - -export type TrustedAppsListResourceStateChanged = ResourceStateChanged< - 'trustedAppsListResourceStateChanged', - TrustedAppsListData ->; - -export type TrustedAppDeletionSubmissionResourceStateChanged = - ResourceStateChanged<'trustedAppDeletionSubmissionResourceStateChanged'>; - -export type TrustedAppDeletionDialogStarted = Action<'trustedAppDeletionDialogStarted'> & { - payload: { - entry: TrustedApp; - }; -}; - -export type TrustedAppDeletionDialogConfirmed = Action<'trustedAppDeletionDialogConfirmed'>; - -export type TrustedAppDeletionDialogClosed = Action<'trustedAppDeletionDialogClosed'>; - -export type TrustedAppCreationSubmissionResourceStateChanged = ResourceStateChanged< - 'trustedAppCreationSubmissionResourceStateChanged', - TrustedApp ->; - -export type TrustedAppCreationDialogStarted = Action<'trustedAppCreationDialogStarted'> & { - payload: { - entry: NewTrustedApp; - }; -}; - -export type TrustedAppCreationDialogFormStateUpdated = - Action<'trustedAppCreationDialogFormStateUpdated'> & { - payload: { - entry: NewTrustedApp; - isValid: boolean; - }; - }; - -export type TrustedAppCreationEditItemStateChanged = - Action<'trustedAppCreationEditItemStateChanged'> & { - payload: AsyncResourceState; - }; - -export type TrustedAppCreationDialogConfirmed = Action<'trustedAppCreationDialogConfirmed'>; - -export type TrustedAppCreationDialogClosed = Action<'trustedAppCreationDialogClosed'>; - -export type TrustedAppsExistResponse = Action<'trustedAppsExistStateChanged'> & { - payload: AsyncResourceState; -}; - -export type TrustedAppsPoliciesStateChanged = Action<'trustedAppsPoliciesStateChanged'> & { - payload: AsyncResourceState; -}; - -export type TrustedAppForceRefresh = Action<'trustedAppForceRefresh'> & { - payload: { - forceRefresh: boolean; - }; -}; - -export type TrustedAppsPageAction = - | TrustedAppsListDataOutdated - | TrustedAppsListResourceStateChanged - | TrustedAppDeletionSubmissionResourceStateChanged - | TrustedAppDeletionDialogStarted - | TrustedAppDeletionDialogConfirmed - | TrustedAppDeletionDialogClosed - | TrustedAppCreationSubmissionResourceStateChanged - | TrustedAppCreationEditItemStateChanged - | TrustedAppCreationDialogStarted - | TrustedAppCreationDialogFormStateUpdated - | TrustedAppCreationDialogConfirmed - | TrustedAppsExistResponse - | TrustedAppsPoliciesStateChanged - | TrustedAppCreationDialogClosed - | TrustedAppForceRefresh; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/builders.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/builders.ts deleted file mode 100644 index f0fab98188927..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/builders.ts +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { ConditionEntryField, OperatingSystem } from '@kbn/securitysolution-utils'; -import { TrustedAppConditionEntry, NewTrustedApp } from '../../../../../common/endpoint/types'; - -import { MANAGEMENT_DEFAULT_PAGE, MANAGEMENT_DEFAULT_PAGE_SIZE } from '../../../common/constants'; - -import { TrustedAppsListPageState } from '../state'; - -export const defaultConditionEntry = (): TrustedAppConditionEntry => ({ - field: ConditionEntryField.HASH, - operator: 'included', - type: 'match', - value: '', -}); - -export const defaultNewTrustedApp = (): NewTrustedApp => ({ - name: '', - os: OperatingSystem.WINDOWS, - entries: [defaultConditionEntry()], - description: '', - effectScope: { type: 'global' }, -}); - -export const initialDeletionDialogState = (): TrustedAppsListPageState['deletionDialog'] => ({ - confirmed: false, - submissionResourceState: { type: 'UninitialisedResourceState' }, -}); - -export const initialCreationDialogState = (): TrustedAppsListPageState['creationDialog'] => ({ - confirmed: false, - submissionResourceState: { type: 'UninitialisedResourceState' }, -}); - -export const initialTrustedAppsPageState = (): TrustedAppsListPageState => ({ - entriesExist: { type: 'UninitialisedResourceState' }, - listView: { - listResourceState: { type: 'UninitialisedResourceState' }, - freshDataTimestamp: Date.now(), - }, - deletionDialog: initialDeletionDialogState(), - creationDialog: initialCreationDialogState(), - policies: { type: 'UninitialisedResourceState' }, - location: { - page_index: MANAGEMENT_DEFAULT_PAGE, - page_size: MANAGEMENT_DEFAULT_PAGE_SIZE, - show: undefined, - id: undefined, - view_type: 'grid', - filter: '', - included_policies: '', - }, - active: false, - forceRefresh: false, -}); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.test.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.test.ts deleted file mode 100644 index 4455baddb047c..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.test.ts +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { applyMiddleware, createStore } from 'redux'; - -import { createSpyMiddleware } from '../../../../common/store/test_utils'; - -import { - createDefaultPagination, - createListLoadedResourceState, - createLoadedListViewWithPagination, - createSampleTrustedApp, - createSampleTrustedApps, - createServerApiError, - createUninitialisedResourceState, - createUserChangedUrlAction, -} from '../test_utils'; - -import { TrustedAppsService } from '../service'; -import { Pagination, TrustedAppsListPageLocation, TrustedAppsListPageState } from '../state'; -import { initialTrustedAppsPageState } from './builders'; -import { trustedAppsPageReducer } from './reducer'; -import { createTrustedAppsPageMiddleware } from './middleware'; -import { Immutable } from '../../../../../common/endpoint/types'; -import { getGeneratedPolicyResponse } from './mocks'; - -const initialNow = 111111; -const dateNowMock = jest.fn(); -dateNowMock.mockReturnValue(initialNow); - -Date.now = dateNowMock; - -const initialState: Immutable = initialTrustedAppsPageState(); - -const createGetTrustedListAppsResponse = (pagination: Partial) => { - const fullPagination = { ...createDefaultPagination(), ...pagination }; - - return { - data: createSampleTrustedApps(pagination), - page: fullPagination.pageIndex, - per_page: fullPagination.pageSize, - total: fullPagination.totalItemCount, - }; -}; - -const createTrustedAppsServiceMock = (): jest.Mocked => ({ - getTrustedAppsList: jest.fn(), - deleteTrustedApp: jest.fn(), - createTrustedApp: jest.fn(), - getPolicyList: jest.fn(), - updateTrustedApp: jest.fn(), - getTrustedApp: jest.fn(), - assignPolicyToTrustedApps: jest.fn(), - removePolicyFromTrustedApps: jest.fn(), -}); - -const createStoreSetup = (trustedAppsService: TrustedAppsService) => { - const spyMiddleware = createSpyMiddleware(); - - return { - spyMiddleware, - store: createStore( - trustedAppsPageReducer, - applyMiddleware( - createTrustedAppsPageMiddleware(trustedAppsService), - spyMiddleware.actionSpyMiddleware - ) - ), - }; -}; - -describe('middleware', () => { - type TrustedAppsEntriesExistState = Pick; - const entriesExistLoadedState = (): TrustedAppsEntriesExistState => { - return { - entriesExist: { - data: true, - type: 'LoadedResourceState', - }, - }; - }; - const entriesExistLoadingState = (): TrustedAppsEntriesExistState => { - return { - entriesExist: { - previousState: { - type: 'UninitialisedResourceState', - }, - type: 'LoadingResourceState', - }, - }; - }; - - const createLocationState = ( - params?: Partial - ): TrustedAppsListPageLocation => { - return { - ...initialState.location, - ...(params ?? {}), - }; - }; - - beforeEach(() => { - dateNowMock.mockReturnValue(initialNow); - }); - - describe('initial state', () => { - it('sets initial state properly', async () => { - expect(createStoreSetup(createTrustedAppsServiceMock()).store.getState()).toStrictEqual( - initialState - ); - }); - }); - - describe('refreshing list resource state', () => { - it('refreshes the list when location changes and data gets outdated', async () => { - const pagination = { pageIndex: 2, pageSize: 50 }; - const location = createLocationState({ - page_index: 2, - page_size: 50, - }); - const service = createTrustedAppsServiceMock(); - const { store, spyMiddleware } = createStoreSetup(service); - - service.getTrustedAppsList.mockResolvedValue(createGetTrustedListAppsResponse(pagination)); - - store.dispatch( - createUserChangedUrlAction('/administration/trusted_apps', '?page_index=2&page_size=50') - ); - - expect(store.getState()).toStrictEqual({ - ...initialState, - listView: { - listResourceState: { - type: 'LoadingResourceState', - previousState: createUninitialisedResourceState(), - }, - freshDataTimestamp: initialNow, - }, - active: true, - location, - }); - - await spyMiddleware.waitForAction('trustedAppsListResourceStateChanged'); - - expect(store.getState()).toStrictEqual({ - ...initialState, - ...entriesExistLoadingState(), - listView: createLoadedListViewWithPagination(initialNow, pagination), - active: true, - location, - }); - }); - - it('does not refresh the list when location changes and data does not get outdated', async () => { - const pagination = { pageIndex: 2, pageSize: 50 }; - const location = createLocationState({ - page_index: 2, - page_size: 50, - }); - const service = createTrustedAppsServiceMock(); - const { store, spyMiddleware } = createStoreSetup(service); - - service.getTrustedAppsList.mockResolvedValue(createGetTrustedListAppsResponse(pagination)); - - store.dispatch( - createUserChangedUrlAction('/administration/trusted_apps', '?page_index=2&page_size=50') - ); - - await spyMiddleware.waitForAction('trustedAppsListResourceStateChanged'); - - store.dispatch( - createUserChangedUrlAction('/administration/trusted_apps', '?page_index=2&page_size=50') - ); - - expect(service.getTrustedAppsList).toBeCalledTimes(2); - expect(store.getState()).toStrictEqual({ - ...initialState, - ...entriesExistLoadingState(), - listView: createLoadedListViewWithPagination(initialNow, pagination), - active: true, - location, - }); - }); - - it('refreshes the list when data gets outdated with and outdate action', async () => { - const newNow = 222222; - const pagination = { pageIndex: 0, pageSize: 10 }; - const location = createLocationState(); - const service = createTrustedAppsServiceMock(); - const { store, spyMiddleware } = createStoreSetup(service); - const policiesResponse = getGeneratedPolicyResponse(); - - service.getTrustedAppsList.mockResolvedValue(createGetTrustedListAppsResponse(pagination)); - service.getPolicyList.mockResolvedValue(policiesResponse); - - store.dispatch(createUserChangedUrlAction('/administration/trusted_apps')); - - await spyMiddleware.waitForAction('trustedAppsListResourceStateChanged'); - - dateNowMock.mockReturnValue(newNow); - - store.dispatch({ type: 'trustedAppsListDataOutdated' }); - - expect(store.getState()).toStrictEqual({ - ...initialState, - ...entriesExistLoadingState(), - listView: { - listResourceState: { - type: 'LoadingResourceState', - previousState: createListLoadedResourceState(pagination, initialNow), - }, - freshDataTimestamp: newNow, - }, - active: true, - location, - }); - - await spyMiddleware.waitForAction('trustedAppsListResourceStateChanged'); - await spyMiddleware.waitForAction('trustedAppsPoliciesStateChanged'); - - expect(store.getState()).toStrictEqual({ - ...initialState, - ...entriesExistLoadedState(), - policies: { - data: policiesResponse, - type: 'LoadedResourceState', - }, - listView: createLoadedListViewWithPagination(newNow, pagination), - active: true, - location, - }); - }); - - it('set list resource state to failed when failing to load data', async () => { - const service = createTrustedAppsServiceMock(); - const { store, spyMiddleware } = createStoreSetup(service); - - service.getTrustedAppsList.mockRejectedValue({ - body: createServerApiError('Internal Server Error'), - }); - - store.dispatch( - createUserChangedUrlAction('/administration/trusted_apps', '?page_index=2&page_size=50') - ); - - await spyMiddleware.waitForAction('trustedAppsListResourceStateChanged'); - - expect(store.getState()).toStrictEqual({ - ...initialState, - ...entriesExistLoadingState(), - listView: { - listResourceState: { - type: 'FailedResourceState', - error: createServerApiError('Internal Server Error'), - lastLoadedState: undefined, - }, - freshDataTimestamp: initialNow, - }, - active: true, - location: createLocationState({ - page_index: 2, - page_size: 50, - }), - }); - - const infiniteLoopTest = async () => { - await spyMiddleware.waitForAction('trustedAppsListResourceStateChanged'); - }; - - await expect(infiniteLoopTest).rejects.not.toBeNull(); - }); - }); - - describe('submitting deletion dialog', () => { - const newNow = 222222; - const entry = createSampleTrustedApp(3); - const notFoundError = createServerApiError('Not Found'); - const pagination = { pageIndex: 0, pageSize: 10 }; - const location = createLocationState(); - const getTrustedAppsListResponse = createGetTrustedListAppsResponse(pagination); - const listView = createLoadedListViewWithPagination(initialNow, pagination); - const listViewNew = createLoadedListViewWithPagination(newNow, pagination); - const testStartState = { - ...initialState, - ...entriesExistLoadingState(), - listView, - active: true, - location, - }; - - it('does not submit when entry is undefined', async () => { - const service = createTrustedAppsServiceMock(); - const { store, spyMiddleware } = createStoreSetup(service); - - service.getTrustedAppsList.mockResolvedValue(getTrustedAppsListResponse); - service.deleteTrustedApp.mockResolvedValue(); - - store.dispatch(createUserChangedUrlAction('/administration/trusted_apps')); - - await spyMiddleware.waitForAction('trustedAppsListResourceStateChanged'); - - store.dispatch({ type: 'trustedAppDeletionDialogConfirmed' }); - - expect(store.getState()).toStrictEqual({ - ...testStartState, - deletionDialog: { ...testStartState.deletionDialog, confirmed: true }, - }); - }); - - it('submits successfully when entry is defined', async () => { - const service = createTrustedAppsServiceMock(); - const { store, spyMiddleware } = createStoreSetup(service); - const policiesResponse = getGeneratedPolicyResponse(); - - service.getTrustedAppsList.mockResolvedValue(getTrustedAppsListResponse); - service.deleteTrustedApp.mockResolvedValue(); - service.getPolicyList.mockResolvedValue(policiesResponse); - - store.dispatch(createUserChangedUrlAction('/administration/trusted_apps')); - - await spyMiddleware.waitForAction('trustedAppsListResourceStateChanged'); - - dateNowMock.mockReturnValue(newNow); - - store.dispatch({ type: 'trustedAppDeletionDialogStarted', payload: { entry } }); - store.dispatch({ type: 'trustedAppDeletionDialogConfirmed' }); - - expect(store.getState()).toStrictEqual({ - ...testStartState, - deletionDialog: { - entry, - confirmed: true, - submissionResourceState: { - type: 'LoadingResourceState', - previousState: { type: 'UninitialisedResourceState' }, - }, - }, - }); - - await spyMiddleware.waitForAction('trustedAppDeletionSubmissionResourceStateChanged'); - await spyMiddleware.waitForAction('trustedAppsListResourceStateChanged'); - - expect(store.getState()).toStrictEqual({ - ...testStartState, - ...entriesExistLoadedState(), - policies: { - data: policiesResponse, - type: 'LoadedResourceState', - }, - listView: listViewNew, - }); - expect(service.deleteTrustedApp).toBeCalledWith({ id: '3' }); - expect(service.deleteTrustedApp).toBeCalledTimes(1); - }); - - it('does not submit twice', async () => { - const service = createTrustedAppsServiceMock(); - const { store, spyMiddleware } = createStoreSetup(service); - const policiesResponse = getGeneratedPolicyResponse(); - - service.getTrustedAppsList.mockResolvedValue(getTrustedAppsListResponse); - service.deleteTrustedApp.mockResolvedValue(); - service.getPolicyList.mockResolvedValue(policiesResponse); - - store.dispatch(createUserChangedUrlAction('/administration/trusted_apps')); - - await spyMiddleware.waitForAction('trustedAppsListResourceStateChanged'); - - dateNowMock.mockReturnValue(newNow); - - store.dispatch({ type: 'trustedAppDeletionDialogStarted', payload: { entry } }); - store.dispatch({ type: 'trustedAppDeletionDialogConfirmed' }); - store.dispatch({ type: 'trustedAppDeletionDialogConfirmed' }); - - expect(store.getState()).toStrictEqual({ - ...testStartState, - deletionDialog: { - entry, - confirmed: true, - submissionResourceState: { - type: 'LoadingResourceState', - previousState: { type: 'UninitialisedResourceState' }, - }, - }, - }); - - await spyMiddleware.waitForAction('trustedAppDeletionSubmissionResourceStateChanged'); - await spyMiddleware.waitForAction('trustedAppsListResourceStateChanged'); - - expect(store.getState()).toStrictEqual({ - ...testStartState, - ...entriesExistLoadedState(), - policies: { - data: policiesResponse, - type: 'LoadedResourceState', - }, - listView: listViewNew, - }); - expect(service.deleteTrustedApp).toBeCalledWith({ id: '3' }); - expect(service.deleteTrustedApp).toBeCalledTimes(1); - }); - - it('does not submit when server response with failure', async () => { - const service = createTrustedAppsServiceMock(); - const { store, spyMiddleware } = createStoreSetup(service); - const policiesResponse = getGeneratedPolicyResponse(); - - service.getTrustedAppsList.mockResolvedValue(getTrustedAppsListResponse); - service.deleteTrustedApp.mockRejectedValue({ body: notFoundError }); - service.getPolicyList.mockResolvedValue(policiesResponse); - - store.dispatch(createUserChangedUrlAction('/administration/trusted_apps')); - - await spyMiddleware.waitForAction('trustedAppsListResourceStateChanged'); - - store.dispatch({ type: 'trustedAppDeletionDialogStarted', payload: { entry } }); - store.dispatch({ type: 'trustedAppDeletionDialogConfirmed' }); - - expect(store.getState()).toStrictEqual({ - ...testStartState, - deletionDialog: { - entry, - confirmed: true, - submissionResourceState: { - type: 'LoadingResourceState', - previousState: { type: 'UninitialisedResourceState' }, - }, - }, - }); - - await spyMiddleware.waitForAction('trustedAppDeletionSubmissionResourceStateChanged'); - await spyMiddleware.waitForAction('trustedAppsPoliciesStateChanged'); - - expect(store.getState()).toStrictEqual({ - ...testStartState, - ...entriesExistLoadedState(), - policies: { - data: policiesResponse, - type: 'LoadedResourceState', - }, - deletionDialog: { - entry, - confirmed: true, - submissionResourceState: { - type: 'FailedResourceState', - error: notFoundError, - lastLoadedState: undefined, - }, - }, - }); - expect(service.deleteTrustedApp).toBeCalledWith({ id: '3' }); - expect(service.deleteTrustedApp).toBeCalledTimes(1); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.ts deleted file mode 100644 index cd39ee27353e9..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.ts +++ /dev/null @@ -1,477 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; -import { - Immutable, - PostTrustedAppCreateRequest, - TrustedApp, -} from '../../../../../common/endpoint/types'; -import { AppAction } from '../../../../common/store/actions'; -import { - ImmutableMiddleware, - ImmutableMiddlewareAPI, - ImmutableMiddlewareFactory, -} from '../../../../common/store'; - -import { TrustedAppsHttpService, TrustedAppsService } from '../service'; - -import { - AsyncResourceState, - getLastLoadedResourceState, - isLoadedResourceState, - isLoadingResourceState, - isStaleResourceState, - isUninitialisedResourceState, - StaleResourceState, - TrustedAppsListData, - TrustedAppsListPageState, -} from '../state'; - -import { defaultNewTrustedApp } from './builders'; - -import { - TrustedAppCreationSubmissionResourceStateChanged, - TrustedAppDeletionSubmissionResourceStateChanged, - TrustedAppsListResourceStateChanged, -} from './action'; - -import { - getListResourceState, - getDeletionDialogEntry, - getDeletionSubmissionResourceState, - getLastLoadedListResourceState, - getCurrentLocationPageIndex, - getCurrentLocationPageSize, - getCurrentLocationFilter, - needsRefreshOfListData, - getCreationSubmissionResourceState, - getCreationDialogFormEntry, - isCreationDialogLocation, - isCreationDialogFormValid, - entriesExist, - getListTotalItemsCount, - trustedAppsListPageActive, - entriesExistState, - policiesState, - isEdit, - isFetchingEditTrustedAppItem, - editItemId, - editingTrustedApp, - getListItems, - getCurrentLocationIncludedPolicies, -} from './selectors'; -import { parsePoliciesToKQL, parseQueryFilterToKQL } from '../../../common/utils'; -import { toUpdateTrustedApp } from '../../../../../common/endpoint/service/trusted_apps/to_update_trusted_app'; -import { SEARCHABLE_FIELDS } from '../constants'; - -const createTrustedAppsListResourceStateChangedAction = ( - newState: Immutable> -): Immutable => ({ - type: 'trustedAppsListResourceStateChanged', - payload: { newState }, -}); - -const refreshListIfNeeded = async ( - store: ImmutableMiddlewareAPI, - trustedAppsService: TrustedAppsService -) => { - if (needsRefreshOfListData(store.getState())) { - store.dispatch({ type: 'trustedAppForceRefresh', payload: { forceRefresh: false } }); - store.dispatch( - createTrustedAppsListResourceStateChangedAction({ - type: 'LoadingResourceState', - // need to think on how to avoid the casting - previousState: getListResourceState(store.getState()) as Immutable< - StaleResourceState - >, - }) - ); - - try { - const pageIndex = getCurrentLocationPageIndex(store.getState()); - const pageSize = getCurrentLocationPageSize(store.getState()); - const filter = getCurrentLocationFilter(store.getState()); - const includedPolicies = getCurrentLocationIncludedPolicies(store.getState()); - - const kuery = []; - - const filterKuery = parseQueryFilterToKQL(filter, SEARCHABLE_FIELDS) || undefined; - if (filterKuery) kuery.push(filterKuery); - - const policiesKuery = - parsePoliciesToKQL(includedPolicies ? includedPolicies.split(',') : []) || undefined; - if (policiesKuery) kuery.push(policiesKuery); - - const response = await trustedAppsService.getTrustedAppsList({ - page: pageIndex + 1, - per_page: pageSize, - kuery: kuery.join(' AND ') || undefined, - }); - - store.dispatch( - createTrustedAppsListResourceStateChangedAction({ - type: 'LoadedResourceState', - data: { - items: response.data, - pageIndex, - pageSize, - totalItemsCount: response.total, - timestamp: Date.now(), - filter, - includedPolicies, - }, - }) - ); - } catch (error) { - store.dispatch( - createTrustedAppsListResourceStateChangedAction({ - type: 'FailedResourceState', - error: error.body, - lastLoadedState: getLastLoadedListResourceState(store.getState()), - }) - ); - } - } -}; - -const updateCreationDialogIfNeeded = ( - store: ImmutableMiddlewareAPI -) => { - const newEntry = getCreationDialogFormEntry(store.getState()); - const shouldShow = isCreationDialogLocation(store.getState()); - - if (shouldShow && !newEntry) { - store.dispatch({ - type: 'trustedAppCreationDialogStarted', - payload: { entry: defaultNewTrustedApp() }, - }); - } else if (!shouldShow && newEntry) { - store.dispatch({ - type: 'trustedAppCreationDialogClosed', - }); - } -}; - -const createTrustedAppCreationSubmissionResourceStateChanged = ( - newState: Immutable> -): Immutable => ({ - type: 'trustedAppCreationSubmissionResourceStateChanged', - payload: { newState }, -}); - -const submitCreationIfNeeded = async ( - store: ImmutableMiddlewareAPI, - trustedAppsService: TrustedAppsService -) => { - const currentState = store.getState(); - const submissionResourceState = getCreationSubmissionResourceState(currentState); - const isValid = isCreationDialogFormValid(currentState); - const entry = getCreationDialogFormEntry(currentState); - const editMode = isEdit(currentState); - - if (isStaleResourceState(submissionResourceState) && entry !== undefined && isValid) { - store.dispatch( - createTrustedAppCreationSubmissionResourceStateChanged({ - type: 'LoadingResourceState', - previousState: submissionResourceState, - }) - ); - - try { - let responseTrustedApp: TrustedApp; - - if (editMode) { - responseTrustedApp = ( - await trustedAppsService.updateTrustedApp( - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - { id: editItemId(currentState)! }, - // TODO: try to remove the cast - entry as PostTrustedAppCreateRequest - ) - ).data; - } else { - // TODO: try to remove the cast - responseTrustedApp = ( - await trustedAppsService.createTrustedApp(entry as PostTrustedAppCreateRequest) - ).data; - } - - store.dispatch( - createTrustedAppCreationSubmissionResourceStateChanged({ - type: 'LoadedResourceState', - data: responseTrustedApp, - }) - ); - store.dispatch({ - type: 'trustedAppsListDataOutdated', - }); - } catch (error) { - store.dispatch( - createTrustedAppCreationSubmissionResourceStateChanged({ - type: 'FailedResourceState', - error: error.body, - lastLoadedState: getLastLoadedResourceState(submissionResourceState), - }) - ); - } - } -}; - -const createTrustedAppDeletionSubmissionResourceStateChanged = ( - newState: Immutable -): Immutable => ({ - type: 'trustedAppDeletionSubmissionResourceStateChanged', - payload: { newState }, -}); - -const submitDeletionIfNeeded = async ( - store: ImmutableMiddlewareAPI, - trustedAppsService: TrustedAppsService -) => { - const submissionResourceState = getDeletionSubmissionResourceState(store.getState()); - const entry = getDeletionDialogEntry(store.getState()); - - if (isStaleResourceState(submissionResourceState) && entry !== undefined) { - store.dispatch( - createTrustedAppDeletionSubmissionResourceStateChanged({ - type: 'LoadingResourceState', - previousState: submissionResourceState, - }) - ); - - try { - await trustedAppsService.deleteTrustedApp({ id: entry.id }); - - store.dispatch( - createTrustedAppDeletionSubmissionResourceStateChanged({ - type: 'LoadedResourceState', - data: null, - }) - ); - store.dispatch({ - type: 'trustedAppDeletionDialogClosed', - }); - store.dispatch({ - type: 'trustedAppsListDataOutdated', - }); - } catch (error) { - store.dispatch( - createTrustedAppDeletionSubmissionResourceStateChanged({ - type: 'FailedResourceState', - error: error.body, - lastLoadedState: getLastLoadedResourceState(submissionResourceState), - }) - ); - } - } -}; - -const checkTrustedAppsExistIfNeeded = async ( - store: ImmutableMiddlewareAPI, - trustedAppsService: TrustedAppsService -) => { - const currentState = store.getState(); - const currentEntriesExistState = entriesExistState(currentState); - - if ( - trustedAppsListPageActive(currentState) && - !isLoadingResourceState(currentEntriesExistState) - ) { - const currentListTotal = getListTotalItemsCount(currentState); - const currentDoEntriesExist = entriesExist(currentState); - - if ( - !isLoadedResourceState(currentEntriesExistState) || - (currentListTotal === 0 && currentDoEntriesExist) || - (currentListTotal > 0 && !currentDoEntriesExist) - ) { - store.dispatch({ - type: 'trustedAppsExistStateChanged', - payload: { type: 'LoadingResourceState', previousState: currentEntriesExistState }, - }); - - let doTheyExist: boolean; - try { - const { total } = await trustedAppsService.getTrustedAppsList({ - page: 1, - per_page: 1, - }); - doTheyExist = total > 0; - } catch (e) { - // If a failure occurs, lets assume entries exits so that the UI is not blocked to the user - doTheyExist = true; - } - - store.dispatch({ - type: 'trustedAppsExistStateChanged', - payload: { type: 'LoadedResourceState', data: doTheyExist }, - }); - } - } -}; - -export const retrieveListOfPoliciesIfNeeded = async ( - { getState, dispatch }: ImmutableMiddlewareAPI, - trustedAppsService: TrustedAppsService -) => { - const currentState = getState(); - const currentPoliciesState = policiesState(currentState); - const isLoading = isLoadingResourceState(currentPoliciesState); - const isPageActive = trustedAppsListPageActive(currentState); - const isCreateFlow = isCreationDialogLocation(currentState); - const isUninitialized = isUninitialisedResourceState(currentPoliciesState); - - if (isPageActive && ((isCreateFlow && !isLoading) || isUninitialized)) { - dispatch({ - type: 'trustedAppsPoliciesStateChanged', - payload: { - type: 'LoadingResourceState', - previousState: currentPoliciesState, - } as TrustedAppsListPageState['policies'], - }); - - try { - const policyList = await trustedAppsService.getPolicyList({ - query: { - page: 1, - perPage: 1000, - }, - }); - - dispatch({ - type: 'trustedAppsPoliciesStateChanged', - payload: { - type: 'LoadedResourceState', - data: policyList, - }, - }); - } catch (error) { - dispatch({ - type: 'trustedAppsPoliciesStateChanged', - payload: { - type: 'FailedResourceState', - error: error.body || error, - lastLoadedState: getLastLoadedResourceState(policiesState(getState())), - }, - }); - } - } -}; - -const fetchEditTrustedAppIfNeeded = async ( - { getState, dispatch }: ImmutableMiddlewareAPI, - trustedAppsService: TrustedAppsService -) => { - const currentState = getState(); - const isPageActive = trustedAppsListPageActive(currentState); - const isEditFlow = isEdit(currentState); - const isAlreadyFetching = isFetchingEditTrustedAppItem(currentState); - const editTrustedAppId = editItemId(currentState); - - if (isPageActive && isEditFlow && !isAlreadyFetching) { - if (!editTrustedAppId) { - const errorMessage = i18n.translate( - 'xpack.securitySolution.trustedapps.middleware.editIdMissing', - { - defaultMessage: 'No id provided', - } - ); - - dispatch({ - type: 'trustedAppCreationEditItemStateChanged', - payload: { - type: 'FailedResourceState', - error: Object.assign(new Error(errorMessage), { statusCode: 404, error: errorMessage }), - }, - }); - return; - } - - let trustedAppForEdit = editingTrustedApp(currentState); - - // If Trusted App is already loaded, then do nothing - if (trustedAppForEdit && trustedAppForEdit.id === editTrustedAppId) { - return; - } - - // See if we can get the Trusted App record from the current list of Trusted Apps being displayed - trustedAppForEdit = getListItems(currentState).find((ta) => ta.id === editTrustedAppId); - - try { - // Retrieve Trusted App record via API if it was not in the list data. - // This would be the case when linking from another place or using an UUID for a Trusted App - // that is not currently displayed on the list view. - if (!trustedAppForEdit) { - dispatch({ - type: 'trustedAppCreationEditItemStateChanged', - payload: { - type: 'LoadingResourceState', - }, - }); - - trustedAppForEdit = (await trustedAppsService.getTrustedApp({ id: editTrustedAppId })).data; - } - - dispatch({ - type: 'trustedAppCreationEditItemStateChanged', - payload: { - type: 'LoadedResourceState', - data: trustedAppForEdit, - }, - }); - - dispatch({ - type: 'trustedAppCreationDialogFormStateUpdated', - payload: { - entry: toUpdateTrustedApp(trustedAppForEdit), - isValid: true, - }, - }); - } catch (e) { - dispatch({ - type: 'trustedAppCreationEditItemStateChanged', - payload: { - type: 'FailedResourceState', - error: e, - }, - }); - } - } -}; - -export const createTrustedAppsPageMiddleware = ( - trustedAppsService: TrustedAppsService -): ImmutableMiddleware => { - return (store) => (next) => async (action) => { - next(action); - - // TODO: need to think if failed state is a good condition to consider need for refresh - if (action.type === 'userChangedUrl' || action.type === 'trustedAppsListDataOutdated') { - await refreshListIfNeeded(store, trustedAppsService); - await checkTrustedAppsExistIfNeeded(store, trustedAppsService); - } - - if (action.type === 'userChangedUrl') { - updateCreationDialogIfNeeded(store); - retrieveListOfPoliciesIfNeeded(store, trustedAppsService); - fetchEditTrustedAppIfNeeded(store, trustedAppsService); - } - - if (action.type === 'trustedAppCreationDialogConfirmed') { - await submitCreationIfNeeded(store, trustedAppsService); - } - - if (action.type === 'trustedAppDeletionDialogConfirmed') { - await submitDeletionIfNeeded(store, trustedAppsService); - } - }; -}; - -export const trustedAppsPageMiddlewareFactory: ImmutableMiddlewareFactory< - TrustedAppsListPageState -> = (coreStart) => createTrustedAppsPageMiddleware(new TrustedAppsHttpService(coreStart.http)); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/mocks.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/mocks.ts deleted file mode 100644 index c97dd37db6bbf..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/mocks.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { GetPolicyListResponse } from '../../policy/types'; - -import { EndpointDocGenerator } from '../../../../../common/endpoint/generate_data'; - -export const getGeneratedPolicyResponse = (): GetPolicyListResponse => ({ - items: [new EndpointDocGenerator('seed').generatePolicyPackagePolicy()], - total: 1, - perPage: 1, - page: 1, -}); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/reducer.test.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/reducer.test.ts deleted file mode 100644 index 5047608cbb4ec..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/reducer.test.ts +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { AsyncResourceState } from '../state'; -import { initialTrustedAppsPageState } from './builders'; -import { trustedAppsPageReducer } from './reducer'; -import { - createSampleTrustedApp, - createListLoadedResourceState, - createLoadedListViewWithPagination, - createUserChangedUrlAction, - createTrustedAppsListResourceStateChangedAction, -} from '../test_utils'; - -const initialNow = 111111; -const dateNowMock = jest.fn(); -dateNowMock.mockReturnValue(initialNow); - -Date.now = dateNowMock; - -const initialState = initialTrustedAppsPageState(); - -describe('reducer', () => { - describe('UserChangedUrl', () => { - it('makes page state active and extracts all parameters', () => { - const result = trustedAppsPageReducer( - initialState, - createUserChangedUrlAction( - '/administration/trusted_apps', - '?page_index=5&page_size=50&show=create&view_type=list&filter=test&included_policies=global' - ) - ); - - expect(result).toStrictEqual({ - ...initialState, - location: { - page_index: 5, - page_size: 50, - show: 'create', - view_type: 'list', - id: undefined, - filter: 'test', - included_policies: 'global', - }, - active: true, - }); - }); - - it('extracts default pagination parameters when invalid provided', () => { - const result = trustedAppsPageReducer( - { - ...initialState, - location: { - page_index: 5, - page_size: 50, - view_type: 'grid', - filter: '', - included_policies: '', - }, - }, - createUserChangedUrlAction( - '/administration/trusted_apps', - '?page_index=b&page_size=60&show=a&view_type=c' - ) - ); - - expect(result).toStrictEqual({ ...initialState, active: true }); - }); - - it('extracts default pagination parameters when none provided', () => { - const result = trustedAppsPageReducer( - { - ...initialState, - location: { - page_index: 5, - page_size: 50, - view_type: 'grid', - filter: '', - included_policies: '', - }, - }, - createUserChangedUrlAction('/administration/trusted_apps') - ); - - expect(result).toStrictEqual({ ...initialState, active: true }); - }); - - it('makes page state inactive and resets list to uninitialised state when navigating away', () => { - const result = trustedAppsPageReducer( - { ...initialState, listView: createLoadedListViewWithPagination(initialNow), active: true }, - createUserChangedUrlAction('/administration/endpoints') - ); - - expect(result).toStrictEqual(initialState); - }); - }); - - describe('TrustedAppsListResourceStateChanged', () => { - it('sets the current list resource state', () => { - const listResourceState = createListLoadedResourceState( - { pageIndex: 3, pageSize: 50 }, - initialNow - ); - const result = trustedAppsPageReducer( - initialState, - createTrustedAppsListResourceStateChangedAction(listResourceState) - ); - - expect(result).toStrictEqual({ - ...initialState, - listView: { ...initialState.listView, listResourceState }, - }); - }); - }); - - describe('TrustedAppsListDataOutdated', () => { - it('sets the list view freshness timestamp', () => { - const newNow = 222222; - dateNowMock.mockReturnValue(newNow); - - const result = trustedAppsPageReducer(initialState, { type: 'trustedAppsListDataOutdated' }); - - expect(result).toStrictEqual({ - ...initialState, - listView: { ...initialState.listView, freshDataTimestamp: newNow }, - }); - }); - }); - - describe('TrustedAppDeletionSubmissionResourceStateChanged', () => { - it('sets the deletion dialog submission resource state', () => { - const submissionResourceState: AsyncResourceState = { - type: 'LoadedResourceState', - data: null, - }; - const result = trustedAppsPageReducer(initialState, { - type: 'trustedAppDeletionSubmissionResourceStateChanged', - payload: { newState: submissionResourceState }, - }); - - expect(result).toStrictEqual({ - ...initialState, - deletionDialog: { ...initialState.deletionDialog, submissionResourceState }, - }); - }); - }); - - describe('TrustedAppDeletionDialogStarted', () => { - it('sets the deletion dialog state to started', () => { - const entry = createSampleTrustedApp(3); - const result = trustedAppsPageReducer(initialState, { - type: 'trustedAppDeletionDialogStarted', - payload: { entry }, - }); - - expect(result).toStrictEqual({ - ...initialState, - deletionDialog: { ...initialState.deletionDialog, entry }, - }); - }); - }); - - describe('TrustedAppDeletionDialogConfirmed', () => { - it('sets the deletion dialog state to confirmed', () => { - const entry = createSampleTrustedApp(3); - const result = trustedAppsPageReducer( - { - ...initialState, - deletionDialog: { - entry, - confirmed: false, - submissionResourceState: { type: 'UninitialisedResourceState' }, - }, - }, - { type: 'trustedAppDeletionDialogConfirmed' } - ); - - expect(result).toStrictEqual({ - ...initialState, - deletionDialog: { - entry, - confirmed: true, - submissionResourceState: { type: 'UninitialisedResourceState' }, - }, - }); - }); - }); - - describe('TrustedAppDeletionDialogClosed', () => { - it('sets the deletion dialog state to confirmed', () => { - const result = trustedAppsPageReducer( - { - ...initialState, - deletionDialog: { - entry: createSampleTrustedApp(3), - confirmed: true, - submissionResourceState: { type: 'UninitialisedResourceState' }, - }, - }, - { type: 'trustedAppDeletionDialogClosed' } - ); - - expect(result).toStrictEqual(initialState); - }); - }); - - describe('TrustedAppsForceRefresh', () => { - it('sets the force refresh state to true', () => { - const result = trustedAppsPageReducer( - { - ...initialState, - forceRefresh: false, - }, - { type: 'trustedAppForceRefresh', payload: { forceRefresh: true } } - ); - - expect(result).toStrictEqual({ ...initialState, forceRefresh: true }); - }); - it('sets the force refresh state to false', () => { - const result = trustedAppsPageReducer( - { - ...initialState, - forceRefresh: true, - }, - { type: 'trustedAppForceRefresh', payload: { forceRefresh: false } } - ); - - expect(result).toStrictEqual({ ...initialState, forceRefresh: false }); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/reducer.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/reducer.ts deleted file mode 100644 index 07409a46156db..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/reducer.ts +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -// eslint-disable-next-line import/no-nodejs-modules -import { parse } from 'querystring'; -import { matchPath } from 'react-router-dom'; -import { ImmutableReducer } from '../../../../common/store'; -import { AppLocation, Immutable } from '../../../../../common/endpoint/types'; -import { UserChangedUrl } from '../../../../common/store/routing/action'; -import { AppAction } from '../../../../common/store/actions'; -import { extractTrustedAppsListPageLocation } from '../../../common/routing'; - -import { MANAGEMENT_ROUTING_TRUSTED_APPS_PATH } from '../../../common/constants'; - -import { - TrustedAppDeletionDialogClosed, - TrustedAppDeletionDialogConfirmed, - TrustedAppDeletionDialogStarted, - TrustedAppDeletionSubmissionResourceStateChanged, - TrustedAppCreationSubmissionResourceStateChanged, - TrustedAppsListDataOutdated, - TrustedAppsListResourceStateChanged, - TrustedAppCreationDialogStarted, - TrustedAppCreationDialogFormStateUpdated, - TrustedAppCreationDialogConfirmed, - TrustedAppCreationDialogClosed, - TrustedAppsExistResponse, - TrustedAppsPoliciesStateChanged, - TrustedAppCreationEditItemStateChanged, - TrustedAppForceRefresh, -} from './action'; - -import { TrustedAppsListPageState } from '../state'; -import { - initialCreationDialogState, - initialDeletionDialogState, - initialTrustedAppsPageState, -} from './builders'; -import { entriesExistState, trustedAppsListPageActive } from './selectors'; - -type StateReducer = ImmutableReducer; -type CaseReducer = ( - state: Immutable, - action: Immutable -) => Immutable; - -const isTrustedAppsPageLocation = (location: Immutable) => { - return ( - matchPath(location.pathname ?? '', { - path: MANAGEMENT_ROUTING_TRUSTED_APPS_PATH, - exact: true, - }) !== null - ); -}; - -const trustedAppsListDataOutdated: CaseReducer = (state, action) => { - return { ...state, listView: { ...state.listView, freshDataTimestamp: Date.now() } }; -}; - -const trustedAppsListResourceStateChanged: CaseReducer = ( - state, - action -) => { - return { ...state, listView: { ...state.listView, listResourceState: action.payload.newState } }; -}; - -const trustedAppDeletionSubmissionResourceStateChanged: CaseReducer< - TrustedAppDeletionSubmissionResourceStateChanged -> = (state, action) => { - return { - ...state, - deletionDialog: { ...state.deletionDialog, submissionResourceState: action.payload.newState }, - }; -}; - -const trustedAppDeletionDialogStarted: CaseReducer = ( - state, - action -) => { - return { ...state, deletionDialog: { ...initialDeletionDialogState(), ...action.payload } }; -}; - -const trustedAppDeletionDialogConfirmed: CaseReducer = ( - state -) => { - return { ...state, deletionDialog: { ...state.deletionDialog, confirmed: true } }; -}; - -const trustedAppDeletionDialogClosed: CaseReducer = (state) => { - return { ...state, deletionDialog: initialDeletionDialogState() }; -}; - -const trustedAppCreationSubmissionResourceStateChanged: CaseReducer< - TrustedAppCreationSubmissionResourceStateChanged -> = (state, action) => { - return { - ...state, - creationDialog: { ...state.creationDialog, submissionResourceState: action.payload.newState }, - }; -}; - -const trustedAppCreationDialogStarted: CaseReducer = ( - state, - action -) => { - return { - ...state, - creationDialog: { - ...initialCreationDialogState(), - formState: { ...action.payload, isValid: false }, - }, - }; -}; - -const trustedAppCreationDialogFormStateUpdated: CaseReducer< - TrustedAppCreationDialogFormStateUpdated -> = (state, action) => { - return { - ...state, - creationDialog: { ...state.creationDialog, formState: { ...action.payload } }, - }; -}; - -const handleUpdateToEditItemState: CaseReducer = ( - state, - action -) => { - return { - ...state, - creationDialog: { ...state.creationDialog, editItem: action.payload }, - }; -}; - -const trustedAppCreationDialogConfirmed: CaseReducer = ( - state -) => { - return { ...state, creationDialog: { ...state.creationDialog, confirmed: true } }; -}; - -const trustedAppCreationDialogClosed: CaseReducer = (state) => { - return { ...state, creationDialog: initialCreationDialogState() }; -}; - -const userChangedUrl: CaseReducer = (state, action) => { - if (isTrustedAppsPageLocation(action.payload)) { - const location = extractTrustedAppsListPageLocation(parse(action.payload.search.slice(1))); - - return { ...state, active: true, location }; - } else { - return initialTrustedAppsPageState(); - } -}; - -const updateEntriesExists: CaseReducer = (state, { payload }) => { - if (entriesExistState(state) !== payload) { - return { - ...state, - entriesExist: payload, - }; - } - return state; -}; - -const updatePolicies: CaseReducer = (state, { payload }) => { - if (trustedAppsListPageActive(state)) { - return { - ...state, - policies: payload, - }; - } - return state; -}; - -const forceRefresh: CaseReducer = (state, { payload }) => { - return { - ...state, - forceRefresh: payload.forceRefresh, - }; -}; - -export const trustedAppsPageReducer: StateReducer = ( - state = initialTrustedAppsPageState(), - action -) => { - switch (action.type) { - case 'trustedAppsListDataOutdated': - return trustedAppsListDataOutdated(state, action); - - case 'trustedAppsListResourceStateChanged': - return trustedAppsListResourceStateChanged(state, action); - - case 'trustedAppDeletionSubmissionResourceStateChanged': - return trustedAppDeletionSubmissionResourceStateChanged(state, action); - - case 'trustedAppDeletionDialogStarted': - return trustedAppDeletionDialogStarted(state, action); - - case 'trustedAppDeletionDialogConfirmed': - return trustedAppDeletionDialogConfirmed(state, action); - - case 'trustedAppDeletionDialogClosed': - return trustedAppDeletionDialogClosed(state, action); - - case 'trustedAppCreationSubmissionResourceStateChanged': - return trustedAppCreationSubmissionResourceStateChanged(state, action); - - case 'trustedAppCreationDialogStarted': - return trustedAppCreationDialogStarted(state, action); - - case 'trustedAppCreationDialogFormStateUpdated': - return trustedAppCreationDialogFormStateUpdated(state, action); - - case 'trustedAppCreationEditItemStateChanged': - return handleUpdateToEditItemState(state, action); - - case 'trustedAppCreationDialogConfirmed': - return trustedAppCreationDialogConfirmed(state, action); - - case 'trustedAppCreationDialogClosed': - return trustedAppCreationDialogClosed(state, action); - - case 'userChangedUrl': - return userChangedUrl(state, action); - - case 'trustedAppsExistStateChanged': - return updateEntriesExists(state, action); - - case 'trustedAppsPoliciesStateChanged': - return updatePolicies(state, action); - - case 'trustedAppForceRefresh': - return forceRefresh(state, action); - } - - return state; -}; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/selectors.test.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/selectors.test.ts deleted file mode 100644 index 4468d044827c0..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/selectors.test.ts +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - AsyncResourceState, - TrustedAppsListPageLocation, - TrustedAppsListPageState, -} from '../state'; -import { initialTrustedAppsPageState } from './builders'; -import { - getListResourceState, - getLastLoadedListResourceState, - getCurrentLocationPageIndex, - getCurrentLocationPageSize, - getListErrorMessage, - getListItems, - getListTotalItemsCount, - isListLoading, - needsRefreshOfListData, - isDeletionDialogOpen, - isDeletionInProgress, - isDeletionSuccessful, - getDeletionError, - getDeletionDialogEntry, - getDeletionSubmissionResourceState, -} from './selectors'; - -import { - createDefaultPagination, - createListComplexLoadingResourceState, - createListFailedResourceState, - createListLoadedResourceState, - createLoadedListViewWithPagination, - createSampleTrustedApp, - createSampleTrustedApps, - createServerApiError, - createUninitialisedResourceState, -} from '../test_utils'; - -const initialNow = 111111; -const dateNowMock = jest.fn(); -dateNowMock.mockReturnValue(initialNow); - -Date.now = dateNowMock; - -const initialState = initialTrustedAppsPageState(); - -const createStateWithDeletionSubmissionResourceState = ( - submissionResourceState: AsyncResourceState -): TrustedAppsListPageState => ({ - ...initialState, - deletionDialog: { ...initialState.deletionDialog, submissionResourceState }, -}); - -describe('selectors', () => { - describe('needsRefreshOfListData()', () => { - it('returns false for outdated resource state and inactive state', () => { - expect(needsRefreshOfListData(initialState)).toBe(false); - }); - - it('returns true for outdated resource state and active state', () => { - expect(needsRefreshOfListData({ ...initialState, active: true })).toBe(true); - }); - - it('returns true when current loaded page index is outdated', () => { - const listView = createLoadedListViewWithPagination(initialNow, { pageIndex: 1 }); - - expect(needsRefreshOfListData({ ...initialState, listView, active: true })).toBe(true); - }); - - it('returns true when current loaded page size is outdated', () => { - const listView = createLoadedListViewWithPagination(initialNow, { pageSize: 50 }); - - expect(needsRefreshOfListData({ ...initialState, listView, active: true })).toBe(true); - }); - - it('returns true when current loaded data timestamp is outdated', () => { - const listView = { - ...createLoadedListViewWithPagination(111111), - freshDataTimestamp: 222222, - }; - - expect(needsRefreshOfListData({ ...initialState, listView, active: true })).toBe(true); - }); - - it('returns false when current loaded data is up to date', () => { - const listView = createLoadedListViewWithPagination(initialNow); - const location: TrustedAppsListPageLocation = { - page_index: 0, - page_size: 10, - view_type: 'grid', - filter: '', - included_policies: '', - }; - - expect(needsRefreshOfListData({ ...initialState, listView, active: true, location })).toBe( - false - ); - }); - }); - - describe('getListResourceState()', () => { - it('returns current list resource state', () => { - expect(getListResourceState(initialState)).toStrictEqual(createUninitialisedResourceState()); - }); - }); - - describe('getLastLoadedListResourceState()', () => { - it('returns last loaded list resource state', () => { - const state = { - ...initialState, - listView: { - listResourceState: createListComplexLoadingResourceState( - createDefaultPagination(), - initialNow - ), - freshDataTimestamp: initialNow, - }, - }; - - expect(getLastLoadedListResourceState(state)).toStrictEqual( - createListLoadedResourceState(createDefaultPagination(), initialNow) - ); - }); - }); - - describe('getListItems()', () => { - it('returns empty list when no valid data loaded', () => { - expect(getListItems(initialState)).toStrictEqual([]); - }); - - it('returns last loaded list items', () => { - const state = { - ...initialState, - listView: { - listResourceState: createListComplexLoadingResourceState( - createDefaultPagination(), - initialNow - ), - freshDataTimestamp: initialNow, - }, - }; - - expect(getListItems(state)).toStrictEqual(createSampleTrustedApps(createDefaultPagination())); - }); - }); - - describe('getListTotalItemsCount()', () => { - it('returns 0 when no valid data loaded', () => { - expect(getListTotalItemsCount(initialState)).toBe(0); - }); - - it('returns last loaded total items count', () => { - const state = { - ...initialState, - listView: { - listResourceState: createListComplexLoadingResourceState( - createDefaultPagination(), - initialNow - ), - freshDataTimestamp: initialNow, - }, - }; - - expect(getListTotalItemsCount(state)).toBe(200); - }); - }); - - describe('getListCurrentPageIndex()', () => { - it('returns page index', () => { - const location: TrustedAppsListPageLocation = { - page_index: 3, - page_size: 10, - view_type: 'grid', - filter: '', - included_policies: '', - }; - - expect(getCurrentLocationPageIndex({ ...initialState, location })).toBe(3); - }); - }); - - describe('getListCurrentPageSize()', () => { - it('returns page size', () => { - const location: TrustedAppsListPageLocation = { - page_index: 0, - page_size: 20, - view_type: 'grid', - filter: '', - included_policies: '', - }; - - expect(getCurrentLocationPageSize({ ...initialState, location })).toBe(20); - }); - }); - - describe('getListErrorMessage()', () => { - it('returns undefined when not in failed state', () => { - const state = { - ...initialState, - listView: { - listResourceState: createListComplexLoadingResourceState( - createDefaultPagination(), - initialNow - ), - freshDataTimestamp: initialNow, - }, - }; - - expect(getListErrorMessage(state)).toBeUndefined(); - }); - - it('returns message when not in failed state', () => { - const state = { - ...initialState, - listView: { - listResourceState: createListFailedResourceState('Internal Server Error'), - freshDataTimestamp: initialNow, - }, - }; - - expect(getListErrorMessage(state)).toBe('Internal Server Error'); - }); - }); - - describe('isListLoading()', () => { - it('returns false when no loading is happening', () => { - expect(isListLoading(initialState)).toBe(false); - }); - - it('returns true when loading is in progress', () => { - const state = { - ...initialState, - listView: { - listResourceState: createListComplexLoadingResourceState( - createDefaultPagination(), - initialNow - ), - freshDataTimestamp: initialNow, - }, - }; - - expect(isListLoading(state)).toBe(true); - }); - }); - - describe('isDeletionDialogOpen()', () => { - it('returns false when no entry is set', () => { - expect(isDeletionDialogOpen(initialState)).toBe(false); - }); - - it('returns true when entry is set', () => { - const state = { - ...initialState, - deletionDialog: { - ...initialState.deletionDialog, - entry: createSampleTrustedApp(5), - }, - }; - - expect(isDeletionDialogOpen(state)).toBe(true); - }); - }); - - describe('isDeletionInProgress()', () => { - it('returns false when resource state is uninitialised', () => { - expect(isDeletionInProgress(initialState)).toBe(false); - }); - - it('returns true when resource state is loading', () => { - const state = createStateWithDeletionSubmissionResourceState({ - type: 'LoadingResourceState', - previousState: { type: 'UninitialisedResourceState' }, - }); - - expect(isDeletionInProgress(state)).toBe(true); - }); - - it('returns false when resource state is loaded', () => { - const state = createStateWithDeletionSubmissionResourceState({ - type: 'LoadedResourceState', - data: null, - }); - - expect(isDeletionInProgress(state)).toBe(false); - }); - - it('returns false when resource state is failed', () => { - const state = createStateWithDeletionSubmissionResourceState({ - type: 'FailedResourceState', - error: createServerApiError('Not Found'), - }); - - expect(isDeletionInProgress(state)).toBe(false); - }); - }); - - describe('isDeletionSuccessful()', () => { - it('returns false when resource state is uninitialised', () => { - expect(isDeletionSuccessful(initialState)).toBe(false); - }); - - it('returns false when resource state is loading', () => { - const state = createStateWithDeletionSubmissionResourceState({ - type: 'LoadingResourceState', - previousState: { type: 'UninitialisedResourceState' }, - }); - - expect(isDeletionSuccessful(state)).toBe(false); - }); - - it('returns true when resource state is loaded', () => { - const state = createStateWithDeletionSubmissionResourceState({ - type: 'LoadedResourceState', - data: null, - }); - - expect(isDeletionSuccessful(state)).toBe(true); - }); - - it('returns false when resource state is failed', () => { - const state = createStateWithDeletionSubmissionResourceState({ - type: 'FailedResourceState', - error: createServerApiError('Not Found'), - }); - - expect(isDeletionSuccessful(state)).toBe(false); - }); - }); - - describe('getDeletionError()', () => { - it('returns undefined when resource state is uninitialised', () => { - expect(getDeletionError(initialState)).toBeUndefined(); - }); - - it('returns undefined when resource state is loading', () => { - const state = createStateWithDeletionSubmissionResourceState({ - type: 'LoadingResourceState', - previousState: { type: 'UninitialisedResourceState' }, - }); - - expect(getDeletionError(state)).toBeUndefined(); - }); - - it('returns undefined when resource state is loaded', () => { - const state = createStateWithDeletionSubmissionResourceState({ - type: 'LoadedResourceState', - data: null, - }); - - expect(getDeletionError(state)).toBeUndefined(); - }); - - it('returns error when resource state is failed', () => { - const state = createStateWithDeletionSubmissionResourceState({ - type: 'FailedResourceState', - error: createServerApiError('Not Found'), - }); - - expect(getDeletionError(state)).toStrictEqual(createServerApiError('Not Found')); - }); - }); - - describe('getDeletionSubmissionResourceState()', () => { - it('returns submission resource state', () => { - expect(getDeletionSubmissionResourceState(initialState)).toStrictEqual({ - type: 'UninitialisedResourceState', - }); - }); - }); - - describe('getDeletionDialogEntry()', () => { - it('returns undefined when no entry is set', () => { - expect(getDeletionDialogEntry(initialState)).toBeUndefined(); - }); - - it('returns entry when entry is set', () => { - const entry = createSampleTrustedApp(5); - const state = { ...initialState, deletionDialog: { ...initialState.deletionDialog, entry } }; - - expect(getDeletionDialogEntry(state)).toStrictEqual(entry); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/selectors.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/selectors.ts deleted file mode 100644 index 743d8b84760ba..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/selectors.ts +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { createSelector } from 'reselect'; -import { ServerApiError } from '../../../../common/types'; -import { - Immutable, - NewTrustedApp, - PolicyData, - TrustedApp, -} from '../../../../../common/endpoint/types'; -import { MANAGEMENT_PAGE_SIZE_OPTIONS } from '../../../common/constants'; - -import { - AsyncResourceState, - getCurrentResourceError, - getLastLoadedResourceState, - isFailedResourceState, - isLoadedResourceState, - isLoadingResourceState, - isOutdatedResourceState, - LoadedResourceState, - Pagination, - TrustedAppsListData, - TrustedAppsListPageLocation, - TrustedAppsListPageState, -} from '../state'; -import { GetPolicyListResponse } from '../../policy/types'; - -export const needsRefreshOfListData = (state: Immutable): boolean => { - const freshDataTimestamp = state.listView.freshDataTimestamp; - const currentPage = state.listView.listResourceState; - const location = state.location; - const forceRefresh = state.forceRefresh; - return ( - Boolean(state.active) && - (forceRefresh || - isOutdatedResourceState(currentPage, (data) => { - return ( - data.pageIndex === location.page_index && - data.pageSize === location.page_size && - data.timestamp >= freshDataTimestamp - ); - })) - ); -}; - -export const getListResourceState = ( - state: Immutable -): Immutable> | undefined => { - return state.listView.listResourceState; -}; - -export const getLastLoadedListResourceState = ( - state: Immutable -): Immutable> | undefined => { - return getLastLoadedResourceState(state.listView.listResourceState); -}; - -export const getListItems = ( - state: Immutable -): Immutable => { - return getLastLoadedResourceState(state.listView.listResourceState)?.data.items || []; -}; - -export const getCurrentLocationPageIndex = (state: Immutable): number => { - return state.location.page_index; -}; - -export const getCurrentLocationPageSize = (state: Immutable): number => { - return state.location.page_size; -}; - -export const getCurrentLocationFilter = (state: Immutable): string => { - return state.location.filter; -}; - -export const getCurrentLocationIncludedPolicies = ( - state: Immutable -): string => { - return state.location.included_policies; -}; - -export const getListTotalItemsCount = (state: Immutable): number => { - return getLastLoadedResourceState(state.listView.listResourceState)?.data.totalItemsCount || 0; -}; - -export const getListPagination = (state: Immutable): Pagination => { - const lastLoadedResourceState = getLastLoadedResourceState(state.listView.listResourceState); - - return { - pageIndex: state.location.page_index, - pageSize: state.location.page_size, - totalItemCount: lastLoadedResourceState?.data.totalItemsCount || 0, - pageSizeOptions: [...MANAGEMENT_PAGE_SIZE_OPTIONS], - }; -}; - -export const getCurrentLocation = ( - state: Immutable -): TrustedAppsListPageLocation => state.location; - -export const getListErrorMessage = ( - state: Immutable -): string | undefined => { - return getCurrentResourceError(state.listView.listResourceState)?.message; -}; - -export const isListLoading = (state: Immutable): boolean => { - return isLoadingResourceState(state.listView.listResourceState); -}; - -export const isDeletionDialogOpen = (state: Immutable): boolean => { - return state.deletionDialog.entry !== undefined; -}; - -export const isDeletionInProgress = (state: Immutable): boolean => { - return isLoadingResourceState(state.deletionDialog.submissionResourceState); -}; - -export const isDeletionSuccessful = (state: Immutable): boolean => { - return isLoadedResourceState(state.deletionDialog.submissionResourceState); -}; - -export const getDeletionError = ( - state: Immutable -): Immutable | undefined => { - const submissionResourceState = state.deletionDialog.submissionResourceState; - - return isFailedResourceState(submissionResourceState) ? submissionResourceState.error : undefined; -}; - -export const getDeletionSubmissionResourceState = ( - state: Immutable -): AsyncResourceState => { - return state.deletionDialog.submissionResourceState; -}; - -export const getDeletionDialogEntry = ( - state: Immutable -): Immutable | undefined => { - return state.deletionDialog.entry; -}; - -export const isCreationDialogLocation = (state: Immutable): boolean => { - return !!state.location.show; -}; - -export const getCreationSubmissionResourceState = ( - state: Immutable -): Immutable> => { - return state.creationDialog.submissionResourceState; -}; - -export const getCreationDialogFormEntry = ( - state: Immutable -): Immutable | undefined => { - return state.creationDialog.formState?.entry; -}; - -export const isCreationDialogFormValid = (state: Immutable): boolean => { - return state.creationDialog.formState?.isValid || false; -}; - -export const isCreationInProgress = (state: Immutable): boolean => { - return isLoadingResourceState(state.creationDialog.submissionResourceState); -}; - -export const isCreationSuccessful = (state: Immutable): boolean => { - return isLoadedResourceState(state.creationDialog.submissionResourceState); -}; - -export const getCreationError = ( - state: Immutable -): Immutable | undefined => { - const submissionResourceState = state.creationDialog.submissionResourceState; - - return isFailedResourceState(submissionResourceState) ? submissionResourceState.error : undefined; -}; - -export const entriesExistState: ( - state: Immutable -) => Immutable = (state) => state.entriesExist; - -export const checkingIfEntriesExist: (state: Immutable) => boolean = - createSelector(entriesExistState, (doEntriesExists) => { - return !isLoadedResourceState(doEntriesExists); - }); - -export const entriesExist: (state: Immutable) => boolean = createSelector( - entriesExistState, - (doEntriesExists) => { - return isLoadedResourceState(doEntriesExists) && doEntriesExists.data; - } -); - -export const prevEntriesExist: (state: Immutable) => boolean = - createSelector(entriesExistState, (doEntriesExists) => { - return ( - isLoadingResourceState(doEntriesExists) && !!getLastLoadedResourceState(doEntriesExists)?.data - ); - }); - -export const trustedAppsListPageActive: (state: Immutable) => boolean = ( - state -) => state.active; - -export const policiesState = ( - state: Immutable -): Immutable => state.policies; - -export const loadingPolicies: (state: Immutable) => boolean = - createSelector(policiesState, (policies) => isLoadingResourceState(policies)); - -export const listOfPolicies: ( - state: Immutable -) => Immutable = createSelector(policiesState, (policies) => { - return isLoadedResourceState(policies) ? policies.data.items : []; -}); - -export const isLoadingListOfPolicies: (state: Immutable) => boolean = - createSelector(policiesState, (policies) => { - return isLoadingResourceState(policies); - }); - -export const getMapOfPoliciesById: ( - state: Immutable -) => Immutable>> = createSelector( - listOfPolicies, - (policies) => { - return policies.reduce>>((mapById, policy) => { - mapById[policy.id] = policy; - return mapById; - }, {}) as Immutable>>; - } -); - -export const isEdit: (state: Immutable) => boolean = createSelector( - getCurrentLocation, - ({ show }) => { - return show === 'edit'; - } -); - -export const editItemId: (state: Immutable) => string | undefined = - createSelector(getCurrentLocation, ({ id }) => { - return id; - }); - -export const editItemState: ( - state: Immutable -) => Immutable['creationDialog']['editItem'] = (state) => { - return state.creationDialog.editItem; -}; - -export const isFetchingEditTrustedAppItem: (state: Immutable) => boolean = - createSelector(editItemState, (editTrustedAppState) => { - return editTrustedAppState ? isLoadingResourceState(editTrustedAppState) : false; - }); - -export const editTrustedAppFetchError: ( - state: Immutable -) => ServerApiError | undefined = createSelector(editItemState, (itemForEditState) => { - return itemForEditState && getCurrentResourceError(itemForEditState); -}); - -export const editingTrustedApp: ( - state: Immutable -) => undefined | Immutable = createSelector(editItemState, (editTrustedAppState) => { - if (editTrustedAppState && isLoadedResourceState(editTrustedAppState)) { - return editTrustedAppState.data; - } -}); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/test_utils/index.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/test_utils/index.ts deleted file mode 100644 index 32e1867db567c..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/test_utils/index.ts +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { combineReducers, createStore } from 'redux'; -import { OperatingSystem } from '@kbn/securitysolution-utils'; -import { TrustedApp } from '../../../../../common/endpoint/types'; -import { RoutingAction } from '../../../../common/store/routing'; - -import { - MANAGEMENT_DEFAULT_PAGE, - MANAGEMENT_DEFAULT_PAGE_SIZE, - MANAGEMENT_PAGE_SIZE_OPTIONS, - MANAGEMENT_STORE_GLOBAL_NAMESPACE, - MANAGEMENT_STORE_TRUSTED_APPS_NAMESPACE, -} from '../../../common/constants'; - -import { - AsyncResourceState, - FailedResourceState, - LoadedResourceState, - LoadingResourceState, - Pagination, - StaleResourceState, - TrustedAppsListData, - TrustedAppsListPageState, - UninitialisedResourceState, -} from '../state'; - -import { trustedAppsPageReducer } from '../store/reducer'; -import { TrustedAppsListResourceStateChanged } from '../store/action'; - -const OPERATING_SYSTEMS: OperatingSystem[] = [ - OperatingSystem.WINDOWS, - OperatingSystem.MAC, - OperatingSystem.LINUX, -]; - -const generate = (count: number, generator: (i: number) => T) => - [...new Array(count).keys()].map(generator); - -export const createSampleTrustedApp = (i: number, longTexts?: boolean): TrustedApp => { - return { - id: String(i), - version: 'abc123', - name: generate(longTexts ? 10 : 1, () => `trusted app ${i}`).join(' '), - description: generate(longTexts ? 10 : 1, () => `Trusted App ${i}`).join(' '), - created_at: '1 minute ago', - created_by: 'someone', - updated_at: '1 minute ago', - updated_by: 'someone', - os: OPERATING_SYSTEMS[i % 3], - entries: [], - effectScope: { type: 'global' }, - }; -}; - -export const createSampleTrustedApps = ( - pagination: Partial, - longTexts?: boolean -): TrustedApp[] => { - const fullPagination = { ...createDefaultPagination(), ...pagination }; - - return generate(fullPagination.pageSize, (i: number) => createSampleTrustedApp(i, longTexts)); -}; - -export const createTrustedAppsListData = ( - pagination: Partial, - timestamp: number, - longTexts?: boolean -) => { - const fullPagination = { ...createDefaultPagination(), ...pagination }; - - return { - items: createSampleTrustedApps(fullPagination, longTexts), - pageSize: fullPagination.pageSize, - pageIndex: fullPagination.pageIndex, - totalItemsCount: fullPagination.totalItemCount, - timestamp, - filter: '', - includedPolicies: '', - }; -}; - -export const createServerApiError = (message: string) => ({ - statusCode: 500, - error: 'Internal Server Error', - message, -}); - -export const createUninitialisedResourceState = (): UninitialisedResourceState => ({ - type: 'UninitialisedResourceState', -}); - -export const createListLoadedResourceState = ( - pagination: Partial, - timestamp: number, - longTexts?: boolean -): LoadedResourceState => ({ - type: 'LoadedResourceState', - data: createTrustedAppsListData(pagination, timestamp, longTexts), -}); - -export const createListFailedResourceState = ( - message: string, - lastLoadedState?: LoadedResourceState -): FailedResourceState => ({ - type: 'FailedResourceState', - error: createServerApiError(message), - lastLoadedState, -}); - -export const createListLoadingResourceState = ( - previousState: StaleResourceState = createUninitialisedResourceState() -): LoadingResourceState => ({ - type: 'LoadingResourceState', - previousState, -}); - -export const createListComplexLoadingResourceState = ( - pagination: Partial, - timestamp: number -): LoadingResourceState => - createListLoadingResourceState( - createListFailedResourceState( - 'Internal Server Error', - createListLoadedResourceState(pagination, timestamp) - ) - ); - -export const createDefaultPagination = (): Pagination => ({ - pageIndex: MANAGEMENT_DEFAULT_PAGE, - pageSize: MANAGEMENT_DEFAULT_PAGE_SIZE, - totalItemCount: 200, - pageSizeOptions: [...MANAGEMENT_PAGE_SIZE_OPTIONS], -}); - -export const createLoadedListViewWithPagination = ( - freshDataTimestamp: number, - pagination: Partial = createDefaultPagination() -): TrustedAppsListPageState['listView'] => ({ - listResourceState: createListLoadedResourceState(pagination, freshDataTimestamp), - freshDataTimestamp, -}); - -export const createUserChangedUrlAction = (path: string, search: string = ''): RoutingAction => { - return { type: 'userChangedUrl', payload: { pathname: path, search, hash: '' } }; -}; - -export const createTrustedAppsListResourceStateChangedAction = ( - newState: AsyncResourceState -): TrustedAppsListResourceStateChanged => ({ - type: 'trustedAppsListResourceStateChanged', - payload: { newState }, -}); - -export const createGlobalNoMiddlewareStore = () => { - return createStore( - combineReducers({ - [MANAGEMENT_STORE_GLOBAL_NAMESPACE]: combineReducers({ - [MANAGEMENT_STORE_TRUSTED_APPS_NAMESPACE]: trustedAppsPageReducer, - }), - }) - ); -}; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/__snapshots__/trusted_app_deletion_dialog.test.tsx.snap b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/__snapshots__/trusted_app_deletion_dialog.test.tsx.snap deleted file mode 100644 index 070f1b9eabe23..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/__snapshots__/trusted_app_deletion_dialog.test.tsx.snap +++ /dev/null @@ -1,414 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`TrustedAppDeletionDialog renders correctly initially 1`] = ` - -
- -`; - -exports[`TrustedAppDeletionDialog renders correctly when deletion failed 1`] = ` - -
-
-
-
- -
-
-
- Delete " - - trusted app 3 - - " -
-
-
-
-
-
-
-
-
-

- Deleting this entry will remove it from all associated policies. -

-
-
-
-
-
-

- This action cannot be undone. Are you sure you wish to continue? -

-
-
-
-
- - -
-
-
-
-
- -`; - -exports[`TrustedAppDeletionDialog renders correctly when deletion is in progress 1`] = ` - -
-
-
-
- -
-
-
- Delete " - - trusted app 3 - - " -
-
-
-
-
-
-
-
-
-

- Deleting this entry will remove it from all associated policies. -

-
-
-
-
-
-

- This action cannot be undone. Are you sure you wish to continue? -

-
-
-
-
- - -
-
-
-
-
- -`; - -exports[`TrustedAppDeletionDialog renders correctly when dialog started 1`] = ` - -
-
-
-
- -
-
-
- Delete " - - trusted app 3 - - " -
-
-
-
-
-
-
-
-
-

- Deleting this entry will remove it from all associated policies. -

-
-
-
-
-
-

- This action cannot be undone. Are you sure you wish to continue? -

-
-
-
-
- - -
-
-
-
-
- -`; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_flyout.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_flyout.tsx deleted file mode 100644 index f76ac89474e7b..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_flyout.tsx +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - EuiButton, - EuiButtonEmpty, - EuiCallOut, - EuiFlexGroup, - EuiFlexItem, - EuiFlyout, - EuiFlyoutBody, - EuiFlyoutFooter, - EuiFlyoutHeader, - EuiLink, - EuiSpacer, - EuiText, - EuiTitle, -} from '@elastic/eui'; -import React, { memo, useCallback, useEffect, useState, useMemo } from 'react'; -import { EuiFlyoutProps } from '@elastic/eui/src/components/flyout/flyout'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { useDispatch } from 'react-redux'; -import { useHistory } from 'react-router-dom'; -import { i18n } from '@kbn/i18n'; -import _ from 'lodash'; -import { CreateTrustedAppForm, CreateTrustedAppFormProps } from './create_trusted_app_form'; -import { - editTrustedAppFetchError, - getCreationDialogFormEntry, - getCreationError, - getCurrentLocation, - isCreationDialogFormValid, - isCreationInProgress, - isCreationSuccessful, - isEdit, - listOfPolicies, - loadingPolicies, -} from '../../store/selectors'; -import { AppAction } from '../../../../../common/store/actions'; -import { useTrustedAppsSelector } from '../hooks'; - -import { ABOUT_TRUSTED_APPS } from '../translations'; -import { defaultNewTrustedApp } from '../../store/builders'; -import { getTrustedAppsListPath } from '../../../../common/routing'; -import { useKibana, useToasts } from '../../../../../common/lib/kibana'; -import { useTestIdGenerator } from '../../../../components/hooks/use_test_id_generator'; -import { useLicense } from '../../../../../common/hooks/use_license'; -import { isGlobalEffectScope } from '../../state/type_guards'; -import { NewTrustedApp } from '../../../../../../common/endpoint/types'; - -export type CreateTrustedAppFlyoutProps = Omit; -export const CreateTrustedAppFlyout = memo( - ({ onClose, ...flyoutProps }) => { - const dispatch = useDispatch<(action: AppAction) => void>(); - const history = useHistory(); - const toasts = useToasts(); - - const creationInProgress = useTrustedAppsSelector(isCreationInProgress); - const creationErrors = useTrustedAppsSelector(getCreationError); - const creationSuccessful = useTrustedAppsSelector(isCreationSuccessful); - const isFormValid = useTrustedAppsSelector(isCreationDialogFormValid); - const isLoadingPolicies = useTrustedAppsSelector(loadingPolicies); - const policyList = useTrustedAppsSelector(listOfPolicies); - const isEditMode = useTrustedAppsSelector(isEdit); - const trustedAppFetchError = useTrustedAppsSelector(editTrustedAppFetchError); - const formValues = useTrustedAppsSelector(getCreationDialogFormEntry) || defaultNewTrustedApp(); - const location = useTrustedAppsSelector(getCurrentLocation); - const isPlatinumPlus = useLicense().isPlatinumPlus(); - const docLinks = useKibana().services.docLinks; - const [isFormDirty, setIsFormDirty] = useState(false); - - const dataTestSubj = flyoutProps['data-test-subj']; - - const policies = useMemo(() => { - return { - // Casting is needed due to the use of `Immutable<>` on the return value from the selector above - options: policyList as CreateTrustedAppFormProps['policies']['options'], - isLoading: isLoadingPolicies, - }; - }, [isLoadingPolicies, policyList]); - - const creationErrorsMessage = useMemo(() => { - return creationErrors?.message ?? []; - }, [creationErrors]); - - const getTestId = useTestIdGenerator(dataTestSubj); - - const handleCancelClick = useCallback(() => { - if (creationInProgress) { - return; - } - onClose(); - }, [onClose, creationInProgress]); - - const handleSaveClick = useCallback( - () => dispatch({ type: 'trustedAppCreationDialogConfirmed' }), - [dispatch] - ); - - const handleFormOnChange = useCallback( - (newFormState) => { - dispatch({ - type: 'trustedAppCreationDialogFormStateUpdated', - payload: { entry: newFormState.item, isValid: newFormState.isValid }, - }); - if (_.isEqual(formValues, newFormState.item) === false) { - setIsFormDirty(true); - } - }, - - [dispatch, formValues] - ); - - const [wasByPolicy, setWasByPolicy] = useState(!isGlobalEffectScope(formValues.effectScope)); - // set initial state of `wasByPolicy` that checks if the initial state of the exception was by policy or not - useEffect(() => { - if (!isFormDirty && formValues.effectScope) { - setWasByPolicy(!isGlobalEffectScope(formValues.effectScope)); - } - }, [isFormDirty, formValues.effectScope]); - - const isGlobal = useMemo(() => { - return isGlobalEffectScope((formValues as NewTrustedApp).effectScope); - }, [formValues]); - - const showExpiredLicenseBanner = useMemo(() => { - return !isPlatinumPlus && isEditMode && wasByPolicy && (!isGlobal || isFormDirty); - }, [isPlatinumPlus, isEditMode, isGlobal, isFormDirty, wasByPolicy]); - - // If there was a failure trying to retrieve the Trusted App for edit item, - // then redirect back to the list ++ show toast message. - useEffect(() => { - if (trustedAppFetchError) { - // Replace the current URL route so that user does not keep hitting this page via browser back/fwd buttons - history.replace( - getTrustedAppsListPath({ - ...location, - show: undefined, - id: undefined, - }) - ); - - toasts.addWarning( - i18n.translate( - 'xpack.securitySolution.trustedapps.createTrustedAppFlyout.notFoundToastMessage', - { - defaultMessage: 'Unable to edit trusted application ({apiMsg})', - values: { - apiMsg: trustedAppFetchError.message, - }, - } - ) - ); - } - }, [history, location, toasts, trustedAppFetchError]); - - // If it was created, then close flyout - useEffect(() => { - if (creationSuccessful) { - onClose(); - } - }, [onClose, creationSuccessful]); - - return ( - - - -

- {isEditMode ? ( - - ) : ( - - )} -

-
-
- {showExpiredLicenseBanner && ( - - - - - - - )} - - -

- {i18n.translate('xpack.securitySolution.trustedApps.detailsSectionTitle', { - defaultMessage: 'Details', - })} -

-
- - {!isEditMode && ( - <> - -

{ABOUT_TRUSTED_APPS}

-
- - - )} - -
- - - - - - - - - - - {isEditMode ? ( - - ) : ( - - )} - - - - -
- ); - } -); - -CreateTrustedAppFlyout.displayName = 'NewTrustedAppFlyout'; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.test.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.test.tsx deleted file mode 100644 index 68dd43fa41152..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.test.tsx +++ /dev/null @@ -1,535 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import * as reactTestingLibrary from '@testing-library/react'; -import { fireEvent, getByTestId } from '@testing-library/dom'; - -import { ConditionEntryField, OperatingSystem } from '@kbn/securitysolution-utils'; -import { NewTrustedApp } from '../../../../../../common/endpoint/types'; -import { - AppContextTestRender, - createAppRootMockRenderer, -} from '../../../../../common/mock/endpoint'; - -import { CreateTrustedAppForm, CreateTrustedAppFormProps } from './create_trusted_app_form'; -import { defaultNewTrustedApp } from '../../store/builders'; -import { EndpointDocGenerator } from '../../../../../../common/endpoint/generate_data'; -import { useIsExperimentalFeatureEnabled } from '../../../../../common/hooks/use_experimental_features'; -import { licenseService } from '../../../../../common/hooks/use_license'; -import { forceHTMLElementOffsetWidth } from '../../../../components/effected_policy_select/test_utils'; - -jest.mock('../../../../../common/hooks/use_experimental_features'); -const useIsExperimentalFeatureEnabledMock = useIsExperimentalFeatureEnabled as jest.Mock; - -jest.mock('../../../../../common/hooks/use_license', () => { - const licenseServiceInstance = { - isPlatinumPlus: jest.fn(), - }; - return { - licenseService: licenseServiceInstance, - useLicense: () => { - return licenseServiceInstance; - }, - }; -}); - -describe('When using the Trusted App Form', () => { - const dataTestSubjForForm = 'createForm'; - const generator = new EndpointDocGenerator('effected-policy-select'); - - let resetHTMLElementOffsetWidth: ReturnType; - - let mockedContext: AppContextTestRender; - let formProps: jest.Mocked; - let renderResult: ReturnType; - - // As the form's `onChange()` callback is executed, this variable will - // hold the latest updated trusted app. Use it to re-render - let latestUpdatedTrustedApp: NewTrustedApp; - - const getUI = () => ; - const render = () => { - return (renderResult = mockedContext.render(getUI())); - }; - const rerender = () => renderResult.rerender(getUI()); - const rerenderWithLatestTrustedApp = () => { - formProps.trustedApp = latestUpdatedTrustedApp; - rerender(); - }; - - // Some helpers - const setTextFieldValue = (textField: HTMLInputElement | HTMLTextAreaElement, value: string) => { - reactTestingLibrary.act(() => { - fireEvent.change(textField, { - target: { value }, - }); - fireEvent.blur(textField); - }); - }; - const getNameField = (dataTestSub: string = dataTestSubjForForm): HTMLInputElement => { - return renderResult.getByTestId(`${dataTestSub}-nameTextField`) as HTMLInputElement; - }; - const getOsField = (dataTestSub: string = dataTestSubjForForm): HTMLButtonElement => { - return renderResult.getByTestId(`${dataTestSub}-osSelectField`) as HTMLButtonElement; - }; - const getDescriptionField = (dataTestSub: string = dataTestSubjForForm): HTMLTextAreaElement => { - return renderResult.getByTestId(`${dataTestSub}-descriptionField`) as HTMLTextAreaElement; - }; - const getCondition = ( - index: number = 0, - dataTestSub: string = dataTestSubjForForm - ): HTMLElement => { - return renderResult.getByTestId(`${dataTestSub}-conditionsBuilder-group1-entry${index}`); - }; - const getAllConditions = (dataTestSub: string = dataTestSubjForForm): HTMLElement[] => { - return Array.from( - renderResult.getByTestId(`${dataTestSub}-conditionsBuilder-group1-entries`).children - ) as HTMLElement[]; - }; - const getConditionRemoveButton = (condition: HTMLElement): HTMLButtonElement => { - return getByTestId(condition, `${condition.dataset.testSubj}-remove`) as HTMLButtonElement; - }; - const getConditionFieldSelect = (condition: HTMLElement): HTMLButtonElement => { - return getByTestId(condition, `${condition.dataset.testSubj}-field`) as HTMLButtonElement; - }; - const getConditionValue = (condition: HTMLElement): HTMLInputElement => { - return getByTestId(condition, `${condition.dataset.testSubj}-value`) as HTMLInputElement; - }; - const getConditionBuilderAndButton = ( - dataTestSub: string = dataTestSubjForForm - ): HTMLButtonElement => { - return renderResult.getByTestId( - `${dataTestSub}-conditionsBuilder-group1-AndButton` - ) as HTMLButtonElement; - }; - const getConditionBuilderAndConnectorBadge = ( - dataTestSub: string = dataTestSubjForForm - ): HTMLElement => { - return renderResult.getByTestId(`${dataTestSub}-conditionsBuilder-group1-andConnector`); - }; - const getAllValidationErrors = (): HTMLElement[] => { - return Array.from(renderResult.container.querySelectorAll('.euiFormErrorText')); - }; - const getAllValidationWarnings = (): HTMLElement[] => { - return Array.from(renderResult.container.querySelectorAll('.euiFormHelpText')); - }; - - beforeEach(() => { - resetHTMLElementOffsetWidth = forceHTMLElementOffsetWidth(); - useIsExperimentalFeatureEnabledMock.mockReturnValue(true); - (licenseService.isPlatinumPlus as jest.Mock).mockReturnValue(true); - - mockedContext = createAppRootMockRenderer(); - - latestUpdatedTrustedApp = defaultNewTrustedApp(); - - formProps = { - 'data-test-subj': dataTestSubjForForm, - trustedApp: latestUpdatedTrustedApp, - isEditMode: false, - isDirty: false, - wasByPolicy: false, - onChange: jest.fn((updates) => { - latestUpdatedTrustedApp = updates.item; - }), - policies: { - options: [], - }, - }; - }); - - afterEach(() => { - resetHTMLElementOffsetWidth(); - reactTestingLibrary.cleanup(); - }); - - describe('and the form is rendered', () => { - beforeEach(() => render()); - - it('should show Name as required after blur', () => { - expect(getNameField().required).toBe(false); - reactTestingLibrary.act(() => { - fireEvent.blur(getNameField()); - }); - expect(getNameField().required).toBe(true); - }); - - it('should default OS to Windows', () => { - expect(getOsField().textContent).toEqual('Windows'); - }); - - it('should allow user to select between 3 OSs', () => { - const osField = getOsField(); - reactTestingLibrary.act(() => { - fireEvent.click(osField, { button: 1 }); - }); - const options = Array.from( - renderResult.baseElement.querySelectorAll( - '.euiSuperSelect__listbox button.euiSuperSelect__item' - ) - ).map((button) => button.textContent); - expect(options).toEqual(['Mac', 'Windows', 'Linux']); - }); - - it('should show Description as optional', () => { - expect(getDescriptionField().required).toBe(false); - }); - - it('should NOT initially show any inline validation errors', () => { - expect(renderResult.container.querySelectorAll('.euiFormErrorText').length).toBe(0); - }); - - it('should show top-level Errors', () => { - formProps.isInvalid = true; - formProps.error = 'a top level error'; - rerender(); - expect(renderResult.queryByText(formProps.error as string)).not.toBeNull(); - }); - }); - - describe('the condition builder component', () => { - beforeEach(() => render()); - - it('should show an initial condition entry with labels', () => { - const defaultCondition = getCondition(); - const labels = Array.from(defaultCondition.querySelectorAll('.euiFormRow__labelWrapper')).map( - (label) => (label.textContent || '').trim() - ); - expect(labels).toEqual(['Field', 'Operator', 'Value', '']); - }); - - it('should not allow the entry to be removed if its the only one displayed', () => { - const defaultCondition = getCondition(); - expect(getConditionRemoveButton(defaultCondition).disabled).toBe(true); - }); - - it('should display 3 options for Field for Windows', () => { - const conditionFieldSelect = getConditionFieldSelect(getCondition()); - reactTestingLibrary.act(() => { - fireEvent.click(conditionFieldSelect, { button: 1 }); - }); - const options = Array.from( - renderResult.baseElement.querySelectorAll( - '.euiSuperSelect__listbox button.euiSuperSelect__item' - ) - ).map((button) => button.textContent); - expect(options.length).toEqual(3); - expect(options).toEqual([ - 'Hashmd5, sha1, or sha256', - 'PathThe full path of the application', - 'SignatureThe signer of the application', - ]); - }); - - it('should show the value field as required after blur', () => { - expect(getConditionValue(getCondition()).required).toEqual(false); - reactTestingLibrary.act(() => { - fireEvent.blur(getConditionValue(getCondition())); - }); - expect(getConditionValue(getCondition()).required).toEqual(true); - }); - - it('should display the `AND` button', () => { - const andButton = getConditionBuilderAndButton(); - expect(andButton.textContent).toEqual('AND'); - expect(andButton.disabled).toEqual(false); - }); - - describe('and when the AND button is clicked', () => { - beforeEach(() => { - const andButton = getConditionBuilderAndButton(); - reactTestingLibrary.act(() => { - fireEvent.click(andButton, { button: 1 }); - }); - // re-render with updated `newTrustedApp` - formProps.trustedApp = formProps.onChange.mock.calls[0][0].item; - rerender(); - }); - - it('should add a new condition entry when `AND` is clicked with no column labels', () => { - const condition2 = getCondition(1); - expect(condition2.querySelectorAll('.euiFormRow__labelWrapper')).toHaveLength(0); - }); - - it('should have remove buttons enabled when multiple conditions are present', () => { - getAllConditions().forEach((condition) => { - expect(getConditionRemoveButton(condition).disabled).toBe(false); - }); - }); - - it('should show the AND visual connector when multiple entries are present', () => { - expect(getConditionBuilderAndConnectorBadge().textContent).toEqual('AND'); - }); - }); - }); - - describe('the Policy Selection area', () => { - beforeEach(() => { - const policy = generator.generatePolicyPackagePolicy(); - policy.name = 'test policy A'; - policy.id = '123'; - - formProps.policies.options = [policy]; - }); - - it('should have `global` switch on if effective scope is global and policy options hidden', () => { - render(); - const globalButton = renderResult.getByTestId( - `${dataTestSubjForForm}-effectedPolicies-global` - ) as HTMLButtonElement; - - expect(globalButton.classList.contains('euiButtonGroupButton-isSelected')).toEqual(true); - expect(renderResult.queryByTestId('policy-123')).toBeNull(); - }); - - it('should have policy options visible and specific policies checked if scope is per-policy', () => { - (formProps.trustedApp as NewTrustedApp).effectScope = { - type: 'policy', - policies: ['123'], - }; - render(); - const perPolicyButton = renderResult.getByTestId( - `${dataTestSubjForForm}-effectedPolicies-perPolicy` - ) as HTMLButtonElement; - - expect(perPolicyButton.classList.contains('euiButtonGroupButton-isSelected')).toEqual(true); - expect(renderResult.getByTestId('policy-123').getAttribute('aria-disabled')).toEqual('false'); - expect(renderResult.getByTestId('policy-123').getAttribute('aria-checked')).toEqual('true'); - }); - it('should show loader when setting `policies.isLoading` to true and scope is per-policy', () => { - formProps.policies.isLoading = true; - (formProps.trustedApp as NewTrustedApp).effectScope = { - type: 'policy', - policies: ['123'], - }; - render(); - expect(renderResult.queryByTestId('loading-spinner')).not.toBeNull(); - }); - }); - - describe('the Policy Selection area under feature flag', () => { - it("shouldn't display the policiy selection area ", () => { - useIsExperimentalFeatureEnabledMock.mockReturnValue(false); - render(); - expect( - renderResult.queryByText('Apply trusted application globally') - ).not.toBeInTheDocument(); - }); - }); - - describe('the Policy Selection area when the license downgrades to gold or below', () => { - beforeEach(() => { - // select per policy for trusted app - const policy = generator.generatePolicyPackagePolicy(); - policy.name = 'test policy A'; - policy.id = '123'; - - formProps.policies.options = [policy]; - - (formProps.trustedApp as NewTrustedApp).effectScope = { - type: 'policy', - policies: ['123'], - }; - - formProps.isEditMode = true; - - // downgrade license - (licenseService.isPlatinumPlus as jest.Mock).mockReturnValue(false); - }); - - it('maintains policy configuration but does not allow the user to edit add/remove individual policies in edit mode', () => { - render(); - const perPolicyButton = renderResult.getByTestId( - `${dataTestSubjForForm}-effectedPolicies-perPolicy` - ) as HTMLButtonElement; - - expect(perPolicyButton.classList.contains('euiButtonGroupButton-isSelected')).toEqual(true); - expect(renderResult.getByTestId('policy-123').getAttribute('aria-disabled')).toEqual('true'); - expect(renderResult.getByTestId('policy-123-checkbox')).toBeChecked(); - }); - it("allows the user to set the trusted app entry to 'Global' in the edit option", () => { - render(); - const globalButtonInput = renderResult.getByTestId('globalPolicy') as HTMLButtonElement; - - reactTestingLibrary.act(() => { - fireEvent.click(globalButtonInput); - }); - - expect(formProps.onChange.mock.calls[0][0].item.effectScope.type).toBe('global'); - }); - it('hides the policy assignment section if the TA is set to global', () => { - (formProps.trustedApp as NewTrustedApp).effectScope = { - type: 'global', - }; - expect(renderResult.queryByTestId(`${dataTestSubjForForm}-effectedPolicies`)).toBeNull(); - }); - it('hides the policy assignment section if the user is adding a new TA', () => { - formProps.isEditMode = false; - expect(renderResult.queryByTestId(`${dataTestSubjForForm}-effectedPolicies`)).toBeNull(); - }); - }); - - describe('and the user visits required fields but does not fill them out', () => { - beforeEach(() => { - render(); - reactTestingLibrary.act(() => { - fireEvent.blur(getNameField()); - }); - reactTestingLibrary.act(() => { - fireEvent.blur(getConditionValue(getCondition())); - }); - }); - - it('should show Name validation error', () => { - expect(renderResult.getByText('Name is required')); - }); - - it('should show Condition validation error', () => { - expect(renderResult.getByText('[1] Field entry must have a value')); - }); - - it('should NOT display any other errors', () => { - expect(getAllValidationErrors()).toHaveLength(2); - }); - }); - - describe('and invalid data is entered', () => { - beforeEach(() => render()); - - it('should validate that Name has a non empty space value', () => { - setTextFieldValue(getNameField(), ' '); - expect(renderResult.getByText('Name is required')); - }); - - it('should validate invalid Hash value', () => { - setTextFieldValue(getConditionValue(getCondition()), 'someHASH'); - expect(renderResult.getByText('[1] Invalid hash value')); - }); - - it('should validate that a condition value has a non empty space value', () => { - setTextFieldValue(getConditionValue(getCondition()), ' '); - expect(renderResult.getByText('[1] Field entry must have a value')); - }); - - it('should validate all condition values (when multiples exist) have non empty space value', () => { - const andButton = getConditionBuilderAndButton(); - reactTestingLibrary.act(() => { - fireEvent.click(andButton, { button: 1 }); - }); - rerenderWithLatestTrustedApp(); - - setTextFieldValue(getConditionValue(getCondition()), 'someHASH'); - rerenderWithLatestTrustedApp(); - - expect(renderResult.getByText('[2] Field entry must have a value')); - }); - - it('should validate duplicated conditions', () => { - const andButton = getConditionBuilderAndButton(); - reactTestingLibrary.act(() => { - fireEvent.click(andButton, { button: 1 }); - }); - - setTextFieldValue(getConditionValue(getCondition()), ''); - rerenderWithLatestTrustedApp(); - - expect(renderResult.getByText('Hash cannot be added more than once')); - }); - - it('should validate multiple errors in form', () => { - const andButton = getConditionBuilderAndButton(); - - reactTestingLibrary.act(() => { - fireEvent.click(andButton, { button: 1 }); - }); - rerenderWithLatestTrustedApp(); - - setTextFieldValue(getConditionValue(getCondition()), 'someHASH'); - rerenderWithLatestTrustedApp(); - expect(renderResult.getByText('[1] Invalid hash value')); - expect(renderResult.getByText('[2] Field entry must have a value')); - }); - }); - - describe('and all required data passes validation', () => { - it('should call change callback with isValid set to true and contain the new item', () => { - render(); - - setTextFieldValue(getNameField(), 'Some Process'); - rerenderWithLatestTrustedApp(); - - setTextFieldValue(getConditionValue(getCondition()), 'e50fb1a0e5fff590ece385082edc6c41'); - rerenderWithLatestTrustedApp(); - - setTextFieldValue(getDescriptionField(), 'some description'); - rerenderWithLatestTrustedApp(); - - expect(getAllValidationErrors()).toHaveLength(0); - expect(formProps.onChange).toHaveBeenLastCalledWith({ - isValid: true, - item: { - name: 'Some Process', - description: 'some description', - os: OperatingSystem.WINDOWS, - effectScope: { type: 'global' }, - entries: [ - { - field: ConditionEntryField.HASH, - operator: 'included', - type: 'match', - value: 'e50fb1a0e5fff590ece385082edc6c41', - }, - ], - }, - }); - }); - - it('should not validate form to true if name input is empty', () => { - const props = { - name: 'some name', - description: '', - effectScope: { - type: 'global', - }, - os: OperatingSystem.WINDOWS, - entries: [ - { field: ConditionEntryField.PATH, operator: 'included', type: 'wildcard', value: 'x' }, - ], - } as NewTrustedApp; - - formProps.trustedApp = props; - render(); - - formProps.trustedApp = { - ...props, - name: '', - }; - rerender(); - - expect(getAllValidationErrors()).toHaveLength(0); - expect(getAllValidationWarnings()).toHaveLength(1); - expect(formProps.onChange).toHaveBeenLastCalledWith({ - isValid: false, - item: { - name: '', - description: '', - os: OperatingSystem.WINDOWS, - effectScope: { type: 'global' }, - entries: [ - { - field: ConditionEntryField.PATH, - operator: 'included', - type: 'wildcard', - value: 'x', - }, - ], - }, - }); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.tsx deleted file mode 100644 index 8e7246962b5ee..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.tsx +++ /dev/null @@ -1,623 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { ChangeEventHandler, memo, useCallback, useEffect, useMemo, useState } from 'react'; -import { - EuiFieldText, - EuiForm, - EuiFormRow, - EuiHorizontalRule, - EuiSuperSelect, - EuiSuperSelectOption, - EuiTextArea, - EuiText, - EuiSpacer, -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { - hasSimpleExecutableName, - isPathValid, - ConditionEntryField, - OperatingSystem, -} from '@kbn/securitysolution-utils'; -import { EuiFormProps } from '@elastic/eui/src/components/form/form'; - -import { - TrustedAppConditionEntry, - EffectScope, - MacosLinuxConditionEntry, - MaybeImmutable, - NewTrustedApp, -} from '../../../../../../common/endpoint/types'; -import { - isValidHash, - getDuplicateFields, -} from '../../../../../../common/endpoint/service/trusted_apps/validations'; - -import { - isGlobalEffectScope, - isMacosLinuxTrustedAppCondition, - isPolicyEffectScope, - isWindowsTrustedAppCondition, -} from '../../state/type_guards'; -import { defaultConditionEntry } from '../../store/builders'; -import { CONDITION_FIELD_TITLE, OS_TITLES } from '../translations'; -import { LogicalConditionBuilder, LogicalConditionBuilderProps } from './logical_condition'; -import { useTestIdGenerator } from '../../../../components/hooks/use_test_id_generator'; -import { useLicense } from '../../../../../common/hooks/use_license'; -import { - EffectedPolicySelect, - EffectedPolicySelection, - EffectedPolicySelectProps, -} from '../../../../components/effected_policy_select'; - -const OPERATING_SYSTEMS: readonly OperatingSystem[] = [ - OperatingSystem.MAC, - OperatingSystem.WINDOWS, - OperatingSystem.LINUX, -]; - -interface FieldValidationState { - /** If this fields state is invalid. Drives display of errors on the UI */ - isInvalid: boolean; - errors: React.ReactNode[]; - warnings: React.ReactNode[]; -} -interface ValidationResult { - /** Overall indicator if form is valid */ - isValid: boolean; - - /** Individual form field validations */ - result: Partial<{ - [key in keyof NewTrustedApp]: FieldValidationState; - }>; -} - -const addResultToValidation = ( - validation: ValidationResult, - field: keyof NewTrustedApp, - type: 'warnings' | 'errors', - resultValue: React.ReactNode -) => { - if (!validation.result[field]) { - validation.result[field] = { - isInvalid: false, - errors: [], - warnings: [], - }; - } - const errorMarkup: React.ReactNode = type === 'warnings' ?
{resultValue}
: resultValue; - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - validation.result[field]![type].push(errorMarkup); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - validation.result[field]!.isInvalid = true; -}; - -const validateFormValues = (values: MaybeImmutable): ValidationResult => { - let isValid: ValidationResult['isValid'] = true; - const validation: ValidationResult = { - isValid, - result: {}, - }; - - // Name field - if (!values.name.trim()) { - isValid = false; - addResultToValidation( - validation, - 'name', - 'errors', - i18n.translate('xpack.securitySolution.trustedapps.create.nameRequiredMsg', { - defaultMessage: 'Name is required', - }) - ); - } - - if (!values.os) { - isValid = false; - addResultToValidation( - validation, - 'os', - 'errors', - i18n.translate('xpack.securitySolution.trustedapps.create.osRequiredMsg', { - defaultMessage: 'Operating System is required', - }) - ); - } - - if (!values.entries.length) { - isValid = false; - addResultToValidation( - validation, - 'entries', - 'errors', - i18n.translate('xpack.securitySolution.trustedapps.create.conditionRequiredMsg', { - defaultMessage: 'At least one Field definition is required', - }) - ); - } else { - const duplicated = getDuplicateFields(values.entries as TrustedAppConditionEntry[]); - if (duplicated.length) { - isValid = false; - duplicated.forEach((field) => { - addResultToValidation( - validation, - 'entries', - 'errors', - i18n.translate('xpack.securitySolution.trustedapps.create.conditionFieldDuplicatedMsg', { - defaultMessage: '{field} cannot be added more than once', - values: { field: CONDITION_FIELD_TITLE[field] }, - }) - ); - }); - } - values.entries.forEach((entry, index) => { - const isValidPathEntry = isPathValid({ - os: values.os, - field: entry.field, - type: entry.type, - value: entry.value, - }); - - if (!entry.field || !entry.value.trim()) { - isValid = false; - addResultToValidation( - validation, - 'entries', - 'errors', - i18n.translate( - 'xpack.securitySolution.trustedapps.create.conditionFieldValueRequiredMsg', - { - defaultMessage: '[{row}] Field entry must have a value', - values: { row: index + 1 }, - } - ) - ); - } else if (entry.field === ConditionEntryField.HASH && !isValidHash(entry.value)) { - isValid = false; - addResultToValidation( - validation, - 'entries', - 'errors', - i18n.translate('xpack.securitySolution.trustedapps.create.conditionFieldInvalidHashMsg', { - defaultMessage: '[{row}] Invalid hash value', - values: { row: index + 1 }, - }) - ); - } else if (!isValidPathEntry) { - addResultToValidation( - validation, - 'entries', - 'warnings', - i18n.translate('xpack.securitySolution.trustedapps.create.conditionFieldInvalidPathMsg', { - defaultMessage: '[{row}] Path may be formed incorrectly; verify value', - values: { row: index + 1 }, - }) - ); - } else if ( - isValidPathEntry && - !hasSimpleExecutableName({ os: values.os, value: entry.value, type: entry.type }) - ) { - addResultToValidation( - validation, - 'entries', - 'warnings', - i18n.translate( - 'xpack.securitySolution.trustedapps.create.conditionFieldDegradedPerformanceMsg', - { - defaultMessage: `[{row}] A wildcard in the filename will affect the endpoint's performance`, - values: { row: index + 1 }, - } - ) - ); - } - }); - } - - validation.isValid = isValid; - return validation; -}; - -export interface TrustedAppFormState { - isValid: boolean; - item: NewTrustedApp; -} - -export type CreateTrustedAppFormProps = Pick< - EuiFormProps, - 'className' | 'data-test-subj' | 'isInvalid' | 'error' | 'invalidCallout' -> & { - /** The trusted app values that will be passed to the form */ - trustedApp: MaybeImmutable; - isEditMode: boolean; - isDirty: boolean; - wasByPolicy: boolean; - onChange: (state: TrustedAppFormState) => void; - /** Setting passed on to the EffectedPolicySelect component */ - policies: Pick; - /** if form should be shown full width of parent container */ - fullWidth?: boolean; -}; -export const CreateTrustedAppForm = memo( - ({ - fullWidth, - isEditMode, - isDirty, - wasByPolicy, - onChange, - trustedApp: _trustedApp, - policies = { options: [] }, - ...formProps - }) => { - const trustedApp = _trustedApp as NewTrustedApp; - - const dataTestSubj = formProps['data-test-subj']; - - const isPlatinumPlus = useLicense().isPlatinumPlus(); - - const isGlobal = useMemo(() => { - return isGlobalEffectScope(trustedApp.effectScope); - }, [trustedApp]); - - const showAssignmentSection = useMemo(() => { - return isPlatinumPlus || (isEditMode && (!isGlobal || (wasByPolicy && isGlobal && isDirty))); - }, [isEditMode, isGlobal, isDirty, isPlatinumPlus, wasByPolicy]); - - const osOptions: Array> = useMemo( - () => OPERATING_SYSTEMS.map((os) => ({ value: os, inputDisplay: OS_TITLES[os] })), - [] - ); - - // We create local state for the list of policies because we want the selected policies to - // persist while the user is on the form and possibly toggling between global/non-global - const [selectedPolicies, setSelectedPolicies] = useState({ - isGlobal, - selected: [], - }); - - const [validationResult, setValidationResult] = useState(() => - validateFormValues(trustedApp) - ); - - const [wasVisited, setWasVisited] = useState< - Partial<{ - [key in keyof NewTrustedApp]: boolean; - }> - >({}); - - const getTestId = useTestIdGenerator(dataTestSubj); - - const notifyOfChange = useCallback( - (updatedFormValues: TrustedAppFormState['item']) => { - const updatedValidationResult = validateFormValues(updatedFormValues); - - setValidationResult(updatedValidationResult); - - onChange({ - item: updatedFormValues, - isValid: updatedValidationResult.isValid, - }); - }, - [onChange] - ); - - const handleAndClick = useCallback(() => { - if (trustedApp.os === OperatingSystem.WINDOWS) { - notifyOfChange({ - ...trustedApp, - entries: [...trustedApp.entries, defaultConditionEntry()].filter( - isWindowsTrustedAppCondition - ), - }); - } else { - notifyOfChange({ - ...trustedApp, - entries: [ - ...trustedApp.entries.filter(isMacosLinuxTrustedAppCondition), - defaultConditionEntry(), - ], - }); - } - }, [notifyOfChange, trustedApp]); - - const handleDomChangeEvents = useCallback< - ChangeEventHandler - >( - ({ target: { name, value } }) => { - notifyOfChange({ - ...trustedApp, - [name]: value, - }); - }, - [notifyOfChange, trustedApp] - ); - - // Handles keeping track if an input form field has been visited - const handleDomBlurEvents = useCallback>( - ({ target: { name } }) => { - setWasVisited((prevState) => { - return { - ...prevState, - [name]: true, - }; - }); - }, - [] - ); - - const handleOsChange = useCallback<(v: OperatingSystem) => void>( - (newOsValue) => { - setWasVisited((prevState) => { - return { - ...prevState, - os: true, - }; - }); - - const updatedState: NewTrustedApp = { - ...trustedApp, - entries: [], - os: newOsValue, - }; - if (updatedState.os !== OperatingSystem.WINDOWS) { - updatedState.entries.push( - ...(trustedApp.entries.filter((entry) => - isMacosLinuxTrustedAppCondition(entry) - ) as MacosLinuxConditionEntry[]) - ); - if (updatedState.entries.length === 0) { - updatedState.entries.push(defaultConditionEntry()); - } - } else { - updatedState.entries.push(...trustedApp.entries); - } - - notifyOfChange(updatedState); - }, - [notifyOfChange, trustedApp] - ); - - const handleEntryRemove = useCallback( - (entry: NewTrustedApp['entries'][0]) => { - notifyOfChange({ - ...trustedApp, - entries: trustedApp.entries.filter((item) => item !== entry), - } as NewTrustedApp); - }, - [notifyOfChange, trustedApp] - ); - - const handleEntryChange = useCallback( - (newEntry, oldEntry) => { - if (trustedApp.os === OperatingSystem.WINDOWS) { - notifyOfChange({ - ...trustedApp, - entries: trustedApp.entries.map((item) => { - if (item === oldEntry) { - return newEntry; - } - return item; - }), - } as NewTrustedApp); - } else { - notifyOfChange({ - ...trustedApp, - entries: trustedApp.entries.map((item) => { - if (item === oldEntry) { - return newEntry; - } - return item; - }), - } as NewTrustedApp); - } - }, - [notifyOfChange, trustedApp] - ); - - const handleConditionBuilderOnVisited: LogicalConditionBuilderProps['onVisited'] = - useCallback(() => { - setWasVisited((prevState) => { - return { - ...prevState, - entries: true, - }; - }); - }, []); - - const handlePolicySelectChange: EffectedPolicySelectProps['onChange'] = useCallback( - (selection) => { - setSelectedPolicies(() => selection); - - let newEffectedScope: EffectScope; - - if (selection.isGlobal) { - newEffectedScope = { - type: 'global', - }; - } else { - newEffectedScope = { - type: 'policy', - policies: selection.selected.map((policy) => policy.id), - }; - } - - notifyOfChange({ - ...trustedApp, - effectScope: newEffectedScope, - }); - }, - [notifyOfChange, trustedApp] - ); - - // Anytime the form values change, re-validate - useEffect(() => { - setValidationResult((prevState) => { - const newResults = validateFormValues(trustedApp); - - // Only notify if the overall validation result is different - if (newResults.isValid !== prevState.isValid) { - notifyOfChange(trustedApp); - } - - return newResults; - }); - }, [notifyOfChange, trustedApp]); - - // Anytime the TrustedApp has an effective scope of `policies`, then ensure that - // those polices are selected in the UI while at the same time preserving prior - // selections (UX requirement) - useEffect(() => { - setSelectedPolicies((currentSelection) => { - if (isPolicyEffectScope(trustedApp.effectScope) && policies.options.length > 0) { - const missingSelectedPolicies: EffectedPolicySelectProps['selected'] = []; - - for (const policyId of trustedApp.effectScope.policies) { - if ( - !currentSelection.selected.find( - (currentlySelectedPolicyItem) => currentlySelectedPolicyItem.id === policyId - ) - ) { - const newSelectedPolicy = policies.options.find((policy) => policy.id === policyId); - if (newSelectedPolicy) { - missingSelectedPolicies.push(newSelectedPolicy); - } - } - } - - if (missingSelectedPolicies.length) { - return { - ...currentSelection, - selected: [...currentSelection.selected, ...missingSelectedPolicies], - }; - } - } - - return currentSelection; - }); - }, [policies.options, trustedApp.effectScope]); - - return ( - - - - - - - - - -

- {i18n.translate('xpack.securitySolution.trustedApps.conditionsSectionTitle', { - defaultMessage: 'Conditions', - })} -

-
- - -

- {i18n.translate('xpack.securitySolution.trustedApps.conditionsSectionDescription', { - defaultMessage: - 'Select an operating system and add conditions. Availability of conditions may depend on your chosen OS.', - })} -

-
- - - - - - - - {showAssignmentSection ? ( - <> - - - - - - ) : null} -
- ); - } -); - -CreateTrustedAppForm.displayName = 'NewTrustedAppForm'; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/form.test.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/form.test.tsx new file mode 100644 index 0000000000000..dca86557f6309 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/form.test.tsx @@ -0,0 +1,595 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { screen, cleanup, act, fireEvent, getByTestId } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { + TrustedAppEntryTypes, + OperatingSystem, + ConditionEntryField, +} from '@kbn/securitysolution-utils'; +import { ENDPOINT_TRUSTED_APPS_LIST_ID } from '@kbn/securitysolution-list-constants'; + +import { TrustedAppsForm } from './form'; +import { + ArtifactFormComponentOnChangeCallbackProps, + ArtifactFormComponentProps, +} from '../../../../components/artifact_list_page'; +import { + AppContextTestRender, + createAppRootMockRenderer, +} from '../../../../../common/mock/endpoint'; +import { INPUT_ERRORS } from '../translations'; +import { licenseService } from '../../../../../common/hooks/use_license'; +import { forceHTMLElementOffsetWidth } from '../../../../components/effected_policy_select/test_utils'; +import type { PolicyData, TrustedAppConditionEntry } from '../../../../../../common/endpoint/types'; + +import { EndpointDocGenerator } from '../../../../../../common/endpoint/generate_data'; + +jest.mock('../../../../../common/hooks/use_license', () => { + const licenseServiceInstance = { + isPlatinumPlus: jest.fn(), + }; + return { + licenseService: licenseServiceInstance, + useLicense: () => { + return licenseServiceInstance; + }, + }; +}); + +describe('Trusted apps form', () => { + const formPrefix = 'trustedApps-form'; + const generator = new EndpointDocGenerator('effected-policy-select'); + let resetHTMLElementOffsetWidth: ReturnType; + + let formProps: jest.Mocked; + let mockedContext: AppContextTestRender; + let renderResult: ReturnType; + let latestUpdatedItem: ArtifactFormComponentProps['item']; + + const getUI = () => ; + const render = () => { + return (renderResult = mockedContext.render(getUI())); + }; + const rerender = () => renderResult.rerender(getUI()); + const rerenderWithLatestProps = () => { + formProps.item = latestUpdatedItem; + rerender(); + }; + + function createEntry( + field: T, + type: TrustedAppEntryTypes, + value: string + ): TrustedAppConditionEntry { + return { + field, + type, + operator: 'included', + value, + }; + } + + function createItem( + overrides: Partial = {} + ): ArtifactFormComponentProps['item'] { + const defaults: ArtifactFormComponentProps['item'] = { + list_id: ENDPOINT_TRUSTED_APPS_LIST_ID, + name: '', + description: '', + os_types: [OperatingSystem.WINDOWS], + entries: [createEntry(ConditionEntryField.HASH, 'match', '')], + type: 'simple', + tags: ['policy:all'], + }; + return { + ...defaults, + ...overrides, + }; + } + + function createOnChangeArgs( + overrides: Partial + ): ArtifactFormComponentOnChangeCallbackProps { + const defaults = { + item: createItem(), + isValid: false, + }; + return { + ...defaults, + ...overrides, + }; + } + + function createPolicies(): PolicyData[] { + const policies = [ + generator.generatePolicyPackagePolicy(), + generator.generatePolicyPackagePolicy(), + ]; + policies.map((p, i) => { + p.id = `id-${i}`; + p.name = `some-policy-${Math.random().toString(36).split('.').pop()}`; + return p; + }); + return policies; + } + + // Some helpers + const setTextFieldValue = (textField: HTMLInputElement | HTMLTextAreaElement, value: string) => { + act(() => { + fireEvent.change(textField, { + target: { value }, + }); + fireEvent.blur(textField); + }); + }; + const getDetailsBlurb = (dataTestSub: string = formPrefix): HTMLInputElement => { + return renderResult.queryByTestId(`${dataTestSub}-about`) as HTMLInputElement; + }; + const getNameField = (dataTestSub: string = formPrefix): HTMLInputElement => { + return renderResult.getByTestId(`${dataTestSub}-nameTextField`) as HTMLInputElement; + }; + const getOsField = (dataTestSub: string = formPrefix): HTMLButtonElement => { + return renderResult.getByTestId(`${dataTestSub}-osSelectField`) as HTMLButtonElement; + }; + const getDescriptionField = (dataTestSub: string = formPrefix): HTMLTextAreaElement => { + return renderResult.getByTestId(`${dataTestSub}-descriptionField`) as HTMLTextAreaElement; + }; + const getCondition = (index: number = 0, dataTestSub: string = formPrefix): HTMLElement => { + return renderResult.getByTestId(`${dataTestSub}-conditionsBuilder-group1-entry${index}`); + }; + const getAllConditions = (dataTestSub: string = formPrefix): HTMLElement[] => { + return Array.from( + renderResult.getByTestId(`${dataTestSub}-conditionsBuilder-group1-entries`).children + ) as HTMLElement[]; + }; + const getConditionRemoveButton = (condition: HTMLElement): HTMLButtonElement => { + return getByTestId(condition, `${condition.dataset.testSubj}-remove`) as HTMLButtonElement; + }; + const getConditionFieldSelect = (condition: HTMLElement): HTMLButtonElement => { + return getByTestId(condition, `${condition.dataset.testSubj}-field`) as HTMLButtonElement; + }; + + const getConditionValue = (condition: HTMLElement): HTMLInputElement => { + return getByTestId(condition, `${condition.dataset.testSubj}-value`) as HTMLInputElement; + }; + const getConditionBuilderAndButton = (dataTestSub: string = formPrefix): HTMLButtonElement => { + return renderResult.getByTestId( + `${dataTestSub}-conditionsBuilder-group1-AndButton` + ) as HTMLButtonElement; + }; + const getConditionBuilderAndConnectorBadge = (dataTestSub: string = formPrefix): HTMLElement => { + return renderResult.getByTestId(`${dataTestSub}-conditionsBuilder-group1-andConnector`); + }; + const getAllValidationErrors = (): HTMLElement[] => { + return Array.from(renderResult.container.querySelectorAll('.euiFormErrorText')); + }; + const getAllValidationWarnings = (): HTMLElement[] => { + return Array.from(renderResult.container.querySelectorAll('.euiFormHelpText')); + }; + + beforeEach(() => { + resetHTMLElementOffsetWidth = forceHTMLElementOffsetWidth(); + (licenseService.isPlatinumPlus as jest.Mock).mockReturnValue(true); + mockedContext = createAppRootMockRenderer(); + latestUpdatedItem = createItem(); + + formProps = { + item: latestUpdatedItem, + mode: 'create', + disabled: false, + error: undefined, + policiesIsLoading: false, + onChange: jest.fn((updates) => { + latestUpdatedItem = updates.item; + }), + policies: [], + }; + }); + + afterEach(() => { + resetHTMLElementOffsetWidth(); + cleanup(); + }); + + describe('Details and Conditions', () => { + beforeEach(() => render()); + + it('should NOT initially show any inline validation errors', () => { + expect(renderResult.container.querySelectorAll('.euiFormErrorText').length).toBe(0); + }); + + it('should hide details text when in edit mode', () => { + formProps.mode = 'edit'; + rerenderWithLatestProps(); + expect(getDetailsBlurb()).toBeNull(); + }); + + it('should show name required name blur', () => { + setTextFieldValue(getNameField(), ' '); + expect(renderResult.getByText(INPUT_ERRORS.name)).toBeTruthy(); + }); + + it('should default OS to Windows', () => { + expect(getOsField().textContent).toEqual('Windows'); + }); + + it('should allow user to select between 3 OSs', () => { + const osField = getOsField(); + userEvent.click(osField, { button: 1 }); + const options = Array.from( + renderResult.baseElement.querySelectorAll( + '.euiSuperSelect__listbox button.euiSuperSelect__item' + ) + ).map((button) => button.textContent); + expect(options).toEqual(['Linux', 'Mac', 'Windows']); + }); + + it('should show Description as optional', () => { + expect(getDescriptionField().required).toBe(false); + }); + + it('should be invalid if no name', () => { + const emptyName = ' '; + setTextFieldValue(getNameField(), emptyName); + const expected = createOnChangeArgs({ + item: createItem({ + name: emptyName, + }), + }); + expect(formProps.onChange).toHaveBeenCalledWith(expected); + }); + + it('should correctly edit name', () => { + setTextFieldValue(getNameField(), 'z'); + const expected = createOnChangeArgs({ + item: createItem({ + name: 'z', + }), + }); + expect(formProps.onChange).toHaveBeenCalledWith(expected); + }); + + it('should correctly edit description', () => { + setTextFieldValue(getDescriptionField(), 'describe ta'); + const expected = createOnChangeArgs({ + item: createItem({ description: 'describe ta' }), + }); + expect(formProps.onChange).toHaveBeenCalledWith(expected); + }); + + it('should correctly change OS', () => { + userEvent.click(getOsField()); + userEvent.click(screen.getByRole('option', { name: 'Linux' })); + const expected = createOnChangeArgs({ + item: createItem({ os_types: [OperatingSystem.LINUX] }), + }); + expect(formProps.onChange).toHaveBeenCalledWith(expected); + }); + }); + + describe('ConditionBuilder', () => { + beforeEach(() => render()); + + it('should default to hash entry field', () => { + const defaultCondition = getCondition(); + const labels = Array.from(defaultCondition.querySelectorAll('.euiFormRow__labelWrapper')).map( + (label) => (label.textContent || '').trim() + ); + expect(labels).toEqual(['Field', 'Operator', 'Value', '']); + expect(formProps.onChange).not.toHaveBeenCalled(); + }); + + it('should not allow the entry to be removed if its the only one displayed', () => { + const defaultCondition = getCondition(); + expect(getConditionRemoveButton(defaultCondition).disabled).toBe(true); + }); + + it('should display 3 options for Field for Windows', () => { + const conditionFieldSelect = getConditionFieldSelect(getCondition()); + userEvent.click(conditionFieldSelect, { button: 1 }); + const options = Array.from( + renderResult.baseElement.querySelectorAll( + '.euiSuperSelect__listbox button.euiSuperSelect__item' + ) + ).map((button) => button.textContent); + expect(options.length).toEqual(3); + expect(options).toEqual([ + 'Hashmd5, sha1, or sha256', + 'PathThe full path of the application', + 'SignatureThe signer of the application', + ]); + }); + + it('should show the value field as required after blur', () => { + expect(getConditionValue(getCondition()).required).toEqual(false); + act(() => { + fireEvent.blur(getConditionValue(getCondition())); + }); + expect(getConditionValue(getCondition()).required).toEqual(true); + }); + + it('should show path malformed warning', () => { + render(); + expect(screen.queryByText(INPUT_ERRORS.pathWarning(0))).toBeNull(); + + const propsItem: Partial = { + entries: [createEntry(ConditionEntryField.PATH, 'match', 'malformed-path')], + }; + formProps.item = { ...formProps.item, ...propsItem }; + render(); + expect(screen.getByText(INPUT_ERRORS.pathWarning(0))).not.toBeNull(); + }); + + it('should show wildcard in path warning', () => { + render(); + expect(screen.queryByText(INPUT_ERRORS.wildcardPathWarning(0))).toBeNull(); + + const propsItem: Partial = { + os_types: [OperatingSystem.LINUX], + entries: [createEntry(ConditionEntryField.PATH, 'wildcard', '/sys/wil*/*.app')], + }; + formProps.item = { ...formProps.item, ...propsItem }; + render(); + expect(screen.getByText(INPUT_ERRORS.wildcardPathWarning(0))).not.toBeNull(); + }); + + it('should display the `AND` button', () => { + const andButton = getConditionBuilderAndButton(); + expect(andButton.textContent).toEqual('AND'); + expect(andButton.disabled).toEqual(false); + }); + + describe('and when the AND button is clicked', () => { + beforeEach(() => { + const andButton = getConditionBuilderAndButton(); + userEvent.click(andButton, { button: 1 }); + // re-render with updated `newTrustedApp` + formProps.item = formProps.onChange.mock.calls[0][0].item; + rerender(); + }); + + it('should add a new condition entry when `AND` is clicked with no column labels', () => { + const condition2 = getCondition(1); + expect(condition2.querySelectorAll('.euiFormRow__labelWrapper')).toHaveLength(0); + }); + + it('should have remove buttons enabled when multiple conditions are present', () => { + getAllConditions().forEach((condition) => { + expect(getConditionRemoveButton(condition).disabled).toBe(false); + }); + }); + + it('should show the AND visual connector when multiple entries are present', () => { + expect(getConditionBuilderAndConnectorBadge().textContent).toEqual('AND'); + }); + }); + }); + + describe('the Policy Selection area', () => { + beforeEach(() => { + formProps.policies = createPolicies(); + }); + + it('should have `global` switch on if effective scope is global and policy options hidden', () => { + render(); + const globalButton = renderResult.getByTestId( + `${formPrefix}-effectedPolicies-global` + ) as HTMLButtonElement; + + expect(globalButton.classList.contains('euiButtonGroupButton-isSelected')).toEqual(true); + expect( + renderResult.queryByTestId(`${formPrefix}-effectedPolicies-policiesSelectable`) + ).toBeNull(); + expect(renderResult.queryByTestId('policy-id-0')).toBeNull(); + }); + + it('should have policy options visible and specific policies checked if scope is per-policy', () => { + formProps.item.tags = [formProps.policies.map((p) => `policy:${p.id}`)[0]]; + render(); + + const perPolicyButton = renderResult.getByTestId( + `${formPrefix}-effectedPolicies-perPolicy` + ) as HTMLButtonElement; + + expect(perPolicyButton.classList.contains('euiButtonGroupButton-isSelected')).toEqual(true); + expect(renderResult.getByTestId('policy-id-0').getAttribute('aria-disabled')).toEqual( + 'false' + ); + expect(renderResult.getByTestId('policy-id-0-checkbox')).toBeChecked(); + }); + + it('should show loader when setting `policies.isLoading` to true and scope is per-policy', () => { + formProps.policiesIsLoading = true; + formProps.item.tags = [formProps.policies.map((p) => `policy:${p.id}`)[0]]; + render(); + expect(renderResult.queryByTestId('loading-spinner')).not.toBeNull(); + }); + }); + + describe('the Policy Selection area when the license downgrades to gold or below', () => { + beforeEach(() => { + const policies = createPolicies(); + formProps.policies = policies; + formProps.item.tags = [policies.map((p) => `policy:${p.id}`)[0]]; + formProps.mode = 'edit'; + // downgrade license + (licenseService.isPlatinumPlus as jest.Mock).mockReturnValue(false); + render(); + }); + + it('maintains policy configuration but does not allow the user to edit add/remove individual policies in edit mode', () => { + const perPolicyButton = renderResult.getByTestId( + `${formPrefix}-effectedPolicies-perPolicy` + ) as HTMLButtonElement; + expect(perPolicyButton.classList.contains('euiButtonGroupButton-isSelected')).toEqual(true); + expect(renderResult.getByTestId('policy-id-0').getAttribute('aria-disabled')).toEqual('true'); + expect(renderResult.getByTestId('policy-id-0-checkbox')).toBeChecked(); + }); + it("allows the user to set the trusted app entry to 'Global' in the edit option", () => { + const globalButtonInput = renderResult.getByTestId('globalPolicy') as HTMLButtonElement; + act(() => { + fireEvent.click(globalButtonInput); + }); + + const policyItem = formProps.onChange.mock.calls[0][0].item.tags + ? formProps.onChange.mock.calls[0][0].item.tags[0] + : ''; + expect(policyItem).toBe('policy:all'); + }); + + it('hides the policy assignment section if the TA is set to global', () => { + formProps.item.tags = ['policy:all']; + rerender(); + expect(renderResult.queryByTestId(`${formPrefix}-effectedPolicies`)).toBeNull(); + }); + it('hides the policy assignment section if the user is adding a new TA', () => { + formProps.mode = 'create'; + rerender(); + expect(renderResult.queryByTestId(`${formPrefix}-effectedPolicies`)).toBeNull(); + }); + }); + + describe('and the user visits required fields but does not fill them out', () => { + beforeEach(() => { + render(); + act(() => { + fireEvent.blur(getNameField()); + }); + act(() => { + fireEvent.blur(getConditionValue(getCondition())); + }); + }); + + it('should show Name validation error', () => { + expect(renderResult.getByText(INPUT_ERRORS.name)).not.toBeNull(); + }); + + it('should show Condition validation error', () => { + expect(renderResult.getByText(INPUT_ERRORS.mustHaveValue(0))); + }); + + it('should NOT display any other errors', () => { + expect(getAllValidationErrors()).toHaveLength(2); + }); + }); + + describe('and invalid data is entered', () => { + beforeEach(() => render()); + + it('should validate that Name has a non empty space value', () => { + setTextFieldValue(getNameField(), ' '); + expect(renderResult.getByText(INPUT_ERRORS.name)); + }); + + it('should validate invalid Hash value', () => { + setTextFieldValue(getConditionValue(getCondition()), 'someHASH'); + expect(renderResult.getByText(INPUT_ERRORS.invalidHash(0))); + }); + + it('should validate that a condition value has a non empty space value', () => { + setTextFieldValue(getConditionValue(getCondition()), ' '); + expect(renderResult.getByText(INPUT_ERRORS.mustHaveValue(0))); + }); + + it('should validate all condition values (when multiples exist) have non empty space value', () => { + const andButton = getConditionBuilderAndButton(); + userEvent.click(andButton, { button: 1 }); + rerenderWithLatestProps(); + + setTextFieldValue(getConditionValue(getCondition()), 'someHASH'); + rerenderWithLatestProps(); + + expect(renderResult.getByText(INPUT_ERRORS.mustHaveValue(1))); + }); + + it('should validate duplicated conditions', () => { + const andButton = getConditionBuilderAndButton(); + userEvent.click(andButton, { button: 1 }); + + setTextFieldValue(getConditionValue(getCondition()), ''); + rerenderWithLatestProps(); + + expect(renderResult.getByText(INPUT_ERRORS.noDuplicateField(ConditionEntryField.HASH))); + }); + + it('should validate multiple errors in form', () => { + const andButton = getConditionBuilderAndButton(); + + userEvent.click(andButton, { button: 1 }); + rerenderWithLatestProps(); + + setTextFieldValue(getConditionValue(getCondition()), 'someHASH'); + rerenderWithLatestProps(); + expect(renderResult.getByText(INPUT_ERRORS.invalidHash(0))); + expect(renderResult.getByText(INPUT_ERRORS.mustHaveValue(1))); + }); + }); + + describe('and all required data passes validation', () => { + it('should call change callback with isValid set to true and contain the new item', () => { + const propsItem: Partial = { + os_types: [OperatingSystem.LINUX], + name: 'Some process', + description: 'some description', + entries: [ + createEntry(ConditionEntryField.HASH, 'match', 'e50fb1a0e5fff590ece385082edc6c41'), + ], + }; + formProps.item = { ...formProps.item, ...propsItem }; + render(); + act(() => { + fireEvent.blur(getNameField()); + }); + + expect(getAllValidationErrors()).toHaveLength(0); + const expected = createOnChangeArgs({ + isValid: true, + item: createItem(propsItem), + }); + expect(formProps.onChange).toHaveBeenCalledWith(expected); + }); + + it('should not validate form to true if name input is empty', () => { + const propsItem: Partial = { + name: 'some name', + os_types: [OperatingSystem.LINUX], + entries: [createEntry(ConditionEntryField.PATH, 'wildcard', '/sys/usr*/doc.app')], + }; + formProps.item = { ...formProps.item, ...propsItem }; + render(); + expect(getAllValidationErrors()).toHaveLength(0); + expect(getAllValidationWarnings()).toHaveLength(0); + + formProps.item.name = ''; + rerender(); + act(() => { + fireEvent.blur(getNameField()); + }); + expect(getAllValidationErrors()).toHaveLength(1); + expect(getAllValidationWarnings()).toHaveLength(0); + expect(formProps.onChange).toHaveBeenLastCalledWith({ + isValid: false, + item: { + ...formProps.item, + name: '', + os_types: [OperatingSystem.LINUX], + entries: [ + { + field: ConditionEntryField.PATH, + operator: 'included', + type: 'wildcard', + value: '/sys/usr*/doc.app', + }, + ], + }, + }); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/form.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/form.tsx new file mode 100644 index 0000000000000..9656b5821b756 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/form.tsx @@ -0,0 +1,519 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { ChangeEventHandler, memo, useCallback, useEffect, useMemo, useState } from 'react'; +import { + EuiFieldText, + EuiForm, + EuiFormRow, + EuiHorizontalRule, + EuiSuperSelect, + EuiSuperSelectOption, + EuiTextArea, + EuiText, + EuiTitle, + EuiSpacer, +} from '@elastic/eui'; +import { + hasSimpleExecutableName, + isPathValid, + ConditionEntryField, + OperatingSystem, + AllConditionEntryFields, + EntryTypes, +} from '@kbn/securitysolution-utils'; +import { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; + +import { TrustedAppConditionEntry, NewTrustedApp } from '../../../../../../common/endpoint/types'; +import { + isValidHash, + getDuplicateFields, +} from '../../../../../../common/endpoint/service/artifacts/validations'; + +import { + isArtifactGlobal, + getPolicyIdsFromArtifact, +} from '../../../../../../common/endpoint/service/artifacts'; +import { + isMacosLinuxTrustedAppCondition, + isWindowsTrustedAppCondition, +} from '../../state/type_guards'; + +import { + CONDITIONS_HEADER, + CONDITIONS_HEADER_DESCRIPTION, + DETAILS_HEADER, + DETAILS_HEADER_DESCRIPTION, + DESCRIPTION_LABEL, + INPUT_ERRORS, + NAME_LABEL, + POLICY_SELECT_DESCRIPTION, + SELECT_OS_LABEL, +} from '../translations'; +import { OS_TITLES } from '../../../../common/translations'; +import { LogicalConditionBuilder, LogicalConditionBuilderProps } from './logical_condition'; +import { useTestIdGenerator } from '../../../../components/hooks/use_test_id_generator'; +import { useLicense } from '../../../../../common/hooks/use_license'; +import { + EffectedPolicySelect, + EffectedPolicySelection, +} from '../../../../components/effected_policy_select'; +import { + GLOBAL_ARTIFACT_TAG, + BY_POLICY_ARTIFACT_TAG_PREFIX, +} from '../../../../../../common/endpoint/service/artifacts/constants'; +import type { PolicyData } from '../../../../../../common/endpoint/types'; +import { ArtifactFormComponentProps } from '../../../../components/artifact_list_page'; +import { isGlobalPolicyEffected } from '../../../../components/effected_policy_select/utils'; + +interface FieldValidationState { + /** If this fields state is invalid. Drives display of errors on the UI */ + isInvalid: boolean; + errors: React.ReactNode[]; + warnings: React.ReactNode[]; +} +interface ValidationResult { + /** Overall indicator if form is valid */ + isValid: boolean; + + /** Individual form field validations */ + result: Partial<{ + [key in keyof NewTrustedApp]: FieldValidationState; + }>; +} + +const addResultToValidation = ( + validation: ValidationResult, + field: keyof NewTrustedApp, + type: 'warnings' | 'errors', + resultValue: React.ReactNode +) => { + if (!validation.result[field]) { + validation.result[field] = { + isInvalid: false, + errors: [], + warnings: [], + }; + } + const errorMarkup: React.ReactNode = type === 'warnings' ?
{resultValue}
: resultValue; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + validation.result[field]![type].push(errorMarkup); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + validation.result[field]!.isInvalid = true; +}; + +const validateValues = (values: ArtifactFormComponentProps['item']): ValidationResult => { + let isValid: ValidationResult['isValid'] = true; + const validation: ValidationResult = { + isValid, + result: {}, + }; + + // Name field + if (!values.name.trim()) { + isValid = false; + addResultToValidation(validation, 'name', 'errors', INPUT_ERRORS.name); + } + + if (!values.os_types) { + isValid = false; + addResultToValidation(validation, 'os', 'errors', INPUT_ERRORS.os); + } + + const os = ((values.os_types ?? [])[0] as OperatingSystem) ?? OperatingSystem.WINDOWS; + if (!values.entries.length) { + isValid = false; + addResultToValidation(validation, 'entries', 'errors', INPUT_ERRORS.field); + } else { + const duplicated = getDuplicateFields(values.entries as TrustedAppConditionEntry[]); + if (duplicated.length) { + isValid = false; + duplicated.forEach((field: ConditionEntryField) => { + addResultToValidation( + validation, + 'entries', + 'errors', + INPUT_ERRORS.noDuplicateField(field) + ); + }); + } + values.entries.forEach((entry, index) => { + const isValidPathEntry = isPathValid({ + os, + field: entry.field as AllConditionEntryFields, + type: entry.type as EntryTypes, + value: (entry as TrustedAppConditionEntry).value, + }); + + if (!entry.field || !(entry as TrustedAppConditionEntry).value.trim()) { + isValid = false; + addResultToValidation(validation, 'entries', 'errors', INPUT_ERRORS.mustHaveValue(index)); + } else if ( + entry.field === ConditionEntryField.HASH && + !isValidHash((entry as TrustedAppConditionEntry).value) + ) { + isValid = false; + addResultToValidation(validation, 'entries', 'errors', INPUT_ERRORS.invalidHash(index)); + } else if (!isValidPathEntry) { + addResultToValidation(validation, 'entries', 'warnings', INPUT_ERRORS.pathWarning(index)); + } else if ( + isValidPathEntry && + !hasSimpleExecutableName({ + os, + value: (entry as TrustedAppConditionEntry).value, + type: entry.type as EntryTypes, + }) + ) { + addResultToValidation( + validation, + 'entries', + 'warnings', + INPUT_ERRORS.wildcardPathWarning(index) + ); + } + }); + } + + validation.isValid = isValid; + return validation; +}; + +const defaultConditionEntry = (): TrustedAppConditionEntry => ({ + field: ConditionEntryField.HASH, + operator: 'included', + type: 'match', + value: '', +}); + +export const TrustedAppsForm = memo( + ({ item, policies, policiesIsLoading, onChange, mode }) => { + const getTestId = useTestIdGenerator('trustedApps-form'); + const [visited, setVisited] = useState< + Partial<{ + [key in keyof NewTrustedApp]: boolean; + }> + >({}); + + const [selectedPolicies, setSelectedPolicies] = useState([]); + const isPlatinumPlus = useLicense().isPlatinumPlus(); + const isGlobal = useMemo(() => isArtifactGlobal(item as ExceptionListItemSchema), [item]); + const [wasByPolicy, setWasByPolicy] = useState(!isGlobalPolicyEffected(item.tags)); + const [hasFormChanged, setHasFormChanged] = useState(false); + + useEffect(() => { + if (!hasFormChanged && item.tags) { + setWasByPolicy(!isGlobalPolicyEffected(item.tags)); + } + }, [item.tags, hasFormChanged]); + + // select policies if editing + useEffect(() => { + if (hasFormChanged) { + return; + } + const policyIds = item.tags ? getPolicyIdsFromArtifact({ tags: item.tags }) : []; + if (!policyIds.length) { + return; + } + const policiesData = policies.filter((policy) => policyIds.includes(policy.id)); + + setSelectedPolicies(policiesData); + }, [hasFormChanged, item, policies]); + + const showAssignmentSection = useMemo(() => { + return ( + isPlatinumPlus || + (mode === 'edit' && (!isGlobal || (wasByPolicy && isGlobal && hasFormChanged))) + ); + }, [mode, isGlobal, hasFormChanged, isPlatinumPlus, wasByPolicy]); + + const [validationResult, setValidationResult] = useState(() => + validateValues(item) + ); + + const processChanged = useCallback( + (updatedFormValues: ArtifactFormComponentProps['item']) => { + const updatedValidationResult = validateValues(updatedFormValues); + setValidationResult(updatedValidationResult); + onChange({ + item: updatedFormValues, + isValid: updatedValidationResult.isValid, + }); + }, + [onChange] + ); + + const handleOnPolicyChange = useCallback( + (change: EffectedPolicySelection) => { + const tags = change.isGlobal + ? [GLOBAL_ARTIFACT_TAG] + : change.selected.map((policy) => `${BY_POLICY_ARTIFACT_TAG_PREFIX}${policy.id}`); + + const nextItem = { ...item, tags }; + // Preserve old selected policies when switching to global + if (!change.isGlobal) { + setSelectedPolicies(change.selected); + } + processChanged(nextItem); + setHasFormChanged(true); + }, + [item, processChanged] + ); + + const handleOnNameOrDescriptionChange = useCallback< + ChangeEventHandler + >( + (event: React.ChangeEvent) => { + const nextItem = { + ...item, + [event.target.name]: event.target.value, + }; + + processChanged(nextItem); + setHasFormChanged(true); + }, + [item, processChanged] + ); + + const handleOnNameBlur = useCallback( + ({ target: { name } }) => { + processChanged(item); + setVisited((prevVisited) => ({ ...prevVisited, [name]: true })); + }, + [item, processChanged] + ); + + const osOptions: Array> = useMemo( + () => + [OperatingSystem.LINUX, OperatingSystem.MAC, OperatingSystem.WINDOWS].map((os) => ({ + value: os, + inputDisplay: OS_TITLES[os], + })), + [] + ); + + const handleOnOsChange = useCallback( + (os: OperatingSystem) => { + setVisited((prevVisited) => { + return { + ...prevVisited, + os: true, + }; + }); + + const nextItem: ArtifactFormComponentProps['item'] = { + ...item, + os_types: [os], + entries: [] as ArtifactFormComponentProps['item']['entries'], + }; + + if (os !== OperatingSystem.WINDOWS) { + const macOsLinuxConditionEntry = item.entries.filter((entry) => + isMacosLinuxTrustedAppCondition(entry as TrustedAppConditionEntry) + ); + nextItem.entries.push(...macOsLinuxConditionEntry); + if (item.entries.length === 0) { + nextItem.entries.push(defaultConditionEntry()); + } + } else { + nextItem.entries.push(...item.entries); + } + + processChanged(nextItem); + setHasFormChanged(true); + }, + [item, processChanged] + ); + + const handleConditionBuilderOnVisited: LogicalConditionBuilderProps['onVisited'] = + useCallback(() => { + setVisited((prevState) => { + return { + ...prevState, + entries: true, + }; + }); + }, []); + + const handleEntryChange = useCallback( + (newEntry, oldEntry) => { + const nextItem: ArtifactFormComponentProps['item'] = { + ...item, + entries: item.entries.map((e) => { + if (e === oldEntry) { + return newEntry; + } + return e; + }), + }; + + processChanged(nextItem); + setHasFormChanged(true); + }, + [item, processChanged] + ); + + const handleEntryRemove = useCallback( + (entry: NewTrustedApp['entries'][0]) => { + const nextItem: ArtifactFormComponentProps['item'] = { + ...item, + entries: item.entries.filter((e) => e !== entry), + }; + + processChanged(nextItem); + setHasFormChanged(true); + }, + [item, processChanged] + ); + + const handleAndClick = useCallback(() => { + const nextItem: ArtifactFormComponentProps['item'] = { + ...item, + entries: [], + }; + const os = ((item.os_types ?? [])[0] as OperatingSystem) ?? OperatingSystem.WINDOWS; + if (os === OperatingSystem.WINDOWS) { + nextItem.entries = [...item.entries, defaultConditionEntry()].filter((entry) => + isWindowsTrustedAppCondition(entry as TrustedAppConditionEntry) + ); + } else { + nextItem.entries = [ + ...item.entries.filter((entry) => + isMacosLinuxTrustedAppCondition(entry as TrustedAppConditionEntry) + ), + defaultConditionEntry(), + ]; + } + processChanged(nextItem); + setHasFormChanged(true); + }, [item, processChanged]); + + const selectedOs = useMemo((): OperatingSystem => { + if (!item?.os_types?.length) { + return OperatingSystem.WINDOWS; + } + return item.os_types[0] as OperatingSystem; + }, [item?.os_types]); + + const trustedApp = useMemo(() => { + const ta = item; + + ta.entries = item.entries.length + ? (item.entries as TrustedAppConditionEntry[]) + : [defaultConditionEntry()]; + + return ta; + }, [item]); + + return ( + + +

{DETAILS_HEADER}

+
+ + {mode === 'create' && ( + +

{DETAILS_HEADER_DESCRIPTION}

+
+ )} + + + + + + + + + +

{CONDITIONS_HEADER}

+
+ + {CONDITIONS_HEADER_DESCRIPTION} + + + + + + + + {showAssignmentSection ? ( + <> + + + + + + ) : null} +
+ ); + } +); + +TrustedAppsForm.displayName = 'TrustedAppsForm'; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/__snapshots__/index.test.tsx.snap deleted file mode 100644 index 8b496dcb519b9..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/__snapshots__/index.test.tsx.snap +++ /dev/null @@ -1,12717 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`TrustedAppsGrid renders correctly initially 1`] = ` -.c1 { - position: relative; - padding-top: 4px; -} - -.c1 .body { - min-height: 40px; -} - -.c1 .body-content { - position: relative; -} - -.c0 .trusted-app + .trusted-app { - margin-top: 24px; -} - -
-
-
-
-
-
-
-
-
- - No items found - -
-
-
-
-
-
-
-
-
-`; - -exports[`TrustedAppsGrid renders correctly when failed loading data for the first time 1`] = ` -.c1 { - position: relative; - padding-top: 4px; -} - -.c1 .body { - min-height: 40px; -} - -.c1 .body-content { - position: relative; -} - -.c0 .trusted-app + .trusted-app { - margin-top: 24px; -} - -
-
-
-
-
-
-
-
- - - Intenal Server Error -
-
-
-
-
-
-
-
-`; - -exports[`TrustedAppsGrid renders correctly when failed loading data for the second time 1`] = ` -.c1 { - position: relative; - padding-top: 4px; -} - -.c1 .body { - min-height: 40px; -} - -.c1 .body-content { - position: relative; -} - -.c0 .trusted-app + .trusted-app { - margin-top: 24px; -} - -
-
-
-
-
-
-
-
- - - Intenal Server Error -
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
- -
-
-
-
-
-
-`; - -exports[`TrustedAppsGrid renders correctly when loaded data 1`] = ` -.c1 { - position: relative; - padding-top: 4px; -} - -.c1 .body { - min-height: 40px; -} - -.c1 .body-content { - position: relative; -} - -.c6 { - padding-top: 2px; -} - -.c5 { - margin-bottom: 4px !important; -} - -.c7 { - margin: 6px; -} - -.c3.artifactEntryCard + .c2.artifactEntryCard { - margin-top: 24px; -} - -.c4 { - padding: 32px; -} - -.c4.top-section { - padding-bottom: 24px; -} - -.c4.bottom-section { - padding-top: 24px; -} - -.c4.artifact-entry-collapsible-card { - padding: 24px !important; -} - -.c0 .trusted-app + .trusted-app { - margin-top: 24px; -} - -
-
-
-
-
-
-
-
-
-
-
-

- trusted app 0 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 0 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Windows - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 1 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 1 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Mac - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 2 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 2 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Linux - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 3 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 3 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Windows - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 4 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 4 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Mac - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 5 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 5 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Linux - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 6 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 6 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Windows - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 7 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 7 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Mac - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 8 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 8 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Linux - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 9 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 9 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Windows - - - -
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
- -
-
-
-
-
-
-`; - -exports[`TrustedAppsGrid renders correctly when loading data for the first time 1`] = ` -.c1 { - position: relative; - padding-top: 4px; -} - -.c1 .body { - min-height: 40px; -} - -.c1 .body-content { - position: relative; -} - -.c0 .trusted-app + .trusted-app { - margin-top: 24px; -} - -
-
-
-
-
-
-
-
-
-
-`; - -exports[`TrustedAppsGrid renders correctly when loading data for the second time 1`] = ` -.c1 { - position: relative; - padding-top: 4px; -} - -.c1 .body { - min-height: 40px; -} - -.c1 .body-content { - position: relative; -} - -.c6 { - padding-top: 2px; -} - -.c5 { - margin-bottom: 4px !important; -} - -.c7 { - margin: 6px; -} - -.c3.artifactEntryCard + .c2.artifactEntryCard { - margin-top: 24px; -} - -.c4 { - padding: 32px; -} - -.c4.top-section { - padding-bottom: 24px; -} - -.c4.bottom-section { - padding-top: 24px; -} - -.c4.artifact-entry-collapsible-card { - padding: 24px !important; -} - -.c0 .trusted-app + .trusted-app { - margin-top: 24px; -} - -
-
-
-
-
-
-
-
-
-
-
-
-

- trusted app 0 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 0 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Windows - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 1 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 1 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Mac - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 2 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 2 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Linux - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 3 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 3 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Windows - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 4 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 4 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Mac - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 5 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 5 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Linux - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 6 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 6 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Windows - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 7 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 7 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Mac - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 8 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 8 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Linux - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 9 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 9 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Windows - - - -
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
- -
-
-
-
-
-
-`; - -exports[`TrustedAppsGrid renders correctly when new page and page size set (not loading yet) 1`] = ` -.c1 { - position: relative; - padding-top: 4px; -} - -.c1 .body { - min-height: 40px; -} - -.c1 .body-content { - position: relative; -} - -.c6 { - padding-top: 2px; -} - -.c5 { - margin-bottom: 4px !important; -} - -.c7 { - margin: 6px; -} - -.c3.artifactEntryCard + .c2.artifactEntryCard { - margin-top: 24px; -} - -.c4 { - padding: 32px; -} - -.c4.top-section { - padding-bottom: 24px; -} - -.c4.bottom-section { - padding-top: 24px; -} - -.c4.artifact-entry-collapsible-card { - padding: 24px !important; -} - -.c0 .trusted-app + .trusted-app { - margin-top: 24px; -} - -
-
-
-
-
-
-
-
-
-
-
-

- trusted app 0 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 0 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Windows - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 1 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 1 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Mac - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 2 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 2 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Linux - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 3 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 3 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Windows - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 4 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 4 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Mac - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 5 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 5 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Linux - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 6 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 6 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Windows - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 7 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 7 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Mac - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 8 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 8 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Linux - - - -
-
-
-
-
-
-
-
-
-
-

- trusted app 9 -

-
-
-
-
-
-
- -
-
-
-
-
- Last updated -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
- -
-
-
-
-
- Created -
-
-
-
- - 1 minute ago - -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
- - - - Created by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
- - - - Updated by - - - -
-
-
-
- -
-
-
- someone -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- Applied globally -
-
-
-
-
-
-
- Trusted App 9 -
-
-
-
-
-
- - - - - - OS - - - - - IS - - - - Windows - - - -
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
- -
-
-
-
-
-
-`; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/index.stories.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/index.stories.tsx deleted file mode 100644 index 682d689c7e82c..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/index.stories.tsx +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { Provider } from 'react-redux'; -import { ThemeProvider } from 'styled-components'; -import { storiesOf } from '@storybook/react'; -import { euiLightVars } from '@kbn/ui-theme'; -import { EuiHorizontalRule } from '@elastic/eui'; - -import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; - -import { - createGlobalNoMiddlewareStore, - createListFailedResourceState, - createListLoadedResourceState, - createListLoadingResourceState, - createTrustedAppsListResourceStateChangedAction, -} from '../../../test_utils'; - -import { TrustedAppsGrid } from '.'; - -const now = 111111; - -const renderGrid = (store: ReturnType) => ( - - 'MMM D, YYYY @ HH:mm:ss.SSS' } }}> - ({ eui: euiLightVars, darkMode: false })}> - - - - - - - - -); - -storiesOf('TrustedApps/TrustedAppsGrid', module) - .add('default', () => { - return renderGrid(createGlobalNoMiddlewareStore()); - }) - .add('loading', () => { - const store = createGlobalNoMiddlewareStore(); - - store.dispatch( - createTrustedAppsListResourceStateChangedAction(createListLoadingResourceState()) - ); - - return renderGrid(store); - }) - .add('error', () => { - const store = createGlobalNoMiddlewareStore(); - - store.dispatch( - createTrustedAppsListResourceStateChangedAction( - createListFailedResourceState('Intenal Server Error') - ) - ); - - return renderGrid(store); - }) - .add('loaded', () => { - const store = createGlobalNoMiddlewareStore(); - - store.dispatch( - createTrustedAppsListResourceStateChangedAction( - createListLoadedResourceState({ pageSize: 10 }, now) - ) - ); - - return renderGrid(store); - }) - .add('loading second time', () => { - const store = createGlobalNoMiddlewareStore(); - - store.dispatch( - createTrustedAppsListResourceStateChangedAction( - createListLoadingResourceState(createListLoadedResourceState({ pageSize: 10 }, now)) - ) - ); - - return renderGrid(store); - }) - .add('long texts', () => { - const store = createGlobalNoMiddlewareStore(); - - store.dispatch( - createTrustedAppsListResourceStateChangedAction( - createListLoadedResourceState({ pageSize: 10 }, now, true) - ) - ); - - return renderGrid(store); - }); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/index.test.tsx deleted file mode 100644 index 6cc292b5a6d3e..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/index.test.tsx +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { render, act } from '@testing-library/react'; -import React from 'react'; -import { Provider } from 'react-redux'; - -import { - createSampleTrustedApp, - createListFailedResourceState, - createListLoadedResourceState, - createListLoadingResourceState, - createTrustedAppsListResourceStateChangedAction, - createUserChangedUrlAction, - createGlobalNoMiddlewareStore, -} from '../../../test_utils'; -import { TrustedAppsGrid } from '.'; -import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; - -jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({ - htmlIdGenerator: () => () => 'mockId', -})); - -jest.mock('../../../../../../common/lib/kibana'); - -const now = 111111; - -const renderList = (store: ReturnType) => { - const Wrapper: React.FC = ({ children }) => ( - - {children} - - ); - - return render(, { wrapper: Wrapper }); -}; - -describe('TrustedAppsGrid', () => { - it('renders correctly initially', () => { - expect(renderList(createGlobalNoMiddlewareStore()).container).toMatchSnapshot(); - }); - - it('renders correctly when loading data for the first time', () => { - const store = createGlobalNoMiddlewareStore(); - - store.dispatch( - createTrustedAppsListResourceStateChangedAction(createListLoadingResourceState()) - ); - - expect(renderList(store).container).toMatchSnapshot(); - }); - - it('renders correctly when failed loading data for the first time', () => { - const store = createGlobalNoMiddlewareStore(); - - store.dispatch( - createTrustedAppsListResourceStateChangedAction( - createListFailedResourceState('Intenal Server Error') - ) - ); - - expect(renderList(store).container).toMatchSnapshot(); - }); - - it('renders correctly when loaded data', () => { - const store = createGlobalNoMiddlewareStore(); - - store.dispatch( - createTrustedAppsListResourceStateChangedAction( - createListLoadedResourceState({ pageSize: 10 }, now) - ) - ); - - expect(renderList(store).container).toMatchSnapshot(); - }); - - it('renders correctly when new page and page size set (not loading yet)', () => { - const store = createGlobalNoMiddlewareStore(); - - store.dispatch( - createTrustedAppsListResourceStateChangedAction( - createListLoadedResourceState({ pageSize: 10 }, now) - ) - ); - store.dispatch( - createUserChangedUrlAction('/administration/trusted_apps', '?page_index=2&page_size=50') - ); - - expect(renderList(store).container).toMatchSnapshot(); - }); - - it('renders correctly when loading data for the second time', () => { - const store = createGlobalNoMiddlewareStore(); - - store.dispatch( - createTrustedAppsListResourceStateChangedAction( - createListLoadingResourceState(createListLoadedResourceState({ pageSize: 10 }, now)) - ) - ); - - expect(renderList(store).container).toMatchSnapshot(); - }); - - it('renders correctly when failed loading data for the second time', () => { - const store = createGlobalNoMiddlewareStore(); - - store.dispatch( - createTrustedAppsListResourceStateChangedAction( - createListFailedResourceState( - 'Intenal Server Error', - createListLoadedResourceState({ pageSize: 10 }, now) - ) - ) - ); - - expect(renderList(store).container).toMatchSnapshot(); - }); - - it('triggers deletion dialog when delete action clicked', async () => { - const store = createGlobalNoMiddlewareStore(); - - store.dispatch( - createTrustedAppsListResourceStateChangedAction( - createListLoadedResourceState({ pageSize: 10 }, now) - ) - ); - store.dispatch = jest.fn(); - - const renderResult = renderList(store); - - await act(async () => { - (await renderResult.findAllByTestId('trustedAppCard-header-actions-button'))[0].click(); - }); - - await act(async () => { - (await renderResult.findByTestId('deleteTrustedAppAction')).click(); - }); - - expect(store.dispatch).toBeCalledWith({ - type: 'trustedAppDeletionDialogStarted', - payload: { - entry: createSampleTrustedApp(0), - }, - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/index.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/index.tsx deleted file mode 100644 index a8e2187083523..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/index.tsx +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { memo, useCallback, useMemo } from 'react'; - -import { useHistory } from 'react-router-dom'; -import styled from 'styled-components'; -import { i18n } from '@kbn/i18n'; -import { useDispatch } from 'react-redux'; -import { Dispatch } from 'redux'; -import { Pagination } from '../../../state'; - -import { - getCurrentLocation, - getListErrorMessage, - getListItems, - getListPagination, - isListLoading, - getMapOfPoliciesById, - isLoadingListOfPolicies, -} from '../../../store/selectors'; - -import { useTrustedAppsNavigateCallback, useTrustedAppsSelector } from '../../hooks'; - -import { getPolicyDetailPath, getTrustedAppsListPath } from '../../../../../common/routing'; -import { - PaginatedContent, - PaginatedContentProps, -} from '../../../../../components/paginated_content'; -import { PolicyDetailsRouteState, TrustedApp } from '../../../../../../../common/endpoint/types'; -import { - ArtifactEntryCard, - ArtifactEntryCardProps, -} from '../../../../../components/artifact_entry_card'; -import { AppAction } from '../../../../../../common/store/actions'; -import { APP_UI_ID } from '../../../../../../../common/constants'; -import { useAppUrl } from '../../../../../../common/lib/kibana'; - -export interface PaginationBarProps { - pagination: Pagination; - onChange: (pagination: { size: number; index: number }) => void; -} - -type ArtifactEntryCardType = typeof ArtifactEntryCard; - -const RootWrapper = styled.div` - .trusted-app + .trusted-app { - margin-top: ${({ theme }) => theme.eui.spacerSizes.l}; - } -`; - -const BACK_TO_TRUSTED_APPS_LABEL = i18n.translate( - 'xpack.securitySolution.trustedapps.grid.policyDetailsLinkBackLabel', - { defaultMessage: 'Back to trusted applications' } -); - -const EDIT_TRUSTED_APP_ACTION_LABEL = i18n.translate( - 'xpack.securitySolution.trustedapps.grid.cardAction.edit', - { - defaultMessage: 'Edit trusted application', - } -); - -const DELETE_TRUSTED_APP_ACTION_LABEL = i18n.translate( - 'xpack.securitySolution.trustedapps.grid.cardAction.delete', - { - defaultMessage: 'Delete trusted application', - } -); - -export const TrustedAppsGrid = memo(() => { - const history = useHistory(); - const dispatch = useDispatch>(); - const { getAppUrl } = useAppUrl(); - - const pagination = useTrustedAppsSelector(getListPagination); - const listItems = useTrustedAppsSelector(getListItems); - const isLoading = useTrustedAppsSelector(isListLoading); - const error = useTrustedAppsSelector(getListErrorMessage); - const location = useTrustedAppsSelector(getCurrentLocation); - const policyListById = useTrustedAppsSelector(getMapOfPoliciesById); - const loadingPoliciesList = useTrustedAppsSelector(isLoadingListOfPolicies); - - const handlePaginationChange: PaginatedContentProps< - TrustedApp, - ArtifactEntryCardType - >['onChange'] = useTrustedAppsNavigateCallback(({ pageIndex, pageSize }) => ({ - page_index: pageIndex, - page_size: pageSize, - })); - - const artifactCardPropsPerItem = useMemo(() => { - const cachedCardProps: Record = {}; - - // Casting `listItems` below to remove the `Immutable<>` from it in order to prevent errors - // with common component's props - for (const trustedApp of listItems as TrustedApp[]) { - let policies: ArtifactEntryCardProps['policies']; - - if (trustedApp.effectScope.type === 'policy' && trustedApp.effectScope.policies.length) { - policies = trustedApp.effectScope.policies.reduce< - Required['policies'] - >((policyToNavOptionsMap, policyId) => { - const currentPagePath = getTrustedAppsListPath({ - ...location, - }); - - const policyDetailsPath = getPolicyDetailPath(policyId); - - const routeState: PolicyDetailsRouteState = { - backLink: { - label: BACK_TO_TRUSTED_APPS_LABEL, - navigateTo: [ - APP_UI_ID, - { - path: currentPagePath, - }, - ], - href: getAppUrl({ path: currentPagePath }), - }, - onCancelNavigateTo: [ - APP_UI_ID, - { - path: currentPagePath, - }, - ], - }; - - policyToNavOptionsMap[policyId] = { - navigateAppId: APP_UI_ID, - navigateOptions: { - path: policyDetailsPath, - state: routeState, - }, - href: getAppUrl({ path: policyDetailsPath }), - children: policyListById[policyId]?.name ?? policyId, - target: '_blank', - }; - return policyToNavOptionsMap; - }, {}); - } - - cachedCardProps[trustedApp.id] = { - item: trustedApp, - policies, - loadingPoliciesList, - hideComments: true, - 'data-test-subj': 'trustedAppCard', - actions: [ - { - icon: 'controlsHorizontal', - onClick: () => { - history.push( - getTrustedAppsListPath({ - ...location, - show: 'edit', - id: trustedApp.id, - }) - ); - }, - 'data-test-subj': 'editTrustedAppAction', - children: EDIT_TRUSTED_APP_ACTION_LABEL, - }, - { - icon: 'trash', - onClick: () => { - dispatch({ - type: 'trustedAppDeletionDialogStarted', - payload: { entry: trustedApp }, - }); - }, - 'data-test-subj': 'deleteTrustedAppAction', - children: DELETE_TRUSTED_APP_ACTION_LABEL, - }, - ], - hideDescription: !trustedApp.description, - }; - } - - return cachedCardProps; - }, [dispatch, getAppUrl, history, listItems, location, policyListById, loadingPoliciesList]); - - const handleArtifactCardProps = useCallback( - (trustedApp: TrustedApp) => { - return artifactCardPropsPerItem[trustedApp.id]; - }, - [artifactCardPropsPerItem] - ); - - return ( - - - items={listItems as TrustedApp[]} - onChange={handlePaginationChange} - ItemComponent={ArtifactEntryCard} - itemComponentProps={handleArtifactCardProps} - loading={isLoading} - itemId="id" - error={error} - pagination={pagination} - /> - - ); -}); - -TrustedAppsGrid.displayName = 'TrustedAppsGrid'; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/view_type_toggle/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/view_type_toggle/__snapshots__/index.test.tsx.snap deleted file mode 100644 index 09a13f11d2adb..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/view_type_toggle/__snapshots__/index.test.tsx.snap +++ /dev/null @@ -1,53 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`view_type_toggle ViewTypeToggle should render grid selection correctly 1`] = ` - -`; - -exports[`view_type_toggle ViewTypeToggle should render list selection correctly 1`] = ` - -`; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/view_type_toggle/index.stories.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/view_type_toggle/index.stories.tsx deleted file mode 100644 index 8ba70769838a3..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/view_type_toggle/index.stories.tsx +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useState } from 'react'; -import { ThemeProvider } from 'styled-components'; -import { storiesOf, addDecorator } from '@storybook/react'; -import { euiLightVars } from '@kbn/ui-theme'; - -import { ViewType } from '../../../state'; -import { ViewTypeToggle } from '.'; - -addDecorator((storyFn) => ( - ({ eui: euiLightVars, darkMode: false })}>{storyFn()} -)); - -const useRenderStory = (viewType: ViewType) => { - const [selectedOption, setSelectedOption] = useState(viewType); - - return ; -}; - -storiesOf('TrustedApps/ViewTypeToggle', module) - .add('grid selected', () => useRenderStory('grid')) - .add('list selected', () => useRenderStory('list')); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/view_type_toggle/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/view_type_toggle/index.test.tsx deleted file mode 100644 index d6b2bb5a2e7ef..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/view_type_toggle/index.test.tsx +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { render } from '@testing-library/react'; -import { shallow } from 'enzyme'; -import React from 'react'; - -import { ViewTypeToggle } from '.'; - -describe('view_type_toggle', () => { - describe('ViewTypeToggle', () => { - it('should render grid selection correctly', () => { - const element = shallow( {}} />); - - expect(element).toMatchSnapshot(); - }); - - it('should render list selection correctly', () => { - const element = shallow( {}} />); - - expect(element).toMatchSnapshot(); - }); - - it('should trigger onToggle', async () => { - const onToggle = jest.fn(); - const element = render(); - - (await element.findAllByTestId('viewTypeToggleButton'))[0].click(); - - expect(onToggle).toBeCalledWith('grid'); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/view_type_toggle/index.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/view_type_toggle/index.tsx deleted file mode 100644 index 700358d6beef6..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/view_type_toggle/index.tsx +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { memo, useCallback } from 'react'; -import { EuiButtonGroup } from '@elastic/eui'; - -import { i18n } from '@kbn/i18n'; -import { ViewType } from '../../../state'; -import { GRID_VIEW_TOGGLE_LABEL, LIST_VIEW_TOGGLE_LABEL } from '../../translations'; - -export interface ViewTypeToggleProps { - selectedOption: ViewType; - onToggle: (type: ViewType) => void; -} - -export const ViewTypeToggle = memo(({ selectedOption, onToggle }: ViewTypeToggleProps) => { - const handleChange = useCallback( - (id) => { - if (id === 'list' || id === 'grid') { - onToggle(id); - } - }, - [onToggle] - ); - - return ( - - ); -}); - -ViewTypeToggle.displayName = 'ViewTypeToggle'; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/hooks.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/hooks.ts deleted file mode 100644 index 4c2747d74d31e..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/hooks.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { useDispatch, useSelector } from 'react-redux'; -import { useHistory } from 'react-router-dom'; -import { useCallback } from 'react'; - -import { State } from '../../../../common/store'; - -import { - MANAGEMENT_STORE_TRUSTED_APPS_NAMESPACE as TRUSTED_APPS_NS, - MANAGEMENT_STORE_GLOBAL_NAMESPACE as GLOBAL_NS, -} from '../../../common/constants'; - -import { AppAction } from '../../../../common/store/actions'; -import { getTrustedAppsListPath } from '../../../common/routing'; -import { TrustedAppsListPageLocation, TrustedAppsListPageState } from '../state'; -import { getCurrentLocation } from '../store/selectors'; - -export function useTrustedAppsSelector(selector: (state: TrustedAppsListPageState) => R): R { - return useSelector((state: State) => - selector(state[GLOBAL_NS][TRUSTED_APPS_NS] as TrustedAppsListPageState) - ); -} - -export type NavigationCallback = ( - ...args: Parameters[0]> -) => Partial; - -export function useTrustedAppsNavigateCallback(callback: NavigationCallback) { - const location = useTrustedAppsSelector(getCurrentLocation); - const history = useHistory(); - - return useCallback( - (...args) => history.push(getTrustedAppsListPath({ ...location, ...callback(...args) })), - // TODO: needs more investigation, but if callback is in dependencies list memoization will never happen - // eslint-disable-next-line react-hooks/exhaustive-deps - [history, location] - ); -} - -export function useTrustedAppsStoreActionCallback( - callback: (...args: Parameters[0]>) => AppAction -) { - const dispatch = useDispatch(); - - // eslint-disable-next-line react-hooks/exhaustive-deps - return useCallback((...args) => dispatch(callback(...args)), [dispatch]); -} diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/index.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/index.ts deleted file mode 100644 index 78c22fc020a45..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export * from './trusted_apps_page'; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/translations.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/translations.ts index 3d8a56ad74315..b5b92f3a686ea 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/translations.ts +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/translations.ts @@ -13,14 +13,54 @@ import { OperatorFieldIds, } from '../../../../../common/endpoint/types'; -export { OS_TITLES } from '../../../common/translations'; - export const ABOUT_TRUSTED_APPS = i18n.translate('xpack.securitySolution.trustedapps.aboutInfo', { defaultMessage: 'Add a trusted application to improve performance or alleviate conflicts with other applications running on ' + 'your hosts.', }); +export const NAME_LABEL = i18n.translate('xpack.securitySolution.trustedApps.name.label', { + defaultMessage: 'Name', +}); + +export const DETAILS_HEADER = i18n.translate('xpack.securitySolution.trustedApps.details.header', { + defaultMessage: 'Details', +}); + +export const DETAILS_HEADER_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.trustedApps.details.header.description', + { + defaultMessage: + 'Trusted applications improve performance or alleviate conflicts with other applications running on your hosts.', + } +); + +export const DESCRIPTION_LABEL = i18n.translate( + 'xpack.securitySolution.trustedapps.create.description', + { + defaultMessage: 'Description', + } +); + +export const CONDITIONS_HEADER = i18n.translate( + 'xpack.securitySolution.trustedApps.conditions.header', + { + defaultMessage: 'Conditions', + } +); + +export const CONDITIONS_HEADER_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.trustedApps.conditions.header.description', + { + defaultMessage: + 'Select an operating system and add conditions. Availability of conditions may depend on your chosen OS.', + } +); + +export const SELECT_OS_LABEL = i18n.translate('xpack.securitySolution.trustedApps.os.label', { + defaultMessage: 'Select operating system', +}); + export const CONDITION_FIELD_TITLE: { [K in ConditionEntryField]: string } = { [ConditionEntryField.HASH]: i18n.translate( 'xpack.securitySolution.trustedapps.logicalConditionBuilder.entry.field.hash', @@ -74,23 +114,50 @@ export const ENTRY_PROPERTY_TITLES: Readonly<{ }), }; -export const GRID_VIEW_TOGGLE_LABEL = i18n.translate( - 'xpack.securitySolution.trustedapps.view.toggle.grid', +export const POLICY_SELECT_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.trustedApps.assignmentSectionDescription', { - defaultMessage: 'Grid view', + defaultMessage: + 'Assign this trusted application globally across all policies, or assign it to specific policies.', } ); -export const LIST_VIEW_TOGGLE_LABEL = i18n.translate( - 'xpack.securitySolution.trustedapps.view.toggle.list', - { - defaultMessage: 'List view', - } -); - -export const SEARCH_TRUSTED_APP_PLACEHOLDER = i18n.translate( - 'xpack.securitySolution.trustedapps.list.search.placeholder', - { - defaultMessage: 'Search on the fields below: name, description, value', - } -); +export const INPUT_ERRORS = { + name: i18n.translate('xpack.securitySolution.trustedapps.create.nameRequiredMsg', { + defaultMessage: 'Name is required', + }), + os: i18n.translate('xpack.securitySolution.trustedapps.create.osRequiredMsg', { + defaultMessage: 'Operating System is required', + }), + field: i18n.translate('xpack.securitySolution.trustedapps.create.conditionRequiredMsg', { + defaultMessage: 'At least one Field definition is required', + }), + noDuplicateField: (field: ConditionEntryField) => + i18n.translate('xpack.securitySolution.trustedapps.create.conditionFieldDuplicatedMsg', { + defaultMessage: '{field} cannot be added more than once', + values: { field: CONDITION_FIELD_TITLE[field] }, + }), + mustHaveValue: (index: number) => + i18n.translate('xpack.securitySolution.trustedapps.create.conditionFieldValueRequiredMsg', { + defaultMessage: '[{row}] Field entry must have a value', + values: { row: index + 1 }, + }), + invalidHash: (index: number) => + i18n.translate('xpack.securitySolution.trustedapps.create.conditionFieldInvalidHashMsg', { + defaultMessage: '[{row}] Invalid hash value', + values: { row: index + 1 }, + }), + pathWarning: (index: number) => + i18n.translate('xpack.securitySolution.trustedapps.create.conditionFieldInvalidPathMsg', { + defaultMessage: '[{row}] Path may be formed incorrectly; verify value', + values: { row: index + 1 }, + }), + wildcardPathWarning: (index: number) => + i18n.translate( + 'xpack.securitySolution.trustedapps.create.conditionFieldDegradedPerformanceMsg', + { + defaultMessage: `[{row}] A wildcard in the filename will affect the endpoint's performance`, + values: { row: index + 1 }, + } + ), +}; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_app_deletion_dialog.test.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_app_deletion_dialog.test.tsx deleted file mode 100644 index 6abce21d7ccf5..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_app_deletion_dialog.test.tsx +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { Provider } from 'react-redux'; -import { render } from '@testing-library/react'; -import { I18nProvider } from '@kbn/i18n-react'; - -import { - createGlobalNoMiddlewareStore, - createSampleTrustedApp, - createServerApiError, -} from '../test_utils'; - -import { - TrustedAppDeletionDialogStarted, - TrustedAppDeletionSubmissionResourceStateChanged, -} from '../store/action'; - -import { TrustedAppDeletionDialog } from './trusted_app_deletion_dialog'; - -const renderDeletionDialog = (store: ReturnType) => { - const Wrapper: React.FC = ({ children }) => ( - - {children} - - ); - - return render(, { wrapper: Wrapper }); -}; - -const createDialogStartAction = (): TrustedAppDeletionDialogStarted => ({ - type: 'trustedAppDeletionDialogStarted', - payload: { entry: createSampleTrustedApp(3) }, -}); - -const createDialogLoadingAction = (): TrustedAppDeletionSubmissionResourceStateChanged => ({ - type: 'trustedAppDeletionSubmissionResourceStateChanged', - payload: { - newState: { - type: 'LoadingResourceState', - previousState: { type: 'UninitialisedResourceState' }, - }, - }, -}); - -const createDialogFailedAction = (): TrustedAppDeletionSubmissionResourceStateChanged => ({ - type: 'trustedAppDeletionSubmissionResourceStateChanged', - payload: { - newState: { type: 'FailedResourceState', error: createServerApiError('Not Found') }, - }, -}); - -describe('TrustedAppDeletionDialog', () => { - it('renders correctly initially', () => { - expect(renderDeletionDialog(createGlobalNoMiddlewareStore()).baseElement).toMatchSnapshot(); - }); - - it('renders correctly when dialog started', () => { - const store = createGlobalNoMiddlewareStore(); - - store.dispatch(createDialogStartAction()); - - expect(renderDeletionDialog(store).baseElement).toMatchSnapshot(); - }); - - it('renders correctly when deletion is in progress', () => { - const store = createGlobalNoMiddlewareStore(); - - store.dispatch(createDialogStartAction()); - store.dispatch(createDialogLoadingAction()); - - expect(renderDeletionDialog(store).baseElement).toMatchSnapshot(); - }); - - it('renders correctly when deletion failed', () => { - const store = createGlobalNoMiddlewareStore(); - - store.dispatch(createDialogStartAction()); - store.dispatch(createDialogFailedAction()); - - expect(renderDeletionDialog(store).baseElement).toMatchSnapshot(); - }); - - it('triggers confirmation action when confirm button clicked', async () => { - const store = createGlobalNoMiddlewareStore(); - - store.dispatch(createDialogStartAction()); - store.dispatch = jest.fn(); - - (await renderDeletionDialog(store).findByTestId('trustedAppDeletionConfirm')).click(); - - expect(store.dispatch).toBeCalledWith({ - type: 'trustedAppDeletionDialogConfirmed', - }); - }); - - it('triggers closing action when cancel button clicked', async () => { - const store = createGlobalNoMiddlewareStore(); - - store.dispatch(createDialogStartAction()); - store.dispatch = jest.fn(); - - (await renderDeletionDialog(store).findByTestId('trustedAppDeletionCancel')).click(); - - expect(store.dispatch).toBeCalledWith({ - type: 'trustedAppDeletionDialogClosed', - }); - }); - - it('does not trigger closing action when deletion in progress and cancel button clicked', async () => { - const store = createGlobalNoMiddlewareStore(); - - store.dispatch(createDialogStartAction()); - store.dispatch(createDialogLoadingAction()); - - store.dispatch = jest.fn(); - - (await renderDeletionDialog(store).findByTestId('trustedAppDeletionCancel')).click(); - - expect(store.dispatch).not.toBeCalled(); - }); -}); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_app_deletion_dialog.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_app_deletion_dialog.tsx deleted file mode 100644 index 458a83d37322e..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_app_deletion_dialog.tsx +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - EuiButtonEmpty, - EuiCallOut, - EuiModal, - EuiModalBody, - EuiModalFooter, - EuiModalHeader, - EuiModalHeaderTitle, - EuiSpacer, - EuiText, -} from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n-react'; -import React, { memo, useCallback, useMemo } from 'react'; -import { useDispatch } from 'react-redux'; -import { Dispatch } from 'redux'; -import { AutoFocusButton } from '../../../../common/components/autofocus_button/autofocus_button'; -import { Immutable, TrustedApp } from '../../../../../common/endpoint/types'; -import { AppAction } from '../../../../common/store/actions'; -import { isPolicyEffectScope } from '../state/type_guards'; -import { - getDeletionDialogEntry, - isDeletionDialogOpen, - isDeletionInProgress, -} from '../store/selectors'; -import { useTrustedAppsSelector } from './hooks'; - -const CANCEL_SUBJ = 'trustedAppDeletionCancel'; -const CONFIRM_SUBJ = 'trustedAppDeletionConfirm'; - -const getTranslations = (entry: Immutable | undefined) => ({ - title: ( - {entry?.name} }} - /> - ), - calloutTitle: ( - - ), - calloutMessage: ( - - ), - subMessage: ( - - ), - cancelButton: ( - - ), - confirmButton: ( - - ), -}); - -export const TrustedAppDeletionDialog = memo(() => { - const dispatch = useDispatch>(); - const isBusy = useTrustedAppsSelector(isDeletionInProgress); - const entry = useTrustedAppsSelector(getDeletionDialogEntry); - const translations = useMemo(() => getTranslations(entry), [entry]); - const onConfirm = useCallback(() => { - dispatch({ type: 'trustedAppDeletionDialogConfirmed' }); - }, [dispatch]); - const onCancel = useCallback(() => { - if (!isBusy) { - dispatch({ type: 'trustedAppDeletionDialogClosed' }); - } - }, [dispatch, isBusy]); - - if (useTrustedAppsSelector(isDeletionDialogOpen)) { - return ( - - - {translations.title} - - - - -

{translations.calloutMessage}

-
- - -

{translations.subMessage}

-
-
- - - - {translations.cancelButton} - - - - {translations.confirmButton} - - -
- ); - } else { - return <>; - } -}); - -TrustedAppDeletionDialog.displayName = 'TrustedAppDeletionDialog'; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_list.test.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_list.test.tsx new file mode 100644 index 0000000000000..f778e6f471e1f --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_list.test.tsx @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { act, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; +import { TRUSTED_APPS_PATH } from '../../../../../common/constants'; +import { AppContextTestRender, createAppRootMockRenderer } from '../../../../common/mock/endpoint'; +import { TrustedAppsList } from './trusted_apps_list'; +import { exceptionsListAllHttpMocks } from '../../mocks/exceptions_list_http_mocks'; +import { SEARCHABLE_FIELDS } from '../constants'; +import { parseQueryFilterToKQL } from '../../../common/utils'; +import { useUserPrivileges as _useUserPrivileges } from '../../../../common/components/user_privileges'; + +jest.mock('../../../../common/components/user_privileges'); + +describe('When on the trusted applications page', () => { + let render: () => ReturnType; + let renderResult: ReturnType; + let history: AppContextTestRender['history']; + let mockedContext: AppContextTestRender; + let apiMocks: ReturnType; + + beforeEach(() => { + mockedContext = createAppRootMockRenderer(); + ({ history } = mockedContext); + render = () => (renderResult = mockedContext.render()); + + apiMocks = exceptionsListAllHttpMocks(mockedContext.coreStart.http); + + act(() => { + history.push(TRUSTED_APPS_PATH); + }); + }); + + it('should search using expected exception item fields', async () => { + const expectedFilterString = parseQueryFilterToKQL('fooFooFoo', SEARCHABLE_FIELDS); + const { findAllByTestId } = render(); + await waitFor(async () => { + await expect(findAllByTestId('trustedAppsListPage-card')).resolves.toHaveLength(10); + }); + + apiMocks.responseProvider.exceptionsFind.mockClear(); + userEvent.type(renderResult.getByTestId('searchField'), 'fooFooFoo'); + userEvent.click(renderResult.getByTestId('searchButton')); + await waitFor(() => { + expect(apiMocks.responseProvider.exceptionsFind).toHaveBeenCalled(); + }); + + expect(apiMocks.responseProvider.exceptionsFind).toHaveBeenLastCalledWith( + expect.objectContaining({ + query: expect.objectContaining({ + filter: expectedFilterString, + }), + }) + ); + }); +}); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_list.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_list.tsx new file mode 100644 index 0000000000000..359e9d1aeb99d --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_list.tsx @@ -0,0 +1,123 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { DocLinks } from '@kbn/doc-links'; +import { EuiLink } from '@elastic/eui'; + +import { useHttp } from '../../../../common/lib/kibana'; +import { ArtifactListPage, ArtifactListPageProps } from '../../../components/artifact_list_page'; +import { TrustedAppsApiClient } from '../service'; +import { TrustedAppsForm } from './components/form'; +import { SEARCHABLE_FIELDS } from '../constants'; + +const TRUSTED_APPS_PAGE_LABELS: ArtifactListPageProps['labels'] = { + pageTitle: i18n.translate('xpack.securitySolution.trustedApps.pageTitle', { + defaultMessage: 'Trusted applications', + }), + pageAboutInfo: i18n.translate('xpack.securitySolution.trustedApps.pageAboutInfo', { + defaultMessage: + 'Trusted applications improve performance or alleviate conflicts with other applications running on your hosts.', + }), + pageAddButtonTitle: i18n.translate('xpack.securitySolution.trustedApps.pageAddButtonTitle', { + defaultMessage: 'Add trusted application', + }), + getShowingCountLabel: (total) => + i18n.translate('xpack.securitySolution.trustedApps.showingTotal', { + defaultMessage: + 'Showing {total} {total, plural, one {trusted application} other {trusted applications}}', + values: { total }, + }), + cardActionEditLabel: i18n.translate('xpack.securitySolution.trustedApps.cardActionEditLabel', { + defaultMessage: 'Edit trusted application', + }), + cardActionDeleteLabel: i18n.translate( + 'xpack.securitySolution.trustedApps.cardActionDeleteLabel', + { + defaultMessage: 'Delete trusted application', + } + ), + flyoutCreateTitle: i18n.translate('xpack.securitySolution.trustedApps.flyoutCreateTitle', { + defaultMessage: 'Add trusted application', + }), + flyoutEditTitle: i18n.translate('xpack.securitySolution.trustedApps.flyoutEditTitle', { + defaultMessage: 'Edit trusted application', + }), + flyoutCreateSubmitButtonLabel: i18n.translate( + 'xpack.securitySolution.trustedApps.flyoutCreateSubmitButtonLabel', + { defaultMessage: 'Add trusted application' } + ), + flyoutCreateSubmitSuccess: ({ name }) => + i18n.translate('xpack.securitySolution.trustedApps.flyoutCreateSubmitSuccess', { + defaultMessage: '"{name}" has been added to your trusted applications.', + values: { name }, + }), + flyoutEditSubmitSuccess: ({ name }) => + i18n.translate('xpack.securitySolution.trustedApps.flyoutEditSubmitSuccess', { + defaultMessage: '"{name}" has been updated.', + values: { name }, + }), + flyoutDowngradedLicenseDocsInfo: ( + securitySolutionDocsLinks: DocLinks['securitySolution'] + ): React.ReactNode => { + return ( + <> + + + + + + ); + }, + deleteActionSuccess: (itemName) => + i18n.translate('xpack.securitySolution.trustedApps.deleteSuccess', { + defaultMessage: '"{itemName}" has been removed from trusted applications.', + values: { itemName }, + }), + emptyStateTitle: i18n.translate('xpack.securitySolution.trustedApps.emptyStateTitle', { + defaultMessage: 'Add your first trusted application', + }), + emptyStateInfo: i18n.translate('xpack.securitySolution.trustedApps.emptyStateInfo', { + defaultMessage: + 'Add a trusted application to improve performance or alleviate conflicts with other applications running on your hosts.', + }), + emptyStatePrimaryButtonLabel: i18n.translate( + 'xpack.securitySolution.trustedApps.emptyStatePrimaryButtonLabel', + { defaultMessage: 'Add trusted application' } + ), + searchPlaceholderInfo: i18n.translate( + 'xpack.securitySolution.trustedApps.searchPlaceholderInfo', + { + defaultMessage: 'Search on the fields below: name, description, value', + } + ), +}; + +export const TrustedAppsList = memo(() => { + const http = useHttp(); + const trustedAppsApiClient = TrustedAppsApiClient.getInstance(http); + + return ( + + ); +}); + +TrustedAppsList.displayName = 'TrustedAppsList'; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_notifications.test.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_notifications.test.tsx deleted file mode 100644 index ebd1e06abdc4f..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_notifications.test.tsx +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { Provider } from 'react-redux'; -import { render } from '@testing-library/react'; - -import { NotificationsStart } from '@kbn/core/public'; - -import { coreMock } from '@kbn/core/public/mocks'; -import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public/context'; - -import { - createGlobalNoMiddlewareStore, - createSampleTrustedApp, - createServerApiError, -} from '../test_utils'; - -import { TrustedAppsNotifications } from './trusted_apps_notifications'; - -const mockNotifications = () => coreMock.createStart({ basePath: '/mock' }).notifications; - -const renderNotifications = ( - store: ReturnType, - notifications: NotificationsStart -) => { - const Wrapper: React.FC = ({ children }) => ( - - {children} - - ); - - return render(, { wrapper: Wrapper }); -}; - -describe('TrustedAppsNotifications', () => { - it('renders correctly initially', () => { - const notifications = mockNotifications(); - - renderNotifications(createGlobalNoMiddlewareStore(), notifications); - - expect(notifications.toasts.addSuccess).not.toBeCalled(); - expect(notifications.toasts.addDanger).not.toBeCalled(); - }); - - it('shows success notification when deletion successful', () => { - const store = createGlobalNoMiddlewareStore(); - const notifications = mockNotifications(); - - renderNotifications(store, notifications); - - store.dispatch({ - type: 'trustedAppDeletionDialogStarted', - payload: { entry: createSampleTrustedApp(3) }, - }); - store.dispatch({ - type: 'trustedAppDeletionSubmissionResourceStateChanged', - payload: { newState: { type: 'LoadedResourceState', data: null } }, - }); - store.dispatch({ - type: 'trustedAppDeletionDialogClosed', - }); - - expect(notifications.toasts.addSuccess).toBeCalledWith({ - text: '"trusted app 3" has been removed from the trusted applications list.', - title: 'Successfully removed', - }); - expect(notifications.toasts.addDanger).not.toBeCalled(); - }); - - it('shows error notification when deletion fails', () => { - const store = createGlobalNoMiddlewareStore(); - const notifications = mockNotifications(); - - renderNotifications(store, notifications); - - store.dispatch({ - type: 'trustedAppDeletionDialogStarted', - payload: { entry: createSampleTrustedApp(3) }, - }); - store.dispatch({ - type: 'trustedAppDeletionSubmissionResourceStateChanged', - payload: { - newState: { type: 'FailedResourceState', error: createServerApiError('Not Found') }, - }, - }); - - expect(notifications.toasts.addSuccess).not.toBeCalled(); - expect(notifications.toasts.addDanger).toBeCalledWith({ - text: 'Unable to remove "trusted app 3" from the trusted applications list. Reason: Not Found', - title: 'Removal failure', - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_notifications.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_notifications.tsx deleted file mode 100644 index dd03636d7cc66..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_notifications.tsx +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { memo, useState } from 'react'; -import { i18n } from '@kbn/i18n'; - -import { ServerApiError } from '../../../../common/types'; -import { Immutable, NewTrustedApp, TrustedApp } from '../../../../../common/endpoint/types'; -import { - getCreationDialogFormEntry, - getDeletionDialogEntry, - getDeletionError, - isCreationSuccessful, - isDeletionSuccessful, - isEdit, -} from '../store/selectors'; - -import { useToasts } from '../../../../common/lib/kibana'; -import { useTrustedAppsSelector } from './hooks'; - -const getDeletionErrorMessage = (error: ServerApiError, entry: Immutable) => { - return { - title: i18n.translate('xpack.securitySolution.trustedapps.deletionError.title', { - defaultMessage: 'Removal failure', - }), - text: i18n.translate('xpack.securitySolution.trustedapps.deletionError.text', { - defaultMessage: - 'Unable to remove "{name}" from the trusted applications list. Reason: {message}', - values: { name: entry.name, message: error.message }, - }), - }; -}; - -const getDeletionSuccessMessage = (entry: Immutable) => { - return { - title: i18n.translate('xpack.securitySolution.trustedapps.deletionSuccess.title', { - defaultMessage: 'Successfully removed', - }), - text: i18n.translate('xpack.securitySolution.trustedapps.deletionSuccess.text', { - defaultMessage: '"{name}" has been removed from the trusted applications list.', - values: { name: entry?.name }, - }), - }; -}; - -const getCreationSuccessMessage = (entry: Immutable) => { - return { - title: i18n.translate('xpack.securitySolution.trustedapps.creationSuccess.title', { - defaultMessage: 'Success!', - }), - text: i18n.translate( - 'xpack.securitySolution.trustedapps.createTrustedAppFlyout.successToastTitle', - { - defaultMessage: '"{name}" has been added to the trusted applications list.', - values: { name: entry.name }, - } - ), - }; -}; - -const getUpdateSuccessMessage = (entry: Immutable) => { - return { - title: i18n.translate('xpack.securitySolution.trustedapps.updateSuccess.title', { - defaultMessage: 'Success!', - }), - text: i18n.translate( - 'xpack.securitySolution.trustedapps.createTrustedAppFlyout.updateSuccessToastTitle', - { - defaultMessage: '"{name}" has been updated.', - values: { name: entry.name }, - } - ), - }; -}; - -export const TrustedAppsNotifications = memo(() => { - const deletionError = useTrustedAppsSelector(getDeletionError); - const deletionDialogEntry = useTrustedAppsSelector(getDeletionDialogEntry); - const deletionSuccessful = useTrustedAppsSelector(isDeletionSuccessful); - const creationDialogNewEntry = useTrustedAppsSelector(getCreationDialogFormEntry); - const creationSuccessful = useTrustedAppsSelector(isCreationSuccessful); - const editMode = useTrustedAppsSelector(isEdit); - const toasts = useToasts(); - - const [wasAlreadyHandled] = useState(new WeakSet()); - - if (deletionError && deletionDialogEntry) { - toasts.addDanger(getDeletionErrorMessage(deletionError, deletionDialogEntry)); - } - - if (deletionSuccessful && deletionDialogEntry) { - toasts.addSuccess(getDeletionSuccessMessage(deletionDialogEntry)); - } - - if ( - creationSuccessful && - creationDialogNewEntry && - !wasAlreadyHandled.has(creationDialogNewEntry) - ) { - wasAlreadyHandled.add(creationDialogNewEntry); - - toasts.addSuccess( - (editMode && getUpdateSuccessMessage(creationDialogNewEntry)) || - getCreationSuccessMessage(creationDialogNewEntry) - ); - } - - return <>; -}); - -TrustedAppsNotifications.displayName = 'TrustedAppsNotifications'; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_page.test.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_page.test.tsx deleted file mode 100644 index d3bf8fe6ed46a..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_page.test.tsx +++ /dev/null @@ -1,885 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import * as reactTestingLibrary from '@testing-library/react'; -import { TrustedAppsPage } from './trusted_apps_page'; -import { AppContextTestRender, createAppRootMockRenderer } from '../../../../common/mock/endpoint'; -import { fireEvent } from '@testing-library/dom'; -import { MiddlewareActionSpyHelper } from '../../../../common/store/test_utils'; -import { ConditionEntryField, OperatingSystem } from '@kbn/securitysolution-utils'; -import { TrustedApp } from '../../../../../common/endpoint/types'; -import { HttpFetchOptions, HttpFetchOptionsWithPath } from '@kbn/core/public'; -import { isFailedResourceState, isLoadedResourceState } from '../state'; -import { forceHTMLElementOffsetWidth } from '../../../components/effected_policy_select/test_utils'; -import { toUpdateTrustedApp } from '../../../../../common/endpoint/service/trusted_apps/to_update_trusted_app'; -import { licenseService } from '../../../../common/hooks/use_license'; -import { FoundExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; -import { EXCEPTION_LIST_ITEM_URL } from '@kbn/securitysolution-list-constants'; -import { trustedAppsAllHttpMocks } from '../../mocks'; -import { waitFor } from '@testing-library/react'; - -jest.mock('../../../../common/hooks/use_license', () => { - const licenseServiceInstance = { - isPlatinumPlus: jest.fn(), - }; - return { - licenseService: licenseServiceInstance, - useLicense: () => { - return licenseServiceInstance; - }, - }; -}); - -jest.mock('../../../../common/components/user_privileges/endpoint/use_endpoint_privileges'); - -describe('When on the Trusted Apps Page', () => { - const expectedAboutInfo = - 'Add a trusted application to improve performance or alleviate conflicts with other ' + - 'applications running on your hosts.'; - - let mockedContext: AppContextTestRender; - let history: AppContextTestRender['history']; - let coreStart: AppContextTestRender['coreStart']; - let waitForAction: MiddlewareActionSpyHelper['waitForAction']; - let render: () => ReturnType; - let renderResult: ReturnType; - let mockedApis: ReturnType; - let getFakeTrustedApp = jest.fn(); - - const originalScrollTo = window.scrollTo; - const act = reactTestingLibrary.act; - const waitForListUI = async (): Promise => { - await waitFor(() => { - expect(renderResult.getByTestId('trustedAppsListPageContent')).toBeTruthy(); - }); - }; - - beforeAll(() => { - window.scrollTo = () => {}; - }); - - afterAll(() => { - window.scrollTo = originalScrollTo; - }); - - beforeEach(() => { - mockedContext = createAppRootMockRenderer(); - getFakeTrustedApp = jest.fn( - (): TrustedApp => ({ - id: '2d95bec3-b48f-4db7-9622-a2b061cc031d', - version: 'abc123', - name: 'Generated Exception (3xnng)', - os: OperatingSystem.WINDOWS, - created_at: '2021-01-04T13:55:00.561Z', - created_by: 'me', - updated_at: '2021-01-04T13:55:00.561Z', - updated_by: 'me', - description: 'created by ExceptionListItemGenerator', - effectScope: { type: 'global' }, - entries: [ - { - field: ConditionEntryField.PATH, - value: 'one/two', - operator: 'included', - type: 'match', - }, - ], - }) - ); - - history = mockedContext.history; - coreStart = mockedContext.coreStart; - (licenseService.isPlatinumPlus as jest.Mock).mockReturnValue(true); - waitForAction = mockedContext.middlewareSpy.waitForAction; - mockedApis = trustedAppsAllHttpMocks(coreStart.http); - render = () => (renderResult = mockedContext.render()); - reactTestingLibrary.act(() => { - history.push('/administration/trusted_apps'); - }); - window.scrollTo = jest.fn(); - }); - - afterEach(() => reactTestingLibrary.cleanup()); - - describe('and there are trusted app entries', () => { - const renderWithListData = async () => { - render(); - await act(async () => { - await waitForListUI(); - }); - - return renderResult; - }; - - it('should display subtitle info about trusted apps', async () => { - const { getByTestId } = await renderWithListData(); - expect(getByTestId('header-panel-subtitle').textContent).toEqual(expectedAboutInfo); - }); - - it('should display a Add Trusted App button', async () => { - const { getByTestId } = await renderWithListData(); - const addButton = getByTestId('trustedAppsListAddButton'); - expect(addButton.textContent).toBe('Add trusted application'); - }); - - it('should display the searchExceptions', async () => { - await renderWithListData(); - expect(await renderResult.findByTestId('searchExceptions')).not.toBeNull(); - }); - - describe('and the Grid view is being displayed', () => { - const renderWithListDataAndClickOnEditCard = async () => { - await renderWithListData(); - - await act(async () => { - // The 3rd Trusted app to be rendered will be a policy specific one - (await renderResult.findAllByTestId('trustedAppCard-header-actions-button'))[2].click(); - }); - - act(() => { - fireEvent.click(renderResult.getByTestId('editTrustedAppAction')); - }); - }; - - const renderWithListDataAndClickAddButton = async (): Promise< - ReturnType - > => { - await renderWithListData(); - - act(() => { - const addButton = renderResult.getByTestId('trustedAppsListAddButton'); - fireEvent.click(addButton, { button: 1 }); - }); - - // Wait for the policies to be loaded - await act(async () => { - await waitForAction('trustedAppsPoliciesStateChanged', { - validate: (action) => { - return isLoadedResourceState(action.payload); - }, - }); - }); - - return renderResult; - }; - - describe('the license is downgraded to gold or below and the user is editing a per policy TA', () => { - beforeEach(async () => { - (licenseService.isPlatinumPlus as jest.Mock).mockReturnValue(false); - - const originalFakeTrustedAppProvider = getFakeTrustedApp.getMockImplementation(); - getFakeTrustedApp.mockImplementation(() => { - return { - ...originalFakeTrustedAppProvider!(), - effectScope: { - type: 'policy', - policies: ['abc123'], - }, - }; - }); - await renderWithListDataAndClickOnEditCard(); - }); - - it('shows a message at the top of the flyout to inform the user their license is expired', () => { - expect( - renderResult.queryByTestId('addTrustedAppFlyout-expired-license-callout') - ).toBeTruthy(); - }); - }); - - describe('the license is downgraded to gold or below and the user is adding a new TA', () => { - beforeEach(async () => { - (licenseService.isPlatinumPlus as jest.Mock).mockReturnValue(false); - - const originalFakeTrustedAppProvider = getFakeTrustedApp.getMockImplementation(); - getFakeTrustedApp.mockImplementation(() => { - return { - ...originalFakeTrustedAppProvider!(), - effectScope: { - type: 'policy', - policies: ['abc123'], - }, - }; - }); - await renderWithListDataAndClickAddButton(); - }); - it('does not show the expired license message at the top of the flyout', async () => { - expect( - renderResult.queryByTestId('addTrustedAppFlyout-expired-license-callout') - ).toBeNull(); - }); - }); - - describe('and the edit trusted app button is clicked', () => { - beforeEach(async () => { - await renderWithListDataAndClickOnEditCard(); - }); - - it('should persist edit params to url', () => { - expect(history.location.search).toEqual( - '?show=edit&id=bec3b48f-ddb7-4622-a2b0-61cc031d17eb' - ); - }); - - it('should display the Edit flyout', () => { - expect(renderResult.getByTestId('addTrustedAppFlyout')); - }); - - it('should NOT display the about info for trusted apps', () => { - expect(renderResult.queryByTestId('addTrustedAppFlyout-about')).toBeNull(); - }); - - it('should show correct flyout title', () => { - expect(renderResult.getByTestId('addTrustedAppFlyout-headerTitle').textContent).toBe( - 'Edit trusted application' - ); - }); - - it('should display the expected text for the Save button', () => { - expect(renderResult.getByTestId('addTrustedAppFlyout-createButton').textContent).toEqual( - 'Save' - ); - }); - - it('should display trusted app data for edit', async () => { - const formNameInput = renderResult.getByTestId( - 'addTrustedAppFlyout-createForm-nameTextField' - ) as HTMLInputElement; - const formDescriptionInput = renderResult.getByTestId( - 'addTrustedAppFlyout-createForm-descriptionField' - ) as HTMLTextAreaElement; - - expect(formNameInput.value).toEqual('Generated Exception (nng74)'); - expect(formDescriptionInput.value).toEqual('created by ExceptionListItemGenerator'); - }); - - describe('and when Save is clicked', () => { - it('should call the correct api (PUT)', async () => { - await act(async () => { - fireEvent.click(renderResult.getByTestId('addTrustedAppFlyout-createButton')); - await waitForAction('trustedAppCreationSubmissionResourceStateChanged', { - validate({ payload }) { - return isLoadedResourceState(payload.newState); - }, - }); - }); - - expect(coreStart.http.put).toHaveBeenCalledTimes(1); - - const lastCallToPut = coreStart.http.put.mock.calls[0] as unknown as [ - string, - HttpFetchOptions - ]; - - expect(lastCallToPut[0]).toEqual('/api/exception_lists/items'); - - expect(JSON.parse(lastCallToPut[1].body as string)).toEqual({ - _version: '9zawi', - name: 'Generated Exception (nng74)', - description: 'created by ExceptionListItemGenerator', - entries: [ - { - field: 'process.hash.md5', - operator: 'included', - type: 'match', - value: '741462ab431a22233c787baab9b653c7', - }, - { - field: 'process.executable.caseless', - operator: 'included', - type: 'match', - value: 'c:\\fol\\bin.exe', - }, - ], - os_types: ['windows'], - tags: [ - 'policy:ddf6570b-9175-4a6d-b288-61a09771c647', - 'policy:b8e616ae-44fc-4be7-846c-ce8fa5c082dd', - ], - id: '05b5e350-0cad-4dc3-a61d-6e6796b0af39', - comments: [], - item_id: 'bec3b48f-ddb7-4622-a2b0-61cc031d17eb', - namespace_type: 'agnostic', - type: 'simple', - }); - }); - }); - }); - - describe('and attempting to show Edit panel based on URL params', () => { - const renderAndWaitForGetApi = async () => { - // the store action watcher is setup prior to render because `renderWithListData()` - // also awaits API calls and this action could be missed. - const apiResponseForEditTrustedApp = waitForAction( - 'trustedAppCreationEditItemStateChanged', - { - validate({ payload }) { - return isLoadedResourceState(payload) || isFailedResourceState(payload); - }, - } - ); - - await renderWithListData(); - - await reactTestingLibrary.act(async () => { - await apiResponseForEditTrustedApp; - }); - - return renderResult; - }; - - beforeEach(() => { - reactTestingLibrary.act(() => { - history.push('/administration/trusted_apps?show=edit&id=9999-edit-8888'); - }); - }); - - it('should retrieve trusted app via API using url `id`', async () => { - await renderAndWaitForGetApi(); - - expect(coreStart.http.get.mock.calls).toContainEqual([ - EXCEPTION_LIST_ITEM_URL, - { - query: { - item_id: '9999-edit-8888', - namespace_type: 'agnostic', - }, - }, - ]); - - expect( - ( - renderResult.getByTestId( - 'addTrustedAppFlyout-createForm-nameTextField' - ) as HTMLInputElement - ).value - ).toEqual('Generated Exception (u6kh2)'); - }); - - it('should redirect to list and show toast message if `id` is missing from URL', async () => { - reactTestingLibrary.act(() => { - history.push('/administration/trusted_apps?show=edit&id='); - }); - - await renderAndWaitForGetApi(); - - expect(history.location.search).toEqual(''); - expect(coreStart.notifications.toasts.addWarning.mock.calls[0][0]).toEqual( - 'Unable to edit trusted application (No id provided)' - ); - }); - - it('should redirect to list and show toast message on API error for GET of `id`', async () => { - // Mock the API GET for the trusted application - mockedApis.responseProvider.trustedApp.mockImplementation(() => { - throw new Error('test: api error response'); - }); - - await renderAndWaitForGetApi(); - - expect(history.location.search).toEqual(''); - expect(coreStart.notifications.toasts.addWarning.mock.calls[0][0]).toEqual( - 'Unable to edit trusted application (test: api error response)' - ); - }); - }); - }); - }); - - describe('and the Add Trusted App button is clicked', () => { - const renderAndClickAddButton = async (): Promise< - ReturnType - > => { - render(); - await act(async () => { - await Promise.all([ - waitForAction('trustedAppsListResourceStateChanged'), - waitForAction('trustedAppsExistStateChanged', { - validate({ payload }) { - return isLoadedResourceState(payload); - }, - }), - ]); - }); - - act(() => { - const addButton = renderResult.getByTestId('trustedAppsListAddButton'); - fireEvent.click(addButton, { button: 1 }); - }); - - // Wait for the policies to be loaded - await act(async () => { - await waitForAction('trustedAppsPoliciesStateChanged', { - validate: (action) => { - return isLoadedResourceState(action.payload); - }, - }); - }); - - return renderResult; - }; - - it('should display the create flyout', async () => { - const { getByTestId } = await renderAndClickAddButton(); - const flyout = getByTestId('addTrustedAppFlyout'); - expect(flyout).not.toBeNull(); - - const flyoutTitle = getByTestId('addTrustedAppFlyout-headerTitle'); - expect(flyoutTitle.textContent).toBe('Add trusted application'); - - expect(getByTestId('addTrustedAppFlyout-about')); - }); - - it('should update the URL to indicate the flyout is opened', async () => { - await renderAndClickAddButton(); - expect(/show\=create/.test(history.location.search)).toBe(true); - }); - - it('should preserve other URL search params', async () => { - const createListResponse = - mockedApis.responseProvider.trustedAppsList.getMockImplementation()!; - mockedApis.responseProvider.trustedAppsList.mockImplementation((...args) => { - const response = createListResponse(...args); - response.total = 100; // Trigger the UI to show pagination - return response; - }); - - reactTestingLibrary.act(() => { - history.push('/administration/trusted_apps?page_index=2&page_size=20'); - }); - await renderAndClickAddButton(); - expect(history.location.search).toBe('?page_index=2&page_size=20&show=create'); - }); - - it('should display create form', async () => { - const { queryByTestId } = await renderAndClickAddButton(); - expect(queryByTestId('addTrustedAppFlyout-createForm')).not.toBeNull(); - }); - - it('should have list of policies populated', async () => { - const resetEnv = forceHTMLElementOffsetWidth(); - await renderAndClickAddButton(); - act(() => { - fireEvent.click(renderResult.getByTestId('perPolicy')); - }); - expect(renderResult.getByTestId('policy-ddf6570b-9175-4a6d-b288-61a09771c647')); - resetEnv(); - }); - - it('should initially have the flyout Add button disabled', async () => { - const { getByTestId } = await renderAndClickAddButton(); - expect((getByTestId('addTrustedAppFlyout-createButton') as HTMLButtonElement).disabled).toBe( - true - ); - }); - - it('should close flyout if cancel button is clicked', async () => { - const { getByTestId, queryByTestId } = await renderAndClickAddButton(); - const cancelButton = getByTestId('addTrustedAppFlyout-cancelButton'); - await reactTestingLibrary.act(async () => { - fireEvent.click(cancelButton, { button: 1 }); - await waitForAction('trustedAppCreationDialogClosed'); - }); - expect(history.location.search).toBe(''); - expect(queryByTestId('addTrustedAppFlyout')).toBeNull(); - }); - - it('should close flyout if flyout close button is clicked', async () => { - const { getByTestId, queryByTestId } = await renderAndClickAddButton(); - const flyoutCloseButton = getByTestId('euiFlyoutCloseButton'); - await reactTestingLibrary.act(async () => { - fireEvent.click(flyoutCloseButton, { button: 1 }); - await waitForAction('trustedAppCreationDialogClosed'); - }); - expect(queryByTestId('addTrustedAppFlyout')).toBeNull(); - expect(history.location.search).toBe(''); - }); - - describe('and when the form data is valid', () => { - const fillInCreateForm = async () => { - mockedContext.store.dispatch({ - type: 'trustedAppCreationDialogFormStateUpdated', - payload: { - isValid: true, - entry: toUpdateTrustedApp(getFakeTrustedApp()), - }, - }); - }; - - it('should enable the Flyout Add button', async () => { - await renderAndClickAddButton(); - await fillInCreateForm(); - - const flyoutAddButton = renderResult.getByTestId( - 'addTrustedAppFlyout-createButton' - ) as HTMLButtonElement; - - expect(flyoutAddButton.disabled).toBe(false); - }); - - describe('and the Flyout Add button is clicked', () => { - let releasePostCreateApi: () => void; - - beforeEach(async () => { - // Add a delay to the create api response provider and expose a function that allows - // us to release it at the right time. - mockedApis.responseProvider.trustedAppCreate.mockDelay.mockReturnValue( - new Promise((resolve) => { - releasePostCreateApi = resolve as typeof releasePostCreateApi; - }) - ); - - await renderAndClickAddButton(); - await fillInCreateForm(); - - const userClickedSaveActionWatcher = waitForAction('trustedAppCreationDialogConfirmed'); - reactTestingLibrary.act(() => { - fireEvent.click(renderResult.getByTestId('addTrustedAppFlyout-createButton'), { - button: 1, - }); - }); - - await reactTestingLibrary.act(async () => { - await userClickedSaveActionWatcher; - }); - }); - - afterEach(() => releasePostCreateApi()); - - it('should display info about Trusted Apps', async () => { - expect(renderResult.getByTestId('addTrustedAppFlyout-about').textContent).toEqual( - expectedAboutInfo - ); - }); - - it('should disable the Cancel button', async () => { - expect( - (renderResult.getByTestId('addTrustedAppFlyout-cancelButton') as HTMLButtonElement) - .disabled - ).toBe(true); - releasePostCreateApi(); - }); - - it('should hide the dialog close button', async () => { - expect(renderResult.queryByTestId('euiFlyoutCloseButton')).toBeNull(); - }); - - it('should disable the flyout Add button and set it to loading', async () => { - const saveButton = renderResult.getByTestId( - 'addTrustedAppFlyout-createButton' - ) as HTMLButtonElement; - expect(saveButton.disabled).toBe(true); - expect(saveButton.querySelector('.euiLoadingSpinner')).not.toBeNull(); - }); - - describe('and if create was successful', () => { - beforeEach(async () => { - await reactTestingLibrary.act(async () => { - const serverResponseAction = waitForAction( - 'trustedAppCreationSubmissionResourceStateChanged' - ); - - coreStart.http.get.mockClear(); - releasePostCreateApi(); - await serverResponseAction; - }); - }); - - it('should close the flyout', () => { - expect(renderResult.queryByTestId('addTrustedAppFlyout')).toBeNull(); - }); - - it('should show success toast notification', () => { - expect(coreStart.notifications.toasts.addSuccess.mock.calls[0][0]).toEqual({ - text: '"Generated Exception (3xnng)" has been added to the trusted applications list.', - title: 'Success!', - }); - }); - - it('should trigger the List to reload', () => { - const isCalled = coreStart.http.get.mock.calls.some( - (call) => call[0].toString() === `${EXCEPTION_LIST_ITEM_URL}/_find` - ); - expect(isCalled).toEqual(true); - }); - }); - - describe('and if create failed', () => { - const ServerErrorResponseBodyMock = class extends Error { - public readonly body: { message: string }; - constructor(message = 'Test - Bad Call') { - super(message); - this.body = { - message, - }; - } - }; - beforeEach(async () => { - const failedCreateApiResponse = new ServerErrorResponseBodyMock(); - - mockedApis.responseProvider.trustedAppCreate.mockImplementation(() => { - throw failedCreateApiResponse; - }); - - await reactTestingLibrary.act(async () => { - const serverResponseAction = waitForAction( - 'trustedAppCreationSubmissionResourceStateChanged', - { - validate({ payload }) { - return isFailedResourceState(payload.newState); - }, - } - ); - - releasePostCreateApi(); - await serverResponseAction; - }); - }); - - it('should continue to show the flyout', () => { - expect(renderResult.getByTestId('addTrustedAppFlyout')).not.toBeNull(); - }); - - it('should enable the Cancel Button', () => { - expect( - (renderResult.getByTestId('addTrustedAppFlyout-cancelButton') as HTMLButtonElement) - .disabled - ).toBe(false); - }); - - it('should show the dialog close button', () => { - expect(renderResult.getByTestId('euiFlyoutCloseButton')).not.toBeNull(); - }); - - it('should enable the flyout Add button and remove loading indicating', () => { - expect( - (renderResult.getByTestId('addTrustedAppFlyout-createButton') as HTMLButtonElement) - .disabled - ).toBe(false); - }); - - it('should show API errors in the form', () => { - expect(renderResult.container.querySelector('.euiForm__errors')).not.toBeNull(); - }); - }); - }); - }); - - describe('and when the form data is not valid', () => { - it('should not enable the Flyout Add button with an invalid hash', async () => { - await renderAndClickAddButton(); - const { getByTestId } = renderResult; - - reactTestingLibrary.act(() => { - fireEvent.change(getByTestId('addTrustedAppFlyout-createForm-nameTextField'), { - target: { value: 'trusted app A' }, - }); - - fireEvent.change( - getByTestId('addTrustedAppFlyout-createForm-conditionsBuilder-group1-entry0-value'), - { target: { value: 'invalid hash' } } - ); - }); - - const flyoutAddButton = getByTestId( - 'addTrustedAppFlyout-createButton' - ) as HTMLButtonElement; - expect(flyoutAddButton.disabled).toBe(true); - }); - }); - }); - - describe('and there are no trusted apps', () => { - const releaseExistsResponse = jest.fn((): FoundExceptionListItemSchema => { - return { - data: [], - total: 0, - page: 1, - per_page: 1, - }; - }); - const releaseListResponse = jest.fn((): FoundExceptionListItemSchema => { - return { - data: [], - total: 0, - page: 1, - per_page: 20, - }; - }); - - beforeEach(() => { - mockedApis.responseProvider.trustedAppsList.mockImplementation(({ query }) => { - const { page, per_page: perPage } = query as { page: number; per_page: number }; - - if (page === 1 && perPage === 1) { - return releaseExistsResponse(); - } else { - return releaseListResponse(); - } - }); - }); - - afterEach(() => { - releaseExistsResponse.mockClear(); - releaseListResponse.mockClear(); - }); - - it('should show a loader until trusted apps existence can be confirmed', async () => { - render(); - expect(await renderResult.findByTestId('trustedAppsListLoader')).not.toBeNull(); - }); - - it('should show Empty Prompt if not entries exist', async () => { - render(); - await act(async () => { - await waitForAction('trustedAppsExistStateChanged'); - }); - expect(await renderResult.findByTestId('trustedAppEmptyState')).not.toBeNull(); - }); - - it('should hide empty prompt and show list after one trusted app is added', async () => { - render(); - await act(async () => { - await waitForAction('trustedAppsExistStateChanged'); - }); - expect(await renderResult.findByTestId('trustedAppEmptyState')).not.toBeNull(); - releaseListResponse.mockReturnValueOnce({ - data: [mockedApis.responseProvider.trustedApp({ query: {} } as HttpFetchOptionsWithPath)], - total: 1, - page: 1, - per_page: 20, - }); - releaseExistsResponse.mockReturnValueOnce({ - data: [mockedApis.responseProvider.trustedApp({ query: {} } as HttpFetchOptionsWithPath)], - total: 1, - page: 1, - per_page: 1, - }); - - await act(async () => { - mockedContext.store.dispatch({ - type: 'trustedAppsListDataOutdated', - }); - await waitForAction('trustedAppsListResourceStateChanged'); - }); - - expect(await renderResult.findByTestId('trustedAppsListPageContent')).not.toBeNull(); - }); - - it('should should show empty prompt once the last trusted app entry is deleted', async () => { - releaseListResponse.mockReturnValueOnce({ - data: [mockedApis.responseProvider.trustedApp({ query: {} } as HttpFetchOptionsWithPath)], - total: 1, - page: 1, - per_page: 20, - }); - releaseExistsResponse.mockReturnValueOnce({ - data: [mockedApis.responseProvider.trustedApp({ query: {} } as HttpFetchOptionsWithPath)], - total: 1, - page: 1, - per_page: 1, - }); - - render(); - - await act(async () => { - await waitForAction('trustedAppsExistStateChanged'); - }); - - expect(await renderResult.findByTestId('trustedAppsListPageContent')).not.toBeNull(); - - await act(async () => { - mockedContext.store.dispatch({ - type: 'trustedAppsListDataOutdated', - }); - await waitForAction('trustedAppsListResourceStateChanged'); - }); - - expect(await renderResult.findByTestId('trustedAppEmptyState')).not.toBeNull(); - }); - - it('should not display the searchExceptions', async () => { - render(); - await act(async () => { - await waitForAction('trustedAppsExistStateChanged'); - }); - expect(renderResult.queryByTestId('searchExceptions')).toBeNull(); - }); - }); - - describe('and the search is dispatched', () => { - beforeEach(async () => { - reactTestingLibrary.act(() => { - history.push('/administration/trusted_apps?filter=test'); - }); - render(); - await act(async () => { - await waitForListUI(); - }); - }); - - it('search bar is filled with query params', () => { - expect(renderResult.getByDisplayValue('test')).not.toBeNull(); - }); - - it('search action is dispatched', async () => { - await act(async () => { - fireEvent.click(renderResult.getByTestId('searchButton')); - expect(await waitForAction('userChangedUrl')).not.toBeNull(); - }); - }); - }); - - describe('and the back button is present', () => { - beforeEach(async () => { - render(); - await act(async () => { - await waitForListUI(); - }); - reactTestingLibrary.act(() => { - history.push('/administration/trusted_apps', { - onBackButtonNavigateTo: [{ appId: 'appId' }], - backButtonLabel: 'back to fleet', - backButtonUrl: '/fleet', - }); - }); - }); - - it('back button is present', () => { - const button = renderResult.queryByTestId('backToOrigin'); - expect(button).not.toBeNull(); - expect(button).toHaveAttribute('href', '/fleet'); - }); - - it('back button is present after push history', () => { - reactTestingLibrary.act(() => { - history.push('/administration/trusted_apps'); - }); - const button = renderResult.queryByTestId('backToOrigin'); - expect(button).not.toBeNull(); - expect(button).toHaveAttribute('href', '/fleet'); - }); - }); - - describe('and the back button is not present', () => { - beforeEach(async () => { - render(); - await act(async () => { - await waitForAction('trustedAppsListResourceStateChanged'); - }); - reactTestingLibrary.act(() => { - history.push('/administration/trusted_apps'); - }); - }); - - it('back button is not present when missing history params', () => { - const button = renderResult.queryByTestId('backToOrigin'); - expect(button).toBeNull(); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_page.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_page.tsx deleted file mode 100644 index 6b3f59f44ce12..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_page.tsx +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { memo, useMemo, useCallback } from 'react'; -import { useDispatch } from 'react-redux'; -import { Dispatch } from 'redux'; -import { useLocation } from 'react-router-dom'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; - -import { - checkingIfEntriesExist, - entriesExist, - getCurrentLocation, - getListTotalItemsCount, - listOfPolicies, - prevEntriesExist, -} from '../store/selectors'; -import { useTrustedAppsNavigateCallback, useTrustedAppsSelector } from './hooks'; -import { AdministrationListPage } from '../../../components/administration_list_page'; -import { CreateTrustedAppFlyout } from './components/create_trusted_app_flyout'; -import { TrustedAppsGrid } from './components/trusted_apps_grid'; -import { TrustedAppDeletionDialog } from './trusted_app_deletion_dialog'; -import { TrustedAppsNotifications } from './trusted_apps_notifications'; -import { AppAction } from '../../../../common/store/actions'; -import { ABOUT_TRUSTED_APPS, SEARCH_TRUSTED_APP_PLACEHOLDER } from './translations'; -import { EmptyState } from './components/empty_state'; -import { SearchExceptions } from '../../../components/search_exceptions'; -import { BackToExternalAppSecondaryButton } from '../../../components/back_to_external_app_secondary_button'; -import { BackToExternalAppButton } from '../../../components/back_to_external_app_button'; -import { ListPageRouteState } from '../../../../../common/endpoint/types'; -import { ManagementPageLoader } from '../../../components/management_page_loader'; -import { useMemoizedRouteState } from '../../../common/hooks'; - -export const TrustedAppsPage = memo(() => { - const dispatch = useDispatch>(); - const { state: routeState } = useLocation(); - const location = useTrustedAppsSelector(getCurrentLocation); - const totalItemsCount = useTrustedAppsSelector(getListTotalItemsCount); - const isCheckingIfEntriesExists = useTrustedAppsSelector(checkingIfEntriesExist); - const policyList = useTrustedAppsSelector(listOfPolicies); - const doEntriesExist = useTrustedAppsSelector(entriesExist); - const didEntriesExist = useTrustedAppsSelector(prevEntriesExist); - const navigationCallbackQuery = useTrustedAppsNavigateCallback( - (query: string, includedPolicies?: string) => ({ - filter: query, - included_policies: includedPolicies, - }) - ); - - const memoizedRouteState = useMemoizedRouteState(routeState); - - const backButtonEmptyComponent = useMemo(() => { - if (memoizedRouteState && memoizedRouteState.onBackButtonNavigateTo) { - return ; - } - }, [memoizedRouteState]); - - const backButtonHeaderComponent = useMemo(() => { - if (memoizedRouteState && memoizedRouteState.onBackButtonNavigateTo) { - return ; - } - }, [memoizedRouteState]); - - const handleAddButtonClick = useTrustedAppsNavigateCallback(() => ({ - show: 'create', - id: undefined, - })); - const handleAddFlyoutClose = useTrustedAppsNavigateCallback(() => ({ - show: undefined, - id: undefined, - })); - - const handleOnSearch = useCallback( - (query: string, includedPolicies?: string) => { - dispatch({ type: 'trustedAppForceRefresh', payload: { forceRefresh: true } }); - navigationCallbackQuery(query, includedPolicies); - }, - [dispatch, navigationCallbackQuery] - ); - - const showCreateFlyout = !!location.show; - - const canDisplayContent = useCallback( - () => doEntriesExist || (isCheckingIfEntriesExists && didEntriesExist), - [didEntriesExist, doEntriesExist, isCheckingIfEntriesExists] - ); - - const addButton = ( - - - - ); - - const content = ( - <> - - - {showCreateFlyout && ( - - )} - - {canDisplayContent() ? ( - <> - - - - - - {i18n.translate('xpack.securitySolution.trustedapps.list.totalCount', { - defaultMessage: - 'Showing {totalItemsCount, plural, one {# trusted application} other {# trusted applications}}', - values: { totalItemsCount }, - })} - - - - - - - - - - ) : ( - - )} - - ); - - return ( - - } - subtitle={ABOUT_TRUSTED_APPS} - actions={addButton} - hideHeader={!canDisplayContent()} - > - - - {isCheckingIfEntriesExists && !didEntriesExist ? ( - - ) : ( - content - )} - - ); -}); - -TrustedAppsPage.displayName = 'TrustedAppsPage'; diff --git a/x-pack/plugins/security_solution/public/management/services/policies/hooks.ts b/x-pack/plugins/security_solution/public/management/services/policies/hooks.ts index 6cc6140d336d2..cf053128e5f37 100644 --- a/x-pack/plugins/security_solution/public/management/services/policies/hooks.ts +++ b/x-pack/plugins/security_solution/public/management/services/policies/hooks.ts @@ -40,11 +40,11 @@ export function useGetEndpointSpecificPolicies( }, }); }, - { - refetchIntervalInBackground: false, - refetchOnWindowFocus: false, - onError, - } + onError + ? { + onError, + } + : undefined ); } @@ -56,7 +56,7 @@ export function useGetEndpointSpecificPolicies( */ export function useGetAgentCountForPolicy({ policyIds, - customQueryOptions = {}, + customQueryOptions, }: { policyIds: string[]; customQueryOptions?: UseQueryOptions; @@ -72,11 +72,7 @@ export function useGetAgentCountForPolicy({ }, }); }, - { - refetchIntervalInBackground: false, - refetchOnWindowFocus: false, - ...customQueryOptions, - } + customQueryOptions ); } @@ -84,7 +80,7 @@ export function useGetAgentCountForPolicy({ * This hook returns the endpoint security package which contains endpoint version info */ export function useGetEndpointSecurityPackage({ - customQueryOptions = {}, + customQueryOptions, }: { customQueryOptions?: UseQueryOptions; }): QueryObserverResult { @@ -94,10 +90,6 @@ export function useGetEndpointSecurityPackage({ () => { return sendGetEndpointSecurityPackage(http); }, - { - refetchIntervalInBackground: false, - refetchOnWindowFocus: false, - ...customQueryOptions, - } + customQueryOptions ); } diff --git a/x-pack/plugins/security_solution/public/management/store/middleware.ts b/x-pack/plugins/security_solution/public/management/store/middleware.ts index d011a9dcb91a7..86a5ade340058 100644 --- a/x-pack/plugins/security_solution/public/management/store/middleware.ts +++ b/x-pack/plugins/security_solution/public/management/store/middleware.ts @@ -14,12 +14,10 @@ import { MANAGEMENT_STORE_ENDPOINTS_NAMESPACE, MANAGEMENT_STORE_GLOBAL_NAMESPACE, MANAGEMENT_STORE_POLICY_DETAILS_NAMESPACE, - MANAGEMENT_STORE_TRUSTED_APPS_NAMESPACE, MANAGEMENT_STORE_EVENT_FILTERS_NAMESPACE, } from '../common/constants'; import { policyDetailsMiddlewareFactory } from '../pages/policy/store/policy_details'; import { endpointMiddlewareFactory } from '../pages/endpoint_hosts/store/middleware'; -import { trustedAppsPageMiddlewareFactory } from '../pages/trusted_apps/store/middleware'; import { eventFiltersPageMiddlewareFactory } from '../pages/event_filters/store/middleware'; type ManagementSubStateKey = keyof State[typeof MANAGEMENT_STORE_GLOBAL_NAMESPACE]; @@ -42,10 +40,7 @@ export const managementMiddlewareFactory: SecuritySubPluginMiddlewareFactory = ( createSubStateSelector(MANAGEMENT_STORE_ENDPOINTS_NAMESPACE), endpointMiddlewareFactory(coreStart, depsStart) ), - substateMiddlewareFactory( - createSubStateSelector(MANAGEMENT_STORE_TRUSTED_APPS_NAMESPACE), - trustedAppsPageMiddlewareFactory(coreStart, depsStart) - ), + substateMiddlewareFactory( createSubStateSelector(MANAGEMENT_STORE_EVENT_FILTERS_NAMESPACE), eventFiltersPageMiddlewareFactory(coreStart, depsStart) diff --git a/x-pack/plugins/security_solution/public/management/store/reducer.ts b/x-pack/plugins/security_solution/public/management/store/reducer.ts index 662d2b4322bcb..2fd20129ddca8 100644 --- a/x-pack/plugins/security_solution/public/management/store/reducer.ts +++ b/x-pack/plugins/security_solution/public/management/store/reducer.ts @@ -13,15 +13,12 @@ import { import { MANAGEMENT_STORE_ENDPOINTS_NAMESPACE, MANAGEMENT_STORE_POLICY_DETAILS_NAMESPACE, - MANAGEMENT_STORE_TRUSTED_APPS_NAMESPACE, MANAGEMENT_STORE_EVENT_FILTERS_NAMESPACE, } from '../common/constants'; import { ImmutableCombineReducers } from '../../common/store'; import { Immutable } from '../../../common/endpoint/types'; import { ManagementState } from '../types'; import { endpointListReducer } from '../pages/endpoint_hosts/store/reducer'; -import { initialTrustedAppsPageState } from '../pages/trusted_apps/store/builders'; -import { trustedAppsPageReducer } from '../pages/trusted_apps/store/reducer'; import { initialEventFiltersPageState } from '../pages/event_filters/store/builders'; import { eventFiltersPageReducer } from '../pages/event_filters/store/reducer'; import { initialEndpointPageState } from '../pages/endpoint_hosts/store/builders'; @@ -34,7 +31,6 @@ const immutableCombineReducers: ImmutableCombineReducers = combineReducers; export const mockManagementState: Immutable = { [MANAGEMENT_STORE_POLICY_DETAILS_NAMESPACE]: initialPolicyDetailsState(), [MANAGEMENT_STORE_ENDPOINTS_NAMESPACE]: initialEndpointPageState(), - [MANAGEMENT_STORE_TRUSTED_APPS_NAMESPACE]: initialTrustedAppsPageState(), [MANAGEMENT_STORE_EVENT_FILTERS_NAMESPACE]: initialEventFiltersPageState(), }; @@ -44,6 +40,5 @@ export const mockManagementState: Immutable = { export const managementReducer = immutableCombineReducers({ [MANAGEMENT_STORE_POLICY_DETAILS_NAMESPACE]: policyDetailsReducer, [MANAGEMENT_STORE_ENDPOINTS_NAMESPACE]: endpointListReducer, - [MANAGEMENT_STORE_TRUSTED_APPS_NAMESPACE]: trustedAppsPageReducer, [MANAGEMENT_STORE_EVENT_FILTERS_NAMESPACE]: eventFiltersPageReducer, }); diff --git a/x-pack/plugins/security_solution/public/management/types.ts b/x-pack/plugins/security_solution/public/management/types.ts index 65063fce96e67..0ad0f2e757c00 100644 --- a/x-pack/plugins/security_solution/public/management/types.ts +++ b/x-pack/plugins/security_solution/public/management/types.ts @@ -9,7 +9,6 @@ import { CombinedState } from 'redux'; import { SecurityPageName } from '../app/types'; import { PolicyDetailsState } from './pages/policy/types'; import { EndpointState } from './pages/endpoint_hosts/types'; -import { TrustedAppsListPageState } from './pages/trusted_apps/state'; import { EventFiltersListPageState } from './pages/event_filters/types'; /** @@ -21,7 +20,6 @@ export type ManagementStoreGlobalNamespace = 'management'; export type ManagementState = CombinedState<{ policyDetails: PolicyDetailsState; endpoints: EndpointState; - trustedApps: TrustedAppsListPageState; eventFilters: EventFiltersListPageState; }>; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.test.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.test.tsx new file mode 100644 index 0000000000000..4c8280f90304d --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.test.tsx @@ -0,0 +1,122 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import { render } from '@testing-library/react'; +import { AlertsByStatus } from './alerts_by_status'; +import { parsedMockAlertsData } from './mock_data'; +import { useKibana } from '../../../../common/lib/kibana/kibana_react'; +import { mockCasesContract } from '@kbn/cases-plugin/public/mocks'; +import { CASES_FEATURE_ID } from '../../../../../common/constants'; +import { TestProviders } from '../../../../common/mock/test_providers'; +import { useAlertsByStatus } from './use_alerts_by_status'; + +jest.mock('../../../../common/lib/kibana/kibana_react'); + +jest.mock('./chart_label', () => { + return { + ChartLabel: jest.fn((props) => ), + }; +}); +jest.mock('./use_alerts_by_status', () => ({ + useAlertsByStatus: jest.fn().mockReturnValue({ + items: [], + isLoading: true, + }), +})); +describe('AlertsByStatus', () => { + const mockCases = mockCasesContract(); + + const props = { + showInspectButton: true, + signalIndexName: 'mock-signal-index', + }; + + beforeEach(() => { + jest.clearAllMocks(); + (useKibana as jest.Mock).mockReturnValue({ + services: { + cases: mockCases, + application: { + capabilities: { [CASES_FEATURE_ID]: { crud_cases: true, read_cases: true } }, + getUrlForApp: jest.fn(), + }, + theme: {}, + }, + }); + (useAlertsByStatus as jest.Mock).mockReturnValue({ + items: [], + isLoading: true, + }); + }); + + test('render HoverVisibilityContainer', () => { + const { container } = render( + + + + ); + expect( + container.querySelector(`[data-test-subj="hoverVisibilityContainer"]`) + ).toBeInTheDocument(); + }); + test('render HistogramPanel', () => { + const { container } = render( + + + + ); + expect( + container.querySelector(`[data-test-subj="detection-response-alerts-by-status-panel"]`) + ).toBeInTheDocument(); + }); + + test('render HeaderSection', () => { + const { container } = render( + + + + ); + expect(container.querySelector(`[data-test-subj="header-section"]`)).toBeInTheDocument(); + }); + + test('render Legend', () => { + const testProps = { + ...props, + isInitialLoading: false, + }; + (useAlertsByStatus as jest.Mock).mockReturnValue({ + items: parsedMockAlertsData, + isLoading: false, + }); + + const { container } = render( + + + + ); + expect(container.querySelector(`[data-test-subj="legend"]`)).toBeInTheDocument(); + }); + + test('render toggle query button', () => { + const testProps = { + ...props, + isInitialLoading: false, + }; + + (useAlertsByStatus as jest.Mock).mockReturnValue({ + items: parsedMockAlertsData, + isLoading: false, + }); + + const { container } = render( + + + + ); + expect(container.querySelector(`[data-test-subj="query-toggle-header"]`)).toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.tsx new file mode 100644 index 0000000000000..2e1b96447f3df --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.tsx @@ -0,0 +1,211 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiProgress, EuiSpacer, EuiText } from '@elastic/eui'; +import React, { useCallback, useMemo } from 'react'; +import { ShapeTreeNode } from '@elastic/charts'; +import { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; +import styled from 'styled-components'; +import { DonutChart, FillColor } from '../../../../common/components/charts/donutchart'; +import { SecurityPageName } from '../../../../../common/constants'; +import { useNavigation } from '../../../../common/lib/kibana'; +import { HeaderSection } from '../../../../common/components/header_section'; +import { HoverVisibilityContainer } from '../../../../common/components/hover_visibility_container'; +import { BUTTON_CLASS as INPECT_BUTTON_CLASS } from '../../../../common/components/inspect'; +import { LegendItem } from '../../../../common/components/charts/legend_item'; +import { useAlertsByStatus } from './use_alerts_by_status'; +import { + ALERTS, + ALERTS_TEXT, + STATUS_ACKNOWLEDGED, + STATUS_CLOSED, + STATUS_CRITICAL_LABEL, + STATUS_HIGH_LABEL, + STATUS_LOW_LABEL, + STATUS_MEDIUM_LABEL, + STATUS_OPEN, +} from '../translations'; +import { useQueryToggle } from '../../../../common/containers/query_toggle'; +import { getDetectionEngineUrl, useFormatUrl } from '../../../../common/components/link_to'; +import { VIEW_ALERTS } from '../../../pages/translations'; +import { LastUpdatedAt, SEVERITY_COLOR } from '../utils'; +import { FormattedCount } from '../../../../common/components/formatted_number'; +import { ChartLabel } from './chart_label'; +import { Legend } from '../../../../common/components/charts/legend'; +import { emptyDonutColor } from '../../../../common/components/charts/donutchart_empty'; +import { LinkButton } from '../../../../common/components/links'; + +const donutHeight = 120; +const StyledFlexItem = styled(EuiFlexItem)` + padding: 0 4px; +`; + +const StyledLegendFlexItem = styled(EuiFlexItem)` + padding-left: 32px; + padding-top: 45px; +`; + +interface AlertsByStatusProps { + signalIndexName: string | null; +} + +const legendField = 'kibana.alert.severity'; +const chartConfigs: Array<{ key: Severity; label: string; color: string }> = [ + { key: 'critical', label: STATUS_CRITICAL_LABEL, color: SEVERITY_COLOR.critical }, + { key: 'high', label: STATUS_HIGH_LABEL, color: SEVERITY_COLOR.high }, + { key: 'medium', label: STATUS_MEDIUM_LABEL, color: SEVERITY_COLOR.medium }, + { key: 'low', label: STATUS_LOW_LABEL, color: SEVERITY_COLOR.low }, +]; +const DETECTION_RESPONSE_ALERTS_BY_STATUS_ID = 'detection-response-alerts-by-status'; + +export const AlertsByStatus = ({ signalIndexName }: AlertsByStatusProps) => { + const { toggleStatus, setToggleStatus } = useQueryToggle(DETECTION_RESPONSE_ALERTS_BY_STATUS_ID); + const { formatUrl, search: urlSearch } = useFormatUrl(SecurityPageName.alerts); + const { navigateTo } = useNavigation(); + const goToAlerts = useCallback( + (ev) => { + ev.preventDefault(); + navigateTo({ + deepLinkId: SecurityPageName.alerts, + path: getDetectionEngineUrl(urlSearch), + }); + }, + [navigateTo, urlSearch] + ); + + const detailsButtonOptions = useMemo( + () => ({ + name: VIEW_ALERTS, + href: formatUrl(getDetectionEngineUrl()), + onClick: goToAlerts, + }), + [formatUrl, goToAlerts] + ); + + const { + items: donutData, + isLoading: loading, + updatedAt, + } = useAlertsByStatus({ + signalIndexName, + queryId: DETECTION_RESPONSE_ALERTS_BY_STATUS_ID, + skip: !toggleStatus, + }); + const legendItems: LegendItem[] = useMemo( + () => + chartConfigs.map((d) => ({ + color: d.color, + field: legendField, + value: d.label, + })), + [] + ); + + const openCount = donutData?.open?.total ?? 0; + const acknowledgedCount = donutData?.acknowledged?.total ?? 0; + const closedCount = donutData?.closed?.total ?? 0; + + const totalAlerts = + loading || donutData == null ? 0 : openCount + acknowledgedCount + closedCount; + + const fillColor: FillColor = useCallback((d: ShapeTreeNode) => { + return chartConfigs.find((cfg) => cfg.label === d.dataName)?.color ?? emptyDonutColor; + }, []); + + return ( + <> + + + {loading && ( + + )} + } + inspectMultiple + toggleStatus={toggleStatus} + toggleQuery={setToggleStatus} + > + + + + {detailsButtonOptions.name} + + + + + {toggleStatus && ( + <> + + + {totalAlerts !== 0 && ( + + <> + + + + <> + {ALERTS(totalAlerts)} + + + )} + + + + } + totalCount={openCount} + /> + + + } + totalCount={acknowledgedCount} + /> + + + } + totalCount={closedCount} + /> + + + + + {legendItems.length > 0 && } + + + + + )} + + + + ); +}; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/chart_label.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/chart_label.tsx new file mode 100644 index 0000000000000..ad609102409d2 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/chart_label.tsx @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import styled from 'styled-components'; +import { FormattedCount } from '../../../../common/components/formatted_number'; + +interface ChartLabelProps { + count: number | null | undefined; +} + +const PlaceHolder = styled.div` + padding: ${(props) => props.theme.eui.paddingSizes.s}; +`; + +const ChartLabelComponent: React.FC = ({ count }) => { + return count != null ? ( + + + + ) : ( + + ); +}; + +ChartLabelComponent.displayName = 'ChartLabelComponent'; +export const ChartLabel = React.memo(ChartLabelComponent); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/index.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/index.ts new file mode 100644 index 0000000000000..257e690ba72e5 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { AlertsByStatus } from './alerts_by_status'; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/mock_data.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/mock_data.ts new file mode 100644 index 0000000000000..f8aff3bdc87ac --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/mock_data.ts @@ -0,0 +1,137 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { AlertsByStatusResponse, AlertsByStatusAgg, ParsedAlertsData } from './types'; + +export const from = '2022-04-05T12:00:00.000Z'; +export const to = '2022-04-08T12:00:00.000Z'; + +export const mockAlertsData: AlertsByStatusResponse<[], AlertsByStatusAgg> = { + took: 4, + _shards: { + total: 1, + successful: 1, + skipped: 0, + failed: 0, + }, + hits: { + total: { + value: 10000, + relation: 'gte', + }, + hits: [], + }, + aggregations: { + alertsByStatus: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { + key: 'open', + doc_count: 28149, + statusBySeverity: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { + key: 'low', + doc_count: 22717, + }, + { + key: 'high', + doc_count: 5027, + }, + { + key: 'medium', + doc_count: 405, + }, + ], + }, + }, + { + key: 'closed', + doc_count: 4, + statusBySeverity: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { + key: 'high', + doc_count: 4, + }, + { + key: 'low', + doc_count: 0, + }, + ], + }, + }, + ], + }, + }, +}; + +export const parsedMockAlertsData: ParsedAlertsData = { + open: { + total: 28149, + severities: [ + { + key: 'low', + label: 'Low', + value: 22717, + }, + { + key: 'high', + label: 'High', + value: 5027, + }, + { + key: 'medium', + label: 'Medium', + value: 405, + }, + ], + }, + closed: { + total: 4, + severities: [ + { + key: 'high', + label: 'High', + value: 4, + }, + { + key: 'low', + label: 'Low', + value: 0, + }, + ], + }, +}; + +export const alertsByStatusQuery = { + size: 0, + query: { + bool: { + filter: [{ range: { '@timestamp': { gte: from, lte: to } } }], + }, + }, + aggs: { + alertsByStatus: { + terms: { + field: 'kibana.alert.workflow_status', + }, + aggs: { + statusBySeverity: { + terms: { + field: 'kibana.alert.severity', + }, + }, + }, + }, + }, +}; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/types.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/types.ts new file mode 100644 index 0000000000000..523edf91775fe --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/types.ts @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; +import { Status } from '../../../../../common/detection_engine/schemas/common/schemas'; + +interface StatusBySeverity { + doc_count_error_upper_bound: number; + sum_other_doc_count: number; + buckets: SeverityBucket[]; +} + +interface StatusBucket { + key: Status; + doc_count: number; + statusBySeverity?: StatusBySeverity; +} + +interface SeverityBucket { + key: Severity; + doc_count: number; +} + +export interface AlertsByStatusAgg { + alertsByStatus: { + doc_count_error_upper_bound: number; + sum_other_doc_count: number; + buckets: StatusBucket[]; + }; +} + +export interface AlertsByStatusResponse { + took: number; + _shards: { + total: number; + successful: number; + skipped: number; + failed: number; + }; + aggregations?: Aggregations; + hits: { + total: { + value: number; + relation: string; + }; + hits: Hit[]; + }; +} + +export interface SeverityBuckets { + key: Severity; + value: number; + label?: string; +} +export type ParsedAlertsData = Partial< + Record +> | null; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/use_alerts_by_status.test.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/use_alerts_by_status.test.tsx new file mode 100644 index 0000000000000..68ee64370b26d --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/use_alerts_by_status.test.tsx @@ -0,0 +1,131 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { renderHook } from '@testing-library/react-hooks'; +import { TestProviders } from '../../../../common/mock'; +import { from, mockAlertsData, alertsByStatusQuery, parsedMockAlertsData, to } from './mock_data'; +import { + useAlertsByStatus, + UseAlertsByStatus, + UseAlertsByStatusProps, +} from './use_alerts_by_status'; + +const dateNow = new Date('2022-04-08T12:00:00.000Z').valueOf(); +const mockDateNow = jest.fn().mockReturnValue(dateNow); +Date.now = jest.fn(() => mockDateNow()) as unknown as DateConstructor['now']; + +const defaultUseQueryAlertsReturn = { + loading: false, + data: null, + setQuery: () => {}, + response: '', + request: '', + refetch: () => {}, +}; +const mockUseQueryAlerts = jest.fn().mockReturnValue(defaultUseQueryAlertsReturn); +jest.mock('../../../../detections/containers/detection_engine/alerts/use_query', () => { + return { + useQueryAlerts: (...props: unknown[]) => mockUseQueryAlerts(...props), + }; +}); + +const mockUseGlobalTime = jest + .fn() + .mockReturnValue({ from, to, setQuery: jest.fn(), deleteQuery: jest.fn() }); +jest.mock('../../../../common/containers/use_global_time', () => { + return { + useGlobalTime: (...props: unknown[]) => mockUseGlobalTime(...props), + }; +}); + +// helper function to render the hook +const renderUseAlertsByStatus = (props: Partial = {}) => + renderHook>( + () => + useAlertsByStatus({ + queryId: 'test', + signalIndexName: 'signal-alerts', + ...props, + }), + { + wrapper: TestProviders, + } + ); + +describe('useAlertsByStatus', () => { + beforeEach(() => { + jest.clearAllMocks(); + mockDateNow.mockReturnValue(dateNow); + mockUseQueryAlerts.mockReturnValue(defaultUseQueryAlertsReturn); + }); + + it('should return default values', () => { + const { result } = renderUseAlertsByStatus(); + + expect(result.current).toEqual({ + items: null, + isLoading: false, + updatedAt: dateNow, + }); + expect(mockUseQueryAlerts).toBeCalledWith({ + query: alertsByStatusQuery, + indexName: 'signal-alerts', + skip: false, + }); + }); + + it('should return parsed items', () => { + mockUseQueryAlerts.mockReturnValue({ + ...defaultUseQueryAlertsReturn, + data: mockAlertsData, + }); + + const { result } = renderUseAlertsByStatus(); + + expect(result.current).toEqual({ + items: parsedMockAlertsData, + isLoading: false, + updatedAt: dateNow, + }); + }); + + it('should return new updatedAt', () => { + const newDateNow = new Date('2022-04-08T14:00:00.000Z').valueOf(); + mockDateNow.mockReturnValue(newDateNow); // setUpdatedAt call + mockDateNow.mockReturnValueOnce(dateNow); // initialization call + + mockUseQueryAlerts.mockReturnValue({ + ...defaultUseQueryAlertsReturn, + data: mockAlertsData, + }); + + const { result } = renderUseAlertsByStatus(); + + expect(mockDateNow).toHaveBeenCalled(); + expect(result.current).toEqual({ + items: parsedMockAlertsData, + isLoading: false, + updatedAt: newDateNow, + }); + }); + + it('should skip the query', () => { + const { result } = renderUseAlertsByStatus({ skip: true }); + + expect(mockUseQueryAlerts).toBeCalledWith({ + query: alertsByStatusQuery, + indexName: 'signal-alerts', + skip: true, + }); + + expect(result.current).toEqual({ + items: null, + isLoading: false, + updatedAt: dateNow, + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/use_alerts_by_status.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/use_alerts_by_status.ts new file mode 100644 index 0000000000000..979fd6292243f --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/use_alerts_by_status.ts @@ -0,0 +1,151 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useCallback, useEffect, useState } from 'react'; +import { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; +import { useGlobalTime } from '../../../../common/containers/use_global_time'; +import { useQueryAlerts } from '../../../../detections/containers/detection_engine/alerts/use_query'; +import { useQueryInspector } from '../../../../common/components/page/manage_query'; +import { AlertsByStatusAgg, AlertsByStatusResponse, ParsedAlertsData } from './types'; +import { + STATUS_CRITICAL_LABEL, + STATUS_HIGH_LABEL, + STATUS_LOW_LABEL, + STATUS_MEDIUM_LABEL, +} from '../translations'; + +export const severityLabels: Record = { + critical: STATUS_CRITICAL_LABEL, + high: STATUS_HIGH_LABEL, + medium: STATUS_MEDIUM_LABEL, + low: STATUS_LOW_LABEL, +}; + +export const getAlertsByStatusQuery = ({ from, to }: { from: string; to: string }) => ({ + size: 0, + query: { + bool: { + filter: [{ range: { '@timestamp': { gte: from, lte: to } } }], + }, + }, + aggs: { + alertsByStatus: { + terms: { + field: 'kibana.alert.workflow_status', + }, + aggs: { + statusBySeverity: { + terms: { + field: 'kibana.alert.severity', + }, + }, + }, + }, + }, +}); + +export const parseAlertsData = ( + response: AlertsByStatusResponse<{}, AlertsByStatusAgg> +): ParsedAlertsData => { + const statusBuckets = response?.aggregations?.alertsByStatus?.buckets ?? []; + + if (statusBuckets.length === 0) { + return null; + } + + return statusBuckets.reduce((parsedAlertsData, statusBucket) => { + const severityBuckets = statusBucket.statusBySeverity?.buckets ?? []; + + return { + ...parsedAlertsData, + [statusBucket.key]: { + total: statusBucket.doc_count, + severities: severityBuckets.map((severityBucket) => ({ + key: severityBucket.key, + value: severityBucket.doc_count, + label: severityLabels[severityBucket.key], + })), + }, + }; + }, {}); +}; + +export interface UseAlertsByStatusProps { + queryId: string; + signalIndexName: string | null; + skip?: boolean; +} + +export type UseAlertsByStatus = (props: UseAlertsByStatusProps) => { + items: ParsedAlertsData; + isLoading: boolean; + updatedAt: number; +}; + +export const useAlertsByStatus: UseAlertsByStatus = ({ + queryId, + signalIndexName, + skip = false, +}) => { + const { to, from, deleteQuery, setQuery } = useGlobalTime(); + const [updatedAt, setUpdatedAt] = useState(Date.now()); + const [items, setItems] = useState(null); + + const { + data, + loading: isLoading, + refetch: refetchQuery, + request, + response, + setQuery: setAlertsQuery, + } = useQueryAlerts<{}, AlertsByStatusAgg>({ + query: getAlertsByStatusQuery({ + from, + to, + }), + indexName: signalIndexName, + skip, + }); + + useEffect(() => { + setAlertsQuery( + getAlertsByStatusQuery({ + from, + to, + }) + ); + }, [setAlertsQuery, from, to]); + + useEffect(() => { + if (data == null) { + setItems(null); + } else { + setItems(parseAlertsData(data)); + } + setUpdatedAt(Date.now()); + }, [data]); + + const refetch = useCallback(() => { + if (!skip && refetchQuery) { + refetchQuery(); + } + }, [skip, refetchQuery]); + + useQueryInspector({ + deleteQuery, + inspect: { + dsl: [request], + response: [response], + }, + refetch, + setQuery, + queryId, + loading: isLoading, + }); + + return { items, isLoading, updatedAt }; +}; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/cases_by_status.test.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/cases_by_status.test.tsx new file mode 100644 index 0000000000000..18ac775dc5792 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/cases_by_status.test.tsx @@ -0,0 +1,92 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { render, screen } from '@testing-library/react'; +import React from 'react'; +import { BarChartComponentProps } from '../../../../common/components/charts/barchart'; +import { useQueryToggle } from '../../../../common/containers/query_toggle'; +import { TestProviders } from '../../../../common/mock'; +import { CasesByStatus } from './cases_by_status'; +jest.mock('../../../../common/components/link_to'); +jest.mock('../../../../common/containers/query_toggle'); +jest.mock('./use_cases_by_status', () => ({ + useCasesByStatus: jest.fn().mockReturnValue({ + closed: 1, + inProgress: 2, + isLoading: false, + open: 3, + totalCounts: 6, + updatedAt: new Date('2022-04-08T12:00:00.000Z').valueOf(), + }), +})); +jest.mock('../../../../common/lib/kibana', () => { + const actual = jest.requireActual('../../../../common/lib/kibana'); + return { + ...actual, + useNavigation: jest.fn().mockReturnValue({ + getAppUrl: jest.fn(), + navigateTo: jest.fn(), + }), + }; +}); +jest.mock('../../../../common/components/charts/barchart', () => ({ + BarChart: jest.fn((props: BarChartComponentProps) =>
), +})); + +const mockSetToggle = jest.fn(); +(useQueryToggle as jest.Mock).mockReturnValue({ + toggleStatus: true, + setToggleStatus: mockSetToggle, +}); + +describe('CasesByStatus', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + test('renders title', () => { + render( + + + + ); + expect(screen.getByTestId('header-section-title')).toHaveTextContent('Cases'); + }); + + test('renders toggleQuery', () => { + render( + + + + ); + expect(screen.getByTestId('query-toggle-header')).toBeInTheDocument(); + }); + + test('renders BarChart', () => { + render( + + + + ); + expect(screen.getByTestId('chart-wrapper')).toBeInTheDocument(); + expect(screen.queryByTestId('bar-chart-mask')).not.toBeInTheDocument(); + }); + + test('collapses content', () => { + (useQueryToggle as jest.Mock).mockReturnValueOnce({ + toggleStatus: false, + setToggleStatus: mockSetToggle, + }); + render( + + + + ); + + expect(screen.queryByTestId('chart-wrapper')).not.toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/cases_by_status.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/cases_by_status.tsx new file mode 100644 index 0000000000000..13a2459b44d68 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/cases_by_status.tsx @@ -0,0 +1,200 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useMemo } from 'react'; +import { EuiFlexGroup, EuiFlexItem, EuiLink, EuiPanel, EuiText } from '@elastic/eui'; +import { AxisStyle, Rotation, ScaleType } from '@elastic/charts'; +import styled from 'styled-components'; +import { FormattedNumber } from '@kbn/i18n-react'; +import numeral from '@elastic/numeral'; +import { BarChart } from '../../../../common/components/charts/barchart'; +import { LastUpdatedAt } from '../util'; +import { useQueryToggle } from '../../../../common/containers/query_toggle'; +import { HeaderSection } from '../../../../common/components/header_section'; +import { + CASES, + CASES_BY_STATUS_SECTION_TITLE, + STATUS_CLOSED, + STATUS_IN_PROGRESS, + STATUS_OPEN, + VIEW_CASES, +} from '../translations'; +import { LinkButton } from '../../../../common/components/links'; +import { useCasesByStatus } from './use_cases_by_status'; +import { SecurityPageName } from '../../../../../common/constants'; +import { useFormatUrl } from '../../../../common/components/link_to'; +import { appendSearch } from '../../../../common/components/link_to/helpers'; +import { useNavigation } from '../../../../common/lib/kibana'; + +const CASES_BY_STATUS_ID = 'casesByStatus'; + +export const numberFormatter = (value: string | number): string => value.toLocaleString(); + +export const barchartConfigs = { + series: { + xScaleType: ScaleType.Ordinal, + yScaleType: ScaleType.Linear, + stackAccessors: ['g'], + barSeriesStyle: { + rect: { + widthPixel: 22, + opacity: 1, + }, + }, + }, + axis: { + xTickFormatter: numberFormatter, + left: { + style: { + tickLine: { + size: 0, + }, + tickLabel: { + padding: 16, + fontSize: 14, + }, + } as Partial, + }, + bottom: { + style: { + tickLine: { + size: 0, + }, + tickLabel: { + padding: 16, + fontSize: 10.5, + }, + } as Partial, + labelFormat: (d: unknown) => numeral(d).format('0'), + }, + }, + settings: { + rotation: 90 as Rotation, + }, + customHeight: 146, +}; + +const barColors = { + empty: 'rgba(105, 112, 125, 0.1)', + open: '#79aad9', + 'in-progress': '#f1d86f', + closed: '#d3dae6', +}; + +export const emptyChartSettings = [ + { + key: 'open', + value: [{ y: 20, x: STATUS_OPEN, g: STATUS_OPEN }], + color: barColors.empty, + }, + { + key: 'in-progress', + value: [{ y: 20, x: STATUS_IN_PROGRESS, g: STATUS_IN_PROGRESS }], + color: barColors.empty, + }, + { + key: 'closed', + value: [{ y: 20, x: STATUS_CLOSED, g: STATUS_CLOSED }], + color: barColors.empty, + }, +]; + +const StyledEuiFlexItem = styled(EuiFlexItem)` + align-items: center; + width: 70%; +`; + +const Wrapper = styled.div` + width: 100%; +`; + +const CasesByStatusComponent: React.FC = () => { + const { toggleStatus, setToggleStatus } = useQueryToggle(CASES_BY_STATUS_ID); + const { getAppUrl, navigateTo } = useNavigation(); + const { search } = useFormatUrl(SecurityPageName.case); + const caseUrl = getAppUrl({ deepLinkId: SecurityPageName.case, path: appendSearch(search) }); + + const goToCases = useCallback( + (ev) => { + ev.preventDefault(); + navigateTo({ url: caseUrl }); + }, + [caseUrl, navigateTo] + ); + const { closed, inProgress, isLoading, open, totalCounts, updatedAt } = useCasesByStatus({ + skip: !toggleStatus, + }); + + const chartData = useMemo( + () => [ + { + key: 'open', + value: [{ y: open, x: STATUS_OPEN, g: STATUS_OPEN }], + color: barColors.open, + }, + { + key: 'in-progress', + value: [{ y: inProgress, x: STATUS_IN_PROGRESS, g: STATUS_IN_PROGRESS }], + color: barColors['in-progress'], + }, + { + key: 'closed', + value: [{ y: closed, x: STATUS_CLOSED, g: STATUS_CLOSED }], + color: barColors.closed, + }, + ], + [closed, inProgress, open] + ); + + return ( + + } + showInspectButton={false} + > + + + + {VIEW_CASES} + + + + + {!isLoading && toggleStatus && ( + + + {totalCounts !== 0 && ( + + <> + + + + <> + + {CASES(totalCounts)} + + + + )} + + + + + + + + )} + + ); +}; + +export const CasesByStatus = React.memo(CasesByStatusComponent); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/index.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/index.tsx new file mode 100644 index 0000000000000..4e1aceb20f4ed --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/index.tsx @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { CasesByStatus } from './cases_by_status'; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/use_cases_by_status.test.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/use_cases_by_status.test.tsx new file mode 100644 index 0000000000000..eb5daeeb374c2 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/use_cases_by_status.test.tsx @@ -0,0 +1,123 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { renderHook, act } from '@testing-library/react-hooks'; +import { mockCasesContract } from '@kbn/cases-plugin/public/mocks'; +import { useKibana } from '../../../../common/lib/kibana'; +import { TestProviders } from '../../../../common/mock'; +import { + useCasesByStatus, + UseCasesByStatusProps, + UseCasesByStatusResults, +} from './use_cases_by_status'; + +const dateNow = new Date('2022-04-08T12:00:00.000Z').valueOf(); +const mockDateNow = jest.fn().mockReturnValue(dateNow); +Date.now = jest.fn(() => mockDateNow()) as unknown as DateConstructor['now']; + +jest.mock('../../../../common/containers/use_global_time', () => { + return { + useGlobalTime: jest + .fn() + .mockReturnValue({ from: '2022-04-05T12:00:00.000Z', to: '2022-04-08T12:00:00.000Z' }), + }; +}); +jest.mock('../../../../common/lib/kibana'); + +const mockGetAllCasesMetrics = jest.fn(); +mockGetAllCasesMetrics.mockResolvedValue({ + count_open_cases: 1, + count_in_progress_cases: 2, + count_closed_cases: 3, +}); +mockGetAllCasesMetrics.mockResolvedValueOnce({ + count_open_cases: 0, + count_in_progress_cases: 0, + count_closed_cases: 0, +}); + +const mockUseKibana = { + services: { + cases: { + ...mockCasesContract(), + api: { + cases: { + getAllCasesMetrics: mockGetAllCasesMetrics, + }, + }, + }, + }, +}; + +(useKibana as jest.Mock).mockReturnValue(mockUseKibana); + +describe('useCasesByStatus', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + test('init', async () => { + await act(async () => { + const { result, waitForNextUpdate } = renderHook< + UseCasesByStatusProps, + UseCasesByStatusResults + >(() => useCasesByStatus({ skip: false }), { + wrapper: TestProviders, + }); + await waitForNextUpdate(); + expect(result.current).toEqual({ + closed: 0, + inProgress: 0, + isLoading: true, + open: 0, + totalCounts: 0, + updatedAt: dateNow, + }); + }); + }); + + test('fetch data', async () => { + await act(async () => { + const { result, waitForNextUpdate } = renderHook< + UseCasesByStatusProps, + UseCasesByStatusResults + >(() => useCasesByStatus({ skip: false }), { + wrapper: TestProviders, + }); + await waitForNextUpdate(); + await waitForNextUpdate(); + expect(result.current).toEqual({ + closed: 3, + inProgress: 2, + isLoading: false, + open: 1, + totalCounts: 6, + updatedAt: dateNow, + }); + }); + }); + + test('skip', async () => { + const abortSpy = jest.spyOn(AbortController.prototype, 'abort'); + await act(async () => { + const localProps = { skip: false }; + + const { rerender, waitForNextUpdate } = renderHook< + UseCasesByStatusProps, + UseCasesByStatusResults + >(() => useCasesByStatus(localProps), { + wrapper: TestProviders, + }); + await waitForNextUpdate(); + await waitForNextUpdate(); + + localProps.skip = true; + act(() => rerender()); + act(() => rerender()); + expect(abortSpy).toHaveBeenCalledTimes(2); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/use_cases_by_status.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/use_cases_by_status.tsx new file mode 100644 index 0000000000000..813fcaa848115 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/use_cases_by_status.tsx @@ -0,0 +1,93 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useState, useEffect } from 'react'; +import { APP_ID } from '../../../../../common/constants'; +import { useGlobalTime } from '../../../../common/containers/use_global_time'; +import { useKibana } from '../../../../common/lib/kibana'; + +export interface CasesCounts { + count_open_cases?: number; + count_in_progress_cases?: number; + count_closed_cases?: number; +} + +export interface UseCasesByStatusProps { + skip?: boolean; +} + +export interface UseCasesByStatusResults { + closed: number; + inProgress: number; + isLoading: boolean; + open: number; + totalCounts: number; + updatedAt: number; +} + +export const useCasesByStatus = ({ skip = false }) => { + const { + services: { cases }, + } = useKibana(); + const { to, from } = useGlobalTime(); + + const [updatedAt, setUpdatedAt] = useState(Date.now()); + const [isLoading, setIsLoading] = useState(true); + const [casesCounts, setCasesCounts] = useState(null); + + useEffect(() => { + let isSubscribed = true; + const abortCtrl = new AbortController(); + const fetchCases = async () => { + try { + const casesResponse = await cases.api.cases.getAllCasesMetrics({ + from, + to, + owner: APP_ID, + }); + if (isSubscribed) { + setCasesCounts(casesResponse); + } + } catch (error) { + if (isSubscribed) { + setCasesCounts({}); + } + } + if (isSubscribed) { + setIsLoading(false); + setUpdatedAt(Date.now()); + } + }; + + if (!skip) { + fetchCases(); + } + + if (skip) { + setIsLoading(false); + isSubscribed = false; + abortCtrl.abort(); + } + + return () => { + isSubscribed = false; + abortCtrl.abort(); + }; + }, [cases.api.cases, from, skip, to]); + + return { + closed: casesCounts?.count_closed_cases ?? 0, + inProgress: casesCounts?.count_in_progress_cases ?? 0, + isLoading, + open: casesCounts?.count_open_cases ?? 0, + totalCounts: + (casesCounts?.count_closed_cases ?? 0) + + (casesCounts?.count_in_progress_cases ?? 0) + + (casesCounts?.count_open_cases ?? 0), + updatedAt, + }; +}; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/host_alerts_table.test.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/host_alerts_table.test.tsx new file mode 100644 index 0000000000000..4294f23f796bd --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/host_alerts_table.test.tsx @@ -0,0 +1,103 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { render } from '@testing-library/react'; + +import { TestProviders } from '../../../../common/mock'; +import { parsedVulnerableHostsAlertsResult } from './mock_data'; +import { UseHostAlertsItems } from './use_host_alerts_items'; +import { HostAlertsTable } from './host_alerts_table'; + +const mockGetAppUrl = jest.fn(); +jest.mock('../../../../common/lib/kibana/hooks', () => { + const original = jest.requireActual('../../../../common/lib/kibana/hooks'); + return { + ...original, + useNavigation: () => ({ + getAppUrl: mockGetAppUrl, + }), + }; +}); + +type UseHostAlertsItemsReturn = ReturnType; +const defaultUseHostAlertsItemsReturn: UseHostAlertsItemsReturn = { + items: [], + isLoading: false, + updatedAt: Date.now(), +}; +const mockUseHostAlertsItems = jest.fn(() => defaultUseHostAlertsItemsReturn); +const mockUseHostAlertsItemsReturn = (overrides: Partial) => { + mockUseHostAlertsItems.mockReturnValueOnce({ ...defaultUseHostAlertsItemsReturn, ...overrides }); +}; + +jest.mock('./use_host_alerts_items', () => ({ + useHostAlertsItems: () => mockUseHostAlertsItems(), +})); + +const renderComponent = () => + render( + + + + ); + +describe('HostAlertsTable', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should render empty table', () => { + const { getByText, getByTestId } = renderComponent(); + + expect(getByTestId('severityHostAlertsPanel')).toBeInTheDocument(); + expect(getByText('No alerts to display')).toBeInTheDocument(); + expect(getByTestId('severityHostAlertsButton')).toBeInTheDocument(); + }); + + it('should render a loading table', () => { + mockUseHostAlertsItemsReturn({ isLoading: true }); + const { getByText, getByTestId } = renderComponent(); + + expect(getByText('Updating...')).toBeInTheDocument(); + expect(getByTestId('severityHostAlertsButton')).toBeInTheDocument(); + expect(getByTestId('severityHostAlertsTable')).toHaveClass('euiBasicTable-loading'); + }); + + it('should render the updated at subtitle', () => { + mockUseHostAlertsItemsReturn({ isLoading: false }); + const { getByText } = renderComponent(); + + expect(getByText('Updated now')).toBeInTheDocument(); + }); + + it('should render the table columns', () => { + mockUseHostAlertsItemsReturn({ items: parsedVulnerableHostsAlertsResult }); + const { getAllByRole } = renderComponent(); + + const columnHeaders = getAllByRole('columnheader'); + expect(columnHeaders.at(0)).toHaveTextContent('Host name'); + expect(columnHeaders.at(1)).toHaveTextContent('Alerts'); + expect(columnHeaders.at(2)).toHaveTextContent('Critical'); + expect(columnHeaders.at(3)).toHaveTextContent('High'); + expect(columnHeaders.at(4)).toHaveTextContent('Medium'); + expect(columnHeaders.at(5)).toHaveTextContent('Low'); + }); + + it('should render the table items', () => { + mockUseHostAlertsItemsReturn({ items: [parsedVulnerableHostsAlertsResult[0]] }); + const { getByTestId } = renderComponent(); + + expect(getByTestId('hostSeverityAlertsTable-hostName')).toHaveTextContent('Host-342m5gl1g2'); + expect(getByTestId('hostSeverityAlertsTable-totalAlerts')).toHaveTextContent('100'); + expect(getByTestId('hostSeverityAlertsTable-critical')).toHaveTextContent('5'); + expect(getByTestId('hostSeverityAlertsTable-high')).toHaveTextContent('50'); + expect(getByTestId('hostSeverityAlertsTable-medium')).toHaveTextContent('5'); + expect(getByTestId('hostSeverityAlertsTable-low')).toHaveTextContent('40'); + }); +}); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/host_alerts_table.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/host_alerts_table.tsx new file mode 100644 index 0000000000000..4fe5bf7785bc7 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/host_alerts_table.tsx @@ -0,0 +1,150 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useMemo } from 'react'; + +import { + EuiBasicTable, + EuiBasicTableColumn, + EuiButton, + EuiEmptyPrompt, + EuiHealth, + EuiPanel, + EuiSpacer, +} from '@elastic/eui'; + +import { SecurityPageName } from '../../../../app/types'; +import { FormattedCount } from '../../../../common/components/formatted_number'; +import { HeaderSection } from '../../../../common/components/header_section'; +import { HoverVisibilityContainer } from '../../../../common/components/hover_visibility_container'; +import { BUTTON_CLASS as INPECT_BUTTON_CLASS } from '../../../../common/components/inspect'; +import { HostDetailsLink } from '../../../../common/components/links'; +import { useQueryToggle } from '../../../../common/containers/query_toggle'; +import { useNavigation, NavigateTo, GetAppUrl } from '../../../../common/lib/kibana'; +import * as i18n from '../translations'; +import { LastUpdatedAt, SEVERITY_COLOR } from '../util'; +import { HostAlertsItem, useHostAlertsItems } from './use_host_alerts_items'; + +type GetTableColumns = (params: { + getAppUrl: GetAppUrl; + navigateTo: NavigateTo; +}) => Array>; + +interface HostAlertsTableProps { + signalIndexName: string | null; +} + +const DETECTION_RESPONSE_HOST_SEVERITY_QUERY_ID = 'vulnerableHostsBySeverityQuery'; + +export const HostAlertsTable = React.memo(({ signalIndexName }: HostAlertsTableProps) => { + const { getAppUrl, navigateTo } = useNavigation(); + const { toggleStatus, setToggleStatus } = useQueryToggle( + DETECTION_RESPONSE_HOST_SEVERITY_QUERY_ID + ); + + const { items, isLoading, updatedAt } = useHostAlertsItems({ + skip: !toggleStatus, + queryId: DETECTION_RESPONSE_HOST_SEVERITY_QUERY_ID, + signalIndexName, + }); + + const navigateToHosts = useCallback(() => { + navigateTo({ deepLinkId: SecurityPageName.hosts }); + }, [navigateTo]); + + const columns = useMemo( + () => getTableColumns({ getAppUrl, navigateTo }), + [getAppUrl, navigateTo] + ); + + return ( + + + } + titleSize="s" + toggleQuery={setToggleStatus} + toggleStatus={toggleStatus} + /> + {toggleStatus && ( + <> + {i18n.NO_ALERTS_FOUND}} titleSize="xs" /> + } + /> + + + {i18n.VIEW_ALL_HOST_ALERTS} + + + )} + + + ); +}); + +HostAlertsTable.displayName = 'HostAlertsTable'; + +const getTableColumns: GetTableColumns = ({ getAppUrl, navigateTo }) => [ + { + field: 'hostName', + name: i18n.HOST_ALERTS_HOSTNAME_COLUMN, + truncateText: true, + textOnly: true, + 'data-test-subj': 'hostSeverityAlertsTable-hostName', + render: (hostName: string) => , + }, + { + field: 'totalAlerts', + name: i18n.ALERTS_TEXT, + 'data-test-subj': 'hostSeverityAlertsTable-totalAlerts', + render: (totalAlerts: number) => , + }, + { + field: 'critical', + name: i18n.STATUS_CRITICAL_LABEL, + render: (count: number) => ( + + + + ), + }, + { + field: 'high', + name: i18n.STATUS_HIGH_LABEL, + render: (count: number) => ( + + + + ), + }, + { + field: 'medium', + name: i18n.STATUS_MEDIUM_LABEL, + render: (count: number) => ( + + + + ), + }, + { + field: 'low', + name: i18n.STATUS_LOW_LABEL, + render: (count: number) => ( + + + + ), + }, +]; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/index.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/index.ts new file mode 100644 index 0000000000000..62423931bbc4f --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { HostAlertsTable } from './host_alerts_table'; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/mock_data.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/mock_data.ts new file mode 100644 index 0000000000000..d46d1b5401a9e --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/mock_data.ts @@ -0,0 +1,125 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { buildVulnerableHostAggregationQuery } from './use_host_alerts_items'; + +export const mockVulnerableHostsBySeverityResult = { + aggregations: { + hostsBySeverity: { + buckets: [ + { + key: 'Host-342m5gl1g2', + doc_count: 100, + high: { + doc_count: 50, + }, + critical: { + doc_count: 5, + }, + low: { + doc_count: 40, + }, + medium: { + doc_count: 5, + }, + }, + { + key: 'Host-vns3hyykhu', + doc_count: 104, + high: { + doc_count: 100, + }, + critical: { + doc_count: 4, + }, + low: { + doc_count: 0, + }, + medium: { + doc_count: 0, + }, + }, + { + key: 'Host-awafztonav', + doc_count: 108, + high: { + doc_count: 50, + }, + critical: { + doc_count: 4, + }, + low: { + doc_count: 50, + }, + medium: { + doc_count: 4, + }, + }, + { + key: 'Host-56k7zf5kne', + doc_count: 128, + high: { + doc_count: 6, + }, + critical: { + doc_count: 1, + }, + low: { + doc_count: 59, + }, + medium: { + doc_count: 62, + }, + }, + ], + }, + }, +}; + +export const parsedVulnerableHostsAlertsResult = [ + { + hostName: 'Host-342m5gl1g2', + totalAlerts: 100, + critical: 5, + high: 50, + low: 40, + medium: 5, + }, + { + hostName: 'Host-vns3hyykhu', + totalAlerts: 104, + critical: 4, + high: 100, + low: 0, + medium: 0, + }, + { + hostName: 'Host-awafztonav', + totalAlerts: 108, + critical: 4, + high: 50, + low: 50, + medium: 4, + }, + { + hostName: 'Host-56k7zf5kne', + totalAlerts: 128, + critical: 1, + high: 6, + low: 59, + medium: 62, + }, +]; + +export const mockQuery = () => ({ + query: buildVulnerableHostAggregationQuery({ + from: '2020-07-07T08:20:18.966Z', + to: '2020-07-08T08:20:18.966Z', + }), + indexName: 'signal-alerts', + skip: false, +}); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/use_host_alerts_items.test.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/use_host_alerts_items.test.ts new file mode 100644 index 0000000000000..42568a390f686 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/use_host_alerts_items.test.ts @@ -0,0 +1,127 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { renderHook } from '@testing-library/react-hooks'; + +import { + mockQuery, + mockVulnerableHostsBySeverityResult, + parsedVulnerableHostsAlertsResult, +} from './mock_data'; +import { useHostAlertsItems } from './use_host_alerts_items'; + +import type { UseHostAlertsItems, UseHostAlertsItemsProps } from './use_host_alerts_items'; + +const signalIndexName = 'signal-alerts'; + +const dateNow = new Date('2022-04-15T12:00:00.000Z').valueOf(); +const mockDateNow = jest.fn().mockReturnValue(dateNow); +Date.now = jest.fn(() => mockDateNow()) as unknown as DateConstructor['now']; + +const defaultUseQueryAlertsReturn = { + loading: false, + data: null, + setQuery: () => {}, + response: '', + request: '', + refetch: () => {}, +}; + +const mockUseQueryAlerts = jest.fn().mockReturnValue(defaultUseQueryAlertsReturn); +jest.mock('../../../../detections/containers/detection_engine/alerts/use_query', () => { + return { + useQueryAlerts: (...props: unknown[]) => mockUseQueryAlerts(...props), + }; +}); + +const from = '2020-07-07T08:20:18.966Z'; +const to = '2020-07-08T08:20:18.966Z'; + +const mockUseGlobalTime = jest + .fn() + .mockReturnValue({ from, to, setQuery: jest.fn(), deleteQuery: jest.fn() }); +jest.mock('../../../../common/containers/use_global_time', () => { + return { + useGlobalTime: (...props: unknown[]) => mockUseGlobalTime(...props), + }; +}); + +const renderUseHostAlertsItems = (overrides: Partial = {}) => + renderHook>(() => + useHostAlertsItems({ + skip: false, + signalIndexName, + queryId: 'testing', + ...overrides, + }) + ); + +describe('useVulnerableHostsCounters', () => { + beforeEach(() => { + jest.clearAllMocks(); + mockDateNow.mockReturnValue(dateNow); + mockUseQueryAlerts.mockReturnValue(defaultUseQueryAlertsReturn); + }); + + it('should return default values', () => { + const { result } = renderUseHostAlertsItems(); + + expect(result.current).toEqual({ + items: [], + isLoading: false, + updatedAt: dateNow, + }); + + expect(mockUseQueryAlerts).toBeCalledWith(mockQuery()); + }); + + it('should return parsed items', () => { + mockUseQueryAlerts.mockReturnValue({ + ...defaultUseQueryAlertsReturn, + data: mockVulnerableHostsBySeverityResult, + }); + + const { result } = renderUseHostAlertsItems(); + + expect(result.current).toEqual({ + items: parsedVulnerableHostsAlertsResult, + isLoading: false, + updatedAt: dateNow, + }); + }); + + it('should return new updatedAt', () => { + const newDateNow = new Date('2022-04-08T14:00:00.000Z').valueOf(); + mockDateNow.mockReturnValue(newDateNow); // setUpdatedAt call + mockDateNow.mockReturnValueOnce(dateNow); // initialization call + + mockUseQueryAlerts.mockReturnValue({ + ...defaultUseQueryAlertsReturn, + data: mockVulnerableHostsBySeverityResult, + }); + + const { result } = renderUseHostAlertsItems(); + expect(mockDateNow).toHaveBeenCalled(); + expect(result.current).toEqual({ + items: parsedVulnerableHostsAlertsResult, + isLoading: false, + updatedAt: newDateNow, + }); + }); + + it('should skip the query', () => { + const { result } = renderUseHostAlertsItems({ skip: true }); + + expect(mockUseQueryAlerts).toBeCalledWith({ ...mockQuery(), skip: true }); + + expect(result.current).toEqual({ + items: [], + isLoading: false, + updatedAt: dateNow, + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/use_host_alerts_items.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/use_host_alerts_items.ts new file mode 100644 index 0000000000000..ebd7af1b49cc2 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/use_host_alerts_items.ts @@ -0,0 +1,203 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useCallback, useEffect, useState } from 'react'; + +import { useQueryInspector } from '../../../../common/components/page/manage_query'; +import { useGlobalTime } from '../../../../common/containers/use_global_time'; +import { GenericBuckets } from '../../../../../common/search_strategy'; +import { useQueryAlerts } from '../../../../detections/containers/detection_engine/alerts/use_query'; + +const HOSTS_BY_SEVERITY_AGG = 'hostsBySeverity'; + +interface TimeRange { + from: string; + to: string; +} + +export interface UseHostAlertsItemsProps { + skip: boolean; + queryId: string; + signalIndexName: string | null; +} +export interface HostAlertsItem { + hostName: string; + totalAlerts: number; + low: number; + medium: number; + high: number; + critical: number; +} + +export type UseHostAlertsItems = (props: UseHostAlertsItemsProps) => { + items: HostAlertsItem[]; + isLoading: boolean; + updatedAt: number; +}; + +export const useHostAlertsItems: UseHostAlertsItems = ({ skip, queryId, signalIndexName }) => { + const [updatedAt, setUpdatedAt] = useState(Date.now()); + const [items, setItems] = useState([]); + + const { to, from, setQuery: setGlobalQuery, deleteQuery } = useGlobalTime(); + + const { + data, + request, + response, + setQuery, + loading, + refetch: refetchQuery, + } = useQueryAlerts<{}, AlertCountersBySeverityAndHostAggregation>({ + query: buildVulnerableHostAggregationQuery({ from, to }), + indexName: signalIndexName, + skip, + }); + + useEffect(() => { + setQuery(buildVulnerableHostAggregationQuery({ from, to })); + }, [setQuery, from, to]); + + useEffect(() => { + if (data == null || !data.aggregations) { + setItems([]); + } else { + setItems(parseHostsData(data.aggregations)); + } + setUpdatedAt(Date.now()); + }, [data]); + + const refetch = useCallback(() => { + if (!skip && refetchQuery) { + refetchQuery(); + } + }, [skip, refetchQuery]); + + useQueryInspector({ + deleteQuery, + inspect: { + dsl: [request], + response: [response], + }, + refetch, + setQuery: setGlobalQuery, + queryId, + loading, + }); + return { items, isLoading: loading, updatedAt }; +}; + +export const buildVulnerableHostAggregationQuery = ({ from, to }: TimeRange) => ({ + query: { + bool: { + filter: [ + { + term: { + 'kibana.alert.workflow_status': 'open', + }, + }, + { + range: { + '@timestamp': { + gte: from, + lte: to, + }, + }, + }, + ], + }, + }, + size: 0, + aggs: { + [HOSTS_BY_SEVERITY_AGG]: { + terms: { + field: 'host.name', + order: [ + { + 'critical.doc_count': 'desc', + }, + { + 'high.doc_count': 'desc', + }, + { + 'medium.doc_count': 'desc', + }, + { + 'low.doc_count': 'desc', + }, + ], + size: 4, + }, + aggs: { + critical: { + filter: { + term: { + 'kibana.alert.severity': 'critical', + }, + }, + }, + high: { + filter: { + term: { + 'kibana.alert.severity': 'high', + }, + }, + }, + medium: { + filter: { + term: { + 'kibana.alert.severity': 'medium', + }, + }, + }, + low: { + filter: { + term: { + 'kibana.alert.severity': 'low', + }, + }, + }, + }, + }, + }, +}); + +interface SeverityContainer { + doc_count: number; +} +interface AlertBySeverityBucketData extends GenericBuckets { + low: SeverityContainer; + medium: SeverityContainer; + high: SeverityContainer; + critical: SeverityContainer; +} + +interface AlertCountersBySeverityAndHostAggregation { + [HOSTS_BY_SEVERITY_AGG]: { + buckets: AlertBySeverityBucketData[]; + }; +} + +function parseHostsData( + rawAggregation: AlertCountersBySeverityAndHostAggregation +): HostAlertsItem[] { + const buckets = rawAggregation?.[HOSTS_BY_SEVERITY_AGG].buckets ?? []; + + return buckets.reduce((accumalatedAlertsByHost, currentHost) => { + return [ + ...accumalatedAlertsByHost, + { + hostName: currentHost.key, + totalAlerts: currentHost.doc_count, + low: currentHost.low.doc_count, + medium: currentHost.medium.doc_count, + high: currentHost.high.doc_count, + critical: currentHost.critical.doc_count, + }, + ]; + }, []); +} diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/index.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/index.ts new file mode 100644 index 0000000000000..8ab93de825305 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { HostAlertsTable } from './host_alerts_table'; +export { UserAlertsTable } from './user_alerts_table'; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/rule_alerts_table.test.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/rule_alerts_table.test.tsx index f41e05a2c04dc..dafd1ca965a3f 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/rule_alerts_table.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/rule_alerts_table.test.tsx @@ -5,13 +5,15 @@ * 2.0. */ +import moment from 'moment'; import React from 'react'; + import { render } from '@testing-library/react'; + +import { SecurityPageName } from '../../../../../common/constants'; import { TestProviders } from '../../../../common/mock'; import { RuleAlertsTable, RuleAlertsTableProps } from './rule_alerts_table'; import { RuleAlertsItem, UseRuleAlertsItems } from './use_rule_alerts_items'; -import moment from 'moment'; -import { SecurityPageName } from '../../../../../common/constants'; const mockGetAppUrl = jest.fn(); jest.mock('../../../../common/lib/kibana/hooks', () => { diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/rule_alerts_table.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/rule_alerts_table.tsx index 7a053fd0366dd..550e04753e886 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/rule_alerts_table.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/rule_alerts_table.tsx @@ -28,6 +28,9 @@ import { useRuleAlertsItems, RuleAlertsItem } from './use_rule_alerts_items'; import { useNavigation, NavigateTo, GetAppUrl } from '../../../../common/lib/kibana'; import { SecurityPageName } from '../../../../../common/constants'; import { useQueryToggle } from '../../../../common/containers/query_toggle'; +import { HoverVisibilityContainer } from '../../../../common/components/hover_visibility_container'; +import { BUTTON_CLASS as INPECT_BUTTON_CLASS } from '../../../../common/components/inspect'; +import { FormattedCount } from '../../../../common/components/formatted_number'; export interface RuleAlertsTableProps { signalIndexName: string | null; @@ -76,6 +79,7 @@ export const getTableColumns: GetTableColumns = ({ getAppUrl, navigateTo }) => [ field: 'alert_count', name: i18n.RULE_ALERTS_COLUMN_ALERT_COUNT, 'data-test-subj': 'severityRuleAlertsTable-alertCount', + render: (alertCount: number) => , }, { field: 'severity', @@ -106,33 +110,35 @@ export const RuleAlertsTable = React.memo(({ signalIndexNa ); return ( - - } - /> - {toggleStatus && ( - <> - {i18n.NO_ALERTS_FOUND}} titleSize="xs" /> - } - /> - - - {i18n.OPEN_ALL_ALERTS_BUTTON} - - - )} - + + + } + /> + {toggleStatus && ( + <> + {i18n.NO_ALERTS_FOUND}} titleSize="xs" /> + } + /> + + + {i18n.OPEN_ALL_ALERTS_BUTTON} + + + )} + + ); }); RuleAlertsTable.displayName = 'RuleAlertsTable'; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/use_rule_alerts_items.test.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/use_rule_alerts_items.test.ts index 85d4c8e5b6a93..264c1cf404219 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/use_rule_alerts_items.test.ts +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/use_rule_alerts_items.test.ts @@ -6,7 +6,7 @@ */ import { renderHook } from '@testing-library/react-hooks'; -import { TestProviders } from '../../../../common/mock'; + import { from, mockSeverityRuleAlertsResponse, @@ -50,16 +50,12 @@ jest.mock('../../../../common/containers/use_global_time', () => { // helper function to render the hook const renderUseRuleAlertsItems = (props: Partial = {}) => - renderHook>( - () => - useRuleAlertsItems({ - queryId: 'test', - signalIndexName: 'signal-alerts', - ...props, - }), - { - wrapper: TestProviders, - } + renderHook>(() => + useRuleAlertsItems({ + queryId: 'test', + signalIndexName: 'signal-alerts', + ...props, + }) ); describe('useRuleAlertsItems', () => { @@ -103,7 +99,6 @@ describe('useRuleAlertsItems', () => { const newDateNow = new Date('2022-04-08T14:00:00.000Z').valueOf(); mockDateNow.mockReturnValue(newDateNow); // setUpdatedAt call mockDateNow.mockReturnValueOnce(dateNow); // initialization call - mockUseQueryAlerts.mockReturnValue({ ...defaultUseQueryAlertsReturn, data: mockSeverityRuleAlertsResponse, diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/translations.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/translations.ts index 81e3bff33545d..8f37c2e641c7a 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/translations.ts +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/translations.ts @@ -7,18 +7,102 @@ import { i18n } from '@kbn/i18n'; +export const STATUS_CRITICAL_LABEL = i18n.translate( + 'xpack.securitySolution.detectionResponse.alertsByStatus.donut.criticalLabel', + { + defaultMessage: 'Critical', + } +); +export const STATUS_HIGH_LABEL = i18n.translate( + 'xpack.securitySolution.detectionResponse.alertsByStatus.donut.highLabel', + { + defaultMessage: 'High', + } +); +export const STATUS_MEDIUM_LABEL = i18n.translate( + 'xpack.securitySolution.detectionResponse.alertsByStatus.donut.mediumLabel', + { + defaultMessage: 'Medium', + } +); +export const STATUS_LOW_LABEL = i18n.translate( + 'xpack.securitySolution.detectionResponse.alertsByStatus.donut.lowLabel', + { + defaultMessage: 'Low', + } +); +export const STATUS_ACKNOWLEDGED = i18n.translate( + 'xpack.securitySolution.detectionResponse.alertsByStatus.status.acknowledged', + { + defaultMessage: 'Acknowledged', + } +); +export const STATUS_OPEN = i18n.translate('xpack.securitySolution.detectionResponse.status.open', { + defaultMessage: 'Open', +}); +export const STATUS_CLOSED = i18n.translate( + 'xpack.securitySolution.detectionResponse.status.closed', + { + defaultMessage: 'Closed', + } +); +export const STATUS_IN_PROGRESS = i18n.translate( + 'xpack.securitySolution.detectionResponse.status.inProgress', + { + defaultMessage: 'In progress', + } +); +export const ALERTS = (totalAlerts: number) => + i18n.translate('xpack.securitySolution.detectionResponse.alertsByStatus.totalAlerts', { + values: { totalAlerts }, + defaultMessage: 'total {totalAlerts, plural, =1 {alert} other {alerts}}', + }); +export const ALERTS_TEXT = i18n.translate('xpack.securitySolution.detectionResponse.alerts', { + defaultMessage: 'Alerts', +}); export const UPDATING = i18n.translate('xpack.securitySolution.detectionResponse.updating', { defaultMessage: 'Updating...', }); export const UPDATED = i18n.translate('xpack.securitySolution.detectionResponse.updated', { defaultMessage: 'Updated', }); +export const CASES = (totalCases: number) => + i18n.translate('xpack.securitySolution.detectionResponse.casesByStatus.totalCases', { + values: { totalCases }, + defaultMessage: 'total {totalCases, plural, =1 {case} other {cases}}', + }); +export const CASES_BY_STATUS_SECTION_TITLE = i18n.translate( + 'xpack.securitySolution.detectionResponse.casesByStatusSectionTitle', + { + defaultMessage: 'Cases', + } +); + +export const VIEW_CASES = i18n.translate('xpack.securitySolution.detectionResponse.viewCases', { + defaultMessage: 'View cases', +}); + export const RULE_ALERTS_SECTION_TITLE = i18n.translate( 'xpack.securitySolution.detectionResponse.ruleAlertsSectionTitle', { defaultMessage: 'Open alerts by rule', } ); + +export const HOST_ALERTS_SECTION_TITLE = i18n.translate( + 'xpack.securitySolution.detectionResponse.hostAlertsSectionTitle', + { + defaultMessage: 'Vulnerable hosts by severity', + } +); + +export const USER_ALERTS_SECTION_TITLE = i18n.translate( + 'xpack.securitySolution.detectionResponse.userAlertsSectionTitle', + { + defaultMessage: 'Vulnerable users by severity', + } +); + export const NO_ALERTS_FOUND = i18n.translate( 'xpack.securitySolution.detectionResponse.noRuleAlerts', { @@ -68,3 +152,31 @@ export const OPEN_ALL_ALERTS_BUTTON = i18n.translate( defaultMessage: 'View all open alerts', } ); + +export const VIEW_ALL_USER_ALERTS = i18n.translate( + 'xpack.securitySolution.detectionResponse.viewAllUserAlerts', + { + defaultMessage: 'View all other user alerts', + } +); + +export const VIEW_ALL_HOST_ALERTS = i18n.translate( + 'xpack.securitySolution.detectionResponse.viewAllHostAlerts', + { + defaultMessage: 'View all other host alerts', + } +); + +export const HOST_ALERTS_HOSTNAME_COLUMN = i18n.translate( + 'xpack.securitySolution.detectionResponse.hostAlertsHostName', + { + defaultMessage: 'Host name', + } +); + +export const USER_ALERTS_USERNAME_COLUMN = i18n.translate( + 'xpack.securitySolution.detectionResponse.userAlertsUserName', + { + defaultMessage: 'User name', + } +); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/index.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/index.ts new file mode 100644 index 0000000000000..b14cd15e55f18 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { UserAlertsTable } from './user_alerts_table'; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/mock_data.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/mock_data.ts new file mode 100644 index 0000000000000..e10bf1b05f032 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/mock_data.ts @@ -0,0 +1,125 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { buildVulnerableUserAggregationQuery } from './use_user_alerts_items'; + +export const mockVulnerableUsersBySeverityResult = { + aggregations: { + usersBySeverity: { + buckets: [ + { + key: 'crffn20qcs', + doc_count: 4, + high: { + doc_count: 1, + }, + critical: { + doc_count: 4, + }, + low: { + doc_count: 1, + }, + medium: { + doc_count: 1, + }, + }, + { + key: 'd058hziijl', + doc_count: 4, + high: { + doc_count: 11, + }, + critical: { + doc_count: 1, + }, + low: { + doc_count: 1, + }, + medium: { + doc_count: 1, + }, + }, + { + key: 'nenha4bdhv', + doc_count: 4, + high: { + doc_count: 1, + }, + critical: { + doc_count: 1, + }, + low: { + doc_count: 3, + }, + medium: { + doc_count: 3, + }, + }, + { + key: 'u68nq414uw', + doc_count: 2, + high: { + doc_count: 1, + }, + critical: { + doc_count: 0, + }, + low: { + doc_count: 10, + }, + medium: { + doc_count: 0, + }, + }, + ], + }, + }, +}; + +export const parsedVulnerableUserAlertsResult = [ + { + totalAlerts: 4, + critical: 4, + high: 1, + userName: 'crffn20qcs', + low: 1, + medium: 1, + }, + { + totalAlerts: 4, + critical: 1, + high: 11, + userName: 'd058hziijl', + low: 1, + medium: 1, + }, + { + totalAlerts: 4, + critical: 1, + high: 1, + userName: 'nenha4bdhv', + low: 3, + medium: 3, + }, + { + totalAlerts: 2, + critical: 0, + high: 1, + userName: 'u68nq414uw', + low: 10, + medium: 0, + }, +]; + +export const mockQuery = () => ({ + query: buildVulnerableUserAggregationQuery({ + from: '2020-07-07T08:20:18.966Z', + to: '2020-07-08T08:20:18.966Z', + }), + indexName: 'signal-alerts', + skip: false, +}); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/use_user_alerts_items.test.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/use_user_alerts_items.test.ts new file mode 100644 index 0000000000000..22ade5d3341c7 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/use_user_alerts_items.test.ts @@ -0,0 +1,126 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { renderHook } from '@testing-library/react-hooks'; + +import { + mockQuery, + mockVulnerableUsersBySeverityResult, + parsedVulnerableUserAlertsResult, +} from './mock_data'; +import { useUserAlertsItems } from './use_user_alerts_items'; + +import type { UseUserAlertsItems, UseUserAlertsItemsProps } from './use_user_alerts_items'; + +const signalIndexName = 'signal-alerts'; + +const dateNow = new Date('2022-04-08T12:00:00.000Z').valueOf(); +const mockDateNow = jest.fn().mockReturnValue(dateNow); +Date.now = jest.fn(() => mockDateNow()) as unknown as DateConstructor['now']; + +const defaultUseQueryAlertsReturn = { + loading: false, + data: null, + setQuery: () => {}, + response: '', + request: '', + refetch: () => {}, +}; +const mockUseQueryAlerts = jest.fn().mockReturnValue(defaultUseQueryAlertsReturn); +jest.mock('../../../../detections/containers/detection_engine/alerts/use_query', () => { + return { + useQueryAlerts: (...props: unknown[]) => mockUseQueryAlerts(...props), + }; +}); + +const from = '2020-07-07T08:20:18.966Z'; +const to = '2020-07-08T08:20:18.966Z'; + +const mockUseGlobalTime = jest + .fn() + .mockReturnValue({ from, to, setQuery: jest.fn(), deleteQuery: jest.fn() }); +jest.mock('../../../../common/containers/use_global_time', () => { + return { + useGlobalTime: (...props: unknown[]) => mockUseGlobalTime(...props), + }; +}); + +const renderUseUserAlertsItems = (overrides: Partial = {}) => + renderHook>(() => + useUserAlertsItems({ + skip: false, + signalIndexName, + queryId: 'testing', + ...overrides, + }) + ); + +describe('useUserAlertsItems', () => { + beforeEach(() => { + jest.clearAllMocks(); + mockDateNow.mockReturnValue(dateNow); + mockUseQueryAlerts.mockReturnValue(defaultUseQueryAlertsReturn); + }); + + it('should return default values', () => { + const { result } = renderUseUserAlertsItems(); + + expect(result.current).toEqual({ + items: [], + isLoading: false, + updatedAt: dateNow, + }); + + expect(mockUseQueryAlerts).toBeCalledWith(mockQuery()); + }); + + it('should return parsed items', () => { + mockUseQueryAlerts.mockReturnValue({ + ...defaultUseQueryAlertsReturn, + data: mockVulnerableUsersBySeverityResult, + }); + + const { result } = renderUseUserAlertsItems(); + + expect(result.current).toEqual({ + items: parsedVulnerableUserAlertsResult, + isLoading: false, + updatedAt: dateNow, + }); + }); + + it('should return new updatedAt', () => { + const newDateNow = new Date('2022-04-08T14:00:00.000Z').valueOf(); + mockDateNow.mockReturnValue(newDateNow); // setUpdatedAt call + mockDateNow.mockReturnValueOnce(dateNow); // initialization call + + mockUseQueryAlerts.mockReturnValue({ + ...defaultUseQueryAlertsReturn, + data: mockVulnerableUsersBySeverityResult, + }); + + const { result } = renderUseUserAlertsItems(); + expect(mockDateNow).toHaveBeenCalled(); + expect(result.current).toEqual({ + items: parsedVulnerableUserAlertsResult, + isLoading: false, + updatedAt: newDateNow, + }); + }); + + it('should skip the query', () => { + const { result } = renderUseUserAlertsItems({ skip: true }); + + expect(mockUseQueryAlerts).toBeCalledWith({ ...mockQuery(), skip: true }); + + expect(result.current).toEqual({ + items: [], + isLoading: false, + updatedAt: dateNow, + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/use_user_alerts_items.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/use_user_alerts_items.ts new file mode 100644 index 0000000000000..e86ee2f2aef95 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/use_user_alerts_items.ts @@ -0,0 +1,202 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useCallback, useEffect, useState } from 'react'; + +import { useQueryInspector } from '../../../../common/components/page/manage_query'; +import { useGlobalTime } from '../../../../common/containers/use_global_time'; +import { GenericBuckets } from '../../../../../common/search_strategy'; +import { useQueryAlerts } from '../../../../detections/containers/detection_engine/alerts/use_query'; + +const USERS_BY_SEVERITY_AGG = 'usersBySeverity'; + +interface TimeRange { + from: string; + to: string; +} + +export interface UseUserAlertsItemsProps { + skip: boolean; + queryId: string; + signalIndexName: string | null; +} + +export interface UserAlertsItem { + userName: string; + totalAlerts: number; + low: number; + medium: number; + high: number; + critical: number; +} + +export type UseUserAlertsItems = (props: UseUserAlertsItemsProps) => { + items: UserAlertsItem[]; + isLoading: boolean; + updatedAt: number; +}; + +export const useUserAlertsItems: UseUserAlertsItems = ({ skip, queryId, signalIndexName }) => { + const [updatedAt, setUpdatedAt] = useState(Date.now()); + const [items, setItems] = useState([]); + + const { to, from, setQuery: setGlobalQuery, deleteQuery } = useGlobalTime(); + + const { + setQuery, + data, + loading, + request, + response, + refetch: refetchQuery, + } = useQueryAlerts<{}, AlertCountersBySeverityAggregation>({ + query: buildVulnerableUserAggregationQuery({ from, to }), + indexName: signalIndexName, + skip, + }); + + useEffect(() => { + setQuery(buildVulnerableUserAggregationQuery({ from, to })); + }, [setQuery, from, to]); + + useEffect(() => { + if (data == null || !data.aggregations) { + setItems([]); + } else { + setItems(parseUsersData(data.aggregations)); + } + setUpdatedAt(Date.now()); + }, [data]); + + const refetch = useCallback(() => { + if (!skip && refetchQuery) { + refetchQuery(); + } + }, [skip, refetchQuery]); + + useQueryInspector({ + deleteQuery, + inspect: { + dsl: [request], + response: [response], + }, + refetch, + setQuery: setGlobalQuery, + queryId, + loading, + }); + return { items, isLoading: loading, updatedAt }; +}; + +export const buildVulnerableUserAggregationQuery = ({ from, to }: TimeRange) => ({ + query: { + bool: { + filter: [ + { + term: { + 'kibana.alert.workflow_status': 'open', + }, + }, + { + range: { + '@timestamp': { + gte: from, + lte: to, + }, + }, + }, + ], + }, + }, + size: 0, + aggs: { + [USERS_BY_SEVERITY_AGG]: { + terms: { + field: 'user.name', + order: [ + { + 'critical.doc_count': 'desc', + }, + { + 'high.doc_count': 'desc', + }, + { + 'medium.doc_count': 'desc', + }, + { + 'low.doc_count': 'desc', + }, + ], + size: 4, + }, + aggs: { + critical: { + filter: { + term: { + 'kibana.alert.severity': 'critical', + }, + }, + }, + high: { + filter: { + term: { + 'kibana.alert.severity': 'high', + }, + }, + }, + medium: { + filter: { + term: { + 'kibana.alert.severity': 'medium', + }, + }, + }, + low: { + filter: { + term: { + 'kibana.alert.severity': 'low', + }, + }, + }, + }, + }, + }, +}); + +interface SeverityContainer { + doc_count: number; +} +interface AlertBySeverityBucketData extends GenericBuckets { + low: SeverityContainer; + medium: SeverityContainer; + high: SeverityContainer; + critical: SeverityContainer; +} + +interface AlertCountersBySeverityAggregation { + [USERS_BY_SEVERITY_AGG]: { + buckets: AlertBySeverityBucketData[]; + }; +} + +function parseUsersData(rawAggregation: AlertCountersBySeverityAggregation): UserAlertsItem[] { + const buckets = rawAggregation?.[USERS_BY_SEVERITY_AGG].buckets ?? []; + + return buckets.reduce((accumalatedAlertsByUser, currentUser) => { + return [ + ...accumalatedAlertsByUser, + { + userName: currentUser.key, + totalAlerts: currentUser.doc_count, + low: currentUser.low.doc_count, + medium: currentUser.medium.doc_count, + high: currentUser.high.doc_count, + critical: currentUser.critical.doc_count, + }, + ]; + }, []); +} diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/user_alerts_table.test.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/user_alerts_table.test.tsx new file mode 100644 index 0000000000000..74c266243dc56 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/user_alerts_table.test.tsx @@ -0,0 +1,103 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { render } from '@testing-library/react'; + +import { TestProviders } from '../../../../common/mock'; +import { parsedVulnerableUserAlertsResult } from './mock_data'; +import { UseUserAlertsItems } from './use_user_alerts_items'; +import { UserAlertsTable } from './user_alerts_table'; + +const mockGetAppUrl = jest.fn(); +jest.mock('../../../../common/lib/kibana/hooks', () => { + const original = jest.requireActual('../../../../common/lib/kibana/hooks'); + return { + ...original, + useNavigation: () => ({ + getAppUrl: mockGetAppUrl, + }), + }; +}); + +type UseUserAlertsItemsReturn = ReturnType; +const defaultUseUserAlertsItemsReturn: UseUserAlertsItemsReturn = { + items: [], + isLoading: false, + updatedAt: Date.now(), +}; +const mockUseUserAlertsItems = jest.fn(() => defaultUseUserAlertsItemsReturn); +const mockUseUserAlertsItemsReturn = (overrides: Partial) => { + mockUseUserAlertsItems.mockReturnValueOnce({ ...defaultUseUserAlertsItemsReturn, ...overrides }); +}; + +jest.mock('./use_user_alerts_items', () => ({ + useUserAlertsItems: () => mockUseUserAlertsItems(), +})); + +const renderComponent = () => + render( + + + + ); + +describe('UserAlertsTable', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should render empty table', () => { + const { getByText, getByTestId } = renderComponent(); + + expect(getByTestId('severityUserAlertsPanel')).toBeInTheDocument(); + expect(getByText('No alerts to display')).toBeInTheDocument(); + expect(getByTestId('severityUserAlertsButton')).toBeInTheDocument(); + }); + + it('should render a loading table', () => { + mockUseUserAlertsItemsReturn({ isLoading: true }); + const { getByText, getByTestId } = renderComponent(); + + expect(getByText('Updating...')).toBeInTheDocument(); + expect(getByTestId('severityUserAlertsButton')).toBeInTheDocument(); + expect(getByTestId('severityUserAlertsTable')).toHaveClass('euiBasicTable-loading'); + }); + + it('should render the updated at subtitle', () => { + mockUseUserAlertsItemsReturn({ isLoading: false }); + const { getByText } = renderComponent(); + + expect(getByText('Updated now')).toBeInTheDocument(); + }); + + it('should render the table columns', () => { + mockUseUserAlertsItemsReturn({ items: parsedVulnerableUserAlertsResult }); + const { getAllByRole } = renderComponent(); + + const columnHeaders = getAllByRole('columnheader'); + expect(columnHeaders.at(0)).toHaveTextContent('User name'); + expect(columnHeaders.at(1)).toHaveTextContent('Alerts'); + expect(columnHeaders.at(2)).toHaveTextContent('Critical'); + expect(columnHeaders.at(3)).toHaveTextContent('High'); + expect(columnHeaders.at(4)).toHaveTextContent('Medium'); + expect(columnHeaders.at(5)).toHaveTextContent('Low'); + }); + + it('should render the table items', () => { + mockUseUserAlertsItemsReturn({ items: [parsedVulnerableUserAlertsResult[0]] }); + const { getByTestId } = renderComponent(); + + expect(getByTestId('userSeverityAlertsTable-userName')).toHaveTextContent('crffn20qcs'); + expect(getByTestId('userSeverityAlertsTable-totalAlerts')).toHaveTextContent('4'); + expect(getByTestId('userSeverityAlertsTable-critical')).toHaveTextContent('4'); + expect(getByTestId('userSeverityAlertsTable-high')).toHaveTextContent('1'); + expect(getByTestId('userSeverityAlertsTable-medium')).toHaveTextContent('1'); + expect(getByTestId('userSeverityAlertsTable-low')).toHaveTextContent('1'); + }); +}); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/user_alerts_table.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/user_alerts_table.tsx new file mode 100644 index 0000000000000..e54ef27c0db34 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/user_alerts_table.tsx @@ -0,0 +1,150 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useMemo } from 'react'; + +import { + EuiBasicTable, + EuiBasicTableColumn, + EuiButton, + EuiEmptyPrompt, + EuiHealth, + EuiPanel, + EuiSpacer, +} from '@elastic/eui'; + +import { SecurityPageName } from '../../../../app/types'; +import { FormattedCount } from '../../../../common/components/formatted_number'; +import { HeaderSection } from '../../../../common/components/header_section'; +import { HoverVisibilityContainer } from '../../../../common/components/hover_visibility_container'; +import { BUTTON_CLASS as INPECT_BUTTON_CLASS } from '../../../../common/components/inspect'; +import { UserDetailsLink } from '../../../../common/components/links'; +import { useQueryToggle } from '../../../../common/containers/query_toggle'; +import { useNavigation, NavigateTo, GetAppUrl } from '../../../../common/lib/kibana'; +import * as i18n from '../translations'; +import { LastUpdatedAt, SEVERITY_COLOR } from '../util'; +import { UserAlertsItem, useUserAlertsItems } from './use_user_alerts_items'; + +export interface UserAlertsTableProps { + signalIndexName: string | null; +} + +type GetTableColumns = (params: { + getAppUrl: GetAppUrl; + navigateTo: NavigateTo; +}) => Array>; + +const DETECTION_RESPONSE_USER_SEVERITY_QUERY_ID = 'vulnerableUsersBySeverityQuery'; + +export const UserAlertsTable = React.memo(({ signalIndexName }: UserAlertsTableProps) => { + const { getAppUrl, navigateTo } = useNavigation(); + const { toggleStatus, setToggleStatus } = useQueryToggle( + DETECTION_RESPONSE_USER_SEVERITY_QUERY_ID + ); + const { items, isLoading, updatedAt } = useUserAlertsItems({ + skip: !toggleStatus, + queryId: DETECTION_RESPONSE_USER_SEVERITY_QUERY_ID, + signalIndexName, + }); + + const navigateToAlerts = useCallback(() => { + navigateTo({ deepLinkId: SecurityPageName.users }); + }, [navigateTo]); + + const columns = useMemo( + () => getTableColumns({ getAppUrl, navigateTo }), + [getAppUrl, navigateTo] + ); + + return ( + + + } + /> + + {toggleStatus && ( + <> + {i18n.NO_ALERTS_FOUND}} titleSize="xs" /> + } + /> + + + {i18n.VIEW_ALL_USER_ALERTS} + + + )} + + + ); +}); + +UserAlertsTable.displayName = 'UserAlertsTable'; + +const getTableColumns: GetTableColumns = ({ getAppUrl, navigateTo }) => [ + { + field: 'userName', + name: i18n.USER_ALERTS_USERNAME_COLUMN, + truncateText: true, + textOnly: true, + 'data-test-subj': 'userSeverityAlertsTable-userName', + render: (userName: string) => , + }, + { + field: 'totalAlerts', + name: i18n.ALERTS_TEXT, + 'data-test-subj': 'userSeverityAlertsTable-totalAlerts', + render: (totalAlerts: number) => , + }, + { + field: 'critical', + name: i18n.STATUS_CRITICAL_LABEL, + render: (count: number) => ( + + + + ), + }, + { + field: 'high', + name: i18n.STATUS_HIGH_LABEL, + render: (count: number) => ( + + + + ), + }, + { + field: 'medium', + name: i18n.STATUS_MEDIUM_LABEL, + render: (count: number) => ( + + {count} + + ), + }, + { + field: 'low', + name: i18n.STATUS_LOW_LABEL, + render: (count: number) => ( + + + + ), + }, +]; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/utils.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/utils.tsx new file mode 100644 index 0000000000000..4ceba66773397 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/utils.tsx @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { FormattedRelative } from '@kbn/i18n-react'; +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import * as i18n from './translations'; + +export const SEVERITY_COLOR = { + critical: '#EF6550', + high: '#EE9266', + medium: '#F3B689', + low: '#F8D9B2', +} as const; + +export interface LastUpdatedAtProps { + updatedAt: number; + isUpdating: boolean; +} +export const LastUpdatedAt: React.FC = ({ isUpdating, updatedAt }) => ( + + {isUpdating ? ( + {i18n.UPDATING} + ) : ( + + <>{i18n.UPDATED} + + + )} + +); diff --git a/x-pack/plugins/security_solution/public/overview/pages/detection_response.test.tsx b/x-pack/plugins/security_solution/public/overview/pages/detection_response.test.tsx index 8cd387978e97d..4ad2eeac35240 100644 --- a/x-pack/plugins/security_solution/public/overview/pages/detection_response.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/pages/detection_response.test.tsx @@ -14,7 +14,14 @@ import { TestProviders } from '../../common/mock'; jest.mock('../components/detection_response/rule_alerts_table', () => ({ RuleAlertsTable: () =>
, })); -// TODO: add all sections mocks + +jest.mock('../components/detection_response/alerts_by_status', () => ({ + AlertsByStatus: () =>
, +})); + +jest.mock('../components/detection_response/cases_by_status', () => ({ + CasesByStatus: () =>
, +})); jest.mock('../../common/components/search_bar', () => ({ SiemSearchBar: () =>
, @@ -128,9 +135,12 @@ describe('DetectionResponse', () => { ); expect(result.queryByTestId('detectionResponsePage')).toBeInTheDocument(); - expect(result.queryByTestId('mock_RuleAlertsTable')).not.toBeInTheDocument(); // TODO: assert other alert sections are not in the document + expect(result.queryByTestId('mock_RuleAlertsTable')).not.toBeInTheDocument(); + expect(result.queryByTestId('mock_AlertsByStatus')).not.toBeInTheDocument(); + // TODO: assert cases sections are in the document + expect(result.queryByTestId('mock_CasesByStatus')).toBeInTheDocument(); }); it('should not render alerts data sections if user has not kibana read permission', () => { @@ -148,9 +158,13 @@ describe('DetectionResponse', () => { ); expect(result.queryByTestId('detectionResponsePage')).toBeInTheDocument(); - expect(result.queryByTestId('mock_RuleAlertsTable')).not.toBeInTheDocument(); + // TODO: assert all alert sections are not in the document + expect(result.queryByTestId('mock_RuleAlertsTable')).not.toBeInTheDocument(); + expect(result.queryByTestId('mock_AlertsByStatus')).not.toBeInTheDocument(); + // TODO: assert all cases sections are in the document + expect(result.queryByTestId('mock_CasesByStatus')).toBeInTheDocument(); }); it('should not render cases data sections if user has not cases read permission', () => { @@ -165,9 +179,11 @@ describe('DetectionResponse', () => { ); expect(result.queryByTestId('detectionResponsePage')).toBeInTheDocument(); - expect(result.queryByTestId('mock_RuleAlertsTable')).toBeInTheDocument(); // TODO: assert all alert sections are in the document + expect(result.queryByTestId('mock_RuleAlertsTable')).toBeInTheDocument(); + expect(result.queryByTestId('mock_AlertsByStatus')).toBeInTheDocument(); // TODO: assert all cases sections are not in the document + expect(result.queryByTestId('mock_CasesByStatus')).not.toBeInTheDocument(); }); it('should render page permissions message if user has any read permission', () => { diff --git a/x-pack/plugins/security_solution/public/overview/pages/detection_response.tsx b/x-pack/plugins/security_solution/public/overview/pages/detection_response.tsx index 719cb88b62043..5b9d298bf915c 100644 --- a/x-pack/plugins/security_solution/public/overview/pages/detection_response.tsx +++ b/x-pack/plugins/security_solution/public/overview/pages/detection_response.tsx @@ -14,10 +14,14 @@ import { useSourcererDataView } from '../../common/containers/sourcerer'; import { useUserInfo } from '../../detections/components/user_info'; import { HeaderPage } from '../../common/components/header_page'; import { useKibana, useGetUserCasesPermissions } from '../../common/lib/kibana'; -import { RuleAlertsTable } from '../components/detection_response/rule_alerts_table'; +import { HostAlertsTable, UserAlertsTable } from '../components/detection_response'; + import { LandingPageComponent } from '../../common/components/landing_page'; +import { RuleAlertsTable } from '../components/detection_response/rule_alerts_table'; import * as i18n from './translations'; import { EmptyPage } from '../../common/components/empty_page'; +import { CasesByStatus } from '../components/detection_response/cases_by_status'; +import { AlertsByStatus } from '../components/detection_response/alerts_by_status'; const NoPrivilegePage: React.FC = () => { const { docLinks } = useKibana().services; @@ -67,8 +71,16 @@ const DetectionResponseComponent = () => { - {canReadAlerts && {'[alerts chart]'}} - {canReadCases && {'[cases chart]'}} + {canReadAlerts && ( + + + + )} + {canReadCases && ( + + + + )} @@ -83,8 +95,12 @@ const DetectionResponseComponent = () => { {canReadAlerts && ( - {'[hosts table]'} - {'[users table]'} + + + + + + )} diff --git a/x-pack/plugins/security_solution/public/plugin.tsx b/x-pack/plugins/security_solution/public/plugin.tsx index 1dc14ababd781..343259d88cb76 100644 --- a/x-pack/plugins/security_solution/public/plugin.tsx +++ b/x-pack/plugins/security_solution/public/plugin.tsx @@ -142,6 +142,12 @@ export class Plugin implements IPlugin { + // required to show the alert table inside cases + const { alertsTableConfigurationRegistry } = plugins.triggersActionsUi; + const { registerAlertsTableConfiguration } = + await this.lazyRegisterAlertsTableConfiguration(); + registerAlertsTableConfiguration(alertsTableConfigurationRegistry, this.storage); + const [coreStart, startPlugins] = await core.getStartServices(); const subPlugins = await this.startSubPlugins(this.storage, coreStart, startPlugins); const { renderApp } = await this.lazyApplicationDependencies(); @@ -283,6 +289,17 @@ export class Plugin implements IPlugin { - describe('When given a small number under 1000', () => { - it('does not change the presentation of small numbers', () => { - expect(compactNotationParts(1)).toEqual([1, '', '']); - expect(compactNotationParts(100)).toEqual([100, '', '']); - expect(compactNotationParts(999)).toEqual([999, '', '']); - }); - }); - describe('When given a number greater or equal to 1000 but less than 1000000', () => { - it('presents the number as untis of k', () => { - expect(compactNotationParts(1000)).toEqual([1, 'k', '']); - expect(compactNotationParts(1001)).toEqual([1, 'k', '+']); - expect(compactNotationParts(10000)).toEqual([10, 'k', '']); - expect(compactNotationParts(10001)).toEqual([10, 'k', '+']); - expect(compactNotationParts(999999)).toEqual([999, 'k', '+']); - }); - }); - describe('When given a number greater or equal to 1000000 but less than 1000000000', () => { - it('presents the number as untis of M', () => { - expect(compactNotationParts(1000000)).toEqual([1, 'M', '']); - expect(compactNotationParts(1000001)).toEqual([1, 'M', '+']); - expect(compactNotationParts(10000000)).toEqual([10, 'M', '']); - expect(compactNotationParts(10000001)).toEqual([10, 'M', '+']); - expect(compactNotationParts(999999999)).toEqual([999, 'M', '+']); - }); - }); - describe('When given a number greater or equal to 1000000000 but less than 1000000000000', () => { - it('presents the number as untis of B', () => { - expect(compactNotationParts(1000000000)).toEqual([1, 'B', '']); - expect(compactNotationParts(1000000001)).toEqual([1, 'B', '+']); - expect(compactNotationParts(10000000000)).toEqual([10, 'B', '']); - expect(compactNotationParts(10000000001)).toEqual([10, 'B', '+']); - expect(compactNotationParts(999999999999)).toEqual([999, 'B', '+']); - }); - }); - describe('When given a number greater or equal to 1000000000000', () => { - it('presents the number as untis of T', () => { - expect(compactNotationParts(1000000000000)).toEqual([1, 'T', '']); - expect(compactNotationParts(1000000000001)).toEqual([1, 'T', '+']); - expect(compactNotationParts(10000000000000)).toEqual([10, 'T', '']); - expect(compactNotationParts(10000000000001)).toEqual([10, 'T', '+']); - expect(compactNotationParts(999999999999999)).toEqual([999, 'T', '+']); - expect(compactNotationParts(9999999999999990)).toEqual([9999, 'T', '+']); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx b/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx index fe25547ef99dc..878dbe30a6971 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx @@ -5,66 +5,17 @@ * 2.0. */ -import { i18n } from '@kbn/i18n'; import React, { useMemo, useContext, useCallback } from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; import { useDispatch } from 'react-redux'; -import { EuiI18nNumber } from '@elastic/eui'; import { EventStats } from '../../../common/endpoint/types'; import { useColors } from './use_colors'; import { useLinkProps } from './use_link_props'; import { ResolverAction } from '../store/actions'; import { SideEffectContext } from './side_effect_context'; +import { FormattedCount } from '../../common/components/formatted_number'; /* eslint-disable react/display-name */ -/** - * Until browser support accomodates the `notation="compact"` feature of Intl.NumberFormat... - * exported for testing - * @param num The number to format - * @returns [mantissa ("12" in "12k+"), Scalar of compact notation (k,M,B,T), remainder indicator ("+" in "12k+")] - */ -export function compactNotationParts( - num: number -): [mantissa: number, compactNotation: string, remainderIndicator: string] { - if (!Number.isFinite(num)) { - return [num, '', '']; - } - - // "scale" here will be a term indicating how many thousands there are in the number - // e.g. 1001 will be 1000, 1000002 will be 1000000, etc. - const scale = Math.pow(10, 3 * Math.min(Math.floor(Math.floor(Math.log10(num)) / 3), 4)); - - const compactPrefixTranslations = { - compactThousands: i18n.translate('xpack.securitySolution.endpoint.resolver.compactThousands', { - defaultMessage: 'k', - }), - compactMillions: i18n.translate('xpack.securitySolution.endpoint.resolver.compactMillions', { - defaultMessage: 'M', - }), - - compactBillions: i18n.translate('xpack.securitySolution.endpoint.resolver.compactBillions', { - defaultMessage: 'B', - }), - - compactTrillions: i18n.translate('xpack.securitySolution.endpoint.resolver.compactTrillions', { - defaultMessage: 'T', - }), - }; - const prefixMap: Map = new Map([ - [1, ''], - [1000, compactPrefixTranslations.compactThousands], - [1000000, compactPrefixTranslations.compactMillions], - [1000000000, compactPrefixTranslations.compactBillions], - [1000000000000, compactPrefixTranslations.compactTrillions], - ]); - const hasRemainder = i18n.translate('xpack.securitySolution.endpoint.resolver.compactOverflow', { - defaultMessage: '+', - }); - const prefix = prefixMap.get(scale) ?? ''; - return [Math.floor(num / scale), prefix, (num / scale) % 1 > Number.EPSILON ? hasRemainder : '']; -} - /** * A Submenu that displays a collection of "pills" for each related event * category it has events for. @@ -89,15 +40,7 @@ export const NodeSubMenuComponents = React.memo( return []; } else { return Object.entries(nodeStats.byCategory).map(([category, total]) => { - const [mantissa, scale, hasRemainder] = compactNotationParts(total || 0); - const prefix = ( - , scale, hasRemainder }} - /> - ); + const prefix = ; return { prefix, category, diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline_modal/open_timeline_modal_body.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline_modal/open_timeline_modal_body.test.tsx index e2184aaaec773..ddf35eec86e04 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline_modal/open_timeline_modal_body.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline_modal/open_timeline_modal_body.test.tsx @@ -29,6 +29,7 @@ describe('OpenTimelineModal', () => { euiBreakpoints: { s: '500px', }, + paddingSizes: { m: '16px' }, }, }); const title = 'All Timelines / Open Timelines'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/title_row/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/title_row/index.test.tsx index d46cad3c43a98..9e54d708db496 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/title_row/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/title_row/index.test.tsx @@ -14,7 +14,13 @@ import { TitleRow } from '.'; import { getMockTheme } from '../../../../common/lib/kibana/kibana_react.mock'; const mockTheme = getMockTheme({ - eui: { euiSizeS: '10px', euiLineHeight: 10, euiBreakpoints: { s: '10px' }, euiSize: '10px' }, + eui: { + euiSizeS: '10px', + euiLineHeight: 10, + euiBreakpoints: { s: '10px' }, + euiSize: '10px', + paddingSizes: { m: '16px' }, + }, }); describe('TitleRow', () => { diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/column_header.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/column_header.tsx index 74593e40ddf4c..67fcff7de1332 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/column_header.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/column_header.tsx @@ -9,7 +9,6 @@ import { EuiContextMenu, EuiContextMenuPanelDescriptor, EuiIcon, EuiPopover } fr import React, { useCallback, useMemo, useRef, useState } from 'react'; import { Draggable } from 'react-beautiful-dnd'; import { Resizable, ResizeCallback } from 're-resizable'; -import deepEqual from 'fast-deep-equal'; import { useDispatch } from 'react-redux'; import styled from 'styled-components'; import { DRAGGABLE_KEYBOARD_WRAPPER_CLASS_NAME } from '@kbn/securitysolution-t-grid'; @@ -298,14 +297,4 @@ const ColumnHeaderComponent: React.FC = ({ ); }; -export const ColumnHeader = React.memo( - ColumnHeaderComponent, - (prevProps, nextProps) => - prevProps.draggableIndex === nextProps.draggableIndex && - prevProps.tabType === nextProps.tabType && - prevProps.timelineId === nextProps.timelineId && - prevProps.isDragging === nextProps.isDragging && - prevProps.onFilterChange === nextProps.onFilterChange && - deepEqual(prevProps.sort, nextProps.sort) && - deepEqual(prevProps.header, nextProps.header) -); +export const ColumnHeader = React.memo(ColumnHeaderComponent); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.tsx index 56984452964de..2bd5eda49bd98 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/index.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import deepEqual from 'fast-deep-equal'; + import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react'; import { Droppable, DraggableChildrenFn } from 'react-beautiful-dnd'; @@ -312,19 +312,4 @@ export const ColumnHeadersComponent = ({ ); }; -export const ColumnHeaders = React.memo( - ColumnHeadersComponent, - (prevProps, nextProps) => - prevProps.actionsColumnWidth === nextProps.actionsColumnWidth && - prevProps.isEventViewer === nextProps.isEventViewer && - prevProps.isSelectAllChecked === nextProps.isSelectAllChecked && - prevProps.onSelectAll === nextProps.onSelectAll && - prevProps.show === nextProps.show && - prevProps.showEventsSelect === nextProps.showEventsSelect && - prevProps.showSelectAllCheckbox === nextProps.showSelectAllCheckbox && - deepEqual(prevProps.sort, nextProps.sort) && - prevProps.timelineId === nextProps.timelineId && - deepEqual(prevProps.columnHeaders, nextProps.columnHeaders) && - prevProps.tabType === nextProps.tabType && - deepEqual(prevProps.browserFields, nextProps.browserFields) -); +export const ColumnHeaders = React.memo(ColumnHeadersComponent); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/providers.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/providers.tsx index 3db938f5efe07..7e52267cd6f1b 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/providers.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/providers.tsx @@ -11,7 +11,6 @@ import React, { useCallback, useMemo, useRef, useState } from 'react'; import { Draggable, DraggingStyle, Droppable, NotDraggingStyle } from 'react-beautiful-dnd'; import styled from 'styled-components'; import { useDispatch } from 'react-redux'; -import deepEqual from 'fast-deep-equal'; import { DRAGGABLE_KEYBOARD_WRAPPER_CLASS_NAME, @@ -357,14 +356,7 @@ export const DataProvidersGroupItem = React.memo(
); - }, - (prevProps, nextProps) => - prevProps.groupIndex === nextProps.groupIndex && - prevProps.index === nextProps.index && - prevProps.timelineId === nextProps.timelineId && - deepEqual(prevProps.browserFields, nextProps.browserFields) && - deepEqual(prevProps.group, nextProps.group) && - deepEqual(prevProps.dataProvider, nextProps.dataProvider) + } ); DataProvidersGroupItem.displayName = 'DataProvidersGroupItem'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.test.tsx index cae0dda0b4bc3..b301703f3cae2 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.test.tsx @@ -18,6 +18,8 @@ import { FilterStateStore } from '@kbn/es-query'; import { FilterManager } from '@kbn/data-plugin/public'; import { mockDataProviders } from '../data_providers/mock/mock_data_providers'; import { buildGlobalQuery } from '../helpers'; +import { setAutocomplete } from '@kbn/unified-search-plugin/public/services'; +import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; import { QueryBarTimeline, @@ -184,6 +186,11 @@ describe('Timeline QueryBar ', () => { }); describe('#onSavedQuery', () => { + beforeEach(() => { + const autocompleteStart = unifiedSearchPluginMock.createStartContract(); + setAutocomplete(autocompleteStart.autocomplete); + }); + test('is only reference that changed when dataProviders props get updated', async () => { const Proxy = (props: QueryBarTimelineComponentProps) => ( diff --git a/x-pack/plugins/security_solution/public/timelines/containers/index.tsx b/x-pack/plugins/security_solution/public/timelines/containers/index.tsx index 56eb11109d742..fb76d8f2994c6 100644 --- a/x-pack/plugins/security_solution/public/timelines/containers/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/containers/index.tsx @@ -15,7 +15,6 @@ import { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBo import { DataView, isCompleteResponse, isErrorResponse } from '@kbn/data-plugin/common'; import { ESQuery } from '../../../common/typed_json'; -import { useIsExperimentalFeatureEnabled } from '../../common/hooks/use_experimental_features'; import { inputsModel } from '../../common/store'; import { useKibana } from '../../common/lib/kibana'; import { createFilter } from '../../common/containers/helpers'; @@ -211,9 +210,6 @@ export const useTimelineEvents = ({ }); const { addWarning } = useAppToasts(); - // TODO: Once we are past experimental phase this code should be removed - const ruleRegistryEnabled = useIsExperimentalFeatureEnabled('ruleRegistryEnabled'); - const timelineSearch = useCallback( (request: TimelineRequest | null) => { if (request == null || pageName === '' || skip) { @@ -332,10 +328,7 @@ export const useTimelineEvents = ({ ); useEffect(() => { - if ( - skipQueryForDetectionsPage(id, indexNames, ruleRegistryEnabled) || - indexNames.length === 0 - ) { + if (skipQueryForDetectionsPage(id, indexNames) || indexNames.length === 0) { return; } @@ -397,10 +390,7 @@ export const useTimelineEvents = ({ activeTimeline.setActivePage(newActivePage); } } - if ( - !skipQueryForDetectionsPage(id, indexNames, ruleRegistryEnabled) && - !deepEqual(prevRequest, currentRequest) - ) { + if (!skipQueryForDetectionsPage(id, indexNames) && !deepEqual(prevRequest, currentRequest)) { return currentRequest; } return prevRequest; @@ -416,7 +406,6 @@ export const useTimelineEvents = ({ id, language, limit, - ruleRegistryEnabled, startDate, sort, fields, diff --git a/x-pack/plugins/security_solution/public/types.ts b/x-pack/plugins/security_solution/public/types.ts index 3fa7e964f6ca1..fca11f84a7abb 100644 --- a/x-pack/plugins/security_solution/public/types.ts +++ b/x-pack/plugins/security_solution/public/types.ts @@ -44,6 +44,7 @@ import type { Overview } from './overview'; import type { Rules } from './rules'; import type { Timelines } from './timelines'; import type { Management } from './management'; +import { LandingPages } from './landing_pages'; export interface SetupPlugins { home?: HomePublicPluginSetup; @@ -106,6 +107,7 @@ export interface SubPlugins { overview: Overview; timelines: Timelines; management: Management; + landingPages: LandingPages; } // TODO: find a better way to defined these types @@ -120,4 +122,5 @@ export interface StartedSubPlugins { overview: ReturnType; timelines: ReturnType; management: ReturnType; + landingPages: ReturnType; } diff --git a/x-pack/plugins/security_solution/server/config.mock.ts b/x-pack/plugins/security_solution/server/config.mock.ts index bc83a721cbf58..52e68ac548e6c 100644 --- a/x-pack/plugins/security_solution/server/config.mock.ts +++ b/x-pack/plugins/security_solution/server/config.mock.ts @@ -44,12 +44,7 @@ const withExperimentalFeature = ( }; }; -const withRuleRegistryEnabled = (config: ConfigType, isEnabled: boolean): ConfigType => { - return isEnabled ? withExperimentalFeature(config, 'ruleRegistryEnabled') : config; -}; - export const configMock = { createDefault: createMockConfig, withExperimentalFeature, - withRuleRegistryEnabled, }; diff --git a/x-pack/plugins/security_solution/server/endpoint/mocks.ts b/x-pack/plugins/security_solution/server/endpoint/mocks.ts index 46e4df691b086..6d6c83efd70fd 100644 --- a/x-pack/plugins/security_solution/server/endpoint/mocks.ts +++ b/x-pack/plugins/security_solution/server/endpoint/mocks.ts @@ -5,8 +5,13 @@ * 2.0. */ -import { loggingSystemMock, savedObjectsServiceMock } from '@kbn/core/server/mocks'; -import { IScopedClusterClient, SavedObjectsClientContract } from '@kbn/core/server'; +import type { AwaitedProperties } from '@kbn/utility-types'; +import { + loggingSystemMock, + savedObjectsServiceMock, + ScopedClusterClientMock, +} from '@kbn/core/server/mocks'; +import { SavedObjectsClientContract } from '@kbn/core/server'; import { listMock } from '@kbn/lists-plugin/server/mocks'; import { securityMock } from '@kbn/security-plugin/server/mocks'; import { alertsMock } from '@kbn/alerting-plugin/server/mocks'; @@ -35,7 +40,6 @@ import { import { ManifestManager } from './services/artifacts/manifest_manager/manifest_manager'; import { getManifestManagerMock } from './services/artifacts/manifest_manager/manifest_manager.mock'; import { EndpointAppContext } from './types'; -import { MetadataRequestContext } from './routes/metadata/handlers'; import { SecuritySolutionRequestHandlerContext } from '../types'; import { parseExperimentalConfigValue } from '../../common/experimental_features'; import { requestContextFactoryMock } from '../request_context_factory.mock'; @@ -190,24 +194,22 @@ export const createMockFleetStartContract = (indexPattern: string): FleetStartCo }; }; -export const createMockMetadataRequestContext = (): jest.Mocked => { +export const createMockMetadataRequestContext = () => { return { endpointAppContextService: createMockEndpointAppContextService(), logger: loggingSystemMock.create().get('mock_endpoint_app_context'), - requestHandlerContext: - xpackMocks.createRequestHandlerContext() as unknown as jest.Mocked, + requestHandlerContext: xpackMocks.createRequestHandlerContext() as unknown as jest.Mocked< + AwaitedProperties + >, }; }; export function createRouteHandlerContext( - dataClient: jest.Mocked, + dataClient: ScopedClusterClientMock, savedObjectsClient: jest.Mocked, overrides: { endpointAuthz?: Partial } = {} ) { - const context = requestContextMock.create( - createMockClients(), - overrides - ) as jest.Mocked; + const context = requestContextMock.create(createMockClients(), overrides); context.core.elasticsearch.client = dataClient; context.core.savedObjects.client = savedObjectsClient; return context; diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/actions/audit_log.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/actions/audit_log.test.ts index 960969b41966c..c6dbe24cdb901 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/actions/audit_log.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/actions/audit_log.test.ts @@ -9,6 +9,7 @@ import { KibanaResponseFactory, RequestHandler, RouteConfig } from '@kbn/core/server'; import { + coreMock, elasticsearchServiceMock, httpServerMock, httpServiceMock, @@ -162,7 +163,9 @@ describe('Action Log API', () => { path.startsWith(ENDPOINT_ACTION_LOG_ROUTE) )!; await routeHandler( - createRouteHandlerContext(esClientMock, savedObjectsClientMock.create()), + coreMock.createCustomRequestHandlerContext( + createRouteHandlerContext(esClientMock, savedObjectsClientMock.create()) + ) as SecuritySolutionRequestHandlerContext, req, mockResponse ); diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts index e17f48017ba6d..85d3fd1f064e2 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts @@ -6,6 +6,8 @@ */ /* eslint-disable @typescript-eslint/no-explicit-any */ +import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { AwaitedProperties } from '@kbn/utility-types'; import { KibanaRequest, KibanaResponseFactory, @@ -20,7 +22,6 @@ import { savedObjectsClientMock, } from '@kbn/core/server/mocks'; import { parseExperimentalConfigValue } from '../../../../common/experimental_features'; -import { SecuritySolutionRequestHandlerContext } from '../../../types'; import { EndpointAppContextService } from '../../endpoint_app_context_services'; import { createMockEndpointAppContextServiceSetupContract, @@ -55,6 +56,7 @@ import { CasesClientMock } from '@kbn/cases-plugin/server/client/mocks'; import { EndpointAuthz } from '../../../../common/endpoint/types/authz'; import type { PackageClient } from '@kbn/fleet-plugin/server'; import { createMockPackageService } from '@kbn/fleet-plugin/server/mocks'; +import { SecuritySolutionRequestHandlerContextMock } from '../../../lib/detection_engine/routes/__mocks__/request_context'; interface CallRouteInterface { body?: HostIsolationRequestBody; @@ -122,7 +124,7 @@ describe('Host Isolation', () => { routePrefix: string, opts: CallRouteInterface, indexExists?: { endpointDsExists: boolean } - ) => Promise>; + ) => Promise>; const superUser = { username: 'superuser', roles: ['superuser'], @@ -190,7 +192,7 @@ describe('Host Isolation', () => { routePrefix: string, { body, idxResponse, searchResponse, mockUser, license, authz = {} }: CallRouteInterface, indexExists?: { endpointDsExists: boolean } - ): Promise> => { + ): Promise> => { const asUser = mockUser ? mockUser : superUser; (startContract.security.authc.getCurrentUser as jest.Mock).mockImplementationOnce( () => asUser @@ -204,31 +206,30 @@ describe('Host Isolation', () => { }; // mock _index_template - ctx.core.elasticsearch.client.asInternalUser.indices.existsIndexTemplate = jest - .fn() - .mockImplementationOnce(() => { + ctx.core.elasticsearch.client.asInternalUser.indices.existsIndexTemplate.mockResponseImplementationOnce( + () => { if (indexExists) { - return Promise.resolve({ + return { body: true, statusCode: 200, - }); + }; } - return Promise.resolve({ + return { body: false, statusCode: 404, - }); - }); + }; + } + ); const withIdxResp = idxResponse ? idxResponse : { statusCode: 201 }; - const mockIndexResponse = jest.fn().mockImplementation(() => Promise.resolve(withIdxResp)); - const mockSearchResponse = jest - .fn() - .mockImplementation(() => - Promise.resolve({ body: legacyMetadataSearchResponseMock(searchResponse) }) - ); - - ctx.core.elasticsearch.client.asInternalUser.index = mockIndexResponse; - ctx.core.elasticsearch.client.asCurrentUser.search = mockSearchResponse; + ctx.core.elasticsearch.client.asInternalUser.index.mockResponseImplementation( + () => withIdxResp + ); + ctx.core.elasticsearch.client.asCurrentUser.search.mockResponseImplementation(() => { + return { + body: legacyMetadataSearchResponseMock(searchResponse), + }; + }); const withLicense = license ? license : Platinum; licenseEmitter.next(withLicense); @@ -241,7 +242,7 @@ describe('Host Isolation', () => { await routeHandler(ctx, mockRequest, mockResponse); - return ctx as unknown as jest.Mocked; + return ctx; }; }); @@ -283,8 +284,9 @@ describe('Host Isolation', () => { searchResponse: metadataResponse, }); const actionDoc: EndpointAction = ( - ctx.core.elasticsearch.client.asInternalUser.index as jest.Mock - ).mock.calls[0][0].body; + ctx.core.elasticsearch.client.asInternalUser.index.mock + .calls[0][0] as estypes.IndexRequest + ).body!; expect(actionDoc.agents).toContain(AgentID); }); it('records the user who performed the action to the action record', async () => { @@ -294,8 +296,9 @@ describe('Host Isolation', () => { mockUser: testU, }); const actionDoc: EndpointAction = ( - ctx.core.elasticsearch.client.asInternalUser.index as jest.Mock - ).mock.calls[0][0].body; + ctx.core.elasticsearch.client.asInternalUser.index.mock + .calls[0][0] as estypes.IndexRequest + ).body!; expect(actionDoc.user_id).toEqual(testU.username); }); it('records the comment in the action payload', async () => { @@ -304,8 +307,9 @@ describe('Host Isolation', () => { body: { endpoint_ids: ['XYZ'], comment: CommentText }, }); const actionDoc: EndpointAction = ( - ctx.core.elasticsearch.client.asInternalUser.index as jest.Mock - ).mock.calls[0][0].body; + ctx.core.elasticsearch.client.asInternalUser.index.mock + .calls[0][0] as estypes.IndexRequest + ).body!; expect(actionDoc.data.comment).toEqual(CommentText); }); it('creates an action and returns its ID', async () => { @@ -313,8 +317,9 @@ describe('Host Isolation', () => { body: { endpoint_ids: ['XYZ'], comment: 'XYZ' }, }); const actionDoc: EndpointAction = ( - ctx.core.elasticsearch.client.asInternalUser.index as jest.Mock - ).mock.calls[0][0].body; + ctx.core.elasticsearch.client.asInternalUser.index.mock + .calls[0][0] as estypes.IndexRequest + ).body!; const actionID = actionDoc.action_id; expect(mockResponse.ok).toBeCalled(); expect((mockResponse.ok.mock.calls[0][0]?.body as HostIsolationResponse).action).toEqual( @@ -326,8 +331,9 @@ describe('Host Isolation', () => { body: { endpoint_ids: ['XYZ'] }, }); const actionDoc: EndpointAction = ( - ctx.core.elasticsearch.client.asInternalUser.index as jest.Mock - ).mock.calls[0][0].body; + ctx.core.elasticsearch.client.asInternalUser.index.mock + .calls[0][0] as estypes.IndexRequest + ).body!; expect(actionDoc.timeout).toEqual(300); }); it('sends the action to the correct agent when endpoint ID is given', async () => { @@ -339,8 +345,9 @@ describe('Host Isolation', () => { searchResponse: doc, }); const actionDoc: EndpointAction = ( - ctx.core.elasticsearch.client.asInternalUser.index as jest.Mock - ).mock.calls[0][0].body; + ctx.core.elasticsearch.client.asInternalUser.index.mock + .calls[0][0] as estypes.IndexRequest + ).body!; expect(actionDoc.agents).toContain(AgentID); }); @@ -349,8 +356,9 @@ describe('Host Isolation', () => { body: { endpoint_ids: ['XYZ'] }, }); const actionDoc: EndpointAction = ( - ctx.core.elasticsearch.client.asInternalUser.index as jest.Mock - ).mock.calls[0][0].body; + ctx.core.elasticsearch.client.asInternalUser.index.mock + .calls[0][0] as estypes.IndexRequest + ).body!; expect(actionDoc.data.command).toEqual('isolate'); }); it('sends the unisolate command payload from the unisolate route', async () => { @@ -358,8 +366,9 @@ describe('Host Isolation', () => { body: { endpoint_ids: ['XYZ'] }, }); const actionDoc: EndpointAction = ( - ctx.core.elasticsearch.client.asInternalUser.index as jest.Mock - ).mock.calls[0][0].body; + ctx.core.elasticsearch.client.asInternalUser.index.mock + .calls[0][0] as estypes.IndexRequest + ).body!; expect(actionDoc.data.command).toEqual('unisolate'); }); @@ -375,14 +384,17 @@ describe('Host Isolation', () => { const indexDoc = ctx.core.elasticsearch.client.asInternalUser.index; const actionDocs: [ - { index: string; body: LogsEndpointAction }, - { index: string; body: EndpointAction } - ] = [(indexDoc as jest.Mock).mock.calls[0][0], (indexDoc as jest.Mock).mock.calls[1][0]]; + { index: string; body?: LogsEndpointAction }, + { index: string; body?: EndpointAction } + ] = [ + indexDoc.mock.calls[0][0] as estypes.IndexRequest, + indexDoc.mock.calls[1][0] as estypes.IndexRequest, + ]; expect(actionDocs[0].index).toEqual(ENDPOINT_ACTIONS_INDEX); expect(actionDocs[1].index).toEqual(AGENT_ACTIONS_INDEX); - expect(actionDocs[0].body.EndpointActions.data.command).toEqual('unisolate'); - expect(actionDocs[1].body.data.command).toEqual('unisolate'); + expect(actionDocs[0].body!.EndpointActions.data.command).toEqual('unisolate'); + expect(actionDocs[1].body!.data.command).toEqual('unisolate'); }); it('handles isolation', async () => { @@ -395,14 +407,17 @@ describe('Host Isolation', () => { ); const indexDoc = ctx.core.elasticsearch.client.asInternalUser.index; const actionDocs: [ - { index: string; body: LogsEndpointAction }, - { index: string; body: EndpointAction } - ] = [(indexDoc as jest.Mock).mock.calls[0][0], (indexDoc as jest.Mock).mock.calls[1][0]]; + { index: string; body?: LogsEndpointAction }, + { index: string; body?: EndpointAction } + ] = [ + indexDoc.mock.calls[0][0] as estypes.IndexRequest, + indexDoc.mock.calls[1][0] as estypes.IndexRequest, + ]; expect(actionDocs[0].index).toEqual(ENDPOINT_ACTIONS_INDEX); expect(actionDocs[1].index).toEqual(AGENT_ACTIONS_INDEX); - expect(actionDocs[0].body.EndpointActions.data.command).toEqual('isolate'); - expect(actionDocs[1].body.data.command).toEqual('isolate'); + expect(actionDocs[0].body!.EndpointActions.data.command).toEqual('isolate'); + expect(actionDocs[1].body!.data.command).toEqual('isolate'); }); it('handles errors', async () => { diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.ts b/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.ts index 101a55d7acba3..69954dbd7e7a7 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.ts @@ -84,7 +84,7 @@ const createFailedActionResponseEntry = async ({ logger: Logger; }): Promise => { // 8.0+ requires internal user to write to system indices - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; try { await esClient.index({ index: `${ENDPOINT_ACTION_RESPONSES_DS}-default`, @@ -178,7 +178,7 @@ export const isolationRequestHandler = function ( }); // 8.0+ requires internal user to write to system indices - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; // if the new endpoint indices/data streams exists // write the action request to the new endpoint index diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/actions/status.ts b/x-pack/plugins/security_solution/server/endpoint/routes/actions/status.ts index 9b134e385be6f..bfd17cccb3d0d 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/actions/status.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/actions/status.ts @@ -47,7 +47,7 @@ export const actionStatusRequestHandler = function ( SecuritySolutionRequestHandlerContext > { return async (context, req, res) => { - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; const agentIDs: string[] = Array.isArray(req.query.agent_ids) ? [...new Set(req.query.agent_ids)] : [req.query.agent_ids]; diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/enrichment.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/enrichment.test.ts index b508469b88f53..0aaa138c90d31 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/enrichment.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/enrichment.test.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { coreMock } from '@kbn/core/server/mocks'; import { HostStatus } from '../../../../common/endpoint/types'; import { createMockMetadataRequestContext } from '../../mocks'; import { EndpointDocGenerator } from '../../../../common/endpoint/generate_data'; @@ -12,13 +13,21 @@ import { enrichHostMetadata, MetadataRequestContext } from './handlers'; import { AgentClient } from '@kbn/fleet-plugin/server'; describe('test document enrichment', () => { - let metaReqCtx: jest.Mocked; + let metaReqCtx: ReturnType; const docGen = new EndpointDocGenerator(); beforeEach(() => { metaReqCtx = createMockMetadataRequestContext(); }); + const getMetadataRequestContext = () => + ({ + ...metaReqCtx, + requestHandlerContext: coreMock.createCustomRequestHandlerContext( + metaReqCtx.requestHandlerContext + ), + } as unknown as MetadataRequestContext); + describe('host status enrichment', () => { let statusFn: jest.Mock; @@ -32,49 +41,70 @@ describe('test document enrichment', () => { it('should return host healthy for online agent', async () => { statusFn.mockImplementation(() => 'online'); - const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx); + const enrichedHostList = await enrichHostMetadata( + docGen.generateHostMetadata(), + getMetadataRequestContext() + ); expect(enrichedHostList.host_status).toEqual(HostStatus.HEALTHY); }); it('should return host offline for offline agent', async () => { statusFn.mockImplementation(() => 'offline'); - const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx); + const enrichedHostList = await enrichHostMetadata( + docGen.generateHostMetadata(), + getMetadataRequestContext() + ); expect(enrichedHostList.host_status).toEqual(HostStatus.OFFLINE); }); it('should return host updating for unenrolling agent', async () => { statusFn.mockImplementation(() => 'unenrolling'); - const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx); + const enrichedHostList = await enrichHostMetadata( + docGen.generateHostMetadata(), + getMetadataRequestContext() + ); expect(enrichedHostList.host_status).toEqual(HostStatus.UPDATING); }); it('should return host unhealthy for degraded agent', async () => { statusFn.mockImplementation(() => 'degraded'); - const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx); + const enrichedHostList = await enrichHostMetadata( + docGen.generateHostMetadata(), + getMetadataRequestContext() + ); expect(enrichedHostList.host_status).toEqual(HostStatus.UNHEALTHY); }); it('should return host unhealthy for erroring agent', async () => { statusFn.mockImplementation(() => 'error'); - const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx); + const enrichedHostList = await enrichHostMetadata( + docGen.generateHostMetadata(), + getMetadataRequestContext() + ); expect(enrichedHostList.host_status).toEqual(HostStatus.UNHEALTHY); }); it('should return host unhealthy for warning agent', async () => { statusFn.mockImplementation(() => 'warning'); - const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx); + const enrichedHostList = await enrichHostMetadata( + docGen.generateHostMetadata(), + getMetadataRequestContext() + ); expect(enrichedHostList.host_status).toEqual(HostStatus.UNHEALTHY); }); it('should return host unhealthy for invalid agent', async () => { statusFn.mockImplementation(() => 'asliduasofb'); - const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx); + const enrichedHostList = await enrichHostMetadata( + docGen.generateHostMetadata(), + getMetadataRequestContext() + ); expect(enrichedHostList.host_status).toEqual(HostStatus.UNHEALTHY); }); }); @@ -109,7 +139,10 @@ describe('test document enrichment', () => { }; }); - const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx); + const enrichedHostList = await enrichHostMetadata( + docGen.generateHostMetadata(), + getMetadataRequestContext() + ); expect(enrichedHostList.policy_info).toBeDefined(); expect(enrichedHostList.policy_info?.agent.applied.id).toEqual(policyID); expect(enrichedHostList.policy_info?.agent.applied.revision).toEqual(policyRev); @@ -125,7 +158,10 @@ describe('test document enrichment', () => { }; }); - const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx); + const enrichedHostList = await enrichHostMetadata( + docGen.generateHostMetadata(), + getMetadataRequestContext() + ); expect(enrichedHostList.policy_info).toBeDefined(); expect(enrichedHostList.policy_info?.agent.configured.id).toEqual(policyID); expect(enrichedHostList.policy_info?.agent.configured.revision).toEqual(policyRev); @@ -146,7 +182,10 @@ describe('test document enrichment', () => { }; }); - const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx); + const enrichedHostList = await enrichHostMetadata( + docGen.generateHostMetadata(), + getMetadataRequestContext() + ); expect(enrichedHostList.policy_info).toBeDefined(); expect(enrichedHostList.policy_info?.endpoint.id).toEqual(policyID); expect(enrichedHostList.policy_info?.endpoint.revision).toEqual(policyRev); diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/handlers.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/handlers.ts index a8d186e126b62..1b86924101b68 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/handlers.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/handlers.ts @@ -94,7 +94,7 @@ export function getMetadataListRequestHandler( return async (context, request, response) => { const endpointMetadataService = endpointAppContext.service.getEndpointMetadataService(); const fleetServices = endpointAppContext.service.getScopedFleetServices(request); - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; let doesUnitedIndexExist = false; let didUnitedIndexError = false; @@ -168,9 +168,10 @@ export const getMetadataRequestHandler = function ( const endpointMetadataService = endpointAppContext.service.getEndpointMetadataService(); try { + const esClient = (await context.core).elasticsearch.client; return response.ok({ body: await endpointMetadataService.getEnrichedHostMetadata( - context.core.elasticsearch.client.asInternalUser, + esClient.asInternalUser, endpointAppContext.service.getScopedFleetServices(request), request.params.id ), @@ -185,7 +186,7 @@ export function getMetadataTransformStatsHandler( logger: Logger ): RequestHandler { return async (context, _, response) => { - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; try { const transformStats = await esClient.transform.getTransformStats({ transform_id: METADATA_TRANSFORMS_PATTERN, @@ -235,19 +236,14 @@ export async function enrichHostMetadata( let hostStatus = HostStatus.UNHEALTHY; let elasticAgentId = hostMetadata?.elastic?.agent?.id; const log = metadataRequestContext.logger; + const coreContext = await metadataRequestContext.requestHandlerContext?.core; try { - if ( - !metadataRequestContext.esClient && - !metadataRequestContext.requestHandlerContext?.core.elasticsearch.client - ) { + if (!metadataRequestContext.esClient && !coreContext?.elasticsearch.client) { throw new Error('esClient not found'); } - if ( - !metadataRequestContext.savedObjectsClient && - !metadataRequestContext.requestHandlerContext?.core.savedObjects - ) { + if (!metadataRequestContext.savedObjectsClient && !coreContext?.savedObjects) { throw new Error('esSavedObjectClient not found'); } } catch (e) { @@ -257,8 +253,8 @@ export async function enrichHostMetadata( const esSavedObjectClient = metadataRequestContext?.savedObjectsClient ?? - (metadataRequestContext.requestHandlerContext?.core.savedObjects - .client as SavedObjectsClientContract); + (coreContext?.savedObjects.client as SavedObjectsClientContract); + const fleetContext = await metadataRequestContext.requestHandlerContext?.fleet; try { /** @@ -270,10 +266,7 @@ export async function enrichHostMetadata( log.warn(`Missing elastic agent id, using host id instead ${elasticAgentId}`); } - const status = - await metadataRequestContext.requestHandlerContext?.fleet?.agentClient.asCurrentUser.getAgentStatusById( - elasticAgentId - ); + const status = await fleetContext?.agentClient.asCurrentUser.getAgentStatusById(elasticAgentId); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion hostStatus = fleetAgentStatusToEndpointHostStatus(status!); } catch (e) { @@ -287,10 +280,7 @@ export async function enrichHostMetadata( let policyInfo: HostInfo['policy_info']; try { - const agent = - await metadataRequestContext.requestHandlerContext?.fleet?.agentClient.asCurrentUser.getAgent( - elasticAgentId - ); + const agent = await fleetContext?.agentClient.asCurrentUser.getAgent(elasticAgentId); const agentPolicy = await metadataRequestContext.endpointAppContextService .getAgentPolicyService() // eslint-disable-next-line @typescript-eslint/no-non-null-assertion @@ -338,17 +328,18 @@ async function legacyListMetadataQuery( queryOptions: GetMetadataListRequestQuery ): Promise { const fleetAgentClient = fleetServices.agent; + const coreContext = await context.core; const metadataRequestContext: MetadataRequestContext = { - esClient: context.core.elasticsearch.client, + esClient: coreContext.elasticsearch.client, endpointAppContextService: endpointAppContext.service, logger, requestHandlerContext: context, - savedObjectsClient: context.core.savedObjects.client, + savedObjectsClient: coreContext.savedObjects.client, }; const endpointPolicyIds = endpointPolicies.map((policy) => policy.policy_id); - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = coreContext.elasticsearch.client.asInternalUser; const unenrolledAgentIds = await findAllUnenrolledAgentIds(fleetAgentClient, endpointPolicyIds); diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts index 95c3e24709ccc..01136fef81884 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts @@ -24,7 +24,10 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { GetHostPolicyResponse, HostPolicyResponse } from '../../../../common/endpoint/types'; import { EndpointDocGenerator } from '../../../../common/endpoint/generate_data'; import { parseExperimentalConfigValue } from '../../../../common/experimental_features'; -import { createMockConfig } from '../../../lib/detection_engine/routes/__mocks__'; +import { + createMockConfig, + requestContextMock, +} from '../../../lib/detection_engine/routes/__mocks__'; import { Agent } from '@kbn/fleet-plugin/common/types/models'; import { AgentClient, AgentService } from '@kbn/fleet-plugin/server/services'; import { get } from 'lodash'; @@ -59,7 +62,9 @@ describe('test policy response handler', () => { }); await hostPolicyResponseHandler( - createRouteHandlerContext(mockScopedClient, mockSavedObjectClient), + requestContextMock.convertContext( + createRouteHandlerContext(mockScopedClient, mockSavedObjectClient) + ), mockRequest, mockResponse ); @@ -81,7 +86,9 @@ describe('test policy response handler', () => { }); await hostPolicyResponseHandler( - createRouteHandlerContext(mockScopedClient, mockSavedObjectClient), + requestContextMock.convertContext( + createRouteHandlerContext(mockScopedClient, mockSavedObjectClient) + ), mockRequest, mockResponse ); @@ -185,7 +192,9 @@ describe('test policy response handler', () => { }); await policySummarysHandler( - createRouteHandlerContext(mockScopedClient, mockSavedObjectClient), + requestContextMock.convertContext( + createRouteHandlerContext(mockScopedClient, mockSavedObjectClient) + ), mockRequest, mockResponse ); @@ -216,7 +225,9 @@ describe('test policy response handler', () => { }); await agentPolicySummaryHandler( - createRouteHandlerContext(mockScopedClient, mockSavedObjectClient), + requestContextMock.convertContext( + createRouteHandlerContext(mockScopedClient, mockSavedObjectClient) + ), mockRequest, mockResponse ); diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts index 8a32580f9669a..7ccae199a3ed9 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts @@ -22,11 +22,8 @@ export const getHostPolicyResponseHandler = function (): RequestHandler< undefined > { return async (context, request, response) => { - const doc = await getPolicyResponseByAgentId( - policyIndexPattern, - request.query.agentId, - context.core.elasticsearch.client - ); + const client = (await context.core).elasticsearch.client; + const doc = await getPolicyResponseByAgentId(policyIndexPattern, request.query.agentId, client); if (doc) { return response.ok({ body: doc }); diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/entity.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/entity.ts index 58ccd119c4dde..ef438667c3647 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/entity.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/entity.ts @@ -87,7 +87,8 @@ export function handleEntities(): RequestHandler> { return async (context, req, res) => { - const client = context.core.elasticsearch.client; + const client = (await context.core).elasticsearch.client; const fetcher = new Fetcher(client); const body = await fetcher.tree(req.body); return res.ok({ diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/with_endpoint_authz.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/with_endpoint_authz.test.ts index 607b9a8c23508..34f2f7a434fbd 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/with_endpoint_authz.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/with_endpoint_authz.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { httpServerMock, loggingSystemMock } from '@kbn/core/server/mocks'; +import { coreMock, httpServerMock, loggingSystemMock } from '@kbn/core/server/mocks'; import { RequestHandler } from '@kbn/core/server'; import { requestContextMock } from '../../lib/detection_engine/routes/__mocks__'; import { EndpointApiNeededAuthz, withEndpointAuthz } from './with_endpoint_authz'; @@ -14,7 +14,7 @@ import { EndpointAuthorizationError } from '../errors'; describe('When using `withEndpointAuthz()`', () => { let mockRequestHandler: jest.Mocked; - let mockContext: jest.Mocked>; + let mockContext: ReturnType; let mockRequest: ReturnType; let mockResponse: ReturnType; let logger: ReturnType; @@ -58,10 +58,10 @@ describe('When using `withEndpointAuthz()`', () => { }, { canCreateArtifactsByPolicy: false }, ], - ])('should grant access when needed authz is %j', (neededAuthz, authzOverrides) => { + ])('should grant access when needed authz is %j', async (neededAuthz, authzOverrides) => { Object.assign(mockContext.securitySolution.endpointAuthz, authzOverrides); - withEndpointAuthz(neededAuthz, logger, mockRequestHandler)( - mockContext, + await withEndpointAuthz(neededAuthz, logger, mockRequestHandler)( + coreMock.createCustomRequestHandlerContext(mockContext), mockRequest, mockResponse ); @@ -85,11 +85,11 @@ describe('When using `withEndpointAuthz()`', () => { }, { canCreateArtifactsByPolicy: false }, ], - ])('should deny access when not authorized for %j', (neededAuthz, authzOverrides) => { + ])('should deny access when not authorized for %j', async (neededAuthz, authzOverrides) => { Object.assign(mockContext.securitySolution.endpointAuthz, authzOverrides); - withEndpointAuthz(neededAuthz, logger, mockRequestHandler)( - mockContext, + await withEndpointAuthz(neededAuthz, logger, mockRequestHandler)( + coreMock.createCustomRequestHandlerContext(mockContext), mockRequest, mockResponse ); diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/with_endpoint_authz.ts b/x-pack/plugins/security_solution/server/endpoint/routes/with_endpoint_authz.ts index 0ed4adb01a9b6..14a61a92e52e8 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/with_endpoint_authz.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/with_endpoint_authz.ts @@ -51,7 +51,7 @@ export const withEndpointAuthz = ( SecuritySolutionRequestHandlerContext > = async (context, request, response) => { if (enforceAuthz) { - const endpointAuthz = context.securitySolution.endpointAuthz; + const endpointAuthz = (await context.securitySolution).endpointAuthz; const permissionChecker = (permission: EndpointAuthzKeyList[0]) => endpointAuthz[permission]; // has `all`? diff --git a/x-pack/plugins/security_solution/server/endpoint/services/metadata/metadata.ts b/x-pack/plugins/security_solution/server/endpoint/services/metadata/metadata.ts index bd2cdd7e45a3a..9e21c2c192b82 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/metadata/metadata.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/metadata/metadata.ts @@ -18,7 +18,7 @@ export async function getMetadataForEndpoints( requestHandlerContext: SecuritySolutionRequestHandlerContext ): Promise { const query = getESQueryHostMetadataByIDs(endpointIDs); - const esClient = requestHandlerContext.core.elasticsearch.client.asCurrentUser; + const esClient = (await requestHandlerContext.core).elasticsearch.client.asCurrentUser; const { body } = await esClient.search(query as estypes.SearchRequest, { meta: true, }); diff --git a/x-pack/plugins/security_solution/server/endpoint/utils/audit_log_helpers.ts b/x-pack/plugins/security_solution/server/endpoint/utils/audit_log_helpers.ts index 8d9234fab280f..3a1e25c32b683 100644 --- a/x-pack/plugins/security_solution/server/endpoint/utils/audit_log_helpers.ts +++ b/x-pack/plugins/security_solution/server/endpoint/utils/audit_log_helpers.ts @@ -194,7 +194,7 @@ export const getActionRequestsResult = async ({ let actionRequests: TransportResult, unknown>; try { - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; actionRequests = await esClient.search(actionsSearchQuery, { ...queryOptions, meta: true }); const actionIds = actionRequests?.body?.hits?.hits?.map((e) => { return logsEndpointActionsRegex.test(e._index) @@ -251,7 +251,7 @@ export const getActionResponsesResult = async ({ let actionResponses: TransportResult, unknown>; try { - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; actionResponses = await esClient.search(responsesSearchQuery, { ...queryOptions, meta: true }); } catch (error) { logger.error(error); diff --git a/x-pack/plugins/security_solution/server/endpoint/utils/yes_no_data_stream.test.ts b/x-pack/plugins/security_solution/server/endpoint/utils/yes_no_data_stream.test.ts index 43042a332c1d2..eb53a5854c2aa 100644 --- a/x-pack/plugins/security_solution/server/endpoint/utils/yes_no_data_stream.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/utils/yes_no_data_stream.test.ts @@ -6,6 +6,7 @@ */ import { + coreMock, elasticsearchServiceMock, savedObjectsClientMock, loggingSystemMock, @@ -18,7 +19,7 @@ import { } from './yes_no_data_stream'; describe('Accurately answers if index template for data stream exists', () => { - let ctxt: jest.Mocked; + let ctxt: ReturnType; beforeEach(() => { ctxt = createRouteHandlerContext( @@ -27,17 +28,17 @@ describe('Accurately answers if index template for data stream exists', () => { ); }); - const mockEsApiResponse = (response: { body: boolean; statusCode: number }) => { - return jest.fn().mockImplementationOnce(() => Promise.resolve(response)); - }; - it('Returns FALSE for a non-existent data stream index template', async () => { - ctxt.core.elasticsearch.client.asInternalUser.indices.existsIndexTemplate = mockEsApiResponse({ - body: false, - statusCode: 404, - }); + ctxt.core.elasticsearch.client.asInternalUser.indices.existsIndexTemplate.mockResponseImplementation( + () => ({ + body: false, + statusCode: 404, + }) + ); const doesItExist = await doLogsEndpointActionDsExists({ - context: ctxt, + context: coreMock.createCustomRequestHandlerContext( + ctxt + ) as SecuritySolutionRequestHandlerContext, logger: loggingSystemMock.create().get('host-isolation'), dataStreamName: '.test-stream.name', }); @@ -45,12 +46,16 @@ describe('Accurately answers if index template for data stream exists', () => { }); it('Returns TRUE for an existing index', async () => { - ctxt.core.elasticsearch.client.asInternalUser.indices.existsIndexTemplate = mockEsApiResponse({ - body: true, - statusCode: 200, - }); + ctxt.core.elasticsearch.client.asInternalUser.indices.existsIndexTemplate.mockResponseImplementation( + () => ({ + body: true, + statusCode: 200, + }) + ); const doesItExist = await doLogsEndpointActionDsExists({ - context: ctxt, + context: coreMock.createCustomRequestHandlerContext( + ctxt + ) as SecuritySolutionRequestHandlerContext, logger: loggingSystemMock.create().get('host-isolation'), dataStreamName: '.test-stream.name', }); @@ -59,7 +64,7 @@ describe('Accurately answers if index template for data stream exists', () => { }); describe('Accurately answers if index exists', () => { - let ctxt: jest.Mocked; + let ctxt: ReturnType; beforeEach(() => { ctxt = createRouteHandlerContext( @@ -68,17 +73,15 @@ describe('Accurately answers if index exists', () => { ); }); - const mockEsApiResponse = (response: { body: boolean; statusCode: number }) => { - return jest.fn().mockImplementationOnce(() => Promise.resolve(response)); - }; - it('Returns FALSE for a non-existent index', async () => { - ctxt.core.elasticsearch.client.asInternalUser.indices.exists = mockEsApiResponse({ + ctxt.core.elasticsearch.client.asInternalUser.indices.exists.mockResponseImplementation(() => ({ body: false, statusCode: 404, - }); + })); const doesItExist = await doesLogsEndpointActionsIndexExist({ - context: ctxt, + context: coreMock.createCustomRequestHandlerContext( + ctxt + ) as SecuritySolutionRequestHandlerContext, logger: loggingSystemMock.create().get('host-isolation'), indexName: '.test-index.name-default', }); @@ -86,12 +89,14 @@ describe('Accurately answers if index exists', () => { }); it('Returns TRUE for an existing index', async () => { - ctxt.core.elasticsearch.client.asInternalUser.indices.exists = mockEsApiResponse({ + ctxt.core.elasticsearch.client.asInternalUser.indices.exists.mockResponseImplementation(() => ({ body: true, statusCode: 200, - }); + })); const doesItExist = await doesLogsEndpointActionsIndexExist({ - context: ctxt, + context: coreMock.createCustomRequestHandlerContext( + ctxt + ) as SecuritySolutionRequestHandlerContext, logger: loggingSystemMock.create().get('host-isolation'), indexName: '.test-index.name-default', }); diff --git a/x-pack/plugins/security_solution/server/endpoint/utils/yes_no_data_stream.ts b/x-pack/plugins/security_solution/server/endpoint/utils/yes_no_data_stream.ts index b84a026f9e8e0..9e94e4ba29c32 100644 --- a/x-pack/plugins/security_solution/server/endpoint/utils/yes_no_data_stream.ts +++ b/x-pack/plugins/security_solution/server/endpoint/utils/yes_no_data_stream.ts @@ -18,7 +18,7 @@ export const doLogsEndpointActionDsExists = async ({ dataStreamName: string; }): Promise => { try { - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; const doesIndexTemplateExist = await esClient.indices.existsIndexTemplate( { name: dataStreamName, @@ -46,7 +46,7 @@ export const doesLogsEndpointActionsIndexExist = async ({ indexName: string; }): Promise => { try { - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; const doesIndexExist = await esClient.indices.exists( { index: indexName, diff --git a/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts b/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts index 80bafe6b4799a..17bfa0d584f28 100644 --- a/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts +++ b/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts @@ -33,7 +33,6 @@ import { Subject } from 'rxjs'; import { ILicense } from '@kbn/licensing-plugin/common/types'; import { EndpointDocGenerator } from '../../common/endpoint/generate_data'; import { ProtectionModes } from '../../common/endpoint/types'; -import type { SecuritySolutionRequestHandlerContext } from '../types'; import { getExceptionListClientMock } from '@kbn/lists-plugin/server/services/exception_lists/exception_list_client.mock'; import { getExceptionListSchemaMock } from '@kbn/lists-plugin/common/schemas/response/exception_list_schema.mock'; import { ExceptionListClient } from '@kbn/lists-plugin/server'; @@ -50,7 +49,7 @@ import { ALL_ENDPOINT_ARTIFACT_LIST_IDS } from '../../common/endpoint/service/ar describe('ingest_integration tests ', () => { let endpointAppContextMock: EndpointAppContextServiceStartContract; let req: KibanaRequest; - let ctx: SecuritySolutionRequestHandlerContext; + let ctx: ReturnType; const exceptionListClient: ExceptionListClient = getExceptionListClientMock(); let licenseEmitter: Subject; let licenseService: LicenseService; @@ -99,7 +98,7 @@ describe('ingest_integration tests ', () => { exceptionListClient ); - return callback(createNewPackagePolicyMock(), ctx, req); + return callback(createNewPackagePolicyMock(), requestContextMock.convertContext(ctx), req); }; const TEST_POLICY_ID_1 = 'c6d16e42-c32d-4dce-8a88-113cfe276ad1'; @@ -265,9 +264,9 @@ describe('ingest_integration tests ', () => { ); const policyConfig = generator.generatePolicyPackagePolicy(); policyConfig.inputs[0]!.config!.policy.value = mockPolicy; - await expect(() => callback(policyConfig, ctx, req)).rejects.toThrow( - 'Requires Platinum license' - ); + await expect(() => + callback(policyConfig, requestContextMock.convertContext(ctx), req) + ).rejects.toThrow('Requires Platinum license'); }); it('updates successfully if no paid features are turned on in the policy', async () => { const mockPolicy = policyFactoryWithoutPaidFeatures(); @@ -281,7 +280,11 @@ describe('ingest_integration tests ', () => { ); const policyConfig = generator.generatePolicyPackagePolicy(); policyConfig.inputs[0]!.config!.policy.value = mockPolicy; - const updatedPolicyConfig = await callback(policyConfig, ctx, req); + const updatedPolicyConfig = await callback( + policyConfig, + requestContextMock.convertContext(ctx), + req + ); expect(updatedPolicyConfig.inputs[0]!.config!.policy.value).toEqual(mockPolicy); }); }); @@ -302,7 +305,11 @@ describe('ingest_integration tests ', () => { ); const policyConfig = generator.generatePolicyPackagePolicy(); policyConfig.inputs[0]!.config!.policy.value = mockPolicy; - const updatedPolicyConfig = await callback(policyConfig, ctx, req); + const updatedPolicyConfig = await callback( + policyConfig, + requestContextMock.convertContext(ctx), + req + ); expect(updatedPolicyConfig.inputs[0]!.config!.policy.value).toEqual(mockPolicy); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_add_tags.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_add_tags.test.ts deleted file mode 100644 index 95051ad3d8021..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_add_tags.test.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -// eslint-disable-next-line no-restricted-imports -import { legacyAddTags } from './legacy_add_tags'; -import { INTERNAL_RULE_ALERT_ID_KEY } from '../../../../common/constants'; - -describe('legacyAdd_tags', () => { - test('it should add a rule id as an internal structure', () => { - const tags = legacyAddTags([], 'rule-1'); - expect(tags).toEqual([`${INTERNAL_RULE_ALERT_ID_KEY}:rule-1`]); - }); - - test('it should not allow duplicate tags to be created', () => { - const tags = legacyAddTags(['tag-1', 'tag-1'], 'rule-1'); - expect(tags).toEqual(['tag-1', `${INTERNAL_RULE_ALERT_ID_KEY}:rule-1`]); - }); - - test('it should not allow duplicate internal tags to be created when called two times in a row', () => { - const tags1 = legacyAddTags(['tag-1'], 'rule-1'); - const tags2 = legacyAddTags(tags1, 'rule-1'); - expect(tags2).toEqual(['tag-1', `${INTERNAL_RULE_ALERT_ID_KEY}:rule-1`]); - }); -}); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_add_tags.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_add_tags.ts deleted file mode 100644 index b17d8d7226a64..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_add_tags.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { INTERNAL_RULE_ALERT_ID_KEY } from '../../../../common/constants'; - -/** - * @deprecated Once we are confident all rules relying on side-car actions SO's have been migrated to SO references we should remove this function - */ -export const legacyAddTags = (tags: string[], ruleAlertId: string): string[] => - Array.from(new Set([...tags, `${INTERNAL_RULE_ALERT_ID_KEY}:${ruleAlertId}`])); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_create_notifications.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_create_notifications.ts index dec6d51aa9082..e82b19faa40bd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_create_notifications.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_create_notifications.ts @@ -9,8 +9,6 @@ import { SanitizedRule } from '@kbn/alerting-plugin/common'; import { SERVER_APP_ID, LEGACY_NOTIFICATIONS_ID } from '../../../../common/constants'; // eslint-disable-next-line no-restricted-imports import { CreateNotificationParams, LegacyRuleNotificationAlertTypeParams } from './legacy_types'; -// eslint-disable-next-line no-restricted-imports -import { legacyAddTags } from './legacy_add_tags'; /** * @deprecated Once we are confident all rules relying on side-car actions SO's have been migrated to SO references we should remove this function @@ -26,7 +24,7 @@ export const legacyCreateNotifications = async ({ rulesClient.create({ data: { name, - tags: legacyAddTags([], ruleAlertId), + tags: [], alertTypeId: LEGACY_NOTIFICATIONS_ID, consumer: SERVER_APP_ID, params: { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_read_notifications.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_read_notifications.ts index 05f64e19df26e..3e28ac879e2c3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_read_notifications.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_read_notifications.ts @@ -10,7 +10,6 @@ import { RuleTypeParams, SanitizedRule } from '@kbn/alerting-plugin/common'; import { LegacyReadNotificationParams, legacyIsAlertType } from './legacy_types'; // eslint-disable-next-line no-restricted-imports import { legacyFindNotifications } from './legacy_find_notifications'; -import { INTERNAL_RULE_ALERT_ID_KEY } from '../../../../common/constants'; /** * @deprecated Once we are confident all rules relying on side-car actions SO's have been migrated to SO references we should remove this function @@ -39,7 +38,7 @@ export const legacyReadNotifications = async ({ } else if (ruleAlertId != null) { const notificationFromFind = await legacyFindNotifications({ rulesClient, - filter: `alert.attributes.tags: "${INTERNAL_RULE_ALERT_ID_KEY}:${ruleAlertId}"`, + filter: `alert.attributes.params.ruleAlertId: "${ruleAlertId}"`, page: 1, }); if ( diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_rules_notification_alert_type.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_rules_notification_alert_type.test.ts index 0facf29681270..16ce9c7d2a3e2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_rules_notification_alert_type.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_rules_notification_alert_type.test.ts @@ -6,11 +6,12 @@ */ import { loggingSystemMock } from '@kbn/core/server/mocks'; -import { getAlertMock } from '../routes/__mocks__/request_responses'; +import { alertsMock, RuleExecutorServicesMock } from '@kbn/alerting-plugin/server/mocks'; + +import { getRuleMock } from '../routes/__mocks__/request_responses'; // eslint-disable-next-line no-restricted-imports import { legacyRulesNotificationAlertType } from './legacy_rules_notification_alert_type'; import { buildSignalsSearchQuery } from './build_signals_query'; -import { alertsMock, RuleExecutorServicesMock } from '@kbn/alerting-plugin/server/mocks'; // eslint-disable-next-line no-restricted-imports import { LegacyNotificationExecutorOptions } from './legacy_types'; import { @@ -75,10 +76,7 @@ describe('legacyRules_notification_alert_type', () => { }); }); - describe.each([ - ['Legacy', false], - ['RAC', true], - ])('executor - %s', (_, isRuleRegistryEnabled) => { + describe('executor', () => { it('throws an error if rule alert was not found', async () => { alertServices.savedObjectsClient.get.mockResolvedValue({ id: 'id', @@ -93,7 +91,7 @@ describe('legacyRules_notification_alert_type', () => { }); it('should call buildSignalsSearchQuery with proper params', async () => { - const ruleAlert = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const ruleAlert = getRuleMock(getQueryRuleParams()); alertServices.savedObjectsClient.get.mockResolvedValue({ id: 'id', type: 'type', @@ -118,7 +116,7 @@ describe('legacyRules_notification_alert_type', () => { }); it('should resolve results_link when meta is undefined to use "/app/security"', async () => { - const ruleAlert = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const ruleAlert = getRuleMock(getQueryRuleParams()); delete ruleAlert.params.meta; alertServices.savedObjectsClient.get.mockResolvedValue({ id: 'rule-id', @@ -144,7 +142,7 @@ describe('legacyRules_notification_alert_type', () => { }); it('should resolve results_link when meta is an empty object to use "/app/security"', async () => { - const ruleAlert = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const ruleAlert = getRuleMock(getQueryRuleParams()); ruleAlert.params.meta = {}; alertServices.savedObjectsClient.get.mockResolvedValue({ id: 'rule-id', @@ -169,7 +167,7 @@ describe('legacyRules_notification_alert_type', () => { }); it('should resolve results_link to custom kibana link when given one', async () => { - const ruleAlert = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const ruleAlert = getRuleMock(getQueryRuleParams()); ruleAlert.params.meta = { kibana_siem_app_url: 'http://localhost', }; @@ -196,7 +194,7 @@ describe('legacyRules_notification_alert_type', () => { }); it('should not call alertFactory.create if signalsCount was 0', async () => { - const ruleAlert = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const ruleAlert = getRuleMock(getQueryRuleParams()); alertServices.savedObjectsClient.get.mockResolvedValue({ id: 'id', type: 'type', @@ -213,7 +211,7 @@ describe('legacyRules_notification_alert_type', () => { }); it('should call scheduleActions if signalsCount was greater than 0', async () => { - const ruleAlert = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const ruleAlert = getRuleMock(getQueryRuleParams()); alertServices.savedObjectsClient.get.mockResolvedValue({ id: 'id', type: 'type', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_context.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_context.ts index ad0c3eace42c8..60e8f0c8cf858 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_context.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_context.ts @@ -6,6 +6,7 @@ */ import type { MockedKeys } from '@kbn/utility-types/jest'; +import type { AwaitedProperties } from '@kbn/utility-types'; import { coreMock } from '@kbn/core/server/mocks'; import { ActionsApiRequestHandlerContext } from '@kbn/actions-plugin/server'; @@ -62,10 +63,11 @@ export const createMockClients = () => { type MockClients = ReturnType; -type SecuritySolutionRequestHandlerContextMock = - MockedKeys & { - core: MockClients['core']; - }; +export type SecuritySolutionRequestHandlerContextMock = MockedKeys< + AwaitedProperties> +> & { + core: MockClients['core']; +}; const createRequestContextMock = ( clients: MockClients = createMockClients(), @@ -89,6 +91,14 @@ const createRequestContextMock = ( }; }; +const convertRequestContextMock = ( + context: AwaitedProperties +): SecuritySolutionRequestHandlerContext => { + return coreMock.createCustomRequestHandlerContext( + context + ) as unknown as SecuritySolutionRequestHandlerContext; +}; + const createSecuritySolutionRequestContextMock = ( clients: MockClients, overrides: { endpointAuthz?: Partial } = {} @@ -127,6 +137,7 @@ const createTools = () => { export const requestContextMock = { create: createRequestContextMock, + convertContext: convertRequestContextMock, createMockClients, createTools, }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts index b79ae4b38abb9..8e2f0da4e65c9 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts @@ -17,8 +17,6 @@ import { DETECTION_ENGINE_SIGNALS_STATUS_URL, DETECTION_ENGINE_PRIVILEGES_URL, DETECTION_ENGINE_QUERY_SIGNALS_URL, - INTERNAL_RULE_ID_KEY, - INTERNAL_IMMUTABLE_KEY, DETECTION_ENGINE_PREPACKAGED_URL, DETECTION_ENGINE_SIGNALS_FINALIZE_MIGRATION_URL, DETECTION_ENGINE_SIGNALS_MIGRATION_STATUS_URL, @@ -206,18 +204,18 @@ export const getEmptyFindResult = (): FindHit => ({ data: [], }); -export const getFindResultWithSingleHit = (isRuleRegistryEnabled: boolean): FindHit => ({ +export const getFindResultWithSingleHit = (): FindHit => ({ page: 1, perPage: 1, total: 1, - data: [getAlertMock(isRuleRegistryEnabled, getQueryRuleParams())], + data: [getRuleMock(getQueryRuleParams())], }); -export const nonRuleFindResult = (isRuleRegistryEnabled: boolean): FindHit => ({ +export const nonRuleFindResult = (): FindHit => ({ page: 1, perPage: 1, total: 1, - data: [nonRuleAlert(isRuleRegistryEnabled)], + data: [nonRuleAlert()], }); export const getFindResultWithMultiHits = ({ @@ -379,24 +377,22 @@ export const createActionResult = (): ActionResult => ({ name: '', config: {}, isPreconfigured: false, + isDeprecated: false, }); -export const nonRuleAlert = (isRuleRegistryEnabled: boolean) => ({ +export const nonRuleAlert = () => ({ // Defaulting to QueryRuleParams because ts doesn't like empty objects - ...getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()), + ...getRuleMock(getQueryRuleParams()), id: '04128c15-0d1b-4716-a4c5-46997ac7f3bc', name: 'Non-Rule Alert', alertTypeId: 'something', }); -export const getAlertMock = ( - isRuleRegistryEnabled: boolean, - params: T -): SanitizedRule => ({ +export const getRuleMock = (params: T): SanitizedRule => ({ id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', name: 'Detect Root/Admin Users', - tags: [`${INTERNAL_RULE_ID_KEY}:rule-1`, `${INTERNAL_IMMUTABLE_KEY}:false`], - alertTypeId: isRuleRegistryEnabled ? ruleTypeMappings[params.type] : 'siem.signals', + tags: [], + alertTypeId: ruleTypeMappings[params.type], consumer: 'siem', params, createdAt: new Date('2019-12-13T16:40:33.400Z'), @@ -418,12 +414,9 @@ export const getAlertMock = ( }, }); -export const resolveAlertMock = ( - isRuleRegistryEnabled: boolean, - params: T -): ResolvedSanitizedRule => ({ +export const resolveRuleMock = (params: T): ResolvedSanitizedRule => ({ outcome: 'exactMatch', - ...getAlertMock(isRuleRegistryEnabled, params), + ...getRuleMock(params), }); export const updateActionResult = (): ActionResult => ({ @@ -432,6 +425,7 @@ export const updateActionResult = (): ActionResult => ({ name: '', config: {}, isPreconfigured: false, + isDeprecated: false, }); export const getMockPrivilegesResult = () => ({ @@ -697,7 +691,7 @@ export const getSignalsMigrationStatusRequest = () => export const legacyGetNotificationResult = (): LegacyRuleNotificationAlertType => ({ id: '200dbf2f-b269-4bf9-aa85-11ba32ba73ba', name: 'Notification for Rule Test', - tags: ['__internal_rule_alert_id:85b64e8a-2e40-4096-86af-5ac172c10825'], + tags: [], alertTypeId: 'siem.notifications', consumer: 'siem', params: { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/server.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/server.ts index 85cf6a07f4d89..ef2a3016e5f91 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/server.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/server.ts @@ -17,6 +17,7 @@ interface Route { config: RouteConfig; handler: RequestHandler; } + const getRoute = (routerMock: MockServer['router']): Route => { const routeCalls = [ ...routerMock.get.mock.calls, @@ -41,7 +42,7 @@ class MockServer { constructor( public readonly router = httpServiceMock.createRouter(), private responseMock = responseFactoryMock.create(), - private contextMock = requestContextMock.create(), + private contextMock = requestContextMock.convertContext(requestContextMock.create()), private resultMock = buildResultMock() ) {} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/create_index_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/create_index_route.ts index 86e06a71b638b..9879d4f83cfbd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/create_index_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/create_index_route.ts @@ -47,11 +47,12 @@ export const createIndexRoute = (router: SecuritySolutionPluginRouter) => { const siemResponse = buildSiemResponse(response); try { - const siemClient = context.securitySolution?.getAppClient(); + const securitySolution = await context.securitySolution; + const siemClient = securitySolution?.getAppClient(); if (!siemClient) { return siemResponse.error({ statusCode: 404 }); } - await createDetectionIndex(context.securitySolution); + await createDetectionIndex(securitySolution); return response.ok({ body: { acknowledged: true } }); } catch (err) { const error = transformError(err); @@ -67,7 +68,6 @@ export const createIndexRoute = (router: SecuritySolutionPluginRouter) => { export const createDetectionIndex = async ( context: SecuritySolutionApiRequestHandlerContext ): Promise => { - const config = context.getConfig(); const esClient = context.core.elasticsearch.client.asCurrentUser; const siemClient = context.getAppClient(); const spaceId = context.getSpaceId(); @@ -77,11 +77,10 @@ export const createDetectionIndex = async ( context.core.elasticsearch.client.asInternalUser, index ); - const { ruleRegistryEnabled } = config.experimentalFeatures; - // If using the rule registry implementation, we don't want to create new .siem-signals indices - - // only create/update resources if there are existing indices - if (ruleRegistryEnabled && !indexExists) { + // We don't want to create new .siem-signals indices - only create/update + // resources if there are existing indices + if (!indexExists) { return; } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/delete_index_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/delete_index_route.ts index 6eae3908e2156..ddaa497823604 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/delete_index_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/delete_index_route.ts @@ -40,9 +40,9 @@ export const deleteIndexRoute = (router: SecuritySolutionPluginRouter) => { const siemResponse = buildSiemResponse(response); try { - const esClient = context.core.elasticsearch.client.asCurrentUser; + const esClient = (await context.core).elasticsearch.client.asCurrentUser; - const siemClient = context.securitySolution?.getAppClient(); + const siemClient = (await context.securitySolution)?.getAppClient(); if (!siemClient) { return siemResponse.error({ statusCode: 404 }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/read_index_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/read_index_route.ts index 24f05c707e3d4..c03f8e000d0f1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/read_index_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/read_index_route.ts @@ -32,19 +32,22 @@ export const readIndexRoute = ( const siemResponse = buildSiemResponse(response); try { - const siemClient = context.securitySolution?.getAppClient(); - const esClient = context.core.elasticsearch.client.asCurrentUser; + const core = await context.core; + const securitySolution = await context.securitySolution; + + const siemClient = securitySolution?.getAppClient(); + const esClient = core.elasticsearch.client.asCurrentUser; if (!siemClient) { return siemResponse.error({ statusCode: 404 }); } - const spaceId = context.securitySolution.getSpaceId(); + const spaceId = securitySolution.getSpaceId(); const indexName = ruleDataService.getResourceName(`security.alerts-${spaceId}`); const index = siemClient.getSignalsIndex(); const indexExists = await getBootstrapIndexExists( - context.core.elasticsearch.client.asInternalUser, + core.elasticsearch.client.asInternalUser, index ); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/privileges/read_privileges_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/privileges/read_privileges_route.test.ts index c4c205e696065..002b4c2264eee 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/privileges/read_privileges_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/privileges/read_privileges_route.test.ts @@ -30,7 +30,7 @@ describe('read_privileges route', () => { test('returns 200 when doing a normal request', async () => { const response = await server.inject( getPrivilegeRequest({ auth: { isAuthenticated: false } }), - context + requestContextMock.convertContext(context) ); expect(response.status).toEqual(200); }); @@ -38,7 +38,7 @@ describe('read_privileges route', () => { test('returns the payload when doing a normal request', async () => { const response = await server.inject( getPrivilegeRequest({ auth: { isAuthenticated: false } }), - context + requestContextMock.convertContext(context) ); const expectedBody = { ...getMockPrivilegesResult(), @@ -58,7 +58,7 @@ describe('read_privileges route', () => { const response = await server.inject( getPrivilegeRequest({ auth: { isAuthenticated: true } }), - context + requestContextMock.convertContext(context) ); expect(response.status).toEqual(200); expect(response.body).toEqual(expectedBody); @@ -70,7 +70,7 @@ describe('read_privileges route', () => { ); const response = await server.inject( getPrivilegeRequest({ auth: { isAuthenticated: false } }), - context + requestContextMock.convertContext(context) ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', status_code: 500 }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/privileges/read_privileges_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/privileges/read_privileges_route.ts index 22f8ccb39118a..31ea057facb69 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/privileges/read_privileges_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/privileges/read_privileges_route.ts @@ -28,15 +28,17 @@ export const readPrivilegesRoute = ( const siemResponse = buildSiemResponse(response); try { - const esClient = context.core.elasticsearch.client.asCurrentUser; - const siemClient = context.securitySolution?.getAppClient(); + const core = await context.core; + const securitySolution = await context.securitySolution; + const esClient = core.elasticsearch.client.asCurrentUser; + const siemClient = securitySolution?.getAppClient(); if (!siemClient) { return siemResponse.error({ statusCode: 404 }); } - const spaceId = context.securitySolution.getSpaceId(); - const index = context.securitySolution + const spaceId = securitySolution.getSpaceId(); + const index = securitySolution .getRuleDataService() .getResourceName(`security.alerts-${spaceId}`); const clusterPrivileges = await readPrivileges(esClient, index); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.test.ts index d5b301364d4ac..327b8afb46b5d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.test.ts @@ -9,10 +9,10 @@ import { getEmptyFindResult, addPrepackagedRulesRequest, getFindResultWithSingleHit, - getAlertMock, + getRuleMock, getBasicEmptySearchResponse, } from '../__mocks__/request_responses'; -import { configMock, requestContextMock, serverMock } from '../__mocks__'; +import { requestContextMock, serverMock } from '../__mocks__'; import { AddPrepackagedRulesSchemaDecoded } from '../../../../../common/detection_engine/schemas/request/add_prepackaged_rules_schema'; import { addPrepackedRulesRoute, createPrepackagedRules } from './add_prepackaged_rules_route'; import { listMock } from '@kbn/lists-plugin/server/mocks'; @@ -74,19 +74,14 @@ describe('add_prepackaged_rules_route', () => { let server: ReturnType; let { clients, context } = requestContextMock.createTools(); let mockExceptionsClient: ExceptionListClient; - const defaultConfig = context.securitySolution.getConfig(); beforeEach(() => { server = serverMock.create(); ({ clients, context } = requestContextMock.createTools()); mockExceptionsClient = listMock.getExceptionListClient(); - context.securitySolution.getConfig.mockImplementation(() => - configMock.withRuleRegistryEnabled(defaultConfig, true) - ); - - clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(true)); - clients.rulesClient.update.mockResolvedValue(getAlertMock(true, getQueryRuleParams())); + clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); + clients.rulesClient.update.mockResolvedValue(getRuleMock(getQueryRuleParams())); (installPrepackagedTimelines as jest.Mock).mockReset(); (installPrepackagedTimelines as jest.Mock).mockResolvedValue({ @@ -106,7 +101,7 @@ describe('add_prepackaged_rules_route', () => { describe('status codes', () => { test('returns 200', async () => { const request = addPrepackagedRulesRequest(); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); }); @@ -116,7 +111,7 @@ describe('add_prepackaged_rules_route', () => { test('1 rule is installed and 0 are updated when find results are empty', async () => { clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); const request = addPrepackagedRulesRequest(); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -129,7 +124,7 @@ describe('add_prepackaged_rules_route', () => { test('1 rule is updated and 0 are installed when we return a single find and the versions are different', async () => { const request = addPrepackagedRulesRequest(); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -159,7 +154,7 @@ describe('add_prepackaged_rules_route', () => { ], }); const request = addPrepackagedRulesRequest(); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.body).toEqual({ rules_installed: 0, rules_updated: 1, @@ -178,7 +173,7 @@ describe('add_prepackaged_rules_route', () => { errors: [], }); const request = addPrepackagedRulesRequest(); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.body).toEqual({ rules_installed: 0, rules_updated: 1, @@ -197,7 +192,7 @@ describe('add_prepackaged_rules_route', () => { errors: [], }); const request = addPrepackagedRulesRequest(); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.body).toEqual({ rules_installed: 0, rules_updated: 1, @@ -224,7 +219,7 @@ describe('add_prepackaged_rules_route', () => { ], }); const request = addPrepackagedRulesRequest(); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.body).toEqual({ rules_installed: 0, rules_updated: 1, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.ts index 0042030ea21ef..145558cd4a104 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.ts @@ -6,7 +6,7 @@ */ import moment from 'moment'; -import { transformError, getIndexExists } from '@kbn/securitysolution-es-utils'; +import { transformError } from '@kbn/securitysolution-es-utils'; import { validate } from '@kbn/securitysolution-io-ts-utils'; import { RulesClient } from '@kbn/alerting-plugin/server'; import { ExceptionListClient } from '@kbn/lists-plugin/server'; @@ -54,10 +54,10 @@ export const addPrepackedRulesRoute = (router: SecuritySolutionPluginRouter) => const siemResponse = buildSiemResponse(response); try { - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const validated = await createPrepackagedRules( - context.securitySolution, + await context.securitySolution, rulesClient, undefined ); @@ -88,7 +88,6 @@ export const createPrepackagedRules = async ( ): Promise => { const config = context.getConfig(); const frameworkRequest = context.getFrameworkRequest(); - const esClient = context.core.elasticsearch.client; const savedObjectsClient = context.core.savedObjects.client; const siemClient = context.getAppClient(); const exceptionsListClient = context.getExceptionListClient() ?? exceptionsClient; @@ -98,7 +97,6 @@ export const createPrepackagedRules = async ( maxTimelineImportExportSize, prebuiltRulesFromFileSystem, prebuiltRulesFromSavedObjects, - experimentalFeatures: { ruleRegistryEnabled }, } = config; if (!siemClient || !rulesClient) { @@ -117,24 +115,12 @@ export const createPrepackagedRules = async ( ); const prepackagedRules = await getExistingPrepackagedRules({ rulesClient, - isRuleRegistryEnabled: ruleRegistryEnabled, }); const rulesToInstall = getRulesToInstall(latestPrepackagedRules, prepackagedRules); const rulesToUpdate = getRulesToUpdate(latestPrepackagedRules, prepackagedRules); const signalsIndex = siemClient.getSignalsIndex(); - if (!ruleRegistryEnabled && (rulesToInstall.length !== 0 || rulesToUpdate.length !== 0)) { - const signalsIndexExists = await getIndexExists(esClient.asCurrentUser, signalsIndex); - if (!signalsIndexExists) { - throw new PrepackagedRulesError( - `Pre-packaged rules cannot be installed until the signals index is created: ${signalsIndex}`, - 400 - ); - } - } - await Promise.all( - installPrepackagedRules(rulesClient, rulesToInstall, signalsIndex, ruleRegistryEnabled) - ); + await Promise.all(installPrepackagedRules(rulesClient, rulesToInstall, signalsIndex)); const timeline = await installPrepackagedTimelines( maxTimelineImportExportSize, frameworkRequest, @@ -149,7 +135,6 @@ export const createPrepackagedRules = async ( savedObjectsClient, rulesToUpdate, signalsIndex, - ruleRegistryEnabled, context.getRuleExecutionLog() ); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.test.ts index 82813b18cbd04..8b23aca24c791 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.test.ts @@ -12,7 +12,7 @@ import { getReadBulkRequest, getFindResultWithSingleHit, getEmptyFindResult, - getAlertMock, + getRuleMock, createBulkMlRuleRequest, getBasicEmptySearchResponse, getBasicNoShardsSearchResponse, @@ -27,10 +27,7 @@ import { loggingSystemMock } from '@kbn/core/server/mocks'; jest.mock('../../../machine_learning/authz', () => mockMlAuthzFactory.create()); -describe.each([ - ['Legacy', false], - ['RAC', true], -])('create_rules_bulk - %s', (_, isRuleRegistryEnabled) => { +describe('create_rules_bulk', () => { let server: ReturnType; let { clients, context } = requestContextMock.createTools(); let ml: ReturnType; @@ -42,19 +39,20 @@ describe.each([ const logger = loggingSystemMock.createLogger(); clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); // no existing rules - clients.rulesClient.create.mockResolvedValue( - getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) - ); // successful creation + clients.rulesClient.create.mockResolvedValue(getRuleMock(getQueryRuleParams())); // successful creation context.core.elasticsearch.client.asCurrentUser.search.mockResolvedValue( elasticsearchClientMock.createSuccessTransportRequestPromise(getBasicEmptySearchResponse()) ); - createRulesBulkRoute(server.router, ml, isRuleRegistryEnabled, logger); + createRulesBulkRoute(server.router, ml, logger); }); describe('status codes', () => { test('returns 200', async () => { - const response = await server.inject(getReadBulkRequest(), context); + const response = await server.inject( + getReadBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); }); @@ -67,7 +65,10 @@ describe.each([ .mockResolvedValue({ valid: false, message: 'mocked validation message' }), }); - const response = await server.inject(createBulkMlRuleRequest(), context); + const response = await server.inject( + createBulkMlRuleRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual([ { @@ -86,27 +87,20 @@ describe.each([ getBasicNoShardsSearchResponse() ) ); - const response = await server.inject(getReadBulkRequest(), context); + const response = await server.inject( + getReadBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); - - if (!isRuleRegistryEnabled) { - expect(response.body).toEqual([ - { - error: { - message: - 'To create a rule, the index must exist first. Index undefined does not exist', - status_code: 400, - }, - rule_id: 'rule-1', - }, - ]); - } }); test('returns a duplicate error if rule_id already exists', async () => { - clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); - const response = await server.inject(getReadBulkRequest(), context); + clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); + const response = await server.inject( + getReadBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual([ @@ -123,7 +117,10 @@ describe.each([ clients.rulesClient.create.mockImplementation(async () => { throw new Error('Test error'); }); - const response = await server.inject(getReadBulkRequest(), context); + const response = await server.inject( + getReadBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual([ @@ -142,7 +139,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_BULK_CREATE, body: [getCreateRulesSchemaMock(), getCreateRulesSchemaMock()], }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual([ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.ts index cf4633b976816..d0028bbf7752b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.ts @@ -6,7 +6,6 @@ */ import { validate } from '@kbn/securitysolution-io-ts-utils'; -import { getIndexExists } from '@kbn/securitysolution-es-utils'; import { Logger } from '@kbn/core/server'; import { createRuleValidateTypeDependents } from '../../../../../common/detection_engine/schemas/request/create_rules_type_dependents'; import { createRulesBulkSchema } from '../../../../../common/detection_engine/schemas/request/create_rules_bulk_schema'; @@ -34,7 +33,6 @@ import { getDeprecatedBulkEndpointHeader, logDeprecatedBulkEndpoint } from './ut export const createRulesBulkRoute = ( router: SecuritySolutionPluginRouter, ml: SetupPlugins['ml'], - isRuleRegistryEnabled: boolean, logger: Logger ) => { router.post( @@ -51,13 +49,15 @@ export const createRulesBulkRoute = ( logDeprecatedBulkEndpoint(logger, DETECTION_ENGINE_RULES_BULK_CREATE); const siemResponse = buildSiemResponse(response); - const rulesClient = context.alerting.getRulesClient(); - const esClient = context.core.elasticsearch.client; - const savedObjectsClient = context.core.savedObjects.client; - const siemClient = context.securitySolution.getAppClient(); + + const ctx = await context.resolve(['core', 'securitySolution', 'licensing', 'alerting']); + + const rulesClient = ctx.alerting.getRulesClient(); + const savedObjectsClient = ctx.core.savedObjects.client; + const siemClient = ctx.securitySolution.getAppClient(); const mlAuthz = buildMlAuthz({ - license: context.licensing.license, + license: ctx.licensing.license, ml, request, savedObjectsClient, @@ -73,7 +73,6 @@ export const createRulesBulkRoute = ( if (payloadRule.rule_id != null) { const rule = await readRules({ id: undefined, - isRuleRegistryEnabled, rulesClient, ruleId: payloadRule.rule_id, }); @@ -85,11 +84,7 @@ export const createRulesBulkRoute = ( }); } } - const internalRule = convertCreateAPIToInternalSchema( - payloadRule, - siemClient, - isRuleRegistryEnabled - ); + const internalRule = convertCreateAPIToInternalSchema(payloadRule, siemClient); try { const validationErrors = createRuleValidateTypeDependents(payloadRule); if (validationErrors.length) { @@ -101,15 +96,6 @@ export const createRulesBulkRoute = ( } throwAuthzError(await mlAuthz.validateRuleType(internalRule.params.type)); - const finalIndex = internalRule.params.outputIndex; - const indexExists = await getIndexExists(esClient.asCurrentUser, finalIndex); - if (!isRuleRegistryEnabled && !indexExists) { - return createBulkErrorObject({ - ruleId: internalRule.params.ruleId, - statusCode: 400, - message: `To create a rule, the index must exist first. Index ${finalIndex} does not exist`, - }); - } const createdRule = await rulesClient.create({ data: internalRule, @@ -120,12 +106,7 @@ export const createRulesBulkRoute = ( await rulesClient.muteAll({ id: createdRule.id }); } - return transformValidateBulkError( - internalRule.params.ruleId, - createdRule, - null, - isRuleRegistryEnabled - ); + return transformValidateBulkError(internalRule.params.ruleId, createdRule, null); } catch (err) { return transformBulkError( internalRule.params.ruleId, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.test.ts index fb2625f149d86..163a6b8e43229 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.test.ts @@ -8,13 +8,12 @@ import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; import { getEmptyFindResult, - getAlertMock, + getRuleMock, getCreateRequest, getRuleExecutionSummarySucceeded, getFindResultWithSingleHit, createMlRuleRequest, getBasicEmptySearchResponse, - getBasicNoShardsSearchResponse, } from '../__mocks__/request_responses'; import { mlServicesMock, mlAuthzMock as mockMlAuthzFactory } from '../../../machine_learning/mocks'; import { buildMlAuthz } from '../../../machine_learning/authz'; @@ -24,12 +23,10 @@ import { getCreateRulesSchemaMock } from '../../../../../common/detection_engine // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { elasticsearchClientMock } from '@kbn/core/server/elasticsearch/client/mocks'; import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; + jest.mock('../../../machine_learning/authz', () => mockMlAuthzFactory.create()); -describe.each([ - ['Legacy', false], - ['RAC', true], -])('create_rules - %s', (_, isRuleRegistryEnabled) => { +describe('create_rules', () => { let server: ReturnType; let { clients, context } = requestContextMock.createTools(); let ml: ReturnType; @@ -40,9 +37,7 @@ describe.each([ ml = mlServicesMock.createSetupContract(); clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); // no current rules - clients.rulesClient.create.mockResolvedValue( - getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) - ); // creation succeeds + clients.rulesClient.create.mockResolvedValue(getRuleMock(getQueryRuleParams())); // creation succeeds clients.ruleExecutionLog.getExecutionSummary.mockResolvedValue( getRuleExecutionSummarySucceeded() ); @@ -50,26 +45,35 @@ describe.each([ context.core.elasticsearch.client.asCurrentUser.search.mockResolvedValue( elasticsearchClientMock.createSuccessTransportRequestPromise(getBasicEmptySearchResponse()) ); - createRulesRoute(server.router, ml, isRuleRegistryEnabled); + createRulesRoute(server.router, ml); }); describe('status codes', () => { test('returns 200 with a rule created via RulesClient', async () => { - const response = await server.inject(getCreateRequest(), context); + const response = await server.inject( + getCreateRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 200 if license is not platinum', async () => { (context.licensing.license.hasAtLeast as jest.Mock).mockReturnValue(false); - const response = await server.inject(getCreateRequest(), context); + const response = await server.inject( + getCreateRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); }); describe('creating an ML Rule', () => { test('is successful', async () => { - const response = await server.inject(createMlRuleRequest(), context); + const response = await server.inject( + createMlRuleRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); @@ -80,7 +84,10 @@ describe.each([ .mockResolvedValue({ valid: false, message: 'mocked validation message' }), }); - const response = await server.inject(createMlRuleRequest(), context); + const response = await server.inject( + createMlRuleRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(403); expect(response.body).toEqual({ message: 'mocked validation message', @@ -90,27 +97,12 @@ describe.each([ }); describe('unhappy paths', () => { - test('it returns a 400 if the index does not exist when rule registry not enabled', async () => { - context.core.elasticsearch.client.asCurrentUser.search.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise( - getBasicNoShardsSearchResponse() - ) - ); - const response = await server.inject(getCreateRequest(), context); - - expect(response.status).toEqual(isRuleRegistryEnabled ? 200 : 400); - - if (!isRuleRegistryEnabled) { - expect(response.body).toEqual({ - message: 'To create a rule, the index must exist first. Index undefined does not exist', - status_code: 400, - }); - } - }); - test('returns a duplicate error if rule_id already exists', async () => { - clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); - const response = await server.inject(getCreateRequest(), context); + clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); + const response = await server.inject( + getCreateRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(409); expect(response.body).toEqual({ @@ -123,7 +115,10 @@ describe.each([ clients.rulesClient.create.mockImplementation(async () => { throw new Error('Test error'); }); - const response = await server.inject(getCreateRequest(), context); + const response = await server.inject( + getCreateRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.ts index fe39c5cb9680e..b44b2fd0bd6a5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { transformError, getIndexExists } from '@kbn/securitysolution-es-utils'; +import { transformError } from '@kbn/securitysolution-es-utils'; import { buildRouteValidation } from '../../../../utils/build_validation/route_validation'; import { DETECTION_ENGINE_RULES_URL, @@ -25,8 +25,7 @@ import { convertCreateAPIToInternalSchema } from '../../schemas/rule_converters' export const createRulesRoute = ( router: SecuritySolutionPluginRouter, - ml: SetupPlugins['ml'], - isRuleRegistryEnabled: boolean + ml: SetupPlugins['ml'] ): void => { router.post( { @@ -46,15 +45,21 @@ export const createRulesRoute = ( } try { - const rulesClient = context.alerting.getRulesClient(); - const ruleExecutionLog = context.securitySolution.getRuleExecutionLog(); - const esClient = context.core.elasticsearch.client; - const savedObjectsClient = context.core.savedObjects.client; - const siemClient = context.securitySolution.getAppClient(); + const ctx = await context.resolve([ + 'core', + 'securitySolution', + 'licensing', + 'alerting', + 'lists', + ]); + + const rulesClient = ctx.alerting.getRulesClient(); + const ruleExecutionLog = ctx.securitySolution.getRuleExecutionLog(); + const savedObjectsClient = ctx.core.savedObjects.client; + const siemClient = ctx.securitySolution.getAppClient(); if (request.body.rule_id != null) { const rule = await readRules({ - isRuleRegistryEnabled, rulesClient, ruleId: request.body.rule_id, id: undefined, @@ -67,33 +72,18 @@ export const createRulesRoute = ( } } - const internalRule = convertCreateAPIToInternalSchema( - request.body, - siemClient, - isRuleRegistryEnabled - ); + const internalRule = convertCreateAPIToInternalSchema(request.body, siemClient); const mlAuthz = buildMlAuthz({ - license: context.licensing.license, + license: ctx.licensing.license, ml, request, savedObjectsClient, }); throwAuthzError(await mlAuthz.validateRuleType(internalRule.params.type)); - const indexExists = await getIndexExists( - esClient.asCurrentUser, - internalRule.params.outputIndex - ); - if (!isRuleRegistryEnabled && !indexExists) { - return siemResponse.error({ - statusCode: 400, - body: `To create a rule, the index must exist first. Index ${internalRule.params.outputIndex} does not exist`, - }); - } - // This will create the endpoint list if it does not exist yet - await context.lists?.getExceptionListClient().createEndpointList(); + await ctx.lists?.getExceptionListClient().createEndpointList(); const createdRule = await rulesClient.create({ data: internalRule, @@ -106,11 +96,7 @@ export const createRulesRoute = ( const ruleExecutionSummary = await ruleExecutionLog.getExecutionSummary(createdRule.id); - const [validated, errors] = newTransformValidate( - createdRule, - ruleExecutionSummary, - isRuleRegistryEnabled - ); + const [validated, errors] = newTransformValidate(createdRule, ruleExecutionSummary); if (errors != null) { return siemResponse.error({ statusCode: 500, body: errors }); } else { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.test.ts index c8d1628ded783..01683599e4cf6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.test.ts @@ -19,10 +19,7 @@ import { requestContextMock, serverMock, requestMock } from '../__mocks__'; import { deleteRulesBulkRoute } from './delete_rules_bulk_route'; import { loggingSystemMock } from '@kbn/core/server/mocks'; -describe.each([ - ['Legacy', false], - ['RAC', true], -])('delete_rules - %s', (_, isRuleRegistryEnabled) => { +describe('delete_rules', () => { let server: ReturnType; let { clients, context } = requestContextMock.createTools(); @@ -31,49 +28,70 @@ describe.each([ ({ clients, context } = requestContextMock.createTools()); const logger = loggingSystemMock.createLogger(); - clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); // rule exists + clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); // rule exists clients.rulesClient.delete.mockResolvedValue({}); // successful deletion clients.savedObjectsClient.find.mockResolvedValue(getEmptySavedObjectsResponse()); // rule status request - deleteRulesBulkRoute(server.router, isRuleRegistryEnabled, logger); + deleteRulesBulkRoute(server.router, logger); }); describe('status codes with actionClient and alertClient', () => { test('returns 200 when deleting a single rule with a valid actionClient and alertClient by alertId', async () => { - const response = await server.inject(getDeleteBulkRequest(), context); + const response = await server.inject( + getDeleteBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 200 when deleting a single rule and related rule status', async () => { - const response = await server.inject(getDeleteBulkRequest(), context); + const response = await server.inject( + getDeleteBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 200 when deleting a single rule with a valid actionClient and alertClient by alertId using POST', async () => { - const response = await server.inject(getDeleteAsPostBulkRequest(), context); + const response = await server.inject( + getDeleteAsPostBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 200 when deleting a single rule with a valid actionClient and alertClient by id', async () => { - const response = await server.inject(getDeleteBulkRequestById(), context); + const response = await server.inject( + getDeleteBulkRequestById(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 200 when deleting a single rule with a valid actionClient and alertClient by id using POST', async () => { - const response = await server.inject(getDeleteAsPostBulkRequestById(), context); + const response = await server.inject( + getDeleteAsPostBulkRequestById(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 200 because the error is in the payload when deleting a single rule that does not exist with a valid actionClient and alertClient', async () => { clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); - const response = await server.inject(getDeleteBulkRequest(), context); + const response = await server.inject( + getDeleteBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 404 in the payload when deleting a single rule that does not exist with a valid actionClient and alertClient', async () => { clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); - const response = await server.inject(getDeleteBulkRequest(), context); + const response = await server.inject( + getDeleteBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual( expect.arrayContaining([ @@ -93,7 +111,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_BULK_DELETE, body: [{}], }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual([ { @@ -109,7 +127,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_BULK_DELETE, body: [{ id: 'c1e1b359-7ac1-4e96-bc81-c683c092436f', rule_id: 'rule_1' }], }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual([ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts index 674427a0b9229..273d65a5f021b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts @@ -40,11 +40,7 @@ type Handler = RequestHandler< /** * @deprecated since version 8.2.0. Use the detection_engine/rules/_bulk_action API instead */ -export const deleteRulesBulkRoute = ( - router: SecuritySolutionPluginRouter, - isRuleRegistryEnabled: boolean, - logger: Logger -) => { +export const deleteRulesBulkRoute = (router: SecuritySolutionPluginRouter, logger: Logger) => { const config: Config = { validate: { body: buildRouteValidation( @@ -60,9 +56,12 @@ export const deleteRulesBulkRoute = ( logDeprecatedBulkEndpoint(logger, DETECTION_ENGINE_RULES_BULK_DELETE); const siemResponse = buildSiemResponse(response); - const rulesClient = context.alerting.getRulesClient(); - const ruleExecutionLog = context.securitySolution.getRuleExecutionLog(); - const savedObjectsClient = context.core.savedObjects.client; + + const ctx = await context.resolve(['core', 'securitySolution', 'alerting']); + + const rulesClient = ctx.alerting.getRulesClient(); + const ruleExecutionLog = ctx.securitySolution.getRuleExecutionLog(); + const savedObjectsClient = ctx.core.savedObjects.client; const rules = await Promise.all( request.body.map(async (payloadRule) => { @@ -78,7 +77,7 @@ export const deleteRulesBulkRoute = ( } try { - const rule = await readRules({ rulesClient, id, ruleId, isRuleRegistryEnabled }); + const rule = await readRules({ rulesClient, id, ruleId }); const migratedRule = await legacyMigrate({ rulesClient, savedObjectsClient, @@ -99,8 +98,7 @@ export const deleteRulesBulkRoute = ( return transformValidateBulkError( idOrRuleIdOrUnknown, migratedRule, - ruleExecutionSummary, - isRuleRegistryEnabled + ruleExecutionSummary ); } catch (err) { return transformBulkError(idOrRuleIdOrUnknown, err); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts index b18e330eab5a4..83a40005d0148 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts @@ -8,7 +8,7 @@ import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; import { getEmptyFindResult, - resolveAlertMock, + resolveRuleMock, getDeleteRequest, getFindResultWithSingleHit, getDeleteRequestById, @@ -18,10 +18,7 @@ import { requestContextMock, serverMock, requestMock } from '../__mocks__'; import { deleteRulesRoute } from './delete_rules_route'; import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; -describe.each([ - ['Legacy', false], - ['RAC', true], -])('delete_rules - %s', (_, isRuleRegistryEnabled) => { +describe('delete_rules', () => { let server: ReturnType; let { clients, context } = requestContextMock.createTools(); @@ -29,31 +26,38 @@ describe.each([ server = serverMock.create(); ({ clients, context } = requestContextMock.createTools()); - clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); + clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); clients.savedObjectsClient.find.mockResolvedValue(getEmptySavedObjectsResponse()); - deleteRulesRoute(server.router, isRuleRegistryEnabled); + deleteRulesRoute(server.router); }); describe('status codes with actionClient and alertClient', () => { test('returns 200 when deleting a single rule with a valid actionClient and alertClient by alertId', async () => { - const response = await server.inject(getDeleteRequest(), context); + const response = await server.inject( + getDeleteRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 200 when deleting a single rule with a valid actionClient and alertClient by id', async () => { - clients.rulesClient.resolve.mockResolvedValue( - resolveAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) + clients.rulesClient.resolve.mockResolvedValue(resolveRuleMock(getQueryRuleParams())); + const response = await server.inject( + getDeleteRequestById(), + requestContextMock.convertContext(context) ); - const response = await server.inject(getDeleteRequestById(), context); expect(response.status).toEqual(200); }); test('returns 404 when deleting a single rule that does not exist with a valid actionClient and alertClient', async () => { clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); - const response = await server.inject(getDeleteRequest(), context); + const response = await server.inject( + getDeleteRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(404); expect(response.body).toEqual({ @@ -66,7 +70,10 @@ describe.each([ clients.rulesClient.delete.mockImplementation(async () => { throw new Error('Test error'); }); - const response = await server.inject(getDeleteRequest(), context); + const response = await server.inject( + getDeleteRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', @@ -82,7 +89,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_URL, query: {}, }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(400); expect(response.body).toEqual({ message: ['either "id" or "rule_id" must be set'], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.ts index 5e2382cfe640a..beb2cf94c047a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.ts @@ -21,10 +21,7 @@ import { buildSiemResponse } from '../utils'; import { readRules } from '../../rules/read_rules'; import { legacyMigrate } from '../../rules/utils'; -export const deleteRulesRoute = ( - router: SecuritySolutionPluginRouter, - isRuleRegistryEnabled: boolean -) => { +export const deleteRulesRoute = (router: SecuritySolutionPluginRouter) => { router.delete( { path: DETECTION_ENGINE_RULES_URL, @@ -47,11 +44,12 @@ export const deleteRulesRoute = ( try { const { id, rule_id: ruleId } = request.query; - const rulesClient = context.alerting.getRulesClient(); - const ruleExecutionLog = context.securitySolution.getRuleExecutionLog(); - const savedObjectsClient = context.core.savedObjects.client; + const ctx = await context.resolve(['core', 'securitySolution', 'alerting']); + const rulesClient = ctx.alerting.getRulesClient(); + const ruleExecutionLog = ctx.securitySolution.getRuleExecutionLog(); + const savedObjectsClient = ctx.core.savedObjects.client; - const rule = await readRules({ isRuleRegistryEnabled, rulesClient, id, ruleId }); + const rule = await readRules({ rulesClient, id, ruleId }); const migratedRule = await legacyMigrate({ rulesClient, savedObjectsClient, @@ -74,7 +72,7 @@ export const deleteRulesRoute = ( ruleExecutionLog, }); - const transformed = transform(migratedRule, ruleExecutionSummary, isRuleRegistryEnabled); + const transformed = transform(migratedRule, ruleExecutionSummary); if (transformed == null) { return siemResponse.error({ statusCode: 500, body: 'failed to transform alert' }); } else { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/export_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/export_rules_route.ts index de66a6e5a9d99..f21df4556327a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/export_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/export_rules_route.ts @@ -25,8 +25,7 @@ import { buildSiemResponse } from '../utils'; export const exportRulesRoute = ( router: SecuritySolutionPluginRouter, config: ConfigType, - logger: Logger, - isRuleRegistryEnabled: boolean + logger: Logger ) => { router.post( { @@ -45,9 +44,9 @@ export const exportRulesRoute = ( }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); - const rulesClient = context.alerting.getRulesClient(); - const exceptionsClient = context.lists?.getExceptionListClient(); - const savedObjectsClient = context.core.savedObjects.client; + const rulesClient = (await context.alerting).getRulesClient(); + const exceptionsClient = (await context.lists)?.getExceptionListClient(); + const savedObjectsClient = (await context.core).savedObjects.client; try { const exportSizeLimit = config.maxRuleImportExportSize; @@ -58,7 +57,6 @@ export const exportRulesRoute = ( }); } else { const nonPackagedRulesCount = await getNonPackagedRulesCount({ - isRuleRegistryEnabled, rulesClient, }); if (nonPackagedRulesCount > exportSizeLimit) { @@ -76,16 +74,9 @@ export const exportRulesRoute = ( exceptionsClient, savedObjectsClient, request.body.objects, - logger, - isRuleRegistryEnabled + logger ) - : await getExportAll( - rulesClient, - exceptionsClient, - savedObjectsClient, - logger, - isRuleRegistryEnabled - ); + : await getExportAll(rulesClient, exceptionsClient, savedObjectsClient, logger); const responseBody = request.query.exclude_export_details ? exportedRulesAndExceptions.rulesNdjson diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.test.ts index 6183bc78b9160..b4aada2a60b69 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.test.ts @@ -10,7 +10,7 @@ import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; import { requestContextMock, requestMock, serverMock } from '../__mocks__'; import { - getAlertMock, + getRuleMock, getFindRequest, getFindResultWithSingleHit, getEmptySavedObjectsResponse, @@ -18,10 +18,7 @@ import { } from '../__mocks__/request_responses'; import { findRulesRoute } from './find_rules_route'; -describe.each([ - ['Legacy', false], - ['RAC', true], -])('find_rules - %s', (_, isRuleRegistryEnabled) => { +describe('find_rules', () => { let server: ReturnType; let { clients, context } = requestContextMock.createTools(); let logger: ReturnType; @@ -31,21 +28,22 @@ describe.each([ logger = loggingSystemMock.createLogger(); ({ clients, context } = requestContextMock.createTools()); - clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); - clients.rulesClient.get.mockResolvedValue( - getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) - ); + clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); + clients.rulesClient.get.mockResolvedValue(getRuleMock(getQueryRuleParams())); clients.savedObjectsClient.find.mockResolvedValue(getEmptySavedObjectsResponse()); clients.ruleExecutionLog.getExecutionSummariesBulk.mockResolvedValue( getRuleExecutionSummaries() ); - findRulesRoute(server.router, logger, isRuleRegistryEnabled); + findRulesRoute(server.router, logger); }); describe('status codes', () => { test('returns 200', async () => { - const response = await server.inject(getFindRequest(), context); + const response = await server.inject( + getFindRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); @@ -53,7 +51,10 @@ describe.each([ clients.rulesClient.find.mockImplementation(async () => { throw new Error('Test error'); }); - const response = await server.inject(getFindRequest(), context); + const response = await server.inject( + getFindRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.ts index e3749888c2d8f..eac8c4a5001d7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.ts @@ -22,11 +22,7 @@ import { transformFindAlerts } from './utils'; // eslint-disable-next-line no-restricted-imports import { legacyGetBulkRuleActionsSavedObject } from '../../rule_actions/legacy_get_bulk_rule_actions_saved_object'; -export const findRulesRoute = ( - router: SecuritySolutionPluginRouter, - logger: Logger, - isRuleRegistryEnabled: boolean -) => { +export const findRulesRoute = (router: SecuritySolutionPluginRouter, logger: Logger) => { router.get( { path: `${DETECTION_ENGINE_RULES_URL}/_find`, @@ -49,12 +45,12 @@ export const findRulesRoute = ( try { const { query } = request; - const rulesClient = context.alerting.getRulesClient(); - const ruleExecutionLog = context.securitySolution.getRuleExecutionLog(); - const savedObjectsClient = context.core.savedObjects.client; + const ctx = await context.resolve(['core', 'securitySolution', 'alerting']); + const rulesClient = ctx.alerting.getRulesClient(); + const ruleExecutionLog = ctx.securitySolution.getRuleExecutionLog(); + const savedObjectsClient = ctx.core.savedObjects.client; const rules = await findRules({ - isRuleRegistryEnabled, rulesClient, perPage: query.per_page, page: query.page, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts index 10be2ac921c10..2883d9af0f9ed 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts @@ -51,10 +51,7 @@ jest.mock('../../../timeline/utils/check_timelines_status', () => { }; }); -describe.each([ - ['Legacy', false], - ['RAC', true], -])('get_prepackaged_rule_status_route - %s', (_, isRuleRegistryEnabled) => { +describe('get_prepackaged_rule_status_route', () => { const mockGetCurrentUser = { user: { username: 'mockUser', @@ -85,17 +82,15 @@ describe.each([ prepackagedTimelines: [], }); - getPrepackagedRulesStatusRoute( - server.router, - createMockConfig(), - securitySetup, - isRuleRegistryEnabled - ); + getPrepackagedRulesStatusRoute(server.router, createMockConfig(), securitySetup); }); describe('status codes', () => { test('returns 200', async () => { - const response = await server.inject(getPrepackagedRulesStatusRequest(), context); + const response = await server.inject( + getPrepackagedRulesStatusRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); @@ -103,7 +98,10 @@ describe.each([ clients.rulesClient.find.mockImplementation(async () => { throw new Error('Test error'); }); - const response = await server.inject(getPrepackagedRulesStatusRequest(), context); + const response = await server.inject( + getPrepackagedRulesStatusRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', @@ -116,7 +114,7 @@ describe.each([ test('0 rules installed, 0 custom rules, 1 rules not installed, and 1 rule not updated', async () => { clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); const request = getPrepackagedRulesStatusRequest(); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -131,9 +129,9 @@ describe.each([ }); test('1 rule installed, 1 custom rules, 0 rules not installed, and 1 rule to not updated', async () => { - clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); + clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); const request = getPrepackagedRulesStatusRequest(); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -153,7 +151,7 @@ describe.each([ mockCheckTimelinesStatusBeforeInstallResult ); const request = getPrepackagedRulesStatusRequest(); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -173,7 +171,7 @@ describe.each([ mockCheckTimelinesStatusAfterInstallResult ); const request = getPrepackagedRulesStatusRequest(); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.ts index 4fcf1bd992c6a..0f70a12e463cf 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.ts @@ -32,8 +32,7 @@ import { export const getPrepackagedRulesStatusRoute = ( router: SecuritySolutionPluginRouter, config: ConfigType, - security: SetupPlugins['security'], - isRuleRegistryEnabled: boolean + security: SetupPlugins['security'] ) => { router.get( { @@ -45,8 +44,9 @@ export const getPrepackagedRulesStatusRoute = ( }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); - const savedObjectsClient = context.core.savedObjects.client; - const rulesClient = context.alerting.getRulesClient(); + const ctx = await context.resolve(['core', 'alerting']); + const savedObjectsClient = ctx.core.savedObjects.client; + const rulesClient = ctx.alerting.getRulesClient(); const ruleAssetsClient = ruleAssetSavedObjectsClientFactory(savedObjectsClient); try { @@ -56,19 +56,17 @@ export const getPrepackagedRulesStatusRoute = ( config.prebuiltRulesFromSavedObjects ); const customRules = await findRules({ - isRuleRegistryEnabled, rulesClient, perPage: 1, page: 1, sortField: 'enabled', sortOrder: 'desc', - filter: 'alert.attributes.tags:"__internal_immutable:false"', + filter: 'alert.attributes.params.immutable: false', fields: undefined, }); const frameworkRequest = await buildFrameworkRequest(context, security, request); const prepackagedRules = await getExistingPrepackagedRules({ rulesClient, - isRuleRegistryEnabled, }); const rulesToInstall = getRulesToInstall(latestPrepackagedRules, prepackagedRules); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_rule_execution_events_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_rule_execution_events_route.test.ts index b24789d77a9bb..37b1f41328674 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_rule_execution_events_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_rule_execution_events_route.test.ts @@ -30,7 +30,10 @@ describe('getRuleExecutionEventsRoute', () => { const executionEvents = getAggregateExecutionEvents(); clients.ruleExecutionLog.getAggregateExecutionEvents.mockResolvedValue(executionEvents); - const response = await server.inject(getRuleExecutionEventsRequest(), context); + const response = await server.inject( + getRuleExecutionEventsRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual(executionEvents); @@ -41,7 +44,10 @@ describe('getRuleExecutionEventsRoute', () => { it('returns 500 response with it', async () => { clients.ruleExecutionLog.getAggregateExecutionEvents.mockRejectedValue(new Error('Boom!')); - const response = await server.inject(getRuleExecutionEventsRequest(), context); + const response = await server.inject( + getRuleExecutionEventsRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_rule_execution_events_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_rule_execution_events_route.ts index 76088cd07b80e..6bd6610c9c912 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_rule_execution_events_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_rule_execution_events_route.ts @@ -48,7 +48,7 @@ export const getRuleExecutionEventsRoute = (router: SecuritySolutionPluginRouter const siemResponse = buildSiemResponse(response); try { - const executionLog = context.securitySolution.getRuleExecutionLog(); + const executionLog = (await context.securitySolution).getRuleExecutionLog(); const { events, total } = await executionLog.getAggregateExecutionEvents({ ruleId, start, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.test.ts index 63c25da1c2d4c..c2aea239f6569 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.test.ts @@ -10,10 +10,9 @@ import { getImportRulesRequest, getImportRulesRequestOverwriteTrue, getEmptyFindResult, - getAlertMock, + getRuleMock, getFindResultWithSingleHit, getBasicEmptySearchResponse, - getBasicNoShardsSearchResponse, } from '../__mocks__/request_responses'; import { createMockConfig, requestContextMock, serverMock, requestMock } from '../__mocks__'; import { mlServicesMock, mlAuthzMock as mockMlAuthzFactory } from '../../../machine_learning/mocks'; @@ -31,10 +30,7 @@ import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; jest.mock('../../../machine_learning/authz', () => mockMlAuthzFactory.create()); -describe.each([ - ['Legacy', false], - ['RAC', true], -])('import_rules_route - %s', (_, isRuleRegistryEnabled) => { +describe('import_rules_route', () => { let config: ReturnType; let server: ReturnType; let request: ReturnType; @@ -50,19 +46,17 @@ describe.each([ ml = mlServicesMock.createSetupContract(); clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); // no extant rules - clients.rulesClient.update.mockResolvedValue( - getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) - ); + clients.rulesClient.update.mockResolvedValue(getRuleMock(getQueryRuleParams())); clients.actionsClient.getAll.mockResolvedValue([]); context.core.elasticsearch.client.asCurrentUser.search.mockResolvedValue( elasticsearchClientMock.createSuccessTransportRequestPromise(getBasicEmptySearchResponse()) ); - importRulesRoute(server.router, config, ml, isRuleRegistryEnabled); + importRulesRoute(server.router, config, ml); }); describe('status codes', () => { test('returns 200 when importing a single rule with a valid actionClient and alertClient', async () => { - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); }); @@ -70,7 +64,10 @@ describe.each([ test('returns 500 if more than 10,000 rules are imported', async () => { const ruleIds = new Array(10001).fill(undefined).map((__, index) => `rule-${index}`); const multiRequest = getImportRulesRequest(buildHapiStream(ruleIdsToNdJsonString(ruleIds))); - const response = await server.inject(multiRequest, context); + const response = await server.inject( + multiRequest, + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ @@ -81,14 +78,14 @@ describe.each([ }); describe('unhappy paths', () => { - it('returns a 403 error object if ML Authz fails', async () => { + test('returns a 403 error object if ML Authz fails', async () => { (buildMlAuthz as jest.Mock).mockReturnValueOnce({ validateRuleType: jest .fn() .mockResolvedValue({ valid: false, message: 'mocked validation message' }), }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual({ errors: [ @@ -114,50 +111,17 @@ describe.each([ .mockImplementation(() => { throw new Error('Test error'); }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', status_code: 500 }); transformMock.mockRestore(); }); - test('returns an error if the index does not exist when rule registry not enabled', async () => { - clients.appClient.getSignalsIndex.mockReturnValue('mockSignalsIndex'); - context.core.elasticsearch.client.asCurrentUser.search.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise( - getBasicNoShardsSearchResponse() - ) - ); - const response = await server.inject(request, context); - expect(response.status).toEqual(isRuleRegistryEnabled ? 200 : 400); - if (!isRuleRegistryEnabled) { - expect(response.body).toEqual({ - message: - 'To create a rule, the index must exist first. Index mockSignalsIndex does not exist', - status_code: 400, - }); - } - }); - - test('returns an error when cluster throws error', async () => { - context.core.elasticsearch.client.asCurrentUser.search.mockResolvedValue( - elasticsearchClientMock.createErrorTransportRequestPromise({ - body: new Error('Test error'), - }) - ); - - const response = await server.inject(request, context); - expect(response.status).toEqual(500); - expect(response.body).toEqual({ - message: 'Test error', - status_code: 500, - }); - }); - test('returns 400 if file extension type is not .ndjson', async () => { const requestPayload = buildHapiStream(ruleIdsToNdJsonString(['rule-1']), 'wrong.html'); const badRequest = getImportRulesRequest(requestPayload); - const response = await server.inject(badRequest, context); + const response = await server.inject(badRequest, requestContextMock.convertContext(context)); expect(response.status).toEqual(400); expect(response.body).toEqual({ message: 'Invalid file extension .html', status_code: 400 }); @@ -166,10 +130,8 @@ describe.each([ describe('single rule import', () => { test('returns 200 if rule imported successfully', async () => { - clients.rulesClient.create.mockResolvedValue( - getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) - ); - const response = await server.inject(request, context); + clients.rulesClient.create.mockResolvedValue(getRuleMock(getQueryRuleParams())); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual({ errors: [], @@ -184,7 +146,7 @@ describe.each([ test('returns reported conflict if error parsing rule', async () => { const requestPayload = buildHapiStream('this is not a valid ndjson string!'); const badRequest = getImportRulesRequest(requestPayload); - const response = await server.inject(badRequest, context); + const response = await server.inject(badRequest, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -207,10 +169,8 @@ describe.each([ describe('rule with existing rule_id', () => { test('returns with reported conflict if `overwrite` is set to `false`', async () => { - clients.rulesClient.find.mockResolvedValue( - getFindResultWithSingleHit(isRuleRegistryEnabled) - ); // extant rule - const response = await server.inject(request, context); + clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); // extant rule + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -232,13 +192,14 @@ describe.each([ }); test('returns with NO reported conflict if `overwrite` is set to `true`', async () => { - clients.rulesClient.find.mockResolvedValue( - getFindResultWithSingleHit(isRuleRegistryEnabled) - ); // extant rule + clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); // extant rule const overwriteRequest = getImportRulesRequestOverwriteTrue( buildHapiStream(ruleIdsToNdJsonString(['rule-1'])) ); - const response = await server.inject(overwriteRequest, context); + const response = await server.inject( + overwriteRequest, + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -258,7 +219,10 @@ describe.each([ const multiRequest = getImportRulesRequest( buildHapiStream(ruleIdsToNdJsonString(['rule-1', 'rule-2'])) ); - const response = await server.inject(multiRequest, context); + const response = await server.inject( + multiRequest, + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -274,7 +238,10 @@ describe.each([ test('returns 200 if many rules are imported successfully', async () => { const ruleIds = new Array(9999).fill(undefined).map((__, index) => `rule-${index}`); const multiRequest = getImportRulesRequest(buildHapiStream(ruleIdsToNdJsonString(ruleIds))); - const response = await server.inject(multiRequest, context); + const response = await server.inject( + multiRequest, + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -298,7 +265,7 @@ describe.each([ const badPayload = buildHapiStream(rulesToNdJsonString(rulesWithoutRuleIds)); const badRequest = getImportRulesRequest(badPayload); - const response = await server.inject(badRequest, context); + const response = await server.inject(badRequest, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -331,7 +298,10 @@ describe.each([ const multiRequest = getImportRulesRequest( buildHapiStream(ruleIdsToNdJsonString(['rule-1', 'rule-1'])) ); - const response = await server.inject(multiRequest, context); + const response = await server.inject( + multiRequest, + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -357,7 +327,10 @@ describe.each([ buildHapiStream(ruleIdsToNdJsonString(['rule-1', 'rule-1'])) ); - const response = await server.inject(multiRequest, context); + const response = await server.inject( + multiRequest, + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual({ errors: [], @@ -372,16 +345,17 @@ describe.each([ describe('rules with existing rule_id', () => { beforeEach(() => { - clients.rulesClient.find.mockResolvedValueOnce( - getFindResultWithSingleHit(isRuleRegistryEnabled) - ); // extant rule + clients.rulesClient.find.mockResolvedValueOnce(getFindResultWithSingleHit()); // extant rule }); test('returns with reported conflict if `overwrite` is set to `false`', async () => { const multiRequest = getImportRulesRequest( buildHapiStream(ruleIdsToNdJsonString(['rule-1', 'rule-2', 'rule-3'])) ); - const response = await server.inject(multiRequest, context); + const response = await server.inject( + multiRequest, + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual({ errors: [ @@ -405,7 +379,10 @@ describe.each([ const multiRequest = getImportRulesRequestOverwriteTrue( buildHapiStream(ruleIdsToNdJsonString(['rule-1', 'rule-2', 'rule-3'])) ); - const response = await server.inject(multiRequest, context); + const response = await server.inject( + multiRequest, + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual({ errors: [], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.ts index b0f09a8c76d3c..2a344cfb76307 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.ts @@ -10,7 +10,7 @@ import { extname } from 'path'; import { schema } from '@kbn/config-schema'; import { createPromiseFromStreams } from '@kbn/utils'; -import { transformError, getIndexExists } from '@kbn/securitysolution-es-utils'; +import { transformError } from '@kbn/securitysolution-es-utils'; import { validate } from '@kbn/securitysolution-io-ts-utils'; import { ImportQuerySchemaDecoded, importQuerySchema } from '@kbn/securitysolution-io-ts-types'; @@ -52,8 +52,7 @@ const CHUNK_PARSED_OBJECT_SIZE = 50; export const importRulesRoute = ( router: SecuritySolutionPluginRouter, config: ConfigType, - ml: SetupPlugins['ml'], - isRuleRegistryEnabled: boolean + ml: SetupPlugins['ml'] ) => { router.post( { @@ -76,18 +75,25 @@ export const importRulesRoute = ( const siemResponse = buildSiemResponse(response); try { - const rulesClient = context.alerting.getRulesClient(); - const actionsClient = context.actions.getActionsClient(); - const esClient = context.core.elasticsearch.client; - const actionSOClient = context.core.savedObjects.getClient({ + const ctx = await context.resolve([ + 'core', + 'securitySolution', + 'alerting', + 'actions', + 'lists', + 'licensing', + ]); + + const rulesClient = ctx.alerting.getRulesClient(); + const actionsClient = ctx.actions.getActionsClient(); + const actionSOClient = ctx.core.savedObjects.getClient({ includedHiddenTypes: ['action'], }); - const savedObjectsClient = context.core.savedObjects.client; - const siemClient = context.securitySolution.getAppClient(); - const exceptionsClient = context.lists?.getExceptionListClient(); + const savedObjectsClient = ctx.core.savedObjects.client; + const exceptionsClient = ctx.lists?.getExceptionListClient(); const mlAuthz = buildMlAuthz({ - license: context.licensing.license, + license: ctx.licensing.license, ml, request, savedObjectsClient, @@ -102,14 +108,6 @@ export const importRulesRoute = ( }); } - const signalsIndex = siemClient.getSignalsIndex(); - const indexExists = await getIndexExists(esClient.asCurrentUser, signalsIndex); - if (!isRuleRegistryEnabled && !indexExists) { - return siemResponse.error({ - statusCode: 400, - body: `To create a rule, the index must exist first. Index ${signalsIndex} does not exist`, - }); - } const objectLimit = config.maxRuleImportExportSize; // parse file to separate out exceptions from rules @@ -171,9 +169,7 @@ export const importRulesRoute = ( rulesClient, savedObjectsClient, exceptionsClient, - isRuleRegistryEnabled, - spaceId: context.securitySolution.getSpaceId(), - signalsIndex, + spaceId: ctx.securitySolution.getSpaceId(), existingLists: foundReferencedExceptionLists, }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/legacy_create_legacy_notification.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/legacy_create_legacy_notification.ts index 728c5c479007b..ffccedb691db4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/legacy_create_legacy_notification.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/legacy_create_legacy_notification.ts @@ -16,8 +16,6 @@ import { legacyReadNotifications } from '../../notifications/legacy_read_notific // eslint-disable-next-line no-restricted-imports import { LegacyRuleNotificationAlertTypeParams } from '../../notifications/legacy_types'; // eslint-disable-next-line no-restricted-imports -import { legacyAddTags } from '../../notifications/legacy_add_tags'; -// eslint-disable-next-line no-restricted-imports import { legacyCreateNotifications } from '../../notifications/legacy_create_notifications'; /** @@ -56,8 +54,8 @@ export const legacyCreateLegacyNotificationRoute = ( }, }, async (context, request, response) => { - const rulesClient = context.alerting.getRulesClient(); - const savedObjectsClient = context.core.savedObjects.client; + const rulesClient = (await context.alerting).getRulesClient(); + const savedObjectsClient = (await context.core).savedObjects.client; const { alert_id: ruleAlertId } = request.query; const { actions, interval, name } = request.body; try { @@ -72,7 +70,7 @@ export const legacyCreateLegacyNotificationRoute = ( await rulesClient.update({ id: notification.id, data: { - tags: legacyAddTags([], ruleAlertId), + tags: [], name, schedule: { interval, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.test.ts index 8285c2dad45a8..6abac6e946380 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.test.ts @@ -15,7 +15,7 @@ import { getEmptyFindResult, getFindResultWithSingleHit, getPatchBulkRequest, - getAlertMock, + getRuleMock, typicalMlRulePayload, } from '../__mocks__/request_responses'; import { serverMock, requestContextMock, requestMock } from '../__mocks__'; @@ -26,10 +26,7 @@ import { loggingSystemMock } from '@kbn/core/server/mocks'; jest.mock('../../../machine_learning/authz', () => mockMlAuthzFactory.create()); -describe.each([ - ['Legacy', false], - ['RAC', true], -])('patch_rules_bulk - %s', (_, isRuleRegistryEnabled) => { +describe('patch_rules_bulk', () => { let server: ReturnType; let { clients, context } = requestContextMock.createTools(); let ml: ReturnType; @@ -40,23 +37,27 @@ describe.each([ ml = mlServicesMock.createSetupContract(); const logger = loggingSystemMock.createLogger(); - clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); // rule exists - clients.rulesClient.update.mockResolvedValue( - getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) - ); // update succeeds + clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); // rule exists + clients.rulesClient.update.mockResolvedValue(getRuleMock(getQueryRuleParams())); // update succeeds - patchRulesBulkRoute(server.router, ml, isRuleRegistryEnabled, logger); + patchRulesBulkRoute(server.router, ml, logger); }); describe('status codes', () => { test('returns 200', async () => { - const response = await server.inject(getPatchBulkRequest(), context); + const response = await server.inject( + getPatchBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns an error in the response when updating a single rule that does not exist', async () => { clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); - const response = await server.inject(getPatchBulkRequest(), context); + const response = await server.inject( + getPatchBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual([ { @@ -79,7 +80,7 @@ describe.each([ }, ], }); - await server.inject(request, context); + await server.inject(request, requestContextMock.convertContext(context)); expect(clients.rulesClient.update).toHaveBeenCalledWith( expect.objectContaining({ @@ -104,7 +105,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_BULK_UPDATE, body: [typicalMlRulePayload()], }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual([ @@ -130,7 +131,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_BULK_UPDATE, body: [payloadWithoutType], }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual([ @@ -152,7 +153,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_BULK_UPDATE, body: [{ ...getCreateRulesSchemaMock(), rule_id: undefined }], }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual([ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.ts index a0ed8abb8b9aa..ea66999476926 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.ts @@ -34,7 +34,6 @@ import { getDeprecatedBulkEndpointHeader, logDeprecatedBulkEndpoint } from './ut export const patchRulesBulkRoute = ( router: SecuritySolutionPluginRouter, ml: SetupPlugins['ml'], - isRuleRegistryEnabled: boolean, logger: Logger ) => { router.patch( @@ -54,12 +53,14 @@ export const patchRulesBulkRoute = ( const siemResponse = buildSiemResponse(response); - const rulesClient = context.alerting.getRulesClient(); - const ruleExecutionLog = context.securitySolution.getRuleExecutionLog(); - const savedObjectsClient = context.core.savedObjects.client; + const ctx = await context.resolve(['core', 'securitySolution', 'alerting', 'licensing']); + + const rulesClient = ctx.alerting.getRulesClient(); + const ruleExecutionLog = ctx.securitySolution.getRuleExecutionLog(); + const savedObjectsClient = ctx.core.savedObjects.client; const mlAuthz = buildMlAuthz({ - license: context.licensing.license, + license: ctx.licensing.license, ml, request, savedObjectsClient, @@ -129,7 +130,6 @@ export const patchRulesBulkRoute = ( } const existingRule = await readRules({ - isRuleRegistryEnabled, rulesClient, ruleId, id, @@ -198,12 +198,7 @@ export const patchRulesBulkRoute = ( }); if (rule != null && rule.enabled != null && rule.name != null) { const ruleExecutionSummary = await ruleExecutionLog.getExecutionSummary(rule.id); - return transformValidateBulkError( - rule.id, - rule, - ruleExecutionSummary, - isRuleRegistryEnabled - ); + return transformValidateBulkError(rule.id, rule, ruleExecutionSummary); } else { return getIdBulkError({ id, ruleId }); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts index 51bced3480f28..cbcf5540b4f15 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts @@ -11,7 +11,7 @@ import { buildMlAuthz } from '../../../machine_learning/authz'; import { getEmptyFindResult, getRuleExecutionSummarySucceeded, - getAlertMock, + getRuleMock, getPatchRequest, getFindResultWithSingleHit, nonRuleFindResult, @@ -24,10 +24,7 @@ import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; jest.mock('../../../machine_learning/authz', () => mockMlAuthzFactory.create()); -describe.each([ - ['Legacy', false], - ['RAC', true], -])('patch_rules - %s', (_, isRuleRegistryEnabled) => { +describe('patch_rules', () => { let server: ReturnType; let { clients, context } = requestContextMock.createTools(); let ml: ReturnType; @@ -37,29 +34,31 @@ describe.each([ ({ clients, context } = requestContextMock.createTools()); ml = mlServicesMock.createSetupContract(); - clients.rulesClient.get.mockResolvedValue( - getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) - ); // existing rule - clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); // existing rule - clients.rulesClient.update.mockResolvedValue( - getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) - ); // successful update + clients.rulesClient.get.mockResolvedValue(getRuleMock(getQueryRuleParams())); // existing rule + clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); // existing rule + clients.rulesClient.update.mockResolvedValue(getRuleMock(getQueryRuleParams())); // successful update clients.ruleExecutionLog.getExecutionSummary.mockResolvedValue( getRuleExecutionSummarySucceeded() ); - patchRulesRoute(server.router, ml, isRuleRegistryEnabled); + patchRulesRoute(server.router, ml); }); describe('status codes', () => { test('returns 200', async () => { - const response = await server.inject(getPatchRequest(), context); + const response = await server.inject( + getPatchRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 404 when updating a single rule that does not exist', async () => { clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); - const response = await server.inject(getPatchRequest(), context); + const response = await server.inject( + getPatchRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(404); expect(response.body).toEqual({ message: 'rule_id: "rule-1" not found', @@ -68,8 +67,11 @@ describe.each([ }); test('returns error if requesting a non-rule', async () => { - clients.rulesClient.find.mockResolvedValue(nonRuleFindResult(isRuleRegistryEnabled)); - const response = await server.inject(getPatchRequest(), context); + clients.rulesClient.find.mockResolvedValue(nonRuleFindResult()); + const response = await server.inject( + getPatchRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(404); expect(response.body).toEqual({ message: expect.stringContaining('not found'), @@ -81,7 +83,10 @@ describe.each([ clients.rulesClient.update.mockImplementation(async () => { throw new Error('Test error'); }); - const response = await server.inject(getPatchRequest(), context); + const response = await server.inject( + getPatchRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', @@ -100,7 +105,7 @@ describe.each([ machine_learning_job_id: 'some_job_id', }, }); - await server.inject(request, context); + await server.inject(request, requestContextMock.convertContext(context)); expect(clients.rulesClient.update).toHaveBeenCalledWith( expect.objectContaining({ @@ -125,7 +130,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_URL, body: typicalMlRulePayload(), }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(403); expect(response.body).toEqual({ @@ -146,7 +151,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_URL, body: payloadWithoutType, }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(403); expect(response.body).toEqual({ @@ -163,7 +168,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_URL, body: { ...getPatchRulesSchemaMock(), rule_id: undefined }, }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.body).toEqual({ message: ['either "id" or "rule_id" must be set'], status_code: 400, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.ts index a5bc76cc5ef2e..09d9b2691715c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.ts @@ -27,11 +27,7 @@ import { readRules } from '../../rules/read_rules'; import { legacyMigrate } from '../../rules/utils'; import { PartialFilter } from '../../types'; -export const patchRulesRoute = ( - router: SecuritySolutionPluginRouter, - ml: SetupPlugins['ml'], - isRuleRegistryEnabled: boolean -) => { +export const patchRulesRoute = (router: SecuritySolutionPluginRouter, ml: SetupPlugins['ml']) => { router.patch( { path: DETECTION_ENGINE_RULES_URL, @@ -106,12 +102,12 @@ export const patchRulesRoute = ( const actions: RuleAlertAction[] = actionsRest as RuleAlertAction[]; const filters: PartialFilter[] | undefined = filtersRest as PartialFilter[]; - const rulesClient = context.alerting.getRulesClient(); - const ruleExecutionLog = context.securitySolution.getRuleExecutionLog(); - const savedObjectsClient = context.core.savedObjects.client; + const rulesClient = (await context.alerting).getRulesClient(); + const ruleExecutionLog = (await context.securitySolution).getRuleExecutionLog(); + const savedObjectsClient = (await context.core).savedObjects.client; const mlAuthz = buildMlAuthz({ - license: context.licensing.license, + license: (await context.licensing).license, ml, request, savedObjectsClient, @@ -122,7 +118,6 @@ export const patchRulesRoute = ( } const existingRule = await readRules({ - isRuleRegistryEnabled, rulesClient, ruleId, id, @@ -192,11 +187,7 @@ export const patchRulesRoute = ( if (rule != null && rule.enabled != null && rule.name != null) { const ruleExecutionSummary = await ruleExecutionLog.getExecutionSummary(rule.id); - const [validated, errors] = transformValidate( - rule, - ruleExecutionSummary, - isRuleRegistryEnabled - ); + const [validated, errors] = transformValidate(rule, ruleExecutionSummary); if (errors != null) { return siemResponse.error({ statusCode: 500, body: errors }); } else { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.test.ts index e7e960e832458..3dc8ab5199c7f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.test.ts @@ -27,29 +27,29 @@ import { readRules } from '../../rules/read_rules'; jest.mock('../../../machine_learning/authz', () => mockMlAuthzFactory.create()); jest.mock('../../rules/read_rules', () => ({ readRules: jest.fn() })); -describe.each([ - ['Legacy', false], - ['RAC', true], -])('perform_bulk_action - %s', (_, isRuleRegistryEnabled) => { +describe('perform_bulk_action', () => { const readRulesMock = readRules as jest.Mock; let server: ReturnType; let { clients, context } = requestContextMock.createTools(); let ml: ReturnType; let logger: ReturnType; - const mockRule = getFindResultWithSingleHit(isRuleRegistryEnabled).data[0]; + const mockRule = getFindResultWithSingleHit().data[0]; beforeEach(() => { server = serverMock.create(); logger = loggingSystemMock.createLogger(); ({ clients, context } = requestContextMock.createTools()); ml = mlServicesMock.createSetupContract(); - clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); - performBulkActionRoute(server.router, ml, logger, isRuleRegistryEnabled); + clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); + performBulkActionRoute(server.router, ml, logger); }); describe('status codes', () => { it('returns 200 when performing bulk action with all dependencies present', async () => { - const response = await server.inject(getBulkActionRequest(), context); + const response = await server.inject( + getBulkActionRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual({ success: true, @@ -67,7 +67,10 @@ describe.each([ it("returns 200 when provided filter query doesn't match any rules", async () => { clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); - const response = await server.inject(getBulkActionRequest(), context); + const response = await server.inject( + getBulkActionRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual({ success: true, @@ -87,7 +90,10 @@ describe.each([ clients.rulesClient.find.mockResolvedValue( getFindResultWithMultiHits({ data: [], total: Infinity }) ); - const response = await server.inject(getBulkActionRequest(), context); + const response = await server.inject( + getBulkActionRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(400); expect(response.body).toEqual({ message: 'More than 10000 rules matched the filter query. Try to narrow it down.', @@ -105,7 +111,10 @@ describe.each([ }) ); - const response = await server.inject(getBulkActionEditRequest(), context); + const response = await server.inject( + getBulkActionEditRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ @@ -138,7 +147,10 @@ describe.each([ clients.rulesClient.disable.mockImplementation(async () => { throw new Error('Test error'); }); - const response = await server.inject(getBulkActionRequest(), context); + const response = await server.inject( + getBulkActionRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Bulk edit failed', @@ -172,7 +184,10 @@ describe.each([ .fn() .mockResolvedValue({ valid: false, message: 'mocked validation message' }), }); - const response = await server.inject(getBulkActionRequest(), context); + const response = await server.inject( + getBulkActionRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ @@ -222,7 +237,7 @@ describe.each([ }, }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(500); expect(response.body).toEqual({ @@ -273,7 +288,7 @@ describe.each([ }, }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(500); expect(response.body).toEqual({ @@ -325,7 +340,10 @@ describe.each([ .mockImplementationOnce(() => ({ valid: true })) .mockImplementationOnce(() => ({ valid: true })), }); - const response = await server.inject(getBulkActionEditRequest(), context); + const response = await server.inject( + getBulkActionEditRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ @@ -372,7 +390,10 @@ describe.each([ clients.rulesClient.disable.mockImplementation(async () => { throw new Error('a'.repeat(1_300)); }); - const response = await server.inject(getBulkActionRequest(), context); + const response = await server.inject( + getBulkActionRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body.attributes.errors[0].message.length).toEqual(1000); }); @@ -392,7 +413,7 @@ describe.each([ }, }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(500); expect(response.body).toEqual({ @@ -489,7 +510,7 @@ describe.each([ }, }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(400); expect(response.body.message).toEqual('More than 100 ids sent for bulk edit action.'); @@ -506,7 +527,7 @@ describe.each([ }, }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(400); expect(response.body.message).toEqual( @@ -524,7 +545,10 @@ describe.each([ }) ); - const response = await server.inject(getBulkActionEditRequest(), context); + const response = await server.inject( + getBulkActionEditRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual( diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.ts index e5b7dc2ef85ed..ab3de5b8d0f3f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.ts @@ -146,13 +146,11 @@ const fetchRulesByQueryOrIds = async ({ query, ids, rulesClient, - isRuleRegistryEnabled, abortSignal, }: { query: string | undefined; ids: string[] | undefined; rulesClient: RulesClient; - isRuleRegistryEnabled: boolean; abortSignal: AbortSignal; }): Promise> => { if (ids) { @@ -160,7 +158,7 @@ const fetchRulesByQueryOrIds = async ({ concurrency: MAX_RULES_TO_UPDATE_IN_PARALLEL, items: ids, executor: async (id: string) => { - const rule = await readRules({ id, rulesClient, isRuleRegistryEnabled, ruleId: undefined }); + const rule = await readRules({ id, rulesClient, ruleId: undefined }); if (rule == null) { throw Error('Rule not found'); } @@ -171,7 +169,6 @@ const fetchRulesByQueryOrIds = async ({ } const { data, total } = await findRules({ - isRuleRegistryEnabled, rulesClient, perPage: MAX_RULES_TO_PROCESS_TOTAL, filter: query !== '' ? query : undefined, @@ -229,8 +226,7 @@ export const migrateRuleActions = async ({ export const performBulkActionRoute = ( router: SecuritySolutionPluginRouter, ml: SetupPlugins['ml'], - logger: Logger, - isRuleRegistryEnabled: boolean + logger: Logger ) => { router.post( { @@ -270,20 +266,27 @@ export const performBulkActionRoute = ( request.events.completed$.subscribe(() => abortController.abort()); try { - const rulesClient = context.alerting.getRulesClient(); - const ruleExecutionLog = context.securitySolution.getRuleExecutionLog(); - const exceptionsClient = context.lists?.getExceptionListClient(); - const savedObjectsClient = context.core.savedObjects.client; + const ctx = await context.resolve([ + 'core', + 'securitySolution', + 'alerting', + 'licensing', + 'lists', + ]); + + const rulesClient = ctx.alerting.getRulesClient(); + const ruleExecutionLog = ctx.securitySolution.getRuleExecutionLog(); + const exceptionsClient = ctx.lists?.getExceptionListClient(); + const savedObjectsClient = ctx.core.savedObjects.client; const mlAuthz = buildMlAuthz({ - license: context.licensing.license, + license: ctx.licensing.license, ml, request, savedObjectsClient, }); const fetchRulesOutcome = await fetchRulesByQueryOrIds({ - isRuleRegistryEnabled, rulesClient, query: body.query, ids: body.ids, @@ -378,7 +381,7 @@ export const performBulkActionRoute = ( throwAuthzError(await mlAuthz.validateRuleType(migratedRule.params.type)); const createdRule = await rulesClient.create({ - data: duplicateRule(migratedRule, isRuleRegistryEnabled), + data: duplicateRule(migratedRule), }); return createdRule; @@ -392,8 +395,7 @@ export const performBulkActionRoute = ( exceptionsClient, savedObjectsClient, rules.map(({ params }) => ({ rule_id: params.ruleId })), - logger, - isRuleRegistryEnabled + logger ); const responseBody = `${exported.rulesNdjson}${exported.exceptionLists}${exported.exportDetails}`; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/preview_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/preview_rules_route.ts index c9cc0cad0a65f..00fc13315ff36 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/preview_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/preview_rules_route.ts @@ -80,14 +80,15 @@ export const previewRulesRoute = async ( async (context, request, response) => { const siemResponse = buildSiemResponse(response); const validationErrors = createRuleValidateTypeDependents(request.body); + const coreContext = await context.core; if (validationErrors.length) { return siemResponse.error({ statusCode: 400, body: validationErrors }); } try { const [, { data, security: securityService }] = await getStartServices(); const searchSourceClient = data.search.searchSource.asScoped(request); - const savedObjectsClient = context.core.savedObjects.client; - const siemClient = context.securitySolution.getAppClient(); + const savedObjectsClient = coreContext.savedObjects.client; + const siemClient = (await context.securitySolution).getAppClient(); let invocationCount = request.body.invocationCount; if ( @@ -103,17 +104,19 @@ export const previewRulesRoute = async ( }); } - const internalRule = convertCreateAPIToInternalSchema(request.body, siemClient, false); + const internalRule = convertCreateAPIToInternalSchema(request.body, siemClient); const previewRuleParams = internalRule.params; const mlAuthz = buildMlAuthz({ - license: context.licensing.license, + license: (await context.licensing).license, ml, request, savedObjectsClient, }); throwAuthzError(await mlAuthz.validateRuleType(internalRule.params.type)); - await context.lists?.getExceptionListClient().createEndpointList(); + + const listsContext = await context.lists; + await listsContext?.getExceptionListClient().createEndpointList(); const spaceId = siemClient.getSpaceId(); const previewId = uuid.v4(); @@ -234,13 +237,13 @@ export const previewRulesRoute = async ( shouldWriteAlerts, shouldStopExecution: () => false, alertFactory, - savedObjectsClient: context.core.savedObjects.client, + savedObjectsClient: coreContext.savedObjects.client, scopedClusterClient: wrapScopedClusterClient({ abortController, - scopedClusterClient: context.core.elasticsearch.client, + scopedClusterClient: coreContext.elasticsearch.client, }), searchSourceClient, - uiSettingsClient: context.core.uiSettings.client, + uiSettingsClient: coreContext.uiSettings.client, }, spaceId, startedAt: startedAt.toDate(), @@ -339,7 +342,7 @@ export const previewRulesRoute = async ( } // Refreshes alias to ensure index is able to be read before returning - await context.core.elasticsearch.client.asInternalUser.indices.refresh( + await coreContext.elasticsearch.client.asInternalUser.indices.refresh( { index: previewRuleDataClient.indexNameWithNamespace(spaceId), }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.test.ts index c802f9857ce50..44c2c3a075508 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.test.ts @@ -17,15 +17,12 @@ import { nonRuleFindResult, getEmptySavedObjectsResponse, getRuleExecutionSummarySucceeded, - resolveAlertMock, + resolveRuleMock, } from '../__mocks__/request_responses'; import { requestMock, requestContextMock, serverMock } from '../__mocks__'; import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; -describe.each([ - ['Legacy', false], - ['RAC', true], -])('read_rules - %s', (_, isRuleRegistryEnabled) => { +describe('read_rules', () => { let server: ReturnType; let { clients, context } = requestContextMock.createTools(); let logger: ReturnType; @@ -36,61 +33,76 @@ describe.each([ logger = loggingSystemMock.createLogger(); ({ clients, context } = requestContextMock.createTools()); - clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); // rule exists + clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); // rule exists clients.savedObjectsClient.find.mockResolvedValue(getEmptySavedObjectsResponse()); // successful transform clients.ruleExecutionLog.getExecutionSummary.mockResolvedValue( getRuleExecutionSummarySucceeded() ); clients.rulesClient.resolve.mockResolvedValue({ - ...resolveAlertMock(isRuleRegistryEnabled, { + ...resolveRuleMock({ ...getQueryRuleParams(), }), id: myFakeId, }); - readRulesRoute(server.router, logger, isRuleRegistryEnabled); + readRulesRoute(server.router, logger); }); describe('status codes', () => { test('returns 200', async () => { - const response = await server.inject(getReadRequest(), context); + const response = await server.inject( + getReadRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 200 when reading a single rule outcome === exactMatch', async () => { - const response = await server.inject(getReadRequestWithId(myFakeId), context); + const response = await server.inject( + getReadRequestWithId(myFakeId), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 200 when reading a single rule outcome === aliasMatch', async () => { clients.rulesClient.resolve.mockResolvedValue({ - ...resolveAlertMock(isRuleRegistryEnabled, { + ...resolveRuleMock({ ...getQueryRuleParams(), }), id: myFakeId, outcome: 'aliasMatch', }); - const response = await server.inject(getReadRequestWithId(myFakeId), context); + const response = await server.inject( + getReadRequestWithId(myFakeId), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 200 when reading a single rule outcome === conflict', async () => { clients.rulesClient.resolve.mockResolvedValue({ - ...resolveAlertMock(isRuleRegistryEnabled, { + ...resolveRuleMock({ ...getQueryRuleParams(), }), id: myFakeId, outcome: 'conflict', alias_target_id: 'myaliastargetid', }); - const response = await server.inject(getReadRequestWithId(myFakeId), context); + const response = await server.inject( + getReadRequestWithId(myFakeId), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body.alias_target_id).toEqual('myaliastargetid'); }); test('returns error if requesting a non-rule', async () => { - clients.rulesClient.find.mockResolvedValue(nonRuleFindResult(isRuleRegistryEnabled)); - const response = await server.inject(getReadRequest(), context); + clients.rulesClient.find.mockResolvedValue(nonRuleFindResult()); + const response = await server.inject( + getReadRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(404); expect(response.body).toEqual({ message: 'rule_id: "rule-1" not found', @@ -102,7 +114,10 @@ describe.each([ clients.rulesClient.find.mockImplementation(async () => { throw new Error('Test error'); }); - const response = await server.inject(getReadRequest(), context); + const response = await server.inject( + getReadRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', @@ -119,7 +134,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_URL, query: { rule_id: 'DNE_RULE' }, }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(404); expect(response.body).toEqual({ message: 'rule_id: "DNE_RULE" not found', status_code: 404 }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.ts index e1d24677ff4cf..37af66b50c6bb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.ts @@ -22,11 +22,7 @@ import { readRules } from '../../rules/read_rules'; // eslint-disable-next-line no-restricted-imports import { legacyGetRuleActionsSavedObject } from '../../rule_actions/legacy_get_rule_actions_saved_object'; -export const readRulesRoute = ( - router: SecuritySolutionPluginRouter, - logger: Logger, - isRuleRegistryEnabled: boolean -) => { +export const readRulesRoute = (router: SecuritySolutionPluginRouter, logger: Logger) => { router.get( { path: DETECTION_ENGINE_RULES_URL, @@ -49,13 +45,12 @@ export const readRulesRoute = ( const { id, rule_id: ruleId } = request.query; try { - const rulesClient = context.alerting.getRulesClient(); - const ruleExecutionLog = context.securitySolution.getRuleExecutionLog(); - const savedObjectsClient = context.core.savedObjects.client; + const rulesClient = (await context.alerting).getRulesClient(); + const ruleExecutionLog = (await context.securitySolution).getRuleExecutionLog(); + const savedObjectsClient = (await context.core).savedObjects.client; const rule = await readRules({ id, - isRuleRegistryEnabled, rulesClient, ruleId, }); @@ -68,12 +63,7 @@ export const readRulesRoute = ( const ruleExecutionSummary = await ruleExecutionLog.getExecutionSummary(rule.id); - const transformed = transform( - rule, - ruleExecutionSummary, - isRuleRegistryEnabled, - legacyRuleActions - ); + const transformed = transform(rule, ruleExecutionSummary, legacyRuleActions); if (transformed == null) { return siemResponse.error({ statusCode: 500, body: 'Internal error transforming' }); } else { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.test.ts index 21ac33e294008..88720646fa6cd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.test.ts @@ -10,7 +10,7 @@ import { mlServicesMock, mlAuthzMock as mockMlAuthzFactory } from '../../../mach import { buildMlAuthz } from '../../../machine_learning/authz'; import { getEmptyFindResult, - getAlertMock, + getRuleMock, getFindResultWithSingleHit, getUpdateBulkRequest, typicalMlRulePayload, @@ -24,10 +24,7 @@ import { loggingSystemMock } from '@kbn/core/server/mocks'; jest.mock('../../../machine_learning/authz', () => mockMlAuthzFactory.create()); -describe.each([ - ['Legacy', false], - ['RAC', true], -])('update_rules_bulk - %s', (_, isRuleRegistryEnabled) => { +describe('update_rules_bulk', () => { let server: ReturnType; let { clients, context } = requestContextMock.createTools(); let ml: ReturnType; @@ -38,19 +35,20 @@ describe.each([ ml = mlServicesMock.createSetupContract(); const logger = loggingSystemMock.createLogger(); - clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); - clients.rulesClient.update.mockResolvedValue( - getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) - ); + clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); + clients.rulesClient.update.mockResolvedValue(getRuleMock(getQueryRuleParams())); clients.appClient.getSignalsIndex.mockReturnValue('.siem-signals-test-index'); - updateRulesBulkRoute(server.router, ml, isRuleRegistryEnabled, logger); + updateRulesBulkRoute(server.router, ml, logger); }); describe('status codes', () => { test('returns 200', async () => { - const response = await server.inject(getUpdateBulkRequest(), context); + const response = await server.inject( + getUpdateBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); @@ -62,7 +60,10 @@ describe.each([ rule_id: 'rule-1', }, ]; - const response = await server.inject(getUpdateBulkRequest(), context); + const response = await server.inject( + getUpdateBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual(expected); @@ -79,7 +80,10 @@ describe.each([ rule_id: 'rule-1', }, ]; - const response = await server.inject(getUpdateBulkRequest(), context); + const response = await server.inject( + getUpdateBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual(expected); }); @@ -96,7 +100,7 @@ describe.each([ body: [typicalMlRulePayload()], }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual([ { @@ -117,7 +121,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_BULK_UPDATE, body: [{ ...getCreateRulesSchemaMock(), rule_id: undefined }], }); - const response = await server.inject(noIdRequest, context); + const response = await server.inject(noIdRequest, requestContextMock.convertContext(context)); expect(response.body).toEqual([ { error: { message: 'either "id" or "rule_id" must be set', status_code: 400 }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.ts index 0f9bc3535dc57..0ba03ea999548 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.ts @@ -30,7 +30,6 @@ import { getDeprecatedBulkEndpointHeader, logDeprecatedBulkEndpoint } from './ut export const updateRulesBulkRoute = ( router: SecuritySolutionPluginRouter, ml: SetupPlugins['ml'], - isRuleRegistryEnabled: boolean, logger: Logger ) => { router.put( @@ -48,13 +47,15 @@ export const updateRulesBulkRoute = ( const siemResponse = buildSiemResponse(response); - const rulesClient = context.alerting.getRulesClient(); - const ruleExecutionLog = context.securitySolution.getRuleExecutionLog(); - const savedObjectsClient = context.core.savedObjects.client; - const siemClient = context.securitySolution.getAppClient(); + const ctx = await context.resolve(['core', 'securitySolution', 'alerting', 'licensing']); + + const rulesClient = ctx.alerting.getRulesClient(); + const ruleExecutionLog = ctx.securitySolution.getRuleExecutionLog(); + const savedObjectsClient = ctx.core.savedObjects.client; + const siemClient = ctx.securitySolution.getAppClient(); const mlAuthz = buildMlAuthz({ - license: context.licensing.license, + license: ctx.licensing.license, ml, request, savedObjectsClient, @@ -76,7 +77,6 @@ export const updateRulesBulkRoute = ( throwAuthzError(await mlAuthz.validateRuleType(payloadRule.type)); const existingRule = await readRules({ - isRuleRegistryEnabled, rulesClient, ruleId: payloadRule.rule_id, id: payloadRule.id, @@ -96,12 +96,7 @@ export const updateRulesBulkRoute = ( }); if (rule != null) { const ruleExecutionSummary = await ruleExecutionLog.getExecutionSummary(rule.id); - return transformValidateBulkError( - rule.id, - rule, - ruleExecutionSummary, - isRuleRegistryEnabled - ); + return transformValidateBulkError(rule.id, rule, ruleExecutionSummary); } else { return getIdBulkError({ id: payloadRule.id, ruleId: payloadRule.rule_id }); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.test.ts index 8a7a09a80c743..39040f4c9c4fc 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.test.ts @@ -9,7 +9,7 @@ import { mlServicesMock, mlAuthzMock as mockMlAuthzFactory } from '../../../mach import { buildMlAuthz } from '../../../machine_learning/authz'; import { getEmptyFindResult, - getAlertMock, + getRuleMock, getUpdateRequest, getFindResultWithSingleHit, getRuleExecutionSummarySucceeded, @@ -24,10 +24,7 @@ import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; jest.mock('../../../machine_learning/authz', () => mockMlAuthzFactory.create()); -describe.each([ - ['Legacy', false], - ['RAC', true], -])('update_rules - %s', (_, isRuleRegistryEnabled) => { +describe('update_rules', () => { let server: ReturnType; let { clients, context } = requestContextMock.createTools(); let ml: ReturnType; @@ -37,30 +34,32 @@ describe.each([ ({ clients, context } = requestContextMock.createTools()); ml = mlServicesMock.createSetupContract(); - clients.rulesClient.get.mockResolvedValue( - getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) - ); // existing rule - clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); // rule exists - clients.rulesClient.update.mockResolvedValue( - getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) - ); // successful update + clients.rulesClient.get.mockResolvedValue(getRuleMock(getQueryRuleParams())); // existing rule + clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); // rule exists + clients.rulesClient.update.mockResolvedValue(getRuleMock(getQueryRuleParams())); // successful update clients.ruleExecutionLog.getExecutionSummary.mockResolvedValue( getRuleExecutionSummarySucceeded() ); clients.appClient.getSignalsIndex.mockReturnValue('.siem-signals-test-index'); - updateRulesRoute(server.router, ml, isRuleRegistryEnabled); + updateRulesRoute(server.router, ml); }); describe('status codes', () => { test('returns 200', async () => { - const response = await server.inject(getUpdateRequest(), context); + const response = await server.inject( + getUpdateRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 404 when updating a single rule that does not exist', async () => { clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); - const response = await server.inject(getUpdateRequest(), context); + const response = await server.inject( + getUpdateRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(404); expect(response.body).toEqual({ @@ -70,8 +69,11 @@ describe.each([ }); test('returns error when updating non-rule', async () => { - clients.rulesClient.find.mockResolvedValue(nonRuleFindResult(isRuleRegistryEnabled)); - const response = await server.inject(getUpdateRequest(), context); + clients.rulesClient.find.mockResolvedValue(nonRuleFindResult()); + const response = await server.inject( + getUpdateRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(404); expect(response.body).toEqual({ @@ -84,7 +86,10 @@ describe.each([ clients.rulesClient.find.mockImplementation(async () => { throw new Error('Test error'); }); - const response = await server.inject(getUpdateRequest(), context); + const response = await server.inject( + getUpdateRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', @@ -104,7 +109,7 @@ describe.each([ body: typicalMlRulePayload(), }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(403); expect(response.body).toEqual({ message: 'mocked validation message', @@ -123,7 +128,7 @@ describe.each([ id: undefined, }, }); - const response = await server.inject(noIdRequest, context); + const response = await server.inject(noIdRequest, requestContextMock.convertContext(context)); expect(response.body).toEqual({ message: ['either "id" or "rule_id" must be set'], status_code: 400, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.ts index 8ac90748d9217..ec16488944b55 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.ts @@ -22,11 +22,7 @@ import { buildRouteValidation } from '../../../../utils/build_validation/route_v import { legacyMigrate } from '../../rules/utils'; import { readRules } from '../../rules/read_rules'; -export const updateRulesRoute = ( - router: SecuritySolutionPluginRouter, - ml: SetupPlugins['ml'], - isRuleRegistryEnabled: boolean -) => { +export const updateRulesRoute = (router: SecuritySolutionPluginRouter, ml: SetupPlugins['ml']) => { router.put( { path: DETECTION_ENGINE_RULES_URL, @@ -44,12 +40,14 @@ export const updateRulesRoute = ( return siemResponse.error({ statusCode: 400, body: validationErrors }); } try { - const rulesClient = context.alerting.getRulesClient(); - const savedObjectsClient = context.core.savedObjects.client; - const siemClient = context.securitySolution.getAppClient(); + const ctx = await context.resolve(['core', 'securitySolution', 'alerting', 'licensing']); + + const rulesClient = ctx.alerting.getRulesClient(); + const savedObjectsClient = ctx.core.savedObjects.client; + const siemClient = ctx.securitySolution.getAppClient(); const mlAuthz = buildMlAuthz({ - license: context.licensing.license, + license: ctx.licensing.license, ml, request, savedObjectsClient, @@ -57,7 +55,6 @@ export const updateRulesRoute = ( throwAuthzError(await mlAuthz.validateRuleType(request.body.type)); const existingRule = await readRules({ - isRuleRegistryEnabled, rulesClient, ruleId: request.body.rule_id, id: request.body.id, @@ -76,13 +73,9 @@ export const updateRulesRoute = ( }); if (rule != null) { - const ruleExecutionLog = context.securitySolution.getRuleExecutionLog(); + const ruleExecutionLog = ctx.securitySolution.getRuleExecutionLog(); const ruleExecutionSummary = await ruleExecutionLog.getExecutionSummary(rule.id); - const [validated, errors] = transformValidate( - rule, - ruleExecutionSummary, - isRuleRegistryEnabled - ); + const [validated, errors] = transformValidate(rule, ruleExecutionSummary); if (errors != null) { return siemResponse.error({ statusCode: 500, body: errors }); } else { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils.test.ts index 93ec83bb750d1..2fb1dccc64f80 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils.test.ts @@ -13,7 +13,6 @@ import { getIdError, transformFindAlerts, transform, - transformTags, getIdBulkError, transformAlertsToRules, getDuplicates, @@ -22,8 +21,7 @@ import { swapActionIds, migrateLegacyActionsIds, } from './utils'; -import { getAlertMock } from '../__mocks__/request_responses'; -import { INTERNAL_IDENTIFIER } from '../../../../../common/constants'; +import { getRuleMock } from '../__mocks__/request_responses'; import { PartialFilter } from '../../types'; import { BulkError, createBulkErrorObject } from '../utils'; import { getOutputRuleAlertForRest } from '../__mocks__/utils'; @@ -64,21 +62,18 @@ const createMockImportRule = async (rule: ReturnType { +describe('utils', () => { const { clients } = requestContextMock.createTools(); describe('internalRuleToAPIResponse', () => { test('should work with a full data set', () => { - const fullRule = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const fullRule = getRuleMock(getQueryRuleParams()); const rule = internalRuleToAPIResponse(fullRule); expect(rule).toEqual(getOutputRuleAlertForRest()); }); test('should omit note if note is undefined', () => { - const fullRule = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const fullRule = getRuleMock(getQueryRuleParams()); fullRule.params.note = undefined; const rule = internalRuleToAPIResponse(fullRule); const { note, ...expectedWithoutNote } = getOutputRuleAlertForRest(); @@ -86,7 +81,7 @@ describe.each([ }); test('should return enabled is equal to false', () => { - const fullRule = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const fullRule = getRuleMock(getQueryRuleParams()); fullRule.enabled = false; const ruleWithEnabledFalse = internalRuleToAPIResponse(fullRule); const expected = getOutputRuleAlertForRest(); @@ -95,16 +90,16 @@ describe.each([ }); test('should return immutable is equal to false', () => { - const fullRule = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const fullRule = getRuleMock(getQueryRuleParams()); fullRule.params.immutable = false; const ruleWithEnabledFalse = internalRuleToAPIResponse(fullRule); const expected = getOutputRuleAlertForRest(); expect(ruleWithEnabledFalse).toEqual(expected); }); - test('should work with tags but filter out any internal tags', () => { - const fullRule = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - fullRule.tags = ['tag 1', 'tag 2', `${INTERNAL_IDENTIFIER}_some_other_value`]; + test('should work with tags', () => { + const fullRule = getRuleMock(getQueryRuleParams()); + fullRule.tags = ['tag 1', 'tag 2']; const rule = internalRuleToAPIResponse(fullRule); const expected = getOutputRuleAlertForRest(); expected.tags = ['tag 1', 'tag 2']; @@ -112,7 +107,7 @@ describe.each([ }); test('transforms ML Rule fields', () => { - const mlRule = getAlertMock(isRuleRegistryEnabled, getMlRuleParams()); + const mlRule = getRuleMock(getMlRuleParams()); mlRule.params.anomalyThreshold = 55; mlRule.params.machineLearningJobId = ['some_job_id']; mlRule.params.type = 'machine_learning'; @@ -128,7 +123,7 @@ describe.each([ }); test('transforms threat_matching fields', () => { - const threatRule = getAlertMock(isRuleRegistryEnabled, getThreatRuleParams()); + const threatRule = getRuleMock(getThreatRuleParams()); const threatFilters: PartialFilter[] = [ { query: { @@ -181,7 +176,7 @@ describe.each([ test('does not leak a lists structure in the transform which would cause validation issues', () => { const result: RuleAlertType & { lists: [] } = { lists: [], - ...getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()), + ...getRuleMock(getQueryRuleParams()), }; const rule = internalRuleToAPIResponse(result); expect(rule).toEqual( @@ -196,7 +191,7 @@ describe.each([ test('does not leak an exceptions_list structure in the transform which would cause validation issues', () => { const result: RuleAlertType & { exceptions_list: [] } = { exceptions_list: [], - ...getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()), + ...getRuleMock(getQueryRuleParams()), }; const rule = internalRuleToAPIResponse(result); expect(rule).toEqual( @@ -293,7 +288,7 @@ describe.each([ page: 1, perPage: 0, total: 0, - data: [getAlertMock(isRuleRegistryEnabled, getQueryRuleParams())], + data: [getRuleMock(getQueryRuleParams())], }, {}, {} @@ -313,7 +308,7 @@ describe.each([ page: 1, perPage: 0, total: 0, - data: [getAlertMock(isRuleRegistryEnabled, getQueryRuleParams())], + data: [getRuleMock(getQueryRuleParams())], }, {}, { @@ -340,7 +335,7 @@ describe.each([ ]; const legacyRuleActions: Record = { - [getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()).id]: { + [getRuleMock(getQueryRuleParams()).id]: { id: '123', actions, alertThrottle: '1h', @@ -352,7 +347,7 @@ describe.each([ page: 1, perPage: 0, total: 0, - data: [getAlertMock(isRuleRegistryEnabled, getQueryRuleParams())], + data: [getRuleMock(getQueryRuleParams())], }, {}, legacyRuleActions @@ -373,39 +368,18 @@ describe.each([ describe('transform', () => { test('outputs 200 if the data is of type siem alert', () => { - const output = transform( - getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()), - undefined, - isRuleRegistryEnabled - ); + const output = transform(getRuleMock(getQueryRuleParams()), undefined); const expected = getOutputRuleAlertForRest(); expect(output).toEqual(expected); }); test('returns 500 if the data is not of type siem alert', () => { const unsafeCast = { data: [{ random: 1 }] } as unknown as PartialRule; - const output = transform(unsafeCast, undefined, isRuleRegistryEnabled); + const output = transform(unsafeCast, undefined); expect(output).toBeNull(); }); }); - describe('transformTags', () => { - test('it returns tags that have no internal structures', () => { - expect(transformTags(['tag 1', 'tag 2'])).toEqual(['tag 1', 'tag 2']); - }); - - test('it returns empty tags given empty tags', () => { - expect(transformTags([])).toEqual([]); - }); - - test('it returns tags with internal tags stripped out', () => { - expect(transformTags(['tag 1', `${INTERNAL_IDENTIFIER}_some_value`, 'tag 2'])).toEqual([ - 'tag 1', - 'tag 2', - ]); - }); - }); - describe('getIdBulkError', () => { test('outputs message about id and rule_id not being found if both are not null', () => { const error = getIdBulkError({ id: '123', ruleId: '456' }); @@ -496,15 +470,15 @@ describe.each([ }); test('given single alert will return the alert transformed', () => { - const result1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result1 = getRuleMock(getQueryRuleParams()); const transformed = transformAlertsToRules([result1], {}); const expected = getOutputRuleAlertForRest(); expect(transformed).toEqual([expected]); }); test('given two alerts will return the two alerts transformed', () => { - const result1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - const result2 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result1 = getRuleMock(getQueryRuleParams()); + const result2 = getRuleMock(getQueryRuleParams()); result2.id = 'some other id'; result2.params.ruleId = 'some other id'; @@ -1006,6 +980,7 @@ describe.each([ actionTypeId: 'default', name: 'name', isPreconfigured: false, + isDeprecated: false, }, ]); const [errors, output] = await getInvalidConnectors(rules, clients.actionsClient); @@ -1049,6 +1024,7 @@ describe.each([ actionTypeId: 'default', name: 'name', isPreconfigured: false, + isDeprecated: false, }, { id: '789', @@ -1056,6 +1032,7 @@ describe.each([ actionTypeId: 'default', name: 'name', isPreconfigured: false, + isDeprecated: false, }, ]); const [errors, output] = await getInvalidConnectors(rules, clients.actionsClient); @@ -1105,6 +1082,7 @@ describe.each([ actionTypeId: 'default', name: 'name', isPreconfigured: false, + isDeprecated: false, }, { id: '789', @@ -1112,6 +1090,7 @@ describe.each([ actionTypeId: 'default', name: 'name', isPreconfigured: false, + isDeprecated: false, }, ]); const [errors, output] = await getInvalidConnectors(rules, clients.actionsClient); @@ -1168,6 +1147,7 @@ describe.each([ actionTypeId: 'default', name: 'name', isPreconfigured: false, + isDeprecated: false, }, { id: '789', @@ -1175,6 +1155,7 @@ describe.each([ actionTypeId: 'default', name: 'name', isPreconfigured: false, + isDeprecated: false, }, ]); const [errors, output] = await getInvalidConnectors(rules, clients.actionsClient); @@ -1233,6 +1214,7 @@ describe.each([ actionTypeId: 'default', name: 'name', isPreconfigured: false, + isDeprecated: false, }, { id: '789', @@ -1240,6 +1222,7 @@ describe.each([ actionTypeId: 'default', name: 'name', isPreconfigured: false, + isDeprecated: false, }, ]); const [errors, output] = await getInvalidConnectors(rules, clients.actionsClient); @@ -1339,6 +1322,7 @@ describe.each([ actionTypeId: 'default', name: 'name', isPreconfigured: false, + isDeprecated: false, }, { id: '789', @@ -1346,6 +1330,7 @@ describe.each([ actionTypeId: 'default', name: 'name', isPreconfigured: false, + isDeprecated: false, }, ]); const [errors, output] = await getInvalidConnectors(rules, clients.actionsClient); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils.ts index 3c0ad839bc8b3..850d971b39c59 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils.ts @@ -17,7 +17,6 @@ import { RuleExecutionSummary } from '../../../../../common/detection_engine/sch import { RulesSchema } from '../../../../../common/detection_engine/schemas/response/rules_schema'; import { ImportRulesSchemaDecoded } from '../../../../../common/detection_engine/schemas/request/import_rules_schema'; import { CreateRulesBulkSchema } from '../../../../../common/detection_engine/schemas/request/create_rules_bulk_schema'; -import { INTERNAL_IDENTIFIER } from '../../../../../common/constants'; import { RuleAlertType, isAlertType } from '../../rules/types'; import { createBulkErrorObject, BulkError, OutputError } from '../utils'; import { internalRuleToAPIResponse } from '../../schemas/rule_converters'; @@ -88,10 +87,6 @@ export const getIdBulkError = ({ } }; -export const transformTags = (tags: string[]): string[] => { - return tags.filter((tag) => !tag.startsWith(INTERNAL_IDENTIFIER)); -}; - export const transformAlertsToRules = ( rules: RuleAlertType[], legacyRuleActions: Record @@ -123,10 +118,9 @@ export const transformFindAlerts = ( export const transform = ( rule: PartialRule, ruleExecutionSummary?: RuleExecutionSummary | null, - isRuleRegistryEnabled?: boolean, legacyRuleActions?: LegacyRulesActionsSavedObject | null ): Partial | null => { - if (isAlertType(isRuleRegistryEnabled ?? false, rule)) { + if (isAlertType(rule)) { return internalRuleToAPIResponse(rule, ruleExecutionSummary, legacyRuleActions); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/import_rules_utils.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/import_rules_utils.test.ts index 8d78592dc7fc4..1a9d10d2a3d29 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/import_rules_utils.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/import_rules_utils.test.ts @@ -8,7 +8,7 @@ import { requestContextMock } from '../../__mocks__'; import { importRules } from './import_rules_utils'; import { - getAlertMock, + getRuleMock, getEmptyFindResult, getFindResultWithSingleHit, } from '../../__mocks__/request_responses'; @@ -30,7 +30,7 @@ describe('importRules', () => { beforeEach(() => { clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); - clients.rulesClient.update.mockResolvedValue(getAlertMock(true, getQueryRuleParams())); + clients.rulesClient.update.mockResolvedValue(getRuleMock(getQueryRuleParams())); clients.actionsClient.getAll.mockResolvedValue([]); jest.clearAllMocks(); @@ -42,12 +42,10 @@ describe('importRules', () => { rulesResponseAcc: [], mlAuthz, overwriteRules: false, - isRuleRegistryEnabled: true, savedObjectsClient: context.core.savedObjects.client, rulesClient: context.alerting.getRulesClient(), exceptionsClient: context.lists?.getExceptionListClient(), spaceId: 'default', - signalsIndex: '.signals-index', existingLists: {}, }); @@ -60,12 +58,10 @@ describe('importRules', () => { rulesResponseAcc: [], mlAuthz, overwriteRules: false, - isRuleRegistryEnabled: true, savedObjectsClient: context.core.savedObjects.client, rulesClient: context.alerting.getRulesClient(), exceptionsClient: context.lists?.getExceptionListClient(), spaceId: 'default', - signalsIndex: '.signals-index', existingLists: {}, }); @@ -93,12 +89,10 @@ describe('importRules', () => { rulesResponseAcc: [], mlAuthz, overwriteRules: false, - isRuleRegistryEnabled: true, savedObjectsClient: context.core.savedObjects.client, rulesClient: context.alerting.getRulesClient(), exceptionsClient: context.lists?.getExceptionListClient(), spaceId: 'default', - signalsIndex: '.signals-index', existingLists: {}, }); @@ -108,7 +102,7 @@ describe('importRules', () => { }); it('reports error if "overwriteRules" is "false" and matching rule found', async () => { - clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(true)); + clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); const result = await importRules({ ruleChunks: [ @@ -122,12 +116,10 @@ describe('importRules', () => { rulesResponseAcc: [], mlAuthz, overwriteRules: false, - isRuleRegistryEnabled: true, savedObjectsClient: context.core.savedObjects.client, rulesClient: context.alerting.getRulesClient(), exceptionsClient: context.lists?.getExceptionListClient(), spaceId: 'default', - signalsIndex: '.signals-index', existingLists: {}, }); @@ -142,7 +134,7 @@ describe('importRules', () => { }); it('patches rule if "overwriteRules" is "true" and matching rule found', async () => { - clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(true)); + clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); const result = await importRules({ ruleChunks: [ @@ -156,12 +148,10 @@ describe('importRules', () => { rulesResponseAcc: [], mlAuthz, overwriteRules: true, - isRuleRegistryEnabled: true, savedObjectsClient: context.core.savedObjects.client, rulesClient: context.alerting.getRulesClient(), exceptionsClient: context.lists?.getExceptionListClient(), spaceId: 'default', - signalsIndex: '.signals-index', existingLists: {}, }); @@ -185,12 +175,10 @@ describe('importRules', () => { rulesResponseAcc: [], mlAuthz, overwriteRules: true, - isRuleRegistryEnabled: true, savedObjectsClient: context.core.savedObjects.client, rulesClient: context.alerting.getRulesClient(), exceptionsClient: context.lists?.getExceptionListClient(), spaceId: 'default', - signalsIndex: '.signals-index', existingLists: {}, }); @@ -222,12 +210,10 @@ describe('importRules', () => { rulesResponseAcc: [], mlAuthz, overwriteRules: false, - isRuleRegistryEnabled: true, savedObjectsClient: context.core.savedObjects.client, rulesClient: context.alerting.getRulesClient(), exceptionsClient: context.lists?.getExceptionListClient(), spaceId: 'default', - signalsIndex: '.signals-index', existingLists: {}, }); @@ -244,7 +230,7 @@ describe('importRules', () => { it('reports error if "patchRules" throws', async () => { (patchRules as jest.Mock).mockRejectedValue(new Error('error patching rule')); - clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(true)); + clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); const result = await importRules({ ruleChunks: [ @@ -258,12 +244,10 @@ describe('importRules', () => { rulesResponseAcc: [], mlAuthz, overwriteRules: true, - isRuleRegistryEnabled: true, savedObjectsClient: context.core.savedObjects.client, rulesClient: context.alerting.getRulesClient(), exceptionsClient: context.lists?.getExceptionListClient(), spaceId: 'default', - signalsIndex: '.signals-index', existingLists: {}, }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/import_rules_utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/import_rules_utils.ts index 70083f8c04214..d603784fc7081 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/import_rules_utils.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/import_rules_utils.ts @@ -41,13 +41,10 @@ export interface RuleExceptionsPromiseFromStreams { * @param mlAuthz {object} * @param overwriteRules {boolean} - whether to overwrite existing rules * with imported rules if their rule_id matches - * @param isRuleRegistryEnabled {boolean} - feature flag that should be - * removed as this is now on and no going back * @param rulesClient {object} * @param savedObjectsClient {object} * @param exceptionsClient {object} * @param spaceId {string} - space being used during import - * @param signalsIndex {string} - the signals index name * @param existingLists {object} - all exception lists referenced by * rules that were found to exist * @returns {Promise} an array of error and success messages from import @@ -57,24 +54,20 @@ export const importRules = async ({ rulesResponseAcc, mlAuthz, overwriteRules, - isRuleRegistryEnabled, rulesClient, savedObjectsClient, exceptionsClient, spaceId, - signalsIndex, existingLists, }: { ruleChunks: PromiseFromStreams[][]; rulesResponseAcc: ImportRuleResponse[]; mlAuthz: MlAuthz; overwriteRules: boolean; - isRuleRegistryEnabled: boolean; rulesClient: RulesClient; savedObjectsClient: SavedObjectsClientContract; exceptionsClient: ExceptionListClient | undefined; spaceId: string; - signalsIndex: string; existingLists: Record; }) => { let importRuleResponse: ImportRuleResponse[] = [...rulesResponseAcc]; @@ -167,7 +160,6 @@ export const importRules = async ({ const filters: PartialFilter[] | undefined = filtersRest as PartialFilter[]; throwAuthzError(await mlAuthz.validateRuleType(type)); const rule = await readRules({ - isRuleRegistryEnabled, rulesClient, ruleId, id: undefined, @@ -175,7 +167,6 @@ export const importRules = async ({ if (rule == null) { await createRules({ - isRuleRegistryEnabled, rulesClient, anomalyThreshold, author, @@ -190,7 +181,7 @@ export const importRules = async ({ language, license, machineLearningJobId, - outputIndex: signalsIndex, + outputIndex: '', savedId, timelineId, timelineTitle, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/validate.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/validate.test.ts index f2b2c2b5d1f2d..0b8c49cdb4d17 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/validate.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/validate.test.ts @@ -8,7 +8,7 @@ import { transformValidate, transformValidateBulkError } from './validate'; import { BulkError } from '../utils'; import { RulesSchema } from '../../../../../common/detection_engine/schemas/response'; -import { getAlertMock, getRuleExecutionSummarySucceeded } from '../__mocks__/request_responses'; +import { getRuleMock, getRuleExecutionSummarySucceeded } from '../__mocks__/request_responses'; import { getListArrayMock } from '../../../../../common/detection_engine/schemas/types/lists.mock'; import { getThreatMock } from '../../../../../common/detection_engine/schemas/types/threat.mock'; import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; @@ -65,23 +65,20 @@ export const ruleOutput = (): RulesSchema => ({ timeline_id: 'some-timeline-id', }); -describe.each([ - ['Legacy', false], - ['RAC', true], -])('validate - %s', (_, isRuleRegistryEnabled) => { +describe('validate', () => { describe('transformValidate', () => { test('it should do a validation correctly of a partial alert', () => { - const ruleAlert = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - const [validated, errors] = transformValidate(ruleAlert, null, isRuleRegistryEnabled); + const ruleAlert = getRuleMock(getQueryRuleParams()); + const [validated, errors] = transformValidate(ruleAlert, null); expect(validated).toEqual(ruleOutput()); expect(errors).toEqual(null); }); test('it should do an in-validation correctly of a partial alert', () => { - const ruleAlert = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const ruleAlert = getRuleMock(getQueryRuleParams()); // @ts-expect-error delete ruleAlert.name; - const [validated, errors] = transformValidate(ruleAlert, null, isRuleRegistryEnabled); + const [validated, errors] = transformValidate(ruleAlert, null); expect(validated).toEqual(null); expect(errors).toEqual('Invalid value "undefined" supplied to "name"'); }); @@ -89,26 +86,16 @@ describe.each([ describe('transformValidateBulkError', () => { test('it should do a validation correctly of a rule id', () => { - const ruleAlert = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - const validatedOrError = transformValidateBulkError( - 'rule-1', - ruleAlert, - null, - isRuleRegistryEnabled - ); + const ruleAlert = getRuleMock(getQueryRuleParams()); + const validatedOrError = transformValidateBulkError('rule-1', ruleAlert, null); expect(validatedOrError).toEqual(ruleOutput()); }); test('it should do an in-validation correctly of a rule id', () => { - const ruleAlert = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const ruleAlert = getRuleMock(getQueryRuleParams()); // @ts-expect-error delete ruleAlert.name; - const validatedOrError = transformValidateBulkError( - 'rule-1', - ruleAlert, - null, - isRuleRegistryEnabled - ); + const validatedOrError = transformValidateBulkError('rule-1', ruleAlert, null); const expected: BulkError = { error: { message: 'Invalid value "undefined" supplied to "name"', @@ -120,14 +107,9 @@ describe.each([ }); test('it should do a validation correctly of a rule id with rule execution summary passed in', () => { - const rule = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const rule = getRuleMock(getQueryRuleParams()); const ruleExecutionSumary = getRuleExecutionSummarySucceeded(); - const validatedOrError = transformValidateBulkError( - 'rule-1', - rule, - ruleExecutionSumary, - isRuleRegistryEnabled - ); + const validatedOrError = transformValidateBulkError('rule-1', rule, ruleExecutionSumary); const expected: RulesSchema = { ...ruleOutput(), execution_summary: ruleExecutionSumary, @@ -136,15 +118,10 @@ describe.each([ }); test('it should return error object if "alert" is not expected alert type', () => { - const ruleAlert = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const ruleAlert = getRuleMock(getQueryRuleParams()); // @ts-expect-error delete ruleAlert.alertTypeId; - const validatedOrError = transformValidateBulkError( - 'rule-1', - ruleAlert, - null, - isRuleRegistryEnabled - ); + const validatedOrError = transformValidateBulkError('rule-1', ruleAlert, null); const expected: BulkError = { error: { message: 'Internal error transforming', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/validate.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/validate.ts index bde5d3ebf2027..852c06ba394f9 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/validate.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/validate.ts @@ -28,15 +28,9 @@ import { internalRuleToAPIResponse } from '../../schemas/rule_converters'; export const transformValidate = ( rule: PartialRule, ruleExecutionSummary: RuleExecutionSummary | null, - isRuleRegistryEnabled?: boolean, legacyRuleActions?: LegacyRulesActionsSavedObject | null ): [RulesSchema | null, string | null] => { - const transformed = transform( - rule, - ruleExecutionSummary, - isRuleRegistryEnabled, - legacyRuleActions - ); + const transformed = transform(rule, ruleExecutionSummary, legacyRuleActions); if (transformed == null) { return [null, 'Internal error transforming']; } else { @@ -47,15 +41,9 @@ export const transformValidate = ( export const newTransformValidate = ( rule: PartialRule, ruleExecutionSummary: RuleExecutionSummary | null, - isRuleRegistryEnabled?: boolean, legacyRuleActions?: LegacyRulesActionsSavedObject | null ): [FullResponseSchema | null, string | null] => { - const transformed = transform( - rule, - ruleExecutionSummary, - isRuleRegistryEnabled, - legacyRuleActions - ); + const transformed = transform(rule, ruleExecutionSummary, legacyRuleActions); if (transformed == null) { return [null, 'Internal error transforming']; } else { @@ -66,10 +54,9 @@ export const newTransformValidate = ( export const transformValidateBulkError = ( ruleId: string, rule: PartialRule, - ruleExecutionSummary: RuleExecutionSummary | null, - isRuleRegistryEnabled?: boolean + ruleExecutionSummary: RuleExecutionSummary | null ): RulesSchema | BulkError => { - if (isAlertType(isRuleRegistryEnabled ?? false, rule)) { + if (isAlertType(rule)) { const transformed = internalRuleToAPIResponse(rule, ruleExecutionSummary); const [validated, errors] = validateNonExact(transformed, rulesSchema); if (errors != null || validated == null) { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/create_signals_migration_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/create_signals_migration_route.ts index 8da147d64a6cf..df4ff25e9c640 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/create_signals_migration_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/create_signals_migration_route.ts @@ -39,9 +39,12 @@ export const createSignalsMigrationRoute = ( const { index: indices, ...reindexOptions } = request.body; try { - const esClient = context.core.elasticsearch.client.asCurrentUser; - const soClient = context.core.savedObjects.client; - const appClient = context.securitySolution?.getAppClient(); + const core = await context.core; + const securitySolution = await context.securitySolution; + + const esClient = core.elasticsearch.client.asCurrentUser; + const soClient = core.savedObjects.client; + const appClient = securitySolution?.getAppClient(); if (!appClient) { return siemResponse.error({ statusCode: 404 }); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/delete_signals_migration_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/delete_signals_migration_route.ts index 65ed42a0a166e..f94aff365f496 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/delete_signals_migration_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/delete_signals_migration_route.ts @@ -35,9 +35,12 @@ export const deleteSignalsMigrationRoute = ( const { migration_ids: migrationIds } = request.body; try { - const esClient = context.core.elasticsearch.client.asCurrentUser; - const soClient = context.core.savedObjects.client; - const appClient = context.securitySolution?.getAppClient(); + const core = await context.core; + const securitySolution = await context.securitySolution; + + const esClient = core.elasticsearch.client.asCurrentUser; + const soClient = core.savedObjects.client; + const appClient = securitySolution?.getAppClient(); if (!appClient) { return siemResponse.error({ statusCode: 404 }); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/finalize_signals_migration_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/finalize_signals_migration_route.ts index a6f5f28fce8e4..6029ad8e86bbc 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/finalize_signals_migration_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/finalize_signals_migration_route.ts @@ -35,12 +35,16 @@ export const finalizeSignalsMigrationRoute = ( }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); - const esClient = context.core.elasticsearch.client.asCurrentUser; - const soClient = context.core.savedObjects.client; + + const core = await context.core; + const securitySolution = await context.securitySolution; + + const esClient = core.elasticsearch.client.asCurrentUser; + const soClient = core.savedObjects.client; const { migration_ids: migrationIds } = request.body; try { - const appClient = context.securitySolution?.getAppClient(); + const appClient = securitySolution?.getAppClient(); if (!appClient) { return siemResponse.error({ statusCode: 404 }); } @@ -55,7 +59,7 @@ export const finalizeSignalsMigrationRoute = ( soClient, }); - const spaceId = context.securitySolution.getSpaceId(); + const spaceId = securitySolution.getSpaceId(); const signalsAlias = ruleDataService.getResourceName(`security.alerts-${spaceId}`); const finalizeResults = await Promise.all( migrations.map(async (migration) => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/get_signals_migration_status_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/get_signals_migration_status_route.ts index d800cead20cdc..f23bf4ae4185e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/get_signals_migration_status_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/get_signals_migration_status_route.ts @@ -31,11 +31,15 @@ export const getSignalsMigrationStatusRoute = (router: SecuritySolutionPluginRou }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); - const esClient = context.core.elasticsearch.client.asCurrentUser; - const soClient = context.core.savedObjects.client; + + const core = await context.core; + const securitySolution = await context.securitySolution; + + const esClient = core.elasticsearch.client.asCurrentUser; + const soClient = core.savedObjects.client; try { - const appClient = context.securitySolution?.getAppClient(); + const appClient = securitySolution?.getAppClient(); if (!appClient) { return siemResponse.error({ statusCode: 404 }); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals.test.ts index 9cc93bc7f5905..5a46d7a9b55f6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals.test.ts @@ -44,12 +44,18 @@ describe('set signal status', () => { describe('status on signal', () => { test('returns 200 when setting a status on a signal by ids', async () => { - const response = await server.inject(getSetSignalStatusByIdsRequest(), context); + const response = await server.inject( + getSetSignalStatusByIdsRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 200 when setting a status on a signal by query', async () => { - const response = await server.inject(getSetSignalStatusByQueryRequest(), context); + const response = await server.inject( + getSetSignalStatusByQueryRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); @@ -68,7 +74,10 @@ describe('set signal status', () => { context.core.elasticsearch.client.asCurrentUser.updateByQuery.mockRejectedValue( new Error('Test error') ); - const response = await server.inject(getSetSignalStatusByQueryRequest(), context); + const response = await server.inject( + getSetSignalStatusByQueryRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', @@ -106,7 +115,7 @@ describe('set signal status', () => { path: DETECTION_ENGINE_SIGNALS_STATUS_URL, body: setStatusSignalMissingIdsAndQueryPayload(), }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(400); expect(response.body).toEqual({ message: ['either "signal_ids" or "query" must be set'], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts index 8482dd3b94e18..63b90ccc4cfc7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts @@ -49,11 +49,13 @@ export const setSignalsStatusRoute = ( }, async (context, request, response) => { const { conflicts, signal_ids: signalIds, query, status } = request.body; - const esClient = context.core.elasticsearch.client.asCurrentUser; - const siemClient = context.securitySolution?.getAppClient(); + const core = await context.core; + const securitySolution = await context.securitySolution; + const esClient = core.elasticsearch.client.asCurrentUser; + const siemClient = securitySolution?.getAppClient(); const siemResponse = buildSiemResponse(response); const validationErrors = setSignalStatusValidateTypeDependents(request.body); - const spaceId = context.securitySolution?.getSpaceId() ?? 'default'; + const spaceId = securitySolution?.getSpaceId() ?? 'default'; if (validationErrors.length) { return siemResponse.error({ statusCode: 400, body: validationErrors }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.test.ts index b3de63e6d278c..8a8af78a9b86e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.test.ts @@ -35,7 +35,10 @@ describe('query for signal', () => { describe('query and agg on signals index', () => { test('returns 200 when using single query', async () => { - const response = await server.inject(getSignalsQueryRequest(), context); + const response = await server.inject( + getSignalsQueryRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(ruleDataClient.getReader().search).toHaveBeenCalledWith( @@ -46,7 +49,10 @@ describe('query for signal', () => { }); test('returns 200 when using single agg', async () => { - const response = await server.inject(getSignalsAggsQueryRequest(), context); + const response = await server.inject( + getSignalsAggsQueryRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(ruleDataClient.getReader().search).toHaveBeenCalledWith( @@ -55,7 +61,10 @@ describe('query for signal', () => { }); test('returns 200 when using aggs and query together', async () => { - const response = await server.inject(getSignalsAggsAndQueryRequest(), context); + const response = await server.inject( + getSignalsAggsAndQueryRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(ruleDataClient.getReader().search).toHaveBeenCalledWith( @@ -70,7 +79,10 @@ describe('query for signal', () => { test('catches error if query throws error', async () => { ruleDataClient.getReader().search.mockRejectedValue(new Error('Test error')); - const response = await server.inject(getSignalsAggsQueryRequest(), context); + const response = await server.inject( + getSignalsAggsQueryRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', @@ -120,7 +132,7 @@ describe('query for signal', () => { path: DETECTION_ENGINE_QUERY_SIGNALS_URL, body: {}, }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(400); expect(response.body).toEqual({ message: '"value" must have at least 1 children', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.ts index 3740d187347b6..7b8216084ac9d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.ts @@ -52,20 +52,19 @@ export const querySignalsRoute = ( } try { - const result = await ruleDataClient - ?.getReader({ namespace: context.securitySolution.getSpaceId() }) - .search({ - body: { - query, - // Note: I use a spread operator to please TypeScript with aggs: { ...aggs } - aggs: { ...aggs }, - _source, - track_total_hits, - size, - runtime_mappings: runtime_mappings as MappingRuntimeFields, - }, - ignore_unavailable: true, - }); + const spaceId = (await context.securitySolution).getSpaceId(); + const result = await ruleDataClient?.getReader({ namespace: spaceId }).search({ + body: { + query, + // Note: I use a spread operator to please TypeScript with aggs: { ...aggs } + aggs: { ...aggs }, + _source, + track_total_hits, + size, + runtime_mappings: runtime_mappings as MappingRuntimeFields, + }, + ignore_unavailable: true, + }); return response.ok({ body: result }); } catch (err) { // error while getting or updating signal with id: id in signal index .siem-signals diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/tags/read_tags_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/tags/read_tags_route.ts index 04464e5d6f5a7..508495cdeb9ef 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/tags/read_tags_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/tags/read_tags_route.ts @@ -12,10 +12,7 @@ import { buildSiemResponse } from '../utils'; import { readTags } from '../../tags/read_tags'; -export const readTagsRoute = ( - router: SecuritySolutionPluginRouter, - isRuleRegistryEnabled: boolean -) => { +export const readTagsRoute = (router: SecuritySolutionPluginRouter) => { router.get( { path: DETECTION_ENGINE_TAGS_URL, @@ -26,7 +23,7 @@ export const readTagsRoute = ( }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); - const rulesClient = context.alerting?.getRulesClient(); + const rulesClient = (await context.alerting)?.getRulesClient(); if (!rulesClient) { return siemResponse.error({ statusCode: 404 }); @@ -34,7 +31,6 @@ export const readTagsRoute = ( try { const tags = await readTags({ - isRuleRegistryEnabled, rulesClient, }); return response.ok({ body: tags }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/utils.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/utils.test.ts index 4e614b5fc8381..d9845f85b2935 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/utils.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/utils.test.ts @@ -10,10 +10,7 @@ import { transformBulkError, BulkError, convertToSnakeCase, SiemResponseFactory import { responseMock } from './__mocks__'; import { CustomHttpRequestError } from '../../../utils/custom_http_request_error'; -describe.each([ - ['Legacy', false], - ['RAC', true], -])('utils - %s', (_, isRuleRegistryEnabled) => { +describe('utils', () => { describe('transformBulkError', () => { test('returns transformed object if it is a custom error object', () => { const customError = new CustomHttpRequestError('some custom error message', 400); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert.ts index e1259be5062a0..8492ec6cd2c26 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert.ts @@ -78,7 +78,6 @@ import { commonParamsCamelToSnake, typeSpecificCamelToSnake, } from '../../../schemas/rule_converters'; -import { transformTags } from '../../../routes/rules/utils'; import { transformAlertToRuleAction } from '../../../../../../common/detection_engine/transform_actions'; import { AncestorLatest, @@ -215,7 +214,7 @@ export const buildAlert = ( [ALERT_RULE_RULE_ID]: params.ruleId, [ALERT_RULE_RULE_NAME_OVERRIDE]: params.ruleNameOverride, [ALERT_RULE_SEVERITY_MAPPING]: params.severityMapping, - [ALERT_RULE_TAGS]: transformTags(tags), + [ALERT_RULE_TAGS]: tags, [ALERT_RULE_THREAT]: params.threat, [ALERT_RULE_THROTTLE]: throttle ?? undefined, [ALERT_RULE_TIMELINE_ID]: params.timelineId, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/add_tags.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/add_tags.test.ts deleted file mode 100644 index 93fddc06b8068..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/add_tags.test.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { addTags } from './add_tags'; -import { INTERNAL_RULE_ID_KEY, INTERNAL_IMMUTABLE_KEY } from '../../../../common/constants'; - -describe('add_tags', () => { - test('it should add a rule id as an internal structure with immutable true', () => { - const tags = addTags([], 'rule-1', true); - expect(tags).toEqual([`${INTERNAL_RULE_ID_KEY}:rule-1`, `${INTERNAL_IMMUTABLE_KEY}:true`]); - }); - - test('it should add a rule id as an internal structure with immutable false', () => { - const tags = addTags([], 'rule-1', false); - expect(tags).toEqual([`${INTERNAL_RULE_ID_KEY}:rule-1`, `${INTERNAL_IMMUTABLE_KEY}:false`]); - }); - - test('it should not allow duplicate tags to be created', () => { - const tags = addTags(['tag-1', 'tag-1'], 'rule-1', false); - expect(tags).toEqual([ - 'tag-1', - `${INTERNAL_RULE_ID_KEY}:rule-1`, - `${INTERNAL_IMMUTABLE_KEY}:false`, - ]); - }); - - test('it should not allow duplicate internal tags to be created when called two times in a row', () => { - const tags1 = addTags(['tag-1'], 'rule-1', false); - const tags2 = addTags(tags1, 'rule-1', false); - expect(tags2).toEqual([ - 'tag-1', - `${INTERNAL_RULE_ID_KEY}:rule-1`, - `${INTERNAL_IMMUTABLE_KEY}:false`, - ]); - }); - - test('it should overwrite existing immutable tag if it exists', () => { - const tags1 = addTags(['tag-1', `${INTERNAL_IMMUTABLE_KEY}:true`], 'rule-1', false); - expect(tags1).toEqual([ - 'tag-1', - `${INTERNAL_RULE_ID_KEY}:rule-1`, - `${INTERNAL_IMMUTABLE_KEY}:false`, - ]); - }); -}); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/add_tags.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/add_tags.ts deleted file mode 100644 index d66f961b38598..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/add_tags.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { INTERNAL_RULE_ID_KEY, INTERNAL_IMMUTABLE_KEY } from '../../../../common/constants'; - -export const addTags = (tags: string[], ruleId: string, immutable: boolean): string[] => { - return Array.from( - new Set([ - ...tags.filter( - (tag) => !(tag.startsWith(INTERNAL_RULE_ID_KEY) || tag.startsWith(INTERNAL_IMMUTABLE_KEY)) - ), - `${INTERNAL_RULE_ID_KEY}:${ruleId}`, - `${INTERNAL_IMMUTABLE_KEY}:${immutable}`, - ]) - ); -}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules.mock.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules.mock.ts index 126726ab08a79..1a41adb4f6da5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules.mock.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules.mock.ts @@ -8,8 +8,7 @@ import { CreateRulesOptions } from './types'; import { rulesClientMock } from '@kbn/alerting-plugin/server/mocks'; -export const getCreateRulesOptionsMock = (isRuleRegistryEnabled: boolean): CreateRulesOptions => ({ - isRuleRegistryEnabled, +export const getCreateRulesOptionsMock = (): CreateRulesOptions => ({ author: ['Elastic'], buildingBlockType: undefined, rulesClient: rulesClientMock.create(), @@ -62,10 +61,7 @@ export const getCreateRulesOptionsMock = (isRuleRegistryEnabled: boolean): Creat actions: [], }); -export const getCreateMlRulesOptionsMock = ( - isRuleRegistryEnabled: boolean -): CreateRulesOptions => ({ - isRuleRegistryEnabled, +export const getCreateMlRulesOptionsMock = (): CreateRulesOptions => ({ author: ['Elastic'], buildingBlockType: undefined, rulesClient: rulesClientMock.create(), @@ -118,9 +114,7 @@ export const getCreateMlRulesOptionsMock = ( actions: [], }); -export const getCreateThreatMatchRulesOptionsMock = ( - isRuleRegistryEnabled: boolean -): CreateRulesOptions => ({ +export const getCreateThreatMatchRulesOptionsMock = (): CreateRulesOptions => ({ actions: [], anomalyThreshold: undefined, author: ['Elastic'], @@ -136,7 +130,6 @@ export const getCreateThreatMatchRulesOptionsMock = ( immutable: false, index: ['*'], interval: '5m', - isRuleRegistryEnabled, itemsPerSearch: undefined, language: 'kuery', license: 'Elastic License', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules.test.ts index 3d5619ab1306b..ab683effd4c14 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules.test.ts @@ -12,12 +12,9 @@ import { } from './create_rules.mock'; import { DEFAULT_INDICATOR_SOURCE_PATH } from '../../../../common/constants'; -describe.each([ - ['Legacy', false], - ['RAC', true], -])('createRules - %s', (_, isRuleRegistryEnabled) => { +describe('createRules', () => { it('calls the rulesClient with legacy ML params', async () => { - const ruleOptions = getCreateMlRulesOptionsMock(isRuleRegistryEnabled); + const ruleOptions = getCreateMlRulesOptionsMock(); await createRules(ruleOptions); expect(ruleOptions.rulesClient.create).toHaveBeenCalledWith( expect.objectContaining({ @@ -33,7 +30,7 @@ describe.each([ it('calls the rulesClient with ML params', async () => { const ruleOptions = { - ...getCreateMlRulesOptionsMock(isRuleRegistryEnabled), + ...getCreateMlRulesOptionsMock(), machineLearningJobId: ['new_job_1', 'new_job_2'], }; await createRules(ruleOptions); @@ -50,7 +47,7 @@ describe.each([ }); it('populates a threatIndicatorPath value for threat_match rule if empty', async () => { - const ruleOptions = getCreateThreatMatchRulesOptionsMock(isRuleRegistryEnabled); + const ruleOptions = getCreateThreatMatchRulesOptionsMock(); delete ruleOptions.threatIndicatorPath; await createRules(ruleOptions); expect(ruleOptions.rulesClient.create).toHaveBeenCalledWith( @@ -65,7 +62,7 @@ describe.each([ }); it('does not populate a threatIndicatorPath value for other rules if empty', async () => { - const ruleOptions = getCreateMlRulesOptionsMock(isRuleRegistryEnabled); + const ruleOptions = getCreateMlRulesOptionsMock(); delete ruleOptions.threatIndicatorPath; await createRules(ruleOptions); expect(ruleOptions.rulesClient.create).not.toHaveBeenCalledWith( diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules.ts index 9ba39746ae4d2..24017adc20626 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { SIGNALS_ID, ruleTypeMappings } from '@kbn/securitysolution-rules'; +import { ruleTypeMappings } from '@kbn/securitysolution-rules'; import { RuleTypeParams, SanitizedRule } from '@kbn/alerting-plugin/common'; import { @@ -19,7 +19,6 @@ import { SERVER_APP_ID, } from '../../../../common/constants'; import { CreateRulesOptions } from './types'; -import { addTags } from './add_tags'; import { PartialFilter } from '../types'; import { transformToAlertThrottle, transformToNotifyWhen } from './utils'; @@ -75,7 +74,6 @@ export const createRules = async ({ version, exceptionsList, actions, - isRuleRegistryEnabled, id, }: CreateRulesOptions): Promise> => { const rule = await rulesClient.create({ @@ -84,8 +82,8 @@ export const createRules = async ({ }, data: { name, - tags: addTags(tags, ruleId, immutable), - alertTypeId: isRuleRegistryEnabled ? ruleTypeMappings[type] : SIGNALS_ID, + tags, + alertTypeId: ruleTypeMappings[type], consumer: SERVER_APP_ID, params: { anomalyThreshold, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/duplicate_rule.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/duplicate_rule.test.ts index 6d4da61efcc82..04d8e66a076fb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/duplicate_rule.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/duplicate_rule.test.ts @@ -6,7 +6,6 @@ */ import uuid from 'uuid'; -import { INTERNAL_IMMUTABLE_KEY } from '../../../../common/constants'; import { duplicateRule } from './duplicate_rule'; jest.mock('uuid', () => ({ @@ -18,73 +17,70 @@ describe('duplicateRule', () => { (uuid.v4 as jest.Mock).mockReturnValue('newId'); expect( - duplicateRule( - { - id: 'oldTestRuleId', - notifyWhen: 'onActiveAlert', - name: 'test', - tags: ['test', '__internal_rule_id:oldTestRuleId', `${INTERNAL_IMMUTABLE_KEY}:false`], - alertTypeId: 'siem.signals', - consumer: 'siem', - params: { - savedId: undefined, - author: [], - description: 'test', - ruleId: 'oldTestRuleId', - falsePositives: [], - from: 'now-360s', - immutable: false, - license: '', - outputIndex: '.siem-signals-default', - meta: undefined, - maxSignals: 100, - riskScore: 42, - riskScoreMapping: [], - severity: 'low', - severityMapping: [], - threat: [], - to: 'now', - references: [], - version: 1, - exceptionsList: [], - type: 'query', - language: 'kuery', - index: [], - query: 'process.args : "chmod"', - filters: [], - buildingBlockType: undefined, - namespace: undefined, - note: undefined, - timelineId: undefined, - timelineTitle: undefined, - ruleNameOverride: undefined, - timestampOverride: undefined, - }, - schedule: { - interval: '5m', - }, - enabled: false, - actions: [], - throttle: null, - apiKeyOwner: 'kibana', - createdBy: 'kibana', - updatedBy: 'kibana', - muteAll: false, - mutedInstanceIds: [], - updatedAt: new Date(2021, 0), - createdAt: new Date(2021, 0), - scheduledTaskId: undefined, - executionStatus: { - lastExecutionDate: new Date(2021, 0), - status: 'ok', - }, + duplicateRule({ + id: 'oldTestRuleId', + notifyWhen: 'onActiveAlert', + name: 'test', + tags: ['test'], + alertTypeId: 'siem.signals', + consumer: 'siem', + params: { + savedId: undefined, + author: [], + description: 'test', + ruleId: 'oldTestRuleId', + falsePositives: [], + from: 'now-360s', + immutable: false, + license: '', + outputIndex: '.siem-signals-default', + meta: undefined, + maxSignals: 100, + riskScore: 42, + riskScoreMapping: [], + severity: 'low', + severityMapping: [], + threat: [], + to: 'now', + references: [], + version: 1, + exceptionsList: [], + type: 'query', + language: 'kuery', + index: [], + query: 'process.args : "chmod"', + filters: [], + buildingBlockType: undefined, + namespace: undefined, + note: undefined, + timelineId: undefined, + timelineTitle: undefined, + ruleNameOverride: undefined, + timestampOverride: undefined, }, - false - ) + schedule: { + interval: '5m', + }, + enabled: false, + actions: [], + throttle: null, + apiKeyOwner: 'kibana', + createdBy: 'kibana', + updatedBy: 'kibana', + muteAll: false, + mutedInstanceIds: [], + updatedAt: new Date(2021, 0), + createdAt: new Date(2021, 0), + scheduledTaskId: undefined, + executionStatus: { + lastExecutionDate: new Date(2021, 0), + status: 'ok', + }, + }) ).toMatchInlineSnapshot(` Object { "actions": Array [], - "alertTypeId": "siem.signals", + "alertTypeId": "siem.queryRule", "consumer": "siem", "enabled": false, "name": "test [Duplicate]", @@ -128,8 +124,6 @@ describe('duplicateRule', () => { }, "tags": Array [ "test", - "__internal_rule_id:newId", - "__internal_immutable:false", ], "throttle": null, } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/duplicate_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/duplicate_rule.ts index 4efd6934aeee8..4ef21d0450517 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/duplicate_rule.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/duplicate_rule.ts @@ -8,12 +8,11 @@ import uuid from 'uuid'; import { i18n } from '@kbn/i18n'; -import { ruleTypeMappings, SIGNALS_ID } from '@kbn/securitysolution-rules'; +import { ruleTypeMappings } from '@kbn/securitysolution-rules'; import { SanitizedRule } from '@kbn/alerting-plugin/common'; import { SERVER_APP_ID } from '../../../../common/constants'; import { InternalRuleCreate, RuleParams } from '../schemas/rule_schemas'; -import { addTags } from './add_tags'; const DUPLICATE_TITLE = i18n.translate( 'xpack.securitySolution.detectionEngine.rules.cloneRule.duplicateTitle', @@ -22,15 +21,12 @@ const DUPLICATE_TITLE = i18n.translate( } ); -export const duplicateRule = ( - rule: SanitizedRule, - isRuleRegistryEnabled: boolean -): InternalRuleCreate => { +export const duplicateRule = (rule: SanitizedRule): InternalRuleCreate => { const newRuleId = uuid.v4(); return { name: `${rule.name} [${DUPLICATE_TITLE}]`, - tags: addTags(rule.tags, newRuleId, false), - alertTypeId: isRuleRegistryEnabled ? ruleTypeMappings[rule.params.type] : SIGNALS_ID, + tags: rule.tags, + alertTypeId: ruleTypeMappings[rule.params.type], consumer: SERVER_APP_ID, params: { ...rule.params, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/edit_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/edit_rule.ts index 93a297e6965b4..c7f17e100205c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/edit_rule.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/edit_rule.ts @@ -11,7 +11,6 @@ import { validate } from '@kbn/securitysolution-io-ts-utils'; import type { RulesClient } from '@kbn/alerting-plugin/server'; import { RuleAlertType } from './types'; import { InternalRuleUpdate, internalRuleUpdate } from '../schemas/rule_schemas'; -import { addTags } from './add_tags'; class EditRuleError extends Error { public readonly statusCode: number; @@ -103,10 +102,7 @@ const validateAndSanitizeChanges = ( throw new EditRuleError(`Internal rule editing error: can't change "params.version"`, 500); } - return { - ...changed, - tags: addTags(changed.tags, changed.params.ruleId, changed.params.immutable), - }; + return changed; }; const isRuleChanged = (originalRule: RuleAlertType, editedRule: RuleAlertType): boolean => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/find_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/find_rules.test.ts index f4270b359c4da..77fed17c40261 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/find_rules.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/find_rules.test.ts @@ -12,7 +12,6 @@ import { QUERY_RULE_TYPE_ID, SAVED_QUERY_RULE_TYPE_ID, THRESHOLD_RULE_TYPE_ID, - SIGNALS_ID, } from '@kbn/securitysolution-rules'; import { getFilter } from './find_rules'; @@ -25,26 +24,13 @@ const allAlertTypeIds = `(alert.attributes.alertTypeId: ${EQL_RULE_TYPE_ID} OR alert.attributes.alertTypeId: ${THRESHOLD_RULE_TYPE_ID})`.replace(/[\n\r]/g, ''); describe('find_rules', () => { - const fullFilterTestCases: Array<[boolean, string]> = [ - [false, `alert.attributes.alertTypeId: ${SIGNALS_ID} AND alert.attributes.enabled: true`], - [true, `${allAlertTypeIds} AND alert.attributes.enabled: true`], - ]; - const nullFilterTestCases: Array<[boolean, string]> = [ - [false, `alert.attributes.alertTypeId: ${SIGNALS_ID}`], - [true, allAlertTypeIds], - ]; + test('it returns a full filter with an AND if sent down', () => { + expect(getFilter('alert.attributes.enabled: true')).toEqual( + `${allAlertTypeIds} AND alert.attributes.enabled: true` + ); + }); - test.each(fullFilterTestCases)( - 'it returns a full filter with an AND if sent down [rule registry enabled: %p]', - (isRuleRegistryEnabled, expected) => { - expect(getFilter('alert.attributes.enabled: true', isRuleRegistryEnabled)).toEqual(expected); - } - ); - - test.each(nullFilterTestCases)( - 'it returns existing filter with no AND when not set [rule registry enabled: %p]', - (isRuleRegistryEnabled, expected) => { - expect(getFilter(null, isRuleRegistryEnabled)).toEqual(expected); - } - ); + test('it returns existing filter with no AND when not set [rule registry enabled: %p]', () => { + expect(getFilter(null)).toEqual(allAlertTypeIds); + }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/find_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/find_rules.ts index 4f23d1425344f..3d95a13c428a0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/find_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/find_rules.ts @@ -5,22 +5,17 @@ * 2.0. */ -import { SIGNALS_ID, ruleTypeMappings } from '@kbn/securitysolution-rules'; +import { ruleTypeMappings } from '@kbn/securitysolution-rules'; import { FindResult } from '@kbn/alerting-plugin/server'; import { RuleParams } from '../schemas/rule_schemas'; import { FindRuleOptions } from './types'; -export const getFilter = ( - filter: string | null | undefined, - isRuleRegistryEnabled: boolean = false -) => { - const alertTypeFilter = isRuleRegistryEnabled - ? `(${Object.values(ruleTypeMappings) - .map((type) => `alert.attributes.alertTypeId: ${type}`) - .filter((type, i, arr) => type != null && arr.indexOf(type) === i) - .join(' OR ')})` - : `alert.attributes.alertTypeId: ${SIGNALS_ID}`; +export const getFilter = (filter: string | null | undefined) => { + const alertTypeFilter = `(${Object.values(ruleTypeMappings) + .map((type) => `alert.attributes.alertTypeId: ${type}`) + .filter((type, i, arr) => type != null && arr.indexOf(type) === i) + .join(' OR ')})`; if (filter == null) { return alertTypeFilter; } else { @@ -36,14 +31,13 @@ export const findRules = ({ filter, sortField, sortOrder, - isRuleRegistryEnabled, }: FindRuleOptions): Promise> => { return rulesClient.find({ options: { fields, page, perPage, - filter: getFilter(filter, isRuleRegistryEnabled), + filter: getFilter(filter), sortOrder, sortField, }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_existing_prepackaged_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_existing_prepackaged_rules.test.ts index 7ddf4c4427286..279a211c9ea33 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_existing_prepackaged_rules.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_existing_prepackaged_rules.test.ts @@ -7,7 +7,7 @@ import { rulesClientMock } from '@kbn/alerting-plugin/server/mocks'; import { - getAlertMock, + getRuleMock, getFindResultWithSingleHit, getFindResultWithMultiHits, } from '../routes/__mocks__/request_responses'; @@ -20,10 +20,7 @@ import { getNonPackagedRulesCount, } from './get_existing_prepackaged_rules'; -describe.each([ - ['Legacy', false], - ['RAC', true], -])('get_existing_prepackaged_rules - %s', (_, isRuleRegistryEnabled) => { +describe('get_existing_prepackaged_rules', () => { afterEach(() => { jest.resetAllMocks(); }); @@ -31,23 +28,23 @@ describe.each([ describe('getExistingPrepackagedRules', () => { test('should return a single item in a single page', async () => { const rulesClient = rulesClientMock.create(); - rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); - const rules = await getExistingPrepackagedRules({ isRuleRegistryEnabled, rulesClient }); - expect(rules).toEqual([getAlertMock(isRuleRegistryEnabled, getQueryRuleParams())]); + rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); + const rules = await getExistingPrepackagedRules({ rulesClient }); + expect(rules).toEqual([getRuleMock(getQueryRuleParams())]); }); test('should return 3 items over 1 page with all on one page', async () => { const rulesClient = rulesClientMock.create(); - const result1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result1 = getRuleMock(getQueryRuleParams()); result1.params.immutable = true; result1.id = '4baa53f8-96da-44ee-ad58-41bccb7f9f3d'; - const result2 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result2 = getRuleMock(getQueryRuleParams()); result2.params.immutable = true; result2.id = '5baa53f8-96da-44ee-ad58-41bccb7f9f3d'; - const result3 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result3 = getRuleMock(getQueryRuleParams()); result3.params.immutable = true; result3.id = 'f3e1bf0b-b95f-43da-b1de-5d2f0af2287a'; @@ -71,7 +68,7 @@ describe.each([ }) ); - const rules = await getExistingPrepackagedRules({ isRuleRegistryEnabled, rulesClient }); + const rules = await getExistingPrepackagedRules({ rulesClient }); expect(rules).toEqual([result1, result2, result3]); }); }); @@ -79,18 +76,18 @@ describe.each([ describe('getNonPackagedRules', () => { test('should return a single item in a single page', async () => { const rulesClient = rulesClientMock.create(); - rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); - const rules = await getNonPackagedRules({ isRuleRegistryEnabled, rulesClient }); - expect(rules).toEqual([getAlertMock(isRuleRegistryEnabled, getQueryRuleParams())]); + rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); + const rules = await getNonPackagedRules({ rulesClient }); + expect(rules).toEqual([getRuleMock(getQueryRuleParams())]); }); test('should return 2 items over 1 page', async () => { const rulesClient = rulesClientMock.create(); - const result1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result1 = getRuleMock(getQueryRuleParams()); result1.id = '4baa53f8-96da-44ee-ad58-41bccb7f9f3d'; - const result2 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result2 = getRuleMock(getQueryRuleParams()); result2.id = '5baa53f8-96da-44ee-ad58-41bccb7f9f3d'; // first result mock which is for returning the total @@ -108,20 +105,20 @@ describe.each([ getFindResultWithMultiHits({ data: [result1, result2], perPage: 2, page: 1, total: 2 }) ); - const rules = await getNonPackagedRules({ isRuleRegistryEnabled, rulesClient }); + const rules = await getNonPackagedRules({ rulesClient }); expect(rules).toEqual([result1, result2]); }); test('should return 3 items over 1 page with all on one page', async () => { const rulesClient = rulesClientMock.create(); - const result1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result1 = getRuleMock(getQueryRuleParams()); result1.id = '4baa53f8-96da-44ee-ad58-41bccb7f9f3d'; - const result2 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result2 = getRuleMock(getQueryRuleParams()); result2.id = '5baa53f8-96da-44ee-ad58-41bccb7f9f3d'; - const result3 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result3 = getRuleMock(getQueryRuleParams()); result3.id = 'f3e1bf0b-b95f-43da-b1de-5d2f0af2287a'; // first result mock which is for returning the total @@ -144,7 +141,7 @@ describe.each([ }) ); - const rules = await getNonPackagedRules({ isRuleRegistryEnabled, rulesClient }); + const rules = await getNonPackagedRules({ rulesClient }); expect(rules).toEqual([result1, result2, result3]); }); }); @@ -152,18 +149,18 @@ describe.each([ describe('getRules', () => { test('should return a single item in a single page', async () => { const rulesClient = rulesClientMock.create(); - rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); - const rules = await getRules({ isRuleRegistryEnabled, rulesClient, filter: '' }); - expect(rules).toEqual([getAlertMock(isRuleRegistryEnabled, getQueryRuleParams())]); + rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); + const rules = await getRules({ rulesClient, filter: '' }); + expect(rules).toEqual([getRuleMock(getQueryRuleParams())]); }); test('should return 2 items over two pages, one per page', async () => { const rulesClient = rulesClientMock.create(); - const result1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result1 = getRuleMock(getQueryRuleParams()); result1.id = '4baa53f8-96da-44ee-ad58-41bccb7f9f3d'; - const result2 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result2 = getRuleMock(getQueryRuleParams()); result2.id = '5baa53f8-96da-44ee-ad58-41bccb7f9f3d'; // first result mock which is for returning the total @@ -181,7 +178,7 @@ describe.each([ getFindResultWithMultiHits({ data: [result1, result2], perPage: 2, page: 1, total: 2 }) ); - const rules = await getRules({ isRuleRegistryEnabled, rulesClient, filter: '' }); + const rules = await getRules({ rulesClient, filter: '' }); expect(rules).toEqual([result1, result2]); }); }); @@ -189,8 +186,8 @@ describe.each([ describe('getRulesCount', () => { test('it returns a count', async () => { const rulesClient = rulesClientMock.create(); - rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); - const rules = await getRulesCount({ isRuleRegistryEnabled, rulesClient, filter: '' }); + rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); + const rules = await getRulesCount({ rulesClient, filter: '' }); expect(rules).toEqual(1); }); }); @@ -198,8 +195,8 @@ describe.each([ describe('getNonPackagedRulesCount', () => { test('it returns a count', async () => { const rulesClient = rulesClientMock.create(); - rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); - const rules = await getNonPackagedRulesCount({ isRuleRegistryEnabled, rulesClient }); + rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); + const rules = await getNonPackagedRulesCount({ rulesClient }); expect(rules).toEqual(1); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_existing_prepackaged_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_existing_prepackaged_rules.ts index 68a0c077e59a4..440d3db36bd63 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_existing_prepackaged_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_existing_prepackaged_rules.ts @@ -6,34 +6,28 @@ */ import { RulesClient } from '@kbn/alerting-plugin/server'; -import { INTERNAL_IMMUTABLE_KEY } from '../../../../common/constants'; import { RuleAlertType, isAlertTypes } from './types'; import { findRules } from './find_rules'; -export const FILTER_NON_PREPACKED_RULES = `alert.attributes.tags: "${INTERNAL_IMMUTABLE_KEY}:false"`; -export const FILTER_PREPACKED_RULES = `alert.attributes.tags: "${INTERNAL_IMMUTABLE_KEY}:true"`; +export const FILTER_NON_PREPACKED_RULES = 'alert.attributes.params.immutable: false'; +export const FILTER_PREPACKED_RULES = 'alert.attributes.params.immutable: true'; export const getNonPackagedRulesCount = async ({ - isRuleRegistryEnabled, rulesClient, }: { - isRuleRegistryEnabled: boolean; rulesClient: RulesClient; }): Promise => { - return getRulesCount({ isRuleRegistryEnabled, rulesClient, filter: FILTER_NON_PREPACKED_RULES }); + return getRulesCount({ rulesClient, filter: FILTER_NON_PREPACKED_RULES }); }; export const getRulesCount = async ({ rulesClient, filter, - isRuleRegistryEnabled, }: { rulesClient: RulesClient; filter: string; - isRuleRegistryEnabled: boolean; }): Promise => { const firstRule = await findRules({ - isRuleRegistryEnabled, rulesClient, filter, perPage: 1, @@ -48,15 +42,12 @@ export const getRulesCount = async ({ export const getRules = async ({ rulesClient, filter, - isRuleRegistryEnabled, }: { rulesClient: RulesClient; filter: string; - isRuleRegistryEnabled: boolean; }) => { - const count = await getRulesCount({ rulesClient, filter, isRuleRegistryEnabled }); + const count = await getRulesCount({ rulesClient, filter }); const rules = await findRules({ - isRuleRegistryEnabled, rulesClient, filter, perPage: count, @@ -66,7 +57,7 @@ export const getRules = async ({ fields: undefined, }); - if (isAlertTypes(isRuleRegistryEnabled, rules.data)) { + if (isAlertTypes(rules.data)) { return rules.data; } else { // If this was ever true, you have a really messed up system. @@ -77,28 +68,22 @@ export const getRules = async ({ export const getNonPackagedRules = async ({ rulesClient, - isRuleRegistryEnabled, }: { rulesClient: RulesClient; - isRuleRegistryEnabled: boolean; }): Promise => { return getRules({ rulesClient, filter: FILTER_NON_PREPACKED_RULES, - isRuleRegistryEnabled, }); }; export const getExistingPrepackagedRules = async ({ rulesClient, - isRuleRegistryEnabled, }: { rulesClient: RulesClient; - isRuleRegistryEnabled: boolean; }): Promise => { return getRules({ rulesClient, filter: FILTER_PREPACKED_RULES, - isRuleRegistryEnabled, }); }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_all.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_all.test.ts index b42508b0a73b6..de80a8ba8c26b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_all.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_all.test.ts @@ -6,7 +6,7 @@ */ import { - getAlertMock, + getRuleMock, getFindResultWithSingleHit, FindHit, getEmptySavedObjectsResponse, @@ -27,10 +27,7 @@ import { requestContextMock } from '../routes/__mocks__/request_context'; const exceptionsClient = getExceptionListClientMock(); -describe.each([ - ['Legacy', false], - ['RAC', true], -])('getExportAll - %s', (_, isRuleRegistryEnabled) => { +describe('getExportAll', () => { let logger: ReturnType; const { clients } = requestContextMock.createTools(); @@ -40,8 +37,8 @@ describe.each([ test('it exports everything from the alerts client', async () => { const rulesClient = rulesClientMock.create(); - const result = getFindResultWithSingleHit(isRuleRegistryEnabled); - const alert = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result = getFindResultWithSingleHit(); + const alert = getRuleMock(getQueryRuleParams()); alert.params = { ...alert.params, @@ -58,8 +55,7 @@ describe.each([ rulesClient, exceptionsClient, clients.savedObjectsClient, - logger, - isRuleRegistryEnabled + logger ); const rulesJson = JSON.parse(exports.rulesNdjson); const detailsJson = JSON.parse(exports.exportDetails); @@ -134,8 +130,7 @@ describe.each([ rulesClient, exceptionsClient, clients.savedObjectsClient, - logger, - isRuleRegistryEnabled + logger ); expect(exports).toEqual({ rulesNdjson: '', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_all.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_all.ts index 3c2d516b8369d..cf1a9991b3197 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_all.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_all.ts @@ -22,14 +22,13 @@ export const getExportAll = async ( rulesClient: RulesClient, exceptionsClient: ExceptionListClient | undefined, savedObjectsClient: RuleExecutorServices['savedObjectsClient'], - logger: Logger, - isRuleRegistryEnabled: boolean + logger: Logger ): Promise<{ rulesNdjson: string; exportDetails: string; exceptionLists: string | null; }> => { - const ruleAlertTypes = await getNonPackagedRules({ rulesClient, isRuleRegistryEnabled }); + const ruleAlertTypes = await getNonPackagedRules({ rulesClient }); const alertIds = ruleAlertTypes.map((rule) => rule.id); // Gather actions diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts index 7371f2390478e..f297f375dda0b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts @@ -7,7 +7,7 @@ import { getExportByObjectIds, getRulesFromObjects, RulesErrors } from './get_export_by_object_ids'; import { - getAlertMock, + getRuleMock, getFindResultWithSingleHit, FindHit, getEmptySavedObjectsResponse, @@ -26,10 +26,7 @@ const exceptionsClient = getExceptionListClientMock(); import { loggingSystemMock } from '@kbn/core/server/mocks'; import { requestContextMock } from '../routes/__mocks__/request_context'; -describe.each([ - ['Legacy', false], - ['RAC', true], -])('get_export_by_object_ids - %s', (_, isRuleRegistryEnabled) => { +describe('get_export_by_object_ids', () => { let logger: ReturnType; const { clients } = requestContextMock.createTools(); @@ -44,7 +41,7 @@ describe.each([ describe('getExportByObjectIds', () => { test('it exports object ids into an expected string with new line characters', async () => { const rulesClient = rulesClientMock.create(); - rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); + rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); const objects = [{ rule_id: 'rule-1' }]; const exports = await getExportByObjectIds( @@ -52,8 +49,7 @@ describe.each([ exceptionsClient, clients.savedObjectsClient, objects, - logger, - isRuleRegistryEnabled + logger ); const exportsObj = { rulesNdjson: JSON.parse(exports.rulesNdjson), @@ -118,7 +114,7 @@ describe.each([ test('it does not export immutable rules', async () => { const rulesClient = rulesClientMock.create(); - const result = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result = getRuleMock(getQueryRuleParams()); result.params.immutable = true; const findResult: FindHit = { @@ -128,7 +124,7 @@ describe.each([ data: [result], }; - rulesClient.get.mockResolvedValue(getAlertMock(isRuleRegistryEnabled, getQueryRuleParams())); + rulesClient.get.mockResolvedValue(getRuleMock(getQueryRuleParams())); rulesClient.find.mockResolvedValue(findResult); const objects = [{ rule_id: 'rule-1' }]; @@ -137,8 +133,7 @@ describe.each([ exceptionsClient, clients.savedObjectsClient, objects, - logger, - isRuleRegistryEnabled + logger ); const details = getOutputDetailsSampleWithExceptions({ missingRules: [{ rule_id: 'rule-1' }], @@ -155,15 +150,14 @@ describe.each([ describe('getRulesFromObjects', () => { test('it returns transformed rules from objects sent in', async () => { const rulesClient = rulesClientMock.create(); - rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); + rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); const objects = [{ rule_id: 'rule-1' }]; const exports = await getRulesFromObjects( rulesClient, clients.savedObjectsClient, objects, - logger, - isRuleRegistryEnabled + logger ); const expected: RulesErrors = { exportedCount: 1, @@ -220,7 +214,7 @@ describe.each([ test('it does not transform the rule if the rule is an immutable rule and designates it as a missing rule', async () => { const rulesClient = rulesClientMock.create(); - const result = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result = getRuleMock(getQueryRuleParams()); result.params.immutable = true; const findResult: FindHit = { @@ -238,8 +232,7 @@ describe.each([ rulesClient, clients.savedObjectsClient, objects, - logger, - isRuleRegistryEnabled + logger ); const expected: RulesErrors = { exportedCount: 0, @@ -267,8 +260,7 @@ describe.each([ rulesClient, clients.savedObjectsClient, objects, - logger, - isRuleRegistryEnabled + logger ); const expected: RulesErrors = { exportedCount: 0, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_by_object_ids.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_by_object_ids.ts index 5dde3048b61e7..dcf3f7532b53c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_by_object_ids.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_by_object_ids.ts @@ -16,7 +16,6 @@ import { RulesSchema } from '../../../../common/detection_engine/schemas/respons import { getExportDetailsNdjson } from './get_export_details_ndjson'; import { isAlertType } from './types'; -import { INTERNAL_RULE_ID_KEY } from '../../../../common/constants'; import { findRules } from './find_rules'; import { getRuleExceptionsForExport } from './get_export_rule_exceptions'; @@ -45,8 +44,7 @@ export const getExportByObjectIds = async ( exceptionsClient: ExceptionListClient | undefined, savedObjectsClient: RuleExecutorServices['savedObjectsClient'], objects: Array<{ rule_id: string }>, - logger: Logger, - isRuleRegistryEnabled: boolean + logger: Logger ): Promise<{ rulesNdjson: string; exportDetails: string; @@ -56,8 +54,7 @@ export const getExportByObjectIds = async ( rulesClient, savedObjectsClient, objects, - logger, - isRuleRegistryEnabled + logger ); // Retrieve exceptions @@ -83,8 +80,7 @@ export const getRulesFromObjects = async ( rulesClient: RulesClient, savedObjectsClient: RuleExecutorServices['savedObjectsClient'], objects: Array<{ rule_id: string }>, - logger: Logger, - isRuleRegistryEnabled: boolean + logger: Logger ): Promise => { // If we put more than 1024 ids in one block like "alert.attributes.tags: (id1 OR id2 OR ... OR id1100)" // then the KQL -> ES DSL query generator still puts them all in the same "should" array, but ES defaults @@ -95,14 +91,11 @@ export const getRulesFromObjects = async ( const chunkedObjects = chunk(objects, 1024); const filter = chunkedObjects .map((chunkedArray) => { - const joinedIds = chunkedArray - .map((object) => `"${INTERNAL_RULE_ID_KEY}:${object.rule_id}"`) - .join(' OR '); - return `alert.attributes.tags: (${joinedIds})`; + const joinedIds = chunkedArray.map((object) => object.rule_id).join(' OR '); + return `alert.attributes.params.ruleId: (${joinedIds})`; }) .join(' OR '); const rules = await findRules({ - isRuleRegistryEnabled, rulesClient, filter, page: 1, @@ -122,7 +115,7 @@ export const getRulesFromObjects = async ( const matchingRule = rules.data.find((rule) => rule.params.ruleId === ruleId); if ( matchingRule != null && - isAlertType(isRuleRegistryEnabled, matchingRule) && + isAlertType(matchingRule) && matchingRule.params.immutable !== true ) { return { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_rules_to_install.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_rules_to_install.test.ts index c5d4d6d5d2d48..5fcc0aec0f15e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_rules_to_install.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_rules_to_install.test.ts @@ -6,15 +6,12 @@ */ import { getRulesToInstall } from './get_rules_to_install'; -import { getAlertMock } from '../routes/__mocks__/request_responses'; +import { getRuleMock } from '../routes/__mocks__/request_responses'; import { getAddPrepackagedRulesSchemaDecodedMock } from '../../../../common/detection_engine/schemas/request/add_prepackaged_rules_schema.mock'; import { getQueryRuleParams } from '../schemas/rule_schemas.mock'; import { AddPrepackagedRulesSchemaDecoded } from '../../../../common/detection_engine/schemas/request'; -describe.each([ - ['Legacy', false], - ['RAC', true], -])('get_rules_to_install - %s', (_, isRuleRegistryEnabled) => { +describe('get_rules_to_install', () => { test('should return empty array if both rule sets are empty', () => { const update = getRulesToInstall([], []); expect(update).toEqual([]); @@ -25,7 +22,7 @@ describe.each([ getAddPrepackagedRulesSchemaDecodedMock() as AddPrepackagedRulesSchemaDecoded; ruleFromFileSystem.rule_id = 'rule-1'; - const installedRule = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const installedRule = getRuleMock(getQueryRuleParams()); installedRule.params.ruleId = 'rule-1'; const update = getRulesToInstall([ruleFromFileSystem], [installedRule]); expect(update).toEqual([]); @@ -36,7 +33,7 @@ describe.each([ getAddPrepackagedRulesSchemaDecodedMock() as AddPrepackagedRulesSchemaDecoded; ruleFromFileSystem.rule_id = 'rule-1'; - const installedRule = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const installedRule = getRuleMock(getQueryRuleParams()); installedRule.params.ruleId = 'rule-2'; const update = getRulesToInstall([ruleFromFileSystem], [installedRule]); expect(update).toEqual([ruleFromFileSystem]); @@ -51,7 +48,7 @@ describe.each([ getAddPrepackagedRulesSchemaDecodedMock() as AddPrepackagedRulesSchemaDecoded; ruleFromFileSystem2.rule_id = 'rule-2'; - const installedRule = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const installedRule = getRuleMock(getQueryRuleParams()); installedRule.params.ruleId = 'rule-3'; const update = getRulesToInstall([ruleFromFileSystem1, ruleFromFileSystem2], [installedRule]); expect(update).toEqual([ruleFromFileSystem1, ruleFromFileSystem2]); @@ -70,7 +67,7 @@ describe.each([ getAddPrepackagedRulesSchemaDecodedMock() as AddPrepackagedRulesSchemaDecoded; ruleFromFileSystem3.rule_id = 'rule-3'; - const installedRule = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const installedRule = getRuleMock(getQueryRuleParams()); installedRule.params.ruleId = 'rule-3'; const update = getRulesToInstall( [ruleFromFileSystem1, ruleFromFileSystem2, ruleFromFileSystem3], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_rules_to_update.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_rules_to_update.test.ts index dda3bf6efe44c..a1d8458488486 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_rules_to_update.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_rules_to_update.test.ts @@ -6,473 +6,468 @@ */ import { filterInstalledRules, getRulesToUpdate, mergeExceptionLists } from './get_rules_to_update'; -import { getAlertMock } from '../routes/__mocks__/request_responses'; +import { getRuleMock } from '../routes/__mocks__/request_responses'; import { getAddPrepackagedRulesSchemaDecodedMock } from '../../../../common/detection_engine/schemas/request/add_prepackaged_rules_schema.mock'; import { getQueryRuleParams } from '../schemas/rule_schemas.mock'; -describe.each([ - ['Legacy', false], - ['RAC', true], -])('get_rules_to_update - %s', (_, isRuleRegistryEnabled) => { - describe('get_rules_to_update', () => { - test('should return empty array if both rule sets are empty', () => { - const update = getRulesToUpdate([], []); - expect(update).toEqual([]); - }); - - test('should return empty array if the rule_id of the two rules do not match', () => { - const ruleFromFileSystem = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem.rule_id = 'rule-1'; - ruleFromFileSystem.version = 2; - - const installedRule = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule.params.ruleId = 'rule-2'; - installedRule.params.version = 1; - const update = getRulesToUpdate([ruleFromFileSystem], [installedRule]); - expect(update).toEqual([]); - }); - - test('should return empty array if the version of file system rule is less than the installed version', () => { - const ruleFromFileSystem = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem.rule_id = 'rule-1'; - ruleFromFileSystem.version = 1; - - const installedRule = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule.params.ruleId = 'rule-1'; - installedRule.params.version = 2; - const update = getRulesToUpdate([ruleFromFileSystem], [installedRule]); - expect(update).toEqual([]); - }); - - test('should return empty array if the version of file system rule is the same as the installed version', () => { - const ruleFromFileSystem = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem.rule_id = 'rule-1'; - ruleFromFileSystem.version = 1; - - const installedRule = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule.params.ruleId = 'rule-1'; - installedRule.params.version = 1; - const update = getRulesToUpdate([ruleFromFileSystem], [installedRule]); - expect(update).toEqual([]); - }); - - test('should return the rule to update if the version of file system rule is greater than the installed version', () => { - const ruleFromFileSystem = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem.rule_id = 'rule-1'; - ruleFromFileSystem.version = 2; - - const installedRule = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule.params.ruleId = 'rule-1'; - installedRule.params.version = 1; - installedRule.params.exceptionsList = []; - - const update = getRulesToUpdate([ruleFromFileSystem], [installedRule]); - expect(update).toEqual([ruleFromFileSystem]); - }); - - test('should return 1 rule out of 2 to update if the version of file system rule is greater than the installed version of just one', () => { - const ruleFromFileSystem = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem.rule_id = 'rule-1'; - ruleFromFileSystem.version = 2; - - const installedRule1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule1.params.ruleId = 'rule-1'; - installedRule1.params.version = 1; - installedRule1.params.exceptionsList = []; - - const installedRule2 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule2.params.ruleId = 'rule-2'; - installedRule2.params.version = 1; - installedRule2.params.exceptionsList = []; - - const update = getRulesToUpdate([ruleFromFileSystem], [installedRule1, installedRule2]); - expect(update).toEqual([ruleFromFileSystem]); - }); - - test('should return 2 rules out of 2 to update if the version of file system rule is greater than the installed version of both', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem1.rule_id = 'rule-1'; - ruleFromFileSystem1.version = 2; - - const ruleFromFileSystem2 = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem2.rule_id = 'rule-2'; - ruleFromFileSystem2.version = 2; - - const installedRule1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule1.params.ruleId = 'rule-1'; - installedRule1.params.version = 1; - installedRule1.params.exceptionsList = []; - - const installedRule2 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule2.params.ruleId = 'rule-2'; - installedRule2.params.version = 1; - installedRule2.params.exceptionsList = []; - - const update = getRulesToUpdate( - [ruleFromFileSystem1, ruleFromFileSystem2], - [installedRule1, installedRule2] - ); - expect(update).toEqual([ruleFromFileSystem1, ruleFromFileSystem2]); - }); - - test('should add back an exception_list if it was removed by the end user on an immutable rule during an upgrade', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem1.exceptions_list = [ - { - id: 'endpoint_list', - list_id: 'endpoint_list', - namespace_type: 'agnostic', - type: 'endpoint', - }, - ]; - ruleFromFileSystem1.rule_id = 'rule-1'; - ruleFromFileSystem1.version = 2; - - const installedRule1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule1.params.ruleId = 'rule-1'; - installedRule1.params.version = 1; - installedRule1.params.exceptionsList = []; - - const [update] = getRulesToUpdate([ruleFromFileSystem1], [installedRule1]); - expect(update.exceptions_list).toEqual(ruleFromFileSystem1.exceptions_list); - }); - - test('should not remove an additional exception_list if an additional one was added by the end user on an immutable rule during an upgrade', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem1.exceptions_list = [ - { - id: 'endpoint_list', - list_id: 'endpoint_list', - namespace_type: 'agnostic', - type: 'endpoint', - }, - ]; - ruleFromFileSystem1.rule_id = 'rule-1'; - ruleFromFileSystem1.version = 2; - - const installedRule1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule1.params.ruleId = 'rule-1'; - installedRule1.params.version = 1; - installedRule1.params.exceptionsList = [ - { - id: 'second_exception_list', - list_id: 'some-other-id', - namespace_type: 'single', - type: 'detection', - }, - ]; - - const [update] = getRulesToUpdate([ruleFromFileSystem1], [installedRule1]); - expect(update.exceptions_list).toEqual([ - ...ruleFromFileSystem1.exceptions_list, - ...installedRule1.params.exceptionsList, - ]); - }); - - test('should not remove an existing exception_list if they are the same between the current installed one and the upgraded one', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem1.exceptions_list = [ - { - id: 'endpoint_list', - list_id: 'endpoint_list', - namespace_type: 'agnostic', - type: 'endpoint', - }, - ]; - ruleFromFileSystem1.rule_id = 'rule-1'; - ruleFromFileSystem1.version = 2; - - const installedRule1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule1.params.ruleId = 'rule-1'; - installedRule1.params.version = 1; - installedRule1.params.exceptionsList = [ - { - id: 'endpoint_list', - list_id: 'endpoint_list', - namespace_type: 'agnostic', - type: 'endpoint', - }, - ]; - - const [update] = getRulesToUpdate([ruleFromFileSystem1], [installedRule1]); - expect(update.exceptions_list).toEqual(ruleFromFileSystem1.exceptions_list); - }); - - test('should not remove an existing exception_list if the rule has an empty exceptions list', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem1.exceptions_list = []; - ruleFromFileSystem1.rule_id = 'rule-1'; - ruleFromFileSystem1.version = 2; - - const installedRule1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule1.params.ruleId = 'rule-1'; - installedRule1.params.version = 1; - installedRule1.params.exceptionsList = [ - { - id: 'endpoint_list', - list_id: 'endpoint_list', - namespace_type: 'agnostic', - type: 'endpoint', - }, - ]; - - const [update] = getRulesToUpdate([ruleFromFileSystem1], [installedRule1]); - expect(update.exceptions_list).toEqual(installedRule1.params.exceptionsList); - }); - - test('should not remove an existing exception_list if the rule has an empty exceptions list for multiple rules', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem1.exceptions_list = []; - ruleFromFileSystem1.rule_id = 'rule-1'; - ruleFromFileSystem1.version = 2; - - const ruleFromFileSystem2 = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem2.exceptions_list = []; - ruleFromFileSystem2.rule_id = 'rule-2'; - ruleFromFileSystem2.version = 2; - - const installedRule1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule1.params.ruleId = 'rule-1'; - installedRule1.params.version = 1; - installedRule1.params.exceptionsList = [ - { - id: 'endpoint_list', - list_id: 'endpoint_list', - namespace_type: 'agnostic', - type: 'endpoint', - }, - ]; - const installedRule2 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule2.params.ruleId = 'rule-2'; - installedRule2.params.version = 1; - installedRule2.params.exceptionsList = [ - { - id: 'endpoint_list', - list_id: 'endpoint_list', - namespace_type: 'agnostic', - type: 'endpoint', - }, - ]; - - const [update1, update2] = getRulesToUpdate( - [ruleFromFileSystem1, ruleFromFileSystem2], - [installedRule1, installedRule2] - ); - expect(update1.exceptions_list).toEqual(installedRule1.params.exceptionsList); - expect(update2.exceptions_list).toEqual(installedRule2.params.exceptionsList); - }); - - test('should not remove an existing exception_list if the rule has an empty exceptions list for mixed rules', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem1.exceptions_list = []; - ruleFromFileSystem1.rule_id = 'rule-1'; - ruleFromFileSystem1.version = 2; - - const ruleFromFileSystem2 = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem2.exceptions_list = []; - ruleFromFileSystem2.rule_id = 'rule-2'; - ruleFromFileSystem2.version = 2; - ruleFromFileSystem2.exceptions_list = [ - { - id: 'second_list', - list_id: 'second_list', - namespace_type: 'single', - type: 'detection', - }, - ]; - - const installedRule1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule1.params.ruleId = 'rule-1'; - installedRule1.params.version = 1; - installedRule1.params.exceptionsList = [ - { - id: 'endpoint_list', - list_id: 'endpoint_list', - namespace_type: 'agnostic', - type: 'endpoint', - }, - ]; - - const installedRule2 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule2.params.ruleId = 'rule-2'; - installedRule2.params.version = 1; - installedRule2.params.exceptionsList = [ - { - id: 'endpoint_list', - list_id: 'endpoint_list', - namespace_type: 'agnostic', - type: 'endpoint', - }, - ]; - - const [update1, update2] = getRulesToUpdate( - [ruleFromFileSystem1, ruleFromFileSystem2], - [installedRule1, installedRule2] - ); - expect(update1.exceptions_list).toEqual(installedRule1.params.exceptionsList); - expect(update2.exceptions_list).toEqual([ - ...ruleFromFileSystem2.exceptions_list, - ...installedRule2.params.exceptionsList, - ]); - }); +describe('get_rules_to_update', () => { + test('should return empty array if both rule sets are empty', () => { + const update = getRulesToUpdate([], []); + expect(update).toEqual([]); }); - describe('filterInstalledRules', () => { - test('should return "false" if the id of the two rules do not match', () => { - const ruleFromFileSystem = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem.rule_id = 'rule-1'; - ruleFromFileSystem.version = 2; - - const installedRule = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule.params.ruleId = 'rule-2'; - installedRule.params.version = 1; - const shouldUpdate = filterInstalledRules(ruleFromFileSystem, [installedRule]); - expect(shouldUpdate).toEqual(false); - }); - - test('should return "false" if the version of file system rule is less than the installed version', () => { - const ruleFromFileSystem = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem.rule_id = 'rule-1'; - ruleFromFileSystem.version = 1; - - const installedRule = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule.params.ruleId = 'rule-1'; - installedRule.params.version = 2; - const shouldUpdate = filterInstalledRules(ruleFromFileSystem, [installedRule]); - expect(shouldUpdate).toEqual(false); - }); - - test('should return "false" if the version of file system rule is the same as the installed version', () => { - const ruleFromFileSystem = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem.rule_id = 'rule-1'; - ruleFromFileSystem.version = 1; - - const installedRule = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule.params.ruleId = 'rule-1'; - installedRule.params.version = 1; - const shouldUpdate = filterInstalledRules(ruleFromFileSystem, [installedRule]); - expect(shouldUpdate).toEqual(false); - }); - - test('should return "true" to update if the version of file system rule is greater than the installed version', () => { - const ruleFromFileSystem = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem.rule_id = 'rule-1'; - ruleFromFileSystem.version = 2; - - const installedRule = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule.params.ruleId = 'rule-1'; - installedRule.params.version = 1; - installedRule.params.exceptionsList = []; - - const shouldUpdate = filterInstalledRules(ruleFromFileSystem, [installedRule]); - expect(shouldUpdate).toEqual(true); - }); + test('should return empty array if the rule_id of the two rules do not match', () => { + const ruleFromFileSystem = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem.rule_id = 'rule-1'; + ruleFromFileSystem.version = 2; + + const installedRule = getRuleMock(getQueryRuleParams()); + installedRule.params.ruleId = 'rule-2'; + installedRule.params.version = 1; + const update = getRulesToUpdate([ruleFromFileSystem], [installedRule]); + expect(update).toEqual([]); + }); + + test('should return empty array if the version of file system rule is less than the installed version', () => { + const ruleFromFileSystem = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem.rule_id = 'rule-1'; + ruleFromFileSystem.version = 1; + + const installedRule = getRuleMock(getQueryRuleParams()); + installedRule.params.ruleId = 'rule-1'; + installedRule.params.version = 2; + const update = getRulesToUpdate([ruleFromFileSystem], [installedRule]); + expect(update).toEqual([]); + }); + + test('should return empty array if the version of file system rule is the same as the installed version', () => { + const ruleFromFileSystem = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem.rule_id = 'rule-1'; + ruleFromFileSystem.version = 1; + + const installedRule = getRuleMock(getQueryRuleParams()); + installedRule.params.ruleId = 'rule-1'; + installedRule.params.version = 1; + const update = getRulesToUpdate([ruleFromFileSystem], [installedRule]); + expect(update).toEqual([]); + }); + + test('should return the rule to update if the version of file system rule is greater than the installed version', () => { + const ruleFromFileSystem = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem.rule_id = 'rule-1'; + ruleFromFileSystem.version = 2; + + const installedRule = getRuleMock(getQueryRuleParams()); + installedRule.params.ruleId = 'rule-1'; + installedRule.params.version = 1; + installedRule.params.exceptionsList = []; + + const update = getRulesToUpdate([ruleFromFileSystem], [installedRule]); + expect(update).toEqual([ruleFromFileSystem]); + }); + + test('should return 1 rule out of 2 to update if the version of file system rule is greater than the installed version of just one', () => { + const ruleFromFileSystem = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem.rule_id = 'rule-1'; + ruleFromFileSystem.version = 2; + + const installedRule1 = getRuleMock(getQueryRuleParams()); + installedRule1.params.ruleId = 'rule-1'; + installedRule1.params.version = 1; + installedRule1.params.exceptionsList = []; + + const installedRule2 = getRuleMock(getQueryRuleParams()); + installedRule2.params.ruleId = 'rule-2'; + installedRule2.params.version = 1; + installedRule2.params.exceptionsList = []; + + const update = getRulesToUpdate([ruleFromFileSystem], [installedRule1, installedRule2]); + expect(update).toEqual([ruleFromFileSystem]); + }); + + test('should return 2 rules out of 2 to update if the version of file system rule is greater than the installed version of both', () => { + const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem1.rule_id = 'rule-1'; + ruleFromFileSystem1.version = 2; + + const ruleFromFileSystem2 = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem2.rule_id = 'rule-2'; + ruleFromFileSystem2.version = 2; + + const installedRule1 = getRuleMock(getQueryRuleParams()); + installedRule1.params.ruleId = 'rule-1'; + installedRule1.params.version = 1; + installedRule1.params.exceptionsList = []; + + const installedRule2 = getRuleMock(getQueryRuleParams()); + installedRule2.params.ruleId = 'rule-2'; + installedRule2.params.version = 1; + installedRule2.params.exceptionsList = []; + + const update = getRulesToUpdate( + [ruleFromFileSystem1, ruleFromFileSystem2], + [installedRule1, installedRule2] + ); + expect(update).toEqual([ruleFromFileSystem1, ruleFromFileSystem2]); + }); + + test('should add back an exception_list if it was removed by the end user on an immutable rule during an upgrade', () => { + const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem1.exceptions_list = [ + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ]; + ruleFromFileSystem1.rule_id = 'rule-1'; + ruleFromFileSystem1.version = 2; + + const installedRule1 = getRuleMock(getQueryRuleParams()); + installedRule1.params.ruleId = 'rule-1'; + installedRule1.params.version = 1; + installedRule1.params.exceptionsList = []; + + const [update] = getRulesToUpdate([ruleFromFileSystem1], [installedRule1]); + expect(update.exceptions_list).toEqual(ruleFromFileSystem1.exceptions_list); + }); + + test('should not remove an additional exception_list if an additional one was added by the end user on an immutable rule during an upgrade', () => { + const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem1.exceptions_list = [ + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ]; + ruleFromFileSystem1.rule_id = 'rule-1'; + ruleFromFileSystem1.version = 2; + + const installedRule1 = getRuleMock(getQueryRuleParams()); + installedRule1.params.ruleId = 'rule-1'; + installedRule1.params.version = 1; + installedRule1.params.exceptionsList = [ + { + id: 'second_exception_list', + list_id: 'some-other-id', + namespace_type: 'single', + type: 'detection', + }, + ]; + + const [update] = getRulesToUpdate([ruleFromFileSystem1], [installedRule1]); + expect(update.exceptions_list).toEqual([ + ...ruleFromFileSystem1.exceptions_list, + ...installedRule1.params.exceptionsList, + ]); + }); + + test('should not remove an existing exception_list if they are the same between the current installed one and the upgraded one', () => { + const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem1.exceptions_list = [ + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ]; + ruleFromFileSystem1.rule_id = 'rule-1'; + ruleFromFileSystem1.version = 2; + + const installedRule1 = getRuleMock(getQueryRuleParams()); + installedRule1.params.ruleId = 'rule-1'; + installedRule1.params.version = 1; + installedRule1.params.exceptionsList = [ + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ]; + + const [update] = getRulesToUpdate([ruleFromFileSystem1], [installedRule1]); + expect(update.exceptions_list).toEqual(ruleFromFileSystem1.exceptions_list); + }); + + test('should not remove an existing exception_list if the rule has an empty exceptions list', () => { + const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem1.exceptions_list = []; + ruleFromFileSystem1.rule_id = 'rule-1'; + ruleFromFileSystem1.version = 2; + + const installedRule1 = getRuleMock(getQueryRuleParams()); + installedRule1.params.ruleId = 'rule-1'; + installedRule1.params.version = 1; + installedRule1.params.exceptionsList = [ + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ]; + + const [update] = getRulesToUpdate([ruleFromFileSystem1], [installedRule1]); + expect(update.exceptions_list).toEqual(installedRule1.params.exceptionsList); + }); + + test('should not remove an existing exception_list if the rule has an empty exceptions list for multiple rules', () => { + const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem1.exceptions_list = []; + ruleFromFileSystem1.rule_id = 'rule-1'; + ruleFromFileSystem1.version = 2; + + const ruleFromFileSystem2 = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem2.exceptions_list = []; + ruleFromFileSystem2.rule_id = 'rule-2'; + ruleFromFileSystem2.version = 2; + + const installedRule1 = getRuleMock(getQueryRuleParams()); + installedRule1.params.ruleId = 'rule-1'; + installedRule1.params.version = 1; + installedRule1.params.exceptionsList = [ + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ]; + const installedRule2 = getRuleMock(getQueryRuleParams()); + installedRule2.params.ruleId = 'rule-2'; + installedRule2.params.version = 1; + installedRule2.params.exceptionsList = [ + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ]; + + const [update1, update2] = getRulesToUpdate( + [ruleFromFileSystem1, ruleFromFileSystem2], + [installedRule1, installedRule2] + ); + expect(update1.exceptions_list).toEqual(installedRule1.params.exceptionsList); + expect(update2.exceptions_list).toEqual(installedRule2.params.exceptionsList); + }); + + test('should not remove an existing exception_list if the rule has an empty exceptions list for mixed rules', () => { + const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem1.exceptions_list = []; + ruleFromFileSystem1.rule_id = 'rule-1'; + ruleFromFileSystem1.version = 2; + + const ruleFromFileSystem2 = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem2.exceptions_list = []; + ruleFromFileSystem2.rule_id = 'rule-2'; + ruleFromFileSystem2.version = 2; + ruleFromFileSystem2.exceptions_list = [ + { + id: 'second_list', + list_id: 'second_list', + namespace_type: 'single', + type: 'detection', + }, + ]; + + const installedRule1 = getRuleMock(getQueryRuleParams()); + installedRule1.params.ruleId = 'rule-1'; + installedRule1.params.version = 1; + installedRule1.params.exceptionsList = [ + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ]; + + const installedRule2 = getRuleMock(getQueryRuleParams()); + installedRule2.params.ruleId = 'rule-2'; + installedRule2.params.version = 1; + installedRule2.params.exceptionsList = [ + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ]; + + const [update1, update2] = getRulesToUpdate( + [ruleFromFileSystem1, ruleFromFileSystem2], + [installedRule1, installedRule2] + ); + expect(update1.exceptions_list).toEqual(installedRule1.params.exceptionsList); + expect(update2.exceptions_list).toEqual([ + ...ruleFromFileSystem2.exceptions_list, + ...installedRule2.params.exceptionsList, + ]); + }); +}); + +describe('filterInstalledRules', () => { + test('should return "false" if the id of the two rules do not match', () => { + const ruleFromFileSystem = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem.rule_id = 'rule-1'; + ruleFromFileSystem.version = 2; + + const installedRule = getRuleMock(getQueryRuleParams()); + installedRule.params.ruleId = 'rule-2'; + installedRule.params.version = 1; + const shouldUpdate = filterInstalledRules(ruleFromFileSystem, [installedRule]); + expect(shouldUpdate).toEqual(false); + }); + + test('should return "false" if the version of file system rule is less than the installed version', () => { + const ruleFromFileSystem = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem.rule_id = 'rule-1'; + ruleFromFileSystem.version = 1; + + const installedRule = getRuleMock(getQueryRuleParams()); + installedRule.params.ruleId = 'rule-1'; + installedRule.params.version = 2; + const shouldUpdate = filterInstalledRules(ruleFromFileSystem, [installedRule]); + expect(shouldUpdate).toEqual(false); + }); + + test('should return "false" if the version of file system rule is the same as the installed version', () => { + const ruleFromFileSystem = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem.rule_id = 'rule-1'; + ruleFromFileSystem.version = 1; + + const installedRule = getRuleMock(getQueryRuleParams()); + installedRule.params.ruleId = 'rule-1'; + installedRule.params.version = 1; + const shouldUpdate = filterInstalledRules(ruleFromFileSystem, [installedRule]); + expect(shouldUpdate).toEqual(false); + }); + + test('should return "true" to update if the version of file system rule is greater than the installed version', () => { + const ruleFromFileSystem = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem.rule_id = 'rule-1'; + ruleFromFileSystem.version = 2; + + const installedRule = getRuleMock(getQueryRuleParams()); + installedRule.params.ruleId = 'rule-1'; + installedRule.params.version = 1; + installedRule.params.exceptionsList = []; + + const shouldUpdate = filterInstalledRules(ruleFromFileSystem, [installedRule]); + expect(shouldUpdate).toEqual(true); + }); +}); + +describe('mergeExceptionLists', () => { + test('should add back an exception_list if it was removed by the end user on an immutable rule during an upgrade', () => { + const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem1.exceptions_list = [ + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ]; + ruleFromFileSystem1.rule_id = 'rule-1'; + ruleFromFileSystem1.version = 2; + + const installedRule1 = getRuleMock(getQueryRuleParams()); + installedRule1.params.ruleId = 'rule-1'; + installedRule1.params.version = 1; + installedRule1.params.exceptionsList = []; + + const update = mergeExceptionLists(ruleFromFileSystem1, [installedRule1]); + expect(update.exceptions_list).toEqual(ruleFromFileSystem1.exceptions_list); + }); + + test('should not remove an additional exception_list if an additional one was added by the end user on an immutable rule during an upgrade', () => { + const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem1.exceptions_list = [ + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ]; + ruleFromFileSystem1.rule_id = 'rule-1'; + ruleFromFileSystem1.version = 2; + + const installedRule1 = getRuleMock(getQueryRuleParams()); + installedRule1.params.ruleId = 'rule-1'; + installedRule1.params.version = 1; + installedRule1.params.exceptionsList = [ + { + id: 'second_exception_list', + list_id: 'some-other-id', + namespace_type: 'single', + type: 'detection', + }, + ]; + + const update = mergeExceptionLists(ruleFromFileSystem1, [installedRule1]); + expect(update.exceptions_list).toEqual([ + ...ruleFromFileSystem1.exceptions_list, + ...installedRule1.params.exceptionsList, + ]); + }); + + test('should not remove an existing exception_list if they are the same between the current installed one and the upgraded one', () => { + const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem1.exceptions_list = [ + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ]; + ruleFromFileSystem1.rule_id = 'rule-1'; + ruleFromFileSystem1.version = 2; + + const installedRule1 = getRuleMock(getQueryRuleParams()); + installedRule1.params.ruleId = 'rule-1'; + installedRule1.params.version = 1; + installedRule1.params.exceptionsList = [ + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ]; + + const update = mergeExceptionLists(ruleFromFileSystem1, [installedRule1]); + expect(update.exceptions_list).toEqual(ruleFromFileSystem1.exceptions_list); }); - describe('mergeExceptionLists', () => { - test('should add back an exception_list if it was removed by the end user on an immutable rule during an upgrade', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem1.exceptions_list = [ - { - id: 'endpoint_list', - list_id: 'endpoint_list', - namespace_type: 'agnostic', - type: 'endpoint', - }, - ]; - ruleFromFileSystem1.rule_id = 'rule-1'; - ruleFromFileSystem1.version = 2; - - const installedRule1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule1.params.ruleId = 'rule-1'; - installedRule1.params.version = 1; - installedRule1.params.exceptionsList = []; - - const update = mergeExceptionLists(ruleFromFileSystem1, [installedRule1]); - expect(update.exceptions_list).toEqual(ruleFromFileSystem1.exceptions_list); - }); - - test('should not remove an additional exception_list if an additional one was added by the end user on an immutable rule during an upgrade', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem1.exceptions_list = [ - { - id: 'endpoint_list', - list_id: 'endpoint_list', - namespace_type: 'agnostic', - type: 'endpoint', - }, - ]; - ruleFromFileSystem1.rule_id = 'rule-1'; - ruleFromFileSystem1.version = 2; - - const installedRule1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule1.params.ruleId = 'rule-1'; - installedRule1.params.version = 1; - installedRule1.params.exceptionsList = [ - { - id: 'second_exception_list', - list_id: 'some-other-id', - namespace_type: 'single', - type: 'detection', - }, - ]; - - const update = mergeExceptionLists(ruleFromFileSystem1, [installedRule1]); - expect(update.exceptions_list).toEqual([ - ...ruleFromFileSystem1.exceptions_list, - ...installedRule1.params.exceptionsList, - ]); - }); - - test('should not remove an existing exception_list if they are the same between the current installed one and the upgraded one', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem1.exceptions_list = [ - { - id: 'endpoint_list', - list_id: 'endpoint_list', - namespace_type: 'agnostic', - type: 'endpoint', - }, - ]; - ruleFromFileSystem1.rule_id = 'rule-1'; - ruleFromFileSystem1.version = 2; - - const installedRule1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule1.params.ruleId = 'rule-1'; - installedRule1.params.version = 1; - installedRule1.params.exceptionsList = [ - { - id: 'endpoint_list', - list_id: 'endpoint_list', - namespace_type: 'agnostic', - type: 'endpoint', - }, - ]; - - const update = mergeExceptionLists(ruleFromFileSystem1, [installedRule1]); - expect(update.exceptions_list).toEqual(ruleFromFileSystem1.exceptions_list); - }); - - test('should not remove an existing exception_list if the rule has an empty exceptions list', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaDecodedMock(); - ruleFromFileSystem1.exceptions_list = []; - ruleFromFileSystem1.rule_id = 'rule-1'; - ruleFromFileSystem1.version = 2; - - const installedRule1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - installedRule1.params.ruleId = 'rule-1'; - installedRule1.params.version = 1; - installedRule1.params.exceptionsList = [ - { - id: 'endpoint_list', - list_id: 'endpoint_list', - namespace_type: 'agnostic', - type: 'endpoint', - }, - ]; - - const update = mergeExceptionLists(ruleFromFileSystem1, [installedRule1]); - expect(update.exceptions_list).toEqual(installedRule1.params.exceptionsList); - }); + test('should not remove an existing exception_list if the rule has an empty exceptions list', () => { + const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaDecodedMock(); + ruleFromFileSystem1.exceptions_list = []; + ruleFromFileSystem1.rule_id = 'rule-1'; + ruleFromFileSystem1.version = 2; + + const installedRule1 = getRuleMock(getQueryRuleParams()); + installedRule1.params.ruleId = 'rule-1'; + installedRule1.params.version = 1; + installedRule1.params.exceptionsList = [ + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ]; + + const update = mergeExceptionLists(ruleFromFileSystem1, [installedRule1]); + expect(update.exceptions_list).toEqual(installedRule1.params.exceptionsList); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/install_prepacked_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/install_prepacked_rules.ts index 298a87565bdfd..bffa0bc39eb91 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/install_prepacked_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/install_prepacked_rules.ts @@ -14,8 +14,7 @@ import { PartialFilter } from '../types'; export const installPrepackagedRules = ( rulesClient: RulesClient, rules: AddPrepackagedRulesSchemaDecoded[], - outputIndex: string, - isRuleRegistryEnabled: boolean + outputIndex: string ): Array>> => rules.reduce>>>((acc, rule) => { const { @@ -72,7 +71,6 @@ export const installPrepackagedRules = ( return [ ...acc, createRules({ - isRuleRegistryEnabled, rulesClient, anomalyThreshold, author, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/patch_rules.mock.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/patch_rules.mock.ts index b02e297f78c8d..1250746a2b3c4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/patch_rules.mock.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/patch_rules.mock.ts @@ -5,12 +5,13 @@ * 2.0. */ -import { PatchRulesOptions } from './types'; import { rulesClientMock } from '@kbn/alerting-plugin/server/mocks'; -import { getAlertMock } from '../routes/__mocks__/request_responses'; + +import { PatchRulesOptions } from './types'; +import { getRuleMock } from '../routes/__mocks__/request_responses'; import { getMlRuleParams, getQueryRuleParams } from '../schemas/rule_schemas.mock'; -export const getPatchRulesOptionsMock = (isRuleRegistryEnabled: boolean): PatchRulesOptions => ({ +export const getPatchRulesOptionsMock = (): PatchRulesOptions => ({ author: ['Elastic'], buildingBlockType: undefined, rulesClient: rulesClientMock.create(), @@ -59,10 +60,10 @@ export const getPatchRulesOptionsMock = (isRuleRegistryEnabled: boolean): PatchR version: 1, exceptionsList: [], actions: [], - rule: getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()), + rule: getRuleMock(getQueryRuleParams()), }); -export const getPatchMlRulesOptionsMock = (isRuleRegistryEnabled: boolean): PatchRulesOptions => ({ +export const getPatchMlRulesOptionsMock = (): PatchRulesOptions => ({ author: ['Elastic'], buildingBlockType: undefined, rulesClient: rulesClientMock.create(), @@ -111,5 +112,5 @@ export const getPatchMlRulesOptionsMock = (isRuleRegistryEnabled: boolean): Patc version: 1, exceptionsList: [], actions: [], - rule: getAlertMock(isRuleRegistryEnabled, getMlRuleParams()), + rule: getRuleMock(getMlRuleParams()), }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/patch_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/patch_rules.test.ts index e16a108dec907..e2e09e130d5c3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/patch_rules.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/patch_rules.test.ts @@ -5,25 +5,23 @@ * 2.0. */ +import { RulesClientMock } from '@kbn/alerting-plugin/server/rules_client.mock'; + import { patchRules } from './patch_rules'; import { getPatchRulesOptionsMock, getPatchMlRulesOptionsMock } from './patch_rules.mock'; import { PatchRulesOptions } from './types'; -import { RulesClientMock } from '@kbn/alerting-plugin/server/rules_client.mock'; -import { getAlertMock } from '../routes/__mocks__/request_responses'; +import { getRuleMock } from '../routes/__mocks__/request_responses'; import { getQueryRuleParams } from '../schemas/rule_schemas.mock'; -describe.each([ - ['Legacy', false], - ['RAC', true], -])('patchRules - %s', (_, isRuleRegistryEnabled) => { +describe('patchRules', () => { it('should call rulesClient.disable if the rule was enabled and enabled is false', async () => { - const rulesOptionsMock = getPatchRulesOptionsMock(isRuleRegistryEnabled); + const rulesOptionsMock = getPatchRulesOptionsMock(); const ruleOptions: PatchRulesOptions = { ...rulesOptionsMock, enabled: false, }; (rulesOptionsMock.rulesClient as unknown as RulesClientMock).update.mockResolvedValue( - getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) + getRuleMock(getQueryRuleParams()) ); await patchRules(ruleOptions); expect(ruleOptions.rulesClient.disable).toHaveBeenCalledWith( @@ -34,7 +32,7 @@ describe.each([ }); it('should call rulesClient.enable if the rule was disabled and enabled is true', async () => { - const rulesOptionsMock = getPatchRulesOptionsMock(isRuleRegistryEnabled); + const rulesOptionsMock = getPatchRulesOptionsMock(); const ruleOptions: PatchRulesOptions = { ...rulesOptionsMock, enabled: true, @@ -43,7 +41,7 @@ describe.each([ ruleOptions.rule.enabled = false; } (rulesOptionsMock.rulesClient as unknown as RulesClientMock).update.mockResolvedValue( - getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) + getRuleMock(getQueryRuleParams()) ); await patchRules(ruleOptions); expect(ruleOptions.rulesClient.enable).toHaveBeenCalledWith( @@ -54,7 +52,7 @@ describe.each([ }); it('calls the rulesClient with legacy ML params', async () => { - const rulesOptionsMock = getPatchMlRulesOptionsMock(isRuleRegistryEnabled); + const rulesOptionsMock = getPatchMlRulesOptionsMock(); const ruleOptions: PatchRulesOptions = { ...rulesOptionsMock, enabled: true, @@ -63,7 +61,7 @@ describe.each([ ruleOptions.rule.enabled = false; } (rulesOptionsMock.rulesClient as unknown as RulesClientMock).update.mockResolvedValue( - getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) + getRuleMock(getQueryRuleParams()) ); await patchRules(ruleOptions); expect(ruleOptions.rulesClient.update).toHaveBeenCalledWith( @@ -79,7 +77,7 @@ describe.each([ }); it('calls the rulesClient with new ML params', async () => { - const rulesOptionsMock = getPatchMlRulesOptionsMock(isRuleRegistryEnabled); + const rulesOptionsMock = getPatchMlRulesOptionsMock(); const ruleOptions: PatchRulesOptions = { ...rulesOptionsMock, machineLearningJobId: ['new_job_1', 'new_job_2'], @@ -89,7 +87,7 @@ describe.each([ ruleOptions.rule.enabled = false; } (rulesOptionsMock.rulesClient as unknown as RulesClientMock).update.mockResolvedValue( - getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) + getRuleMock(getQueryRuleParams()) ); await patchRules(ruleOptions); expect(ruleOptions.rulesClient.update).toHaveBeenCalledWith( @@ -106,7 +104,7 @@ describe.each([ describe('regression tests', () => { it("updates the rule's actions if provided", async () => { - const rulesOptionsMock = getPatchRulesOptionsMock(isRuleRegistryEnabled); + const rulesOptionsMock = getPatchRulesOptionsMock(); const ruleOptions: PatchRulesOptions = { ...rulesOptionsMock, actions: [ @@ -121,7 +119,7 @@ describe.each([ ], }; (rulesOptionsMock.rulesClient as unknown as RulesClientMock).update.mockResolvedValue( - getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) + getRuleMock(getQueryRuleParams()) ); await patchRules(ruleOptions); expect(ruleOptions.rulesClient.update).toHaveBeenCalledWith( @@ -143,7 +141,7 @@ describe.each([ }); it('does not update actions if none are specified', async () => { - const ruleOptions = getPatchRulesOptionsMock(isRuleRegistryEnabled); + const ruleOptions = getPatchRulesOptionsMock(); delete ruleOptions.actions; if (ruleOptions.rule != null) { ruleOptions.rule.actions = [ @@ -158,7 +156,7 @@ describe.each([ ]; } (ruleOptions.rulesClient as unknown as RulesClientMock).update.mockResolvedValue( - getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) + getRuleMock(getQueryRuleParams()) ); await patchRules(ruleOptions); expect(ruleOptions.rulesClient.update).toHaveBeenCalledWith( diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/patch_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/patch_rules.ts index 05f58e44ecaa2..ad2443b34fa95 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/patch_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/patch_rules.ts @@ -14,7 +14,6 @@ import { normalizeThresholdObject, } from '../../../../common/detection_engine/utils'; import { internalRuleUpdate, RuleParams } from '../schemas/rule_schemas'; -import { addTags } from './add_tags'; import { PatchRulesOptions } from './types'; import { calculateInterval, @@ -190,7 +189,7 @@ export const patchRules = async ({ ); const newRule = { - tags: addTags(tags ?? rule.tags, rule.params.ruleId, rule.params.immutable), + tags: tags ?? rule.tags, name: calculateName({ updatedName: name, originalName: rule.name }), schedule: { interval: calculateInterval(interval, rule.schedule.interval), diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/read_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/read_rules.test.ts index 683744640dc9c..dd0d1ff7090c7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/read_rules.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/read_rules.test.ts @@ -8,8 +8,8 @@ import { readRules } from './read_rules'; import { rulesClientMock } from '@kbn/alerting-plugin/server/mocks'; import { - resolveAlertMock, - getAlertMock, + resolveRuleMock, + getRuleMock, getFindResultWithSingleHit, } from '../routes/__mocks__/request_responses'; import { getQueryRuleParams } from '../schemas/rule_schemas.mock'; @@ -25,10 +25,7 @@ export class TestError extends Error { public output: { statusCode: number }; } -describe.each([ - ['Legacy', false], - ['RAC', true], -])('read_rules - %s', (_, isRuleRegistryEnabled) => { +describe('read_rules', () => { beforeEach(() => { jest.resetAllMocks(); jest.restoreAllMocks(); @@ -37,27 +34,23 @@ describe.each([ describe('readRules', () => { test('should return the output from rulesClient if id is set but ruleId is undefined', async () => { const rulesClient = rulesClientMock.create(); - rulesClient.resolve.mockResolvedValue( - resolveAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) - ); + rulesClient.resolve.mockResolvedValue(resolveRuleMock(getQueryRuleParams())); const rule = await readRules({ - isRuleRegistryEnabled, rulesClient, id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', ruleId: undefined, }); - expect(rule).toEqual(getAlertMock(isRuleRegistryEnabled, getQueryRuleParams())); + expect(rule).toEqual(getRuleMock(getQueryRuleParams())); }); test('should return null if saved object found by alerts client given id is not alert type', async () => { const rulesClient = rulesClientMock.create(); - const result = resolveAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result = resolveRuleMock(getQueryRuleParams()); // @ts-expect-error delete result.alertTypeId; rulesClient.resolve.mockResolvedValue(result); const rule = await readRules({ - isRuleRegistryEnabled, rulesClient, id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', ruleId: undefined, @@ -72,7 +65,6 @@ describe.each([ }); const rule = await readRules({ - isRuleRegistryEnabled, rulesClient, id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', ruleId: undefined, @@ -87,7 +79,6 @@ describe.each([ }); try { await readRules({ - isRuleRegistryEnabled, rulesClient, id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', ruleId: undefined, @@ -99,25 +90,23 @@ describe.each([ test('should return the output from rulesClient if id is undefined but ruleId is set', async () => { const rulesClient = rulesClientMock.create(); - rulesClient.get.mockResolvedValue(getAlertMock(isRuleRegistryEnabled, getQueryRuleParams())); - rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); + rulesClient.get.mockResolvedValue(getRuleMock(getQueryRuleParams())); + rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); const rule = await readRules({ - isRuleRegistryEnabled, rulesClient, id: undefined, ruleId: 'rule-1', }); - expect(rule).toEqual(getAlertMock(isRuleRegistryEnabled, getQueryRuleParams())); + expect(rule).toEqual(getRuleMock(getQueryRuleParams())); }); test('should return null if the output from rulesClient with ruleId set is empty', async () => { const rulesClient = rulesClientMock.create(); - rulesClient.get.mockResolvedValue(getAlertMock(isRuleRegistryEnabled, getQueryRuleParams())); + rulesClient.get.mockResolvedValue(getRuleMock(getQueryRuleParams())); rulesClient.find.mockResolvedValue({ data: [], page: 0, perPage: 1, total: 0 }); const rule = await readRules({ - isRuleRegistryEnabled, rulesClient, id: undefined, ruleId: 'rule-1', @@ -127,25 +116,23 @@ describe.each([ test('should return the output from rulesClient if id is null but ruleId is set', async () => { const rulesClient = rulesClientMock.create(); - rulesClient.get.mockResolvedValue(getAlertMock(isRuleRegistryEnabled, getQueryRuleParams())); - rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); + rulesClient.get.mockResolvedValue(getRuleMock(getQueryRuleParams())); + rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); const rule = await readRules({ - isRuleRegistryEnabled, rulesClient, id: undefined, ruleId: 'rule-1', }); - expect(rule).toEqual(getAlertMock(isRuleRegistryEnabled, getQueryRuleParams())); + expect(rule).toEqual(getRuleMock(getQueryRuleParams())); }); test('should return null if id and ruleId are undefined', async () => { const rulesClient = rulesClientMock.create(); - rulesClient.get.mockResolvedValue(getAlertMock(isRuleRegistryEnabled, getQueryRuleParams())); - rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); + rulesClient.get.mockResolvedValue(getRuleMock(getQueryRuleParams())); + rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); const rule = await readRules({ - isRuleRegistryEnabled, rulesClient, id: undefined, ruleId: undefined, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/read_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/read_rules.ts index 48f3ee86bd0ef..ef9d867105e10 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/read_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/read_rules.ts @@ -6,7 +6,6 @@ */ import { ResolvedSanitizedRule, SanitizedRule } from '@kbn/alerting-plugin/common'; -import { INTERNAL_RULE_ID_KEY } from '../../../../common/constants'; import { RuleParams } from '../schemas/rule_schemas'; import { findRules } from './find_rules'; import { isAlertType, ReadRuleOptions } from './types'; @@ -17,10 +16,9 @@ import { isAlertType, ReadRuleOptions } from './types'; * and the id will either be found through `rulesClient.get({ id })` or it will not * be returned as a not-found or a thrown error that is not 404. * @param ruleId - This is a close second to being fast as long as it can find the rule_id from - * a filter query against the tags using `alert.attributes.tags: "__internal:${ruleId}"]` + * a filter query against the ruleId property in params using `alert.attributes.params.ruleId: "${ruleId}"` */ export const readRules = async ({ - isRuleRegistryEnabled, rulesClient, id, ruleId, @@ -30,7 +28,7 @@ export const readRules = async ({ if (id != null) { try { const rule = await rulesClient.resolve({ id }); - if (isAlertType(isRuleRegistryEnabled, rule)) { + if (isAlertType(rule)) { if (rule?.outcome === 'exactMatch') { const { outcome, ...restOfRule } = rule; return restOfRule; @@ -49,19 +47,15 @@ export const readRules = async ({ } } else if (ruleId != null) { const ruleFromFind = await findRules({ - isRuleRegistryEnabled, rulesClient, - filter: `alert.attributes.tags: "${INTERNAL_RULE_ID_KEY}:${ruleId}"`, + filter: `alert.attributes.params.ruleId: "${ruleId}"`, page: 1, fields: undefined, perPage: undefined, sortField: undefined, sortOrder: undefined, }); - if ( - ruleFromFind.data.length === 0 || - !isAlertType(isRuleRegistryEnabled, ruleFromFind.data[0]) - ) { + if (ruleFromFind.data.length === 0 || !isAlertType(ruleFromFind.data[0])) { return null; } else { return ruleFromFind.data[0]; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/types.ts index 95def15c20e27..8b560d0edea0f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/types.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/types.ts @@ -39,7 +39,7 @@ import type { ThrottleOrNull, } from '@kbn/securitysolution-io-ts-alerting-types'; import type { VersionOrUndefined, Version } from '@kbn/securitysolution-io-ts-types'; -import { SIGNALS_ID, ruleTypeMappings } from '@kbn/securitysolution-rules'; +import { ruleTypeMappings } from '@kbn/securitysolution-rules'; import type { ListArrayOrUndefined, ListArray } from '@kbn/securitysolution-io-ts-list-types'; import { RulesClient, PartialRule } from '@kbn/alerting-plugin/server'; @@ -125,20 +125,16 @@ export interface Clients { } export const isAlertTypes = ( - isRuleRegistryEnabled: boolean, partialAlert: Array> ): partialAlert is RuleAlertType[] => { - return partialAlert.every((rule) => isAlertType(isRuleRegistryEnabled, rule)); + return partialAlert.every((rule) => isAlertType(rule)); }; export const isAlertType = ( - isRuleRegistryEnabled: boolean, partialAlert: PartialRule ): partialAlert is RuleAlertType => { const ruleTypeValues = Object.values(ruleTypeMappings) as unknown as string[]; - return isRuleRegistryEnabled - ? ruleTypeValues.includes(partialAlert.alertTypeId as string) - : partialAlert.alertTypeId === SIGNALS_ID; + return ruleTypeValues.includes(partialAlert.alertTypeId as string); }; export interface CreateRulesOptions { @@ -192,7 +188,6 @@ export interface CreateRulesOptions { version: Version; exceptionsList: ListArray; actions: RuleAlertAction[]; - isRuleRegistryEnabled: boolean; namespace?: NamespaceOrUndefined; id?: string; } @@ -261,7 +256,6 @@ interface PatchRulesFieldsOptions { } export interface ReadRuleOptions { - isRuleRegistryEnabled: boolean; rulesClient: RulesClient; id: IdOrUndefined; ruleId: RuleIdOrUndefined; @@ -274,7 +268,6 @@ export interface DeleteRuleOptions { } export interface FindRuleOptions { - isRuleRegistryEnabled: boolean; rulesClient: RulesClient; perPage: PerPageOrUndefined; page: PageOrUndefined; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_prepacked_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_prepacked_rules.test.ts index ee6179a9c7e68..96fba6703a537 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_prepacked_rules.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_prepacked_rules.test.ts @@ -15,10 +15,7 @@ import { ruleExecutionLogMock } from '../rule_execution_log/__mocks__'; jest.mock('./patch_rules'); -describe.each([ - ['Legacy', false], - ['RAC', true], -])('updatePrepackagedRules - %s', (_, isRuleRegistryEnabled) => { +describe('updatePrepackagedRules', () => { let rulesClient: ReturnType; let savedObjectsClient: ReturnType; let ruleExecutionLog: ReturnType; @@ -40,14 +37,13 @@ describe.each([ ]; const outputIndex = 'outputIndex'; const prepackagedRule = getAddPrepackagedRulesSchemaDecodedMock(); - rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); + rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); await updatePrepackagedRules( rulesClient, savedObjectsClient, [{ ...prepackagedRule, actions }], outputIndex, - isRuleRegistryEnabled, ruleExecutionLog ); @@ -71,14 +67,13 @@ describe.each([ threat_query: 'threat:*', }; const prepackagedRule = getAddPrepackagedRulesSchemaDecodedMock(); - rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); + rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); await updatePrepackagedRules( rulesClient, savedObjectsClient, [{ ...prepackagedRule, ...updatedThreatParams }], 'output-index', - isRuleRegistryEnabled, ruleExecutionLog ); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_prepacked_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_prepacked_rules.ts index b8ff87dbd0ff2..ad35e11d35668 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_prepacked_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_prepacked_rules.ts @@ -35,7 +35,6 @@ export const updatePrepackagedRules = async ( savedObjectsClient: SavedObjectsClientContract, rules: AddPrepackagedRulesSchemaDecoded[], outputIndex: string, - isRuleRegistryEnabled: boolean, ruleExecutionLog: IRuleExecutionLogForRoutes ): Promise => { const ruleChunks = chunk(MAX_RULES_TO_UPDATE_IN_PARALLEL, rules); @@ -45,7 +44,6 @@ export const updatePrepackagedRules = async ( savedObjectsClient, ruleChunk, outputIndex, - isRuleRegistryEnabled, ruleExecutionLog ); await Promise.all(rulePromises); @@ -65,7 +63,6 @@ export const createPromises = ( savedObjectsClient: SavedObjectsClientContract, rules: AddPrepackagedRulesSchemaDecoded[], outputIndex: string, - isRuleRegistryEnabled: boolean, ruleExecutionLog: IRuleExecutionLogForRoutes ): Array | null>> => { return rules.map(async (rule) => { @@ -118,7 +115,6 @@ export const createPromises = ( } = rule; const existingRule = await readRules({ - isRuleRegistryEnabled, rulesClient, ruleId, id: undefined, @@ -149,7 +145,6 @@ export const createPromises = ( return (await createRules({ id: migratedRule.id, - isRuleRegistryEnabled, rulesClient, anomalyThreshold, author, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.mock.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.mock.ts index 9482a1d3aa1c4..9f19e68443c45 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.mock.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.mock.ts @@ -11,27 +11,25 @@ import { getUpdateMachineLearningSchemaMock, getUpdateRulesSchemaMock, } from '../../../../common/detection_engine/schemas/request/rule_schemas.mock'; -import { getAlertMock } from '../routes/__mocks__/request_responses'; +import { getRuleMock } from '../routes/__mocks__/request_responses'; import { getQueryRuleParams } from '../schemas/rule_schemas.mock'; -export const getUpdateRulesOptionsMock = (isRuleRegistryEnabled: boolean) => ({ +export const getUpdateRulesOptionsMock = () => ({ spaceId: 'default', rulesClient: rulesClientMock.create(), savedObjectsClient: savedObjectsClientMock.create(), defaultOutputIndex: '.siem-signals-default', - existingRule: getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()), - migratedRule: getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()), + existingRule: getRuleMock(getQueryRuleParams()), + migratedRule: getRuleMock(getQueryRuleParams()), ruleUpdate: getUpdateRulesSchemaMock(), - isRuleRegistryEnabled, }); -export const getUpdateMlRulesOptionsMock = (isRuleRegistryEnabled: boolean) => ({ +export const getUpdateMlRulesOptionsMock = () => ({ spaceId: 'default', rulesClient: rulesClientMock.create(), savedObjectsClient: savedObjectsClientMock.create(), defaultOutputIndex: '.siem-signals-default', - existingRule: getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()), - migratedRule: getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()), + existingRule: getRuleMock(getQueryRuleParams()), + migratedRule: getRuleMock(getQueryRuleParams()), ruleUpdate: getUpdateMachineLearningSchemaMock(), - isRuleRegistryEnabled, }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.test.ts index 519ecd0c01ed2..a382fc27ed562 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { getAlertMock, resolveAlertMock } from '../routes/__mocks__/request_responses'; +import { getRuleMock, resolveRuleMock } from '../routes/__mocks__/request_responses'; import { updateRules } from './update_rules'; import { getUpdateRulesOptionsMock, getUpdateMlRulesOptionsMock } from './update_rules.mock'; import { RulesClientMock } from '@kbn/alerting-plugin/server/rules_client.mock'; @@ -14,10 +14,10 @@ import { getMlRuleParams, getQueryRuleParams } from '../schemas/rule_schemas.moc // Failing with rule registry enabled describe('updateRules', () => { it('should call rulesClient.disable if the rule was enabled and enabled is false', async () => { - const rulesOptionsMock = getUpdateRulesOptionsMock(true); + const rulesOptionsMock = getUpdateRulesOptionsMock(); rulesOptionsMock.ruleUpdate.enabled = false; (rulesOptionsMock.rulesClient as unknown as RulesClientMock).update.mockResolvedValue( - getAlertMock(true, getQueryRuleParams()) + getRuleMock(getQueryRuleParams()) ); await updateRules(rulesOptionsMock); @@ -30,7 +30,7 @@ describe('updateRules', () => { }); it('should call rulesClient.enable if the rule was disabled and enabled is true', async () => { - const baseRulesOptionsMock = getUpdateRulesOptionsMock(true); + const baseRulesOptionsMock = getUpdateRulesOptionsMock(); const rulesOptionsMock = { ...baseRulesOptionsMock, existingRule: { @@ -41,7 +41,7 @@ describe('updateRules', () => { rulesOptionsMock.ruleUpdate.enabled = true; (rulesOptionsMock.rulesClient as unknown as RulesClientMock).update.mockResolvedValue( - getAlertMock(true, getQueryRuleParams()) + getRuleMock(getQueryRuleParams()) ); await updateRules(rulesOptionsMock); @@ -54,15 +54,15 @@ describe('updateRules', () => { }); it('calls the rulesClient with params', async () => { - const rulesOptionsMock = getUpdateMlRulesOptionsMock(true); + const rulesOptionsMock = getUpdateMlRulesOptionsMock(); rulesOptionsMock.ruleUpdate.enabled = true; (rulesOptionsMock.rulesClient as unknown as RulesClientMock).update.mockResolvedValue( - getAlertMock(true, getMlRuleParams()) + getRuleMock(getMlRuleParams()) ); (rulesOptionsMock.rulesClient as unknown as RulesClientMock).resolve.mockResolvedValue( - resolveAlertMock(true, getMlRuleParams()) + resolveRuleMock(getMlRuleParams()) ); await updateRules(rulesOptionsMock); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.ts index df9a09ba98bb5..ba65b76f01c4a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.ts @@ -12,7 +12,6 @@ import { DEFAULT_MAX_SIGNALS } from '../../../../common/constants'; import { transformRuleToAlertAction } from '../../../../common/detection_engine/transform_actions'; import { UpdateRulesOptions } from './types'; -import { addTags } from './add_tags'; import { typeSpecificSnakeToCamel } from '../schemas/rule_converters'; import { internalRuleUpdate, RuleParams } from '../schemas/rule_schemas'; import { maybeMute, transformToAlertThrottle, transformToNotifyWhen } from './utils'; @@ -39,7 +38,7 @@ export const updateRules = async ({ const enabled = ruleUpdate.enabled ?? true; const newInternalRule = { name: ruleUpdate.name, - tags: addTags(ruleUpdate.tags ?? [], existingRule.params.ruleId, existingRule.params.immutable), + tags: ruleUpdate.tags ?? [], params: { author: ruleUpdate.author ?? [], buildingBlockType: ruleUpdate.building_block_type, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/schemas/rule_converters.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/schemas/rule_converters.ts index b806b42e5180a..fd80bec1f6ad9 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/schemas/rule_converters.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/schemas/rule_converters.ts @@ -7,7 +7,7 @@ import uuid from 'uuid'; -import { SIGNALS_ID, ruleTypeMappings } from '@kbn/securitysolution-rules'; +import { ruleTypeMappings } from '@kbn/securitysolution-rules'; import { ResolvedSanitizedRule, SanitizedRule } from '@kbn/alerting-plugin/common'; import { @@ -29,10 +29,8 @@ import { ResponseTypeSpecific, } from '../../../../common/detection_engine/schemas/request'; import { AppClient } from '../../../types'; -import { addTags } from '../rules/add_tags'; import { DEFAULT_MAX_SIGNALS, SERVER_APP_ID } from '../../../../common/constants'; import { transformRuleToAlertAction } from '../../../../common/detection_engine/transform_actions'; -import { transformTags } from '../routes/rules/utils'; import { transformFromAlertThrottle, transformToAlertThrottle, @@ -127,15 +125,14 @@ export const typeSpecificSnakeToCamel = (params: CreateTypeSpecific): TypeSpecif export const convertCreateAPIToInternalSchema = ( input: CreateRulesSchema, - siemClient: AppClient, - isRuleRegistryEnabled: boolean + siemClient: AppClient ): InternalRuleCreate => { const typeSpecificParams = typeSpecificSnakeToCamel(input); const newRuleId = input.rule_id ?? uuid.v4(); return { name: input.name, - tags: addTags(input.tags ?? [], newRuleId, false), - alertTypeId: isRuleRegistryEnabled ? ruleTypeMappings[input.type] : SIGNALS_ID, + tags: input.tags ?? [], + alertTypeId: ruleTypeMappings[input.type], consumer: SERVER_APP_ID, params: { author: input.author ?? [], @@ -302,7 +299,7 @@ export const internalRuleToAPIResponse = ( created_at: rule.createdAt.toISOString(), created_by: rule.createdBy ?? 'elastic', name: rule.name, - tags: transformTags(rule.tags), + tags: rule.tags, interval: rule.schedule.interval, enabled: rule.enabled, // Security solution shared rule params diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/find_rule_by_filter.sh b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/find_rule_by_filter.sh index 6aab0cd3c9728..35199b775b33c 100755 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/find_rule_by_filter.sh +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/find_rule_by_filter.sh @@ -26,13 +26,13 @@ FILTER=${1:-'alert.attributes.enabled:%20true'} # ./find_rule_by_filter.sh "alert.attributes.tags:tag_1" # Example get all pre-packaged rules -# ./find_rule_by_filter.sh "alert.attributes.tags:%20%22__internal_immutable:true%22" +# ./find_rule_by_filter.sh "alert.attributes.params.immutable:%20true" # Example get all non pre-packaged rules -# ./find_rule_by_filter.sh "alert.attributes.tags:%20%22__internal_immutable:false%22" +# ./find_rule_by_filter.sh "alert.attributes.params.immutable:%20false" # Example get all non pre-packaged rules and a tag_1 -# ./find_rule_by_filter.sh "alert.attributes.tags:%20%22__internal_immutable:false%22%20AND%20alert.attributes.tags:tag_1" +# ./find_rule_by_filter.sh "alert.attributes.params.immutable:%20false%20AND%20alert.attributes.tags:tag_1" curl -s -k \ -u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \ -X GET ${KIBANA_URL}${SPACE_URL}/api/detection_engine/rules/_find?filter=$FILTER | jq . diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts index d699e71947853..9213d6c5b278c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts @@ -910,6 +910,32 @@ export const sampleDocSearchResultsNoSortIdNoHits = ( }, }); +/** + * + * @param count Total number of hits to create + * @param guids List of _id values for the hits. If this array is smaller than count, the remaining hits will receive a default value. + * @param ips List of source.ip values for the hits. If this array is smaller than count, the remaining hits will receive a default value. + * @param destIps List of destination.ip values for the hits. If this array is smaller than count, the remaining hits will receive a default value. + * @param sortIds List of sort IDs. The same list is inserted into every hit. + * @returns Array of mock hits + */ +export const repeatedHitsWithSortId = ( + count: number, + guids: string[], + ips?: Array, + destIps?: Array, + sortIds?: string[] +): SignalSourceHit[] => { + return Array.from({ length: count }).map((x, index) => ({ + ...sampleDocWithSortId( + guids[index], + sortIds, + ips ? ips[index] : '127.0.0.1', + destIps ? destIps[index] : '127.0.0.1' + ), + })); +}; + export const repeatedSearchResultsWithSortId = ( total: number, pageSize: number, @@ -929,14 +955,7 @@ export const repeatedSearchResultsWithSortId = ( hits: { total, max_score: 100, - hits: Array.from({ length: pageSize }).map((x, index) => ({ - ...sampleDocWithSortId( - guids[index], - sortIds, - ips ? ips[index] : '127.0.0.1', - destIps ? destIps[index] : '127.0.0.1' - ), - })), + hits: repeatedHitsWithSortId(pageSize, guids, ips, destIps, sortIds), }, }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_ml_signals.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_ml_signals.ts index 66394d4bca81d..e38ee3952cadb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_ml_signals.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_ml_signals.ts @@ -15,7 +15,7 @@ import { RuleExecutorServices, } from '@kbn/alerting-plugin/server'; import { GenericBulkCreateResponse } from '../rule_types/factories'; -import { AnomalyResults, Anomaly } from '../../machine_learning'; +import { Anomaly } from '../../machine_learning'; import { BuildRuleMessage } from './rule_messages'; import { BulkCreate, WrapHits } from './types'; import { CompleteRule, MachineLearningRuleParams } from '../schemas/rule_schemas'; @@ -23,7 +23,7 @@ import { buildReasonMessageForMlAlert } from './reason_formatters'; import { BaseFieldsLatest } from '../../../../common/detection_engine/schemas/alerts'; interface BulkCreateMlSignalsParams { - someResult: AnomalyResults; + anomalyHits: Array>; completeRule: CompleteRule; services: RuleExecutorServices; logger: Logger; @@ -65,32 +65,23 @@ export const transformAnomalyFieldsToEcs = (anomaly: Anomaly): EcsAnomaly => { }; const transformAnomalyResultsToEcs = ( - results: AnomalyResults -): estypes.SearchResponse => { - const transformedHits = results.hits.hits.map(({ _source, ...rest }) => ({ + results: Array> +): Array> => { + return results.map(({ _source, ...rest }) => ({ ...rest, _source: transformAnomalyFieldsToEcs( // @ts-expect-error @elastic/elasticsearch _source is optional _source ), })); - - // @ts-expect-error Anomaly is not assignable to EcsAnomaly - return { - ...results, - hits: { - ...results.hits, - hits: transformedHits, - }, - }; }; export const bulkCreateMlSignals = async ( params: BulkCreateMlSignalsParams ): Promise> => { - const anomalyResults = params.someResult; + const anomalyResults = params.anomalyHits; const ecsResults = transformAnomalyResultsToEcs(anomalyResults); - const wrappedDocs = params.wrapHits(ecsResults.hits.hits, buildReasonMessageForMlAlert); + const wrappedDocs = params.wrapHits(ecsResults, buildReasonMessageForMlAlert); return params.bulkCreate(wrappedDocs); }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.ts index e601f41aa7628..33ee15d683b7c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.ts @@ -15,9 +15,6 @@ import { } from '@kbn/alerting-plugin/server'; import { buildEqlSearchRequest } from '../build_events_query'; import { hasLargeValueItem } from '../../../../../common/detection_engine/utils'; -import { isOutdated } from '../../migrations/helpers'; -import { getIndexVersion } from '../../routes/index/get_index_version'; -import { MIN_EQL_RULE_INDEX_VERSION } from '../../routes/index/get_signals_template'; import { getInputIndex } from '../get_input_output_index'; import { @@ -71,27 +68,7 @@ export const eqlExecutor = async ({ ); result.warning = true; } - if (!experimentalFeatures.ruleRegistryEnabled) { - try { - const signalIndexVersion = await getIndexVersion( - services.scopedClusterClient.asCurrentUser, - ruleParams.outputIndex - ); - if (isOutdated({ current: signalIndexVersion, target: MIN_EQL_RULE_INDEX_VERSION })) { - throw new Error( - `EQL based rules require an update to version ${MIN_EQL_RULE_INDEX_VERSION} of the detection alerts index mapping` - ); - } - } catch (err) { - if (err.statusCode === 403) { - throw new Error( - `EQL based rules require the user that created it to have the view_index_metadata, read, and write permissions for index: ${ruleParams.outputIndex}` - ); - } else { - throw err; - } - } - } + const inputIndex = await getInputIndex({ experimentalFeatures, services, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/ml.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/ml.ts index 2070d487c49d0..22c11b565e909 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/ml.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/ml.ts @@ -97,21 +97,21 @@ export const mlExecutor = async ({ exceptionItems, }); - const filteredAnomalyResults = await filterEventsAgainstList({ + const [filteredAnomalyHits, _] = await filterEventsAgainstList({ listClient, exceptionsList: exceptionItems, logger, - eventSearchResult: anomalyResults, + events: anomalyResults.hits.hits, buildRuleMessage, }); - const anomalyCount = filteredAnomalyResults.hits.hits.length; + const anomalyCount = filteredAnomalyHits.length; if (anomalyCount) { logger.debug(buildRuleMessage(`Found ${anomalyCount} signals from ML anomalies.`)); } const { success, errors, bulkCreateDuration, createdItemsCount, createdItems } = await bulkCreateMlSignals({ - someResult: filteredAnomalyResults, + anomalyHits: filteredAnomalyHits, completeRule, services, logger, @@ -124,7 +124,7 @@ export const mlExecutor = async ({ // The legacy ES client does not define failures when it can be present on the structure, hence why I have the & { failures: [] } const shardFailures = ( - filteredAnomalyResults._shards as typeof filteredAnomalyResults._shards & { + anomalyResults._shards as typeof anomalyResults._shards & { failures: []; } ).failures ?? []; @@ -134,7 +134,7 @@ export const mlExecutor = async ({ return mergeReturns([ result, createSearchAfterReturnType({ - success: success && filteredAnomalyResults._shards.failed === 0, + success: success && anomalyResults._shards.failed === 0, errors: [...errors, ...searchErrors], createdSignalsCount: createdItemsCount, createdSignals: createdItems, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/filter_events.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/filter_events.test.ts index df9bb0cd59f83..bed5f96fbc233 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/filter_events.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/filter_events.test.ts @@ -9,10 +9,10 @@ import { sampleDocWithSortId } from '../__mocks__/es_results'; import { listMock } from '@kbn/lists-plugin/server/mocks'; import { getSearchListItemResponseMock } from '@kbn/lists-plugin/common/schemas/response/search_list_item_schema.mock'; -import { filterEvents } from './filter_events'; +import { partitionEvents } from './filter_events'; import { FieldSet } from './types'; -describe('filterEvents', () => { +describe('partitionEvents', () => { let listClient = listMock.getListClient(); let events = [sampleDocWithSortId('123', undefined, '1.1.1.1')]; @@ -43,11 +43,12 @@ describe('filterEvents', () => { matchedSet: new Set([JSON.stringify(['1.1.1.1'])]), }, ]; - const field = filterEvents({ + const [included, excluded] = partitionEvents({ events, fieldAndSetTuples, }); - expect([...field]).toEqual([]); + expect(included).toEqual([]); + expect(excluded).toEqual(events); }); test('it does not filter out the event if it is "excluded"', () => { @@ -59,11 +60,12 @@ describe('filterEvents', () => { matchedSet: new Set([JSON.stringify(['1.1.1.1'])]), }, ]; - const field = filterEvents({ + const [included, excluded] = partitionEvents({ events, fieldAndSetTuples, }); - expect([...field]).toEqual(events); + expect(included).toEqual(events); + expect(excluded).toEqual([]); }); test('it does NOT filter out the event if the field is not found', () => { @@ -75,11 +77,12 @@ describe('filterEvents', () => { matchedSet: new Set([JSON.stringify(['1.1.1.1'])]), }, ]; - const field = filterEvents({ + const [included, excluded] = partitionEvents({ events, fieldAndSetTuples, }); - expect([...field]).toEqual(events); + expect(included).toEqual(events); + expect(excluded).toEqual([]); }); test('it does NOT filter out the event if it is in both an inclusion and exclusion list', () => { @@ -100,10 +103,11 @@ describe('filterEvents', () => { }, ]; - const field = filterEvents({ + const [included, excluded] = partitionEvents({ events, fieldAndSetTuples, }); - expect([...field]).toEqual(events); + expect(included).toEqual(events); + expect(excluded).toEqual([]); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/filter_events.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/filter_events.ts index d267153a4813a..aee98b7e0ff5b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/filter_events.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/filter_events.ts @@ -5,6 +5,7 @@ * 2.0. */ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { partition } from 'lodash'; import { FilterEventsOptions } from './types'; /** @@ -12,12 +13,14 @@ import { FilterEventsOptions } from './types'; * If the entry is in both an inclusion and exclusion list it will not be filtered out. * @param events The events to check against * @param fieldAndSetTuples The field and set tuples + * @returns A tuple where the first element is an array of alerts that should be created and second element is + * an array of alerts that matched the exception and should not be created. */ -export const filterEvents = ({ +export const partitionEvents = ({ events, fieldAndSetTuples, -}: FilterEventsOptions): Array> => { - return events.filter((item) => { +}: FilterEventsOptions): [Array>, Array>] => { + return partition(events, (item) => { return fieldAndSetTuples .map((tuple) => { const eventItem = item.fields ? item.fields[tuple.field] : undefined; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/filter_events_against_list.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/filter_events_against_list.test.ts index 8c33cf2ea1314..22dc5136fcded 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/filter_events_against_list.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/filter_events_against_list.test.ts @@ -8,7 +8,7 @@ import uuid from 'uuid'; import { filterEventsAgainstList } from './filter_events_against_list'; import { buildRuleMessageMock as buildRuleMessage } from '../rule_messages.mock'; -import { mockLogger, repeatedSearchResultsWithSortId } from '../__mocks__/es_results'; +import { mockLogger, repeatedHitsWithSortId } from '../__mocks__/es_results'; import { getExceptionListItemSchemaMock } from '@kbn/lists-plugin/common/schemas/response/exception_list_item_schema.mock'; import { listMock } from '@kbn/lists-plugin/server/mocks'; @@ -30,11 +30,11 @@ describe('filterEventsAgainstList', () => { }); it('should respond with eventSearchResult if exceptionList is empty array', async () => { - const res = await filterEventsAgainstList({ + const [included, excluded] = await filterEventsAgainstList({ logger: mockLogger, listClient, exceptionsList: [], - eventSearchResult: repeatedSearchResultsWithSortId(4, 4, someGuids.slice(0, 3), [ + events: repeatedHitsWithSortId(4, someGuids.slice(0, 3), [ '1.1.1.1', '2.2.2.2', '3.3.3.3', @@ -42,15 +42,16 @@ describe('filterEventsAgainstList', () => { ]), buildRuleMessage, }); - expect(res.hits.hits.length).toEqual(4); + expect(included.length).toEqual(4); + expect(excluded.length).toEqual(0); }); it('should respond with eventSearchResult if exceptionList does not contain value list exceptions', async () => { - const res = await filterEventsAgainstList({ + const [included, excluded] = await filterEventsAgainstList({ logger: mockLogger, listClient, exceptionsList: [getExceptionListItemSchemaMock()], - eventSearchResult: repeatedSearchResultsWithSortId(4, 4, someGuids.slice(0, 3), [ + events: repeatedHitsWithSortId(4, someGuids.slice(0, 3), [ '1.1.1.1', '2.2.2.2', '3.3.3.3', @@ -58,7 +59,8 @@ describe('filterEventsAgainstList', () => { ]), buildRuleMessage, }); - expect(res.hits.hits.length).toEqual(4); + expect(included.length).toEqual(4); + expect(excluded.length).toEqual(0); expect((mockLogger.debug as unknown as jest.Mock).mock.calls[0][0]).toContain( 'no exception items of type list found - returning original search result' ); @@ -79,14 +81,15 @@ describe('filterEventsAgainstList', () => { }, ]; - const res = await filterEventsAgainstList({ + const [included, excluded] = await filterEventsAgainstList({ logger: mockLogger, listClient, exceptionsList: [exceptionItem], - eventSearchResult: repeatedSearchResultsWithSortId(4, 4, someGuids.slice(0, 3)), + events: repeatedHitsWithSortId(4, someGuids.slice(0, 3)), buildRuleMessage, }); - expect(res.hits.hits.length).toEqual(4); + expect(included.length).toEqual(4); + expect(excluded.length).toEqual(0); }); it('should respond with less items in the list if some values match', async () => { @@ -110,11 +113,11 @@ describe('filterEventsAgainstList', () => { })) ) ); - const res = await filterEventsAgainstList({ + const [included, excluded] = await filterEventsAgainstList({ logger: mockLogger, listClient, exceptionsList: [exceptionItem], - eventSearchResult: repeatedSearchResultsWithSortId(4, 4, someGuids.slice(0, 3), [ + events: repeatedHitsWithSortId(4, someGuids.slice(0, 3), [ '1.1.1.1', '2.2.2.2', '3.3.3.3', @@ -126,10 +129,11 @@ describe('filterEventsAgainstList', () => { expect((listClient.searchListItemByValues as jest.Mock).mock.calls[0][0].listId).toEqual( 'ci-badguys.txt' ); - expect(res.hits.hits.length).toEqual(2); + expect(included.length).toEqual(2); + expect(excluded.length).toEqual(2); // @ts-expect-error - const ipVals = res.hits.hits.map((item) => item._source.source.ip); + const ipVals = included.map((item) => item._source.source.ip); expect(['3.3.3.3', '7.7.7.7']).toEqual(ipVals); }); @@ -170,11 +174,11 @@ describe('filterEventsAgainstList', () => { { ...getSearchListItemResponseMock(), value: ['6.6.6.6'] }, ]); - const res = await filterEventsAgainstList({ + const [included, excluded] = await filterEventsAgainstList({ logger: mockLogger, listClient, exceptionsList: [exceptionItem, exceptionItemAgain], - eventSearchResult: repeatedSearchResultsWithSortId(9, 9, someGuids.slice(0, 9), [ + events: repeatedHitsWithSortId(9, someGuids.slice(0, 9), [ '1.1.1.1', '2.2.2.2', '3.3.3.3', @@ -188,10 +192,11 @@ describe('filterEventsAgainstList', () => { buildRuleMessage, }); expect(listClient.searchListItemByValues as jest.Mock).toHaveBeenCalledTimes(2); - expect(res.hits.hits.length).toEqual(6); + expect(included.length).toEqual(6); + expect(excluded.length).toEqual(3); // @ts-expect-error - const ipVals = res.hits.hits.map((item) => item._source.source.ip); + const ipVals = included.map((item) => item._source.source.ip); expect(['1.1.1.1', '3.3.3.3', '5.5.5.5', '7.7.7.7', '8.8.8.8', '9.9.9.9']).toEqual(ipVals); }); @@ -231,11 +236,11 @@ describe('filterEventsAgainstList', () => { { ...getSearchListItemResponseMock(), value: ['6.6.6.6'] }, ]); - const res = await filterEventsAgainstList({ + const [included, excluded] = await filterEventsAgainstList({ logger: mockLogger, listClient, exceptionsList: [exceptionItem, exceptionItemAgain], - eventSearchResult: repeatedSearchResultsWithSortId(9, 9, someGuids.slice(0, 9), [ + events: repeatedHitsWithSortId(9, someGuids.slice(0, 9), [ '1.1.1.1', '2.2.2.2', '3.3.3.3', @@ -250,8 +255,9 @@ describe('filterEventsAgainstList', () => { }); expect(listClient.searchListItemByValues as jest.Mock).toHaveBeenCalledTimes(2); // @ts-expect-error - const ipVals = res.hits.hits.map((item) => item._source.source.ip); - expect(res.hits.hits.length).toEqual(7); + const ipVals = included.map((item) => item._source.source.ip); + expect(included.length).toEqual(7); + expect(excluded.length).toEqual(2); expect(['1.1.1.1', '3.3.3.3', '4.4.4.4', '5.5.5.5', '7.7.7.7', '8.8.8.8', '9.9.9.9']).toEqual( ipVals @@ -290,12 +296,11 @@ describe('filterEventsAgainstList', () => { { ...getSearchListItemResponseMock(), value: ['4.4.4.4'] }, ]); - const res = await filterEventsAgainstList({ + const [included, excluded] = await filterEventsAgainstList({ logger: mockLogger, listClient, exceptionsList: [exceptionItem], - eventSearchResult: repeatedSearchResultsWithSortId( - 9, + events: repeatedHitsWithSortId( 9, someGuids.slice(0, 9), [ @@ -324,10 +329,11 @@ describe('filterEventsAgainstList', () => { buildRuleMessage, }); expect(listClient.searchListItemByValues as jest.Mock).toHaveBeenCalledTimes(2); - expect(res.hits.hits.length).toEqual(8); + expect(included.length).toEqual(8); + expect(excluded.length).toEqual(1); // @ts-expect-error - const ipVals = res.hits.hits.map((item) => item._source.source.ip); + const ipVals = included.map((item) => item._source?.source?.ip); expect([ '1.1.1.1', '2.2.2.2', @@ -368,11 +374,11 @@ describe('filterEventsAgainstList', () => { { ...getSearchListItemResponseMock(), value: ['2.2.2.2'] }, ]); - const res = await filterEventsAgainstList({ + const [included, excluded] = await filterEventsAgainstList({ logger: mockLogger, listClient, exceptionsList: [exceptionItem], - eventSearchResult: repeatedSearchResultsWithSortId(9, 9, someGuids.slice(0, 9), [ + events: repeatedHitsWithSortId(9, someGuids.slice(0, 9), [ '1.1.1.1', '2.2.2.2', '3.3.3.3', @@ -386,10 +392,11 @@ describe('filterEventsAgainstList', () => { buildRuleMessage, }); expect(listClient.searchListItemByValues as jest.Mock).toHaveBeenCalledTimes(2); - expect(res.hits.hits.length).toEqual(9); + expect(included.length).toEqual(9); + expect(excluded.length).toEqual(0); // @ts-expect-error - const ipVals = res.hits.hits.map((item) => item._source.source.ip); + const ipVals = included.map((item) => item._source.source.ip); expect([ '1.1.1.1', '2.2.2.2', @@ -435,12 +442,11 @@ describe('filterEventsAgainstList', () => { { ...getSearchListItemResponseMock(), value: ['3.3.3.3', '4.4.4.4'] }, ]); - const res = await filterEventsAgainstList({ + const [included, excluded] = await filterEventsAgainstList({ logger: mockLogger, listClient, exceptionsList: [exceptionItem], - eventSearchResult: repeatedSearchResultsWithSortId( - 3, + events: repeatedHitsWithSortId( 3, someGuids.slice(0, 3), [ @@ -467,16 +473,17 @@ describe('filterEventsAgainstList', () => { ['2.2.2.2', '3.3.3.3'], ['3.3.3.3', '4.4.4.4'], ]); - expect(res.hits.hits.length).toEqual(2); + expect(included.length).toEqual(2); + expect(excluded.length).toEqual(1); // @ts-expect-error - const sourceIpVals = res.hits.hits.map((item) => item._source.source.ip); + const sourceIpVals = included.map((item) => item._source.source.ip); expect([ ['1.1.1.1', '1.1.1.1'], ['1.1.1.1', '2.2.2.2'], ]).toEqual(sourceIpVals); // @ts-expect-error - const destIpVals = res.hits.hits.map((item) => item._source.destination.ip); + const destIpVals = included.map((item) => item._source.destination.ip); expect([ ['1.1.1.1', '2.2.2.2'], ['2.2.2.2', '3.3.3.3'], @@ -497,14 +504,15 @@ describe('filterEventsAgainstList', () => { }, }, ]; - const res = await filterEventsAgainstList({ + const [included, excluded] = await filterEventsAgainstList({ logger: mockLogger, listClient, exceptionsList: [exceptionItem], - eventSearchResult: repeatedSearchResultsWithSortId(4, 4, someGuids.slice(0, 3)), + events: repeatedHitsWithSortId(4, someGuids.slice(0, 3)), buildRuleMessage, }); - expect(res.hits.hits.length).toEqual(0); + expect(included.length).toEqual(0); + expect(excluded.length).toEqual(4); }); it('should respond with less items in the list if some values match', async () => { @@ -528,11 +536,11 @@ describe('filterEventsAgainstList', () => { })) ) ); - const res = await filterEventsAgainstList({ + const [included, excluded] = await filterEventsAgainstList({ logger: mockLogger, listClient, exceptionsList: [exceptionItem], - eventSearchResult: repeatedSearchResultsWithSortId(4, 4, someGuids.slice(0, 3), [ + events: repeatedHitsWithSortId(4, someGuids.slice(0, 3), [ '1.1.1.1', '2.2.2.2', '3.3.3.3', @@ -544,7 +552,8 @@ describe('filterEventsAgainstList', () => { expect((listClient.searchListItemByValues as jest.Mock).mock.calls[0][0].listId).toEqual( 'ci-badguys.txt' ); - expect(res.hits.hits.length).toEqual(2); + expect(included.length).toEqual(2); + expect(excluded.length).toEqual(2); }); it('should respond with the same items in the list given one exception item with two entries of type list and array of values in document', async () => { @@ -582,12 +591,11 @@ describe('filterEventsAgainstList', () => { { ...getSearchListItemResponseMock(), value: ['3.3.3.3', '4.4.4.4'] }, ]); - const res = await filterEventsAgainstList({ + const [included, excluded] = await filterEventsAgainstList({ logger: mockLogger, listClient, exceptionsList: [exceptionItem], - eventSearchResult: repeatedSearchResultsWithSortId( - 3, + events: repeatedHitsWithSortId( 3, someGuids.slice(0, 3), [ @@ -614,16 +622,17 @@ describe('filterEventsAgainstList', () => { ['2.2.2.2', '3.3.3.3'], ['3.3.3.3', '4.4.4.4'], ]); - expect(res.hits.hits.length).toEqual(2); + expect(included.length).toEqual(2); + expect(excluded.length).toEqual(1); // @ts-expect-error - const sourceIpVals = res.hits.hits.map((item) => item._source.source.ip); + const sourceIpVals = included.map((item) => item._source.source.ip); expect([ ['1.1.1.1', '2.2.2.2'], ['2.2.2.2', '3.3.3.3'], ]).toEqual(sourceIpVals); // @ts-expect-error - const destIpVals = res.hits.hits.map((item) => item._source.destination.ip); + const destIpVals = included.map((item) => item._source.destination.ip); expect([ ['2.2.2.2', '3.3.3.3'], ['3.3.3.3', '4.4.4.4'], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/filter_events_against_list.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/filter_events_against_list.ts index 49a8ab0781eb0..7b9f6fde51842 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/filter_events_against_list.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/filter_events_against_list.ts @@ -5,13 +5,12 @@ * 2.0. */ -import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { entriesList, ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; import { hasLargeValueList } from '@kbn/securitysolution-list-utils'; -import { FilterEventsAgainstListOptions } from './types'; -import { filterEvents } from './filter_events'; +import { FilterEventsAgainstListOptions, FilterEventsAgainstListReturn } from './types'; +import { partitionEvents } from './filter_events'; import { createFieldAndSetTuples } from './create_field_and_set_tuples'; /** @@ -39,9 +38,9 @@ export const filterEventsAgainstList = async ({ listClient, exceptionsList, logger, - eventSearchResult, + events, buildRuleMessage, -}: FilterEventsAgainstListOptions): Promise> => { +}: FilterEventsAgainstListOptions): Promise> => { try { const atLeastOneLargeValueList = exceptionsList.some(({ entries }) => hasLargeValueList(entries) @@ -51,46 +50,41 @@ export const filterEventsAgainstList = async ({ logger.debug( buildRuleMessage('no exception items of type list found - returning original search result') ); - return eventSearchResult; + return [events, []]; } const valueListExceptionItems = exceptionsList.filter((listItem: ExceptionListItemSchema) => { return listItem.entries.every((entry) => entriesList.is(entry)); }); - const res = await valueListExceptionItems.reduce>>>( + // Every event starts out in the 'included' list, and each value list item checks all the + // current 'included' events and moves events that match the exception to the 'excluded' list + return valueListExceptionItems.reduce>>( async ( - filteredAccum: Promise>>, + filteredAccum: Promise>, exceptionItem: ExceptionListItemSchema ) => { - const events = await filteredAccum; + const [includedEvents, excludedEvents] = await filteredAccum; const fieldAndSetTuples = await createFieldAndSetTuples({ - events, + events: includedEvents, exceptionItem, listClient, logger, buildRuleMessage, }); - const filteredEvents = filterEvents({ events, fieldAndSetTuples }); - const diff = eventSearchResult.hits.hits.length - filteredEvents.length; + const [nextIncludedEvents, nextExcludedEvents] = partitionEvents({ + events: includedEvents, + fieldAndSetTuples, + }); logger.debug( - buildRuleMessage(`Exception with id ${exceptionItem.id} filtered out ${diff} events`) + buildRuleMessage( + `Exception with id ${exceptionItem.id} filtered out ${nextExcludedEvents.length} events` + ) ); - return filteredEvents; + return [nextIncludedEvents, [...excludedEvents, ...nextExcludedEvents]]; }, - Promise.resolve>>(eventSearchResult.hits.hits) + Promise.resolve>([events, []]) ); - - return { - took: eventSearchResult.took, - timed_out: eventSearchResult.timed_out, - _shards: eventSearchResult._shards, - hits: { - total: res.length, - max_score: eventSearchResult.hits.max_score, - hits: res, - }, - }; } catch (exc) { throw new Error(`Failed to query large value based lists index. Reason: ${exc.message}`); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/types.ts index 051685c67db4a..f5d438f54bdb3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/types.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filters/types.ts @@ -15,10 +15,15 @@ export interface FilterEventsAgainstListOptions { listClient: ListClient; exceptionsList: ExceptionListItemSchema[]; logger: Logger; - eventSearchResult: estypes.SearchResponse; + events: Array>; buildRuleMessage: BuildRuleMessage; } +export type FilterEventsAgainstListReturn = [ + Array>, + Array> +]; + export interface CreateSetToFilterAgainstOptions { events: Array>; field: string; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/README.md b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/README.md index c76a69db084ca..cf8e3262e2826 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/README.md +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/README.md @@ -53,10 +53,7 @@ to any newly saved rule: "_source" : { "alert" : { "name" : "kql test rule 1", - "tags" : [ - "__internal_rule_id:4ec223b9-77fa-4895-8539-6b3e586a2858", - "__internal_immutable:false" - ], + "tags" : [], "alertTypeId" : "siem.signals", "other data... other data": "other data...other data", "exceptionsList" : [ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts index b96b0e6dc7148..4f3a798a327ce 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts @@ -1004,16 +1004,12 @@ describe('searchAfterAndBulkCreate', () => { }); expect(mockEnrichment).toHaveBeenCalledWith( - expect.objectContaining({ - hits: expect.objectContaining({ - hits: expect.arrayContaining([ - expect.objectContaining({ - ...sampleDocWithSortId(), - _id: expect.any(String), - }), - ]), + expect.objectContaining([ + expect.objectContaining({ + ...sampleDocWithSortId(), + _id: expect.any(String), }), - }) + ]) ); expect(success).toEqual(true); expect(mockService.scopedClusterClient.asCurrentUser.search).toHaveBeenCalledTimes(4); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.ts index 69c001898b217..84ef95b856a5f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.ts @@ -127,11 +127,11 @@ export const searchAfterAndBulkCreate = async ({ // filter out the search results that match with the values found in the list. // the resulting set are signals to be indexed, given they are not duplicates // of signals already present in the signals index. - const filteredEvents = await filterEventsAgainstList({ + const [includedEvents, _] = await filterEventsAgainstList({ listClient, exceptionsList, logger, - eventSearchResult: mergedSearchResults, + events: mergedSearchResults.hits.hits, buildRuleMessage, }); @@ -139,16 +139,11 @@ export const searchAfterAndBulkCreate = async ({ // if there isn't anything after going through the value list filter // skip the call to bulk create and proceed to the next search_after, // if there is a sort id to continue the search_after with. - if (filteredEvents.hits.hits.length !== 0) { + if (includedEvents.length !== 0) { // make sure we are not going to create more signals than maxSignals allows - if (signalsCreatedCount + filteredEvents.hits.hits.length > tuple.maxSignals) { - filteredEvents.hits.hits = filteredEvents.hits.hits.slice( - 0, - tuple.maxSignals - signalsCreatedCount - ); - } - const enrichedEvents = await enrichment(filteredEvents); - const wrappedDocs = wrapHits(enrichedEvents.hits.hits, buildReasonMessage); + const limitedEvents = includedEvents.slice(0, tuple.maxSignals - signalsCreatedCount); + const enrichedEvents = await enrichment(limitedEvents); + const wrappedDocs = wrapHits(enrichedEvents, buildReasonMessage); const { bulkCreateDuration: bulkDuration, @@ -171,9 +166,7 @@ export const searchAfterAndBulkCreate = async ({ signalsCreatedCount += createdCount; logger.debug(buildRuleMessage(`created ${createdCount} signals`)); logger.debug(buildRuleMessage(`signalsCreatedCount: ${signalsCreatedCount}`)); - logger.debug( - buildRuleMessage(`enrichedEvents.hits.hits: ${enrichedEvents.hits.hits.length}`) - ); + logger.debug(buildRuleMessage(`enrichedEvents.hits.hits: ${enrichedEvents.length}`)); sendAlertTelemetryEvents( logger, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/send_telemetry_events.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/send_telemetry_events.test.ts index 36bb90936620b..d598b84ea99e2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/send_telemetry_events.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/send_telemetry_events.test.ts @@ -9,100 +9,86 @@ import { selectEvents, enrichEndpointAlertsSignalID } from './send_telemetry_eve describe('sendAlertTelemetry', () => { it('selectEvents', () => { - const filteredEvents = { - took: 0, - timed_out: false, - _shards: { - total: 1, - successful: 1, - failed: 0, - skipped: 0, + const filteredEvents = [ + { + _index: 'x', + _type: 'x', + _id: 'x', + _score: 0, + _source: { + '@timestamp': 'x', + key1: 'hello', + data_stream: { + dataset: 'endpoint.events', + }, + event: { + id: 'foo', + }, + }, }, - hits: { - total: 2, - max_score: 0, - hits: [ - { - _index: 'x', - _type: 'x', - _id: 'x', - _score: 0, - _source: { - '@timestamp': 'x', - key1: 'hello', - data_stream: { - dataset: 'endpoint.events', - }, - event: { - id: 'foo', - }, - }, + { + _index: 'x', + _type: 'x', + _id: 'x', + _score: 0, + _source: { + '@timestamp': 'x', + key2: 'hello', + data_stream: { + dataset: 'endpoint.alerts', + other: 'x', + }, + event: { + id: 'bar', }, - { - _index: 'x', - _type: 'x', - _id: 'x', - _score: 0, - _source: { - '@timestamp': 'x', - key2: 'hello', - data_stream: { - dataset: 'endpoint.alerts', - other: 'x', - }, - event: { - id: 'bar', - }, - }, + }, + }, + { + _index: 'x', + _type: 'x', + _id: 'x', + _score: 0, + _source: { + '@timestamp': 'x', + key3: 'hello', + data_stream: {}, + event: { + id: 'baz', }, - { - _index: 'x', - _type: 'x', - _id: 'x', - _score: 0, - _source: { - '@timestamp': 'x', - key3: 'hello', - data_stream: {}, - event: { - id: 'baz', - }, - }, + }, + }, + { + _index: 'y', + _type: 'y', + _id: 'y', + _score: 0, + _source: { + '@timestamp': 'y', + key3: 'hello', + data_stream: { + dataset: 'endpoint.alerts', + other: 'y', }, - { - _index: 'y', - _type: 'y', - _id: 'y', - _score: 0, - _source: { - '@timestamp': 'y', - key3: 'hello', - data_stream: { - dataset: 'endpoint.alerts', - other: 'y', - }, - event: { - id: 'not-in-map', - }, - }, + event: { + id: 'not-in-map', }, - { - _index: 'z', - _type: 'z', - _id: 'z', - _score: 0, - _source: { - '@timestamp': 'z', - key3: 'no-event-id', - data_stream: { - dataset: 'endpoint.alerts', - other: 'z', - }, - }, + }, + }, + { + _index: 'z', + _type: 'z', + _id: 'z', + _score: 0, + _source: { + '@timestamp': 'z', + key3: 'no-event-id', + data_stream: { + dataset: 'endpoint.alerts', + other: 'z', }, - ], + }, }, - }; + ]; const joinMap = new Map([ ['foo', '1234'], ['bar', 'abcd'], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/send_telemetry_events.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/send_telemetry_events.ts index 511f148f13d68..e419fdf632137 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/send_telemetry_events.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/send_telemetry_events.ts @@ -9,7 +9,7 @@ import { Logger } from '@kbn/core/server'; import { ITelemetryEventsSender } from '../../telemetry/sender'; import { TelemetryEvent } from '../../telemetry/types'; import { BuildRuleMessage } from './rule_messages'; -import { SignalSearchResponse, SignalSource } from './types'; +import { SignalSource, SignalSourceHit } from './types'; interface SearchResultSource { _source: SignalSource; @@ -18,9 +18,9 @@ interface SearchResultSource { type CreatedSignalId = string; type AlertId = string; -export function selectEvents(filteredEvents: SignalSearchResponse): TelemetryEvent[] { +export function selectEvents(filteredEvents: SignalSourceHit[]): TelemetryEvent[] { // @ts-expect-error @elastic/elasticsearch _source is optional - const sources: TelemetryEvent[] = filteredEvents.hits.hits.map(function ( + const sources: TelemetryEvent[] = filteredEvents.map(function ( obj: SearchResultSource ): TelemetryEvent { return obj._source; @@ -46,7 +46,7 @@ export function enrichEndpointAlertsSignalID( export function sendAlertTelemetryEvents( logger: Logger, eventsTelemetry: ITelemetryEventsSender | undefined, - filteredEvents: SignalSearchResponse, + filteredEvents: SignalSourceHit[], createdEvents: SignalSource[], buildRuleMessage: BuildRuleMessage ) { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/build_threat_enrichment.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/build_threat_enrichment.ts index bc31ee660aad8..4c5391d238b31 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/build_threat_enrichment.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/build_threat_enrichment.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { SignalSearchResponse, SignalsEnrichment } from '../types'; +import { SignalsEnrichment } from '../types'; import { enrichSignalThreatMatches } from './enrich_signal_threat_matches'; import { BuildThreatEnrichmentOptions, GetMatchedThreats } from './types'; import { getThreatList } from './get_threat_list'; @@ -55,6 +55,5 @@ export const buildThreatEnrichment = ({ return threatResponse.hits.hits; }; - return (signals: SignalSearchResponse): Promise => - enrichSignalThreatMatches(signals, getMatchedThreats, threatIndicatorPath); + return (signals) => enrichSignalThreatMatches(signals, getMatchedThreats, threatIndicatorPath); }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/create_event_signal.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/create_event_signal.ts index c5d86c9ab460c..2587c76907ccb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/create_event_signal.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/create_event_signal.ts @@ -10,7 +10,7 @@ import { getFilter } from '../get_filter'; import { searchAfterAndBulkCreate } from '../search_after_bulk_create'; import { buildReasonMessageForThreatMatchAlert } from '../reason_formatters'; import { CreateEventSignalOptions } from './types'; -import { SearchAfterAndBulkCreateReturnType, SignalSearchResponse } from '../types'; +import { SearchAfterAndBulkCreateReturnType, SignalSourceHit } from '../types'; import { getAllThreatListHits } from './get_threat_list'; import { enrichSignalThreatMatches, @@ -112,7 +112,7 @@ export const createEventSignal = async ({ ) ); - const threatEnrichment = (signals: SignalSearchResponse): Promise => + const threatEnrichment = (signals: SignalSourceHit[]): Promise => enrichSignalThreatMatches( signals, () => Promise.resolve(threatListHits), diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/enrich_signal_threat_matches.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/enrich_signal_threat_matches.test.ts index 66e44e5796eb6..b6df435c04dda 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/enrich_signal_threat_matches.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/enrich_signal_threat_matches.test.ts @@ -8,6 +8,7 @@ import { get } from 'lodash'; import { ENRICHMENT_DESTINATION_PATH } from '../../../../../common/constants'; import { ENRICHMENT_TYPES } from '../../../../../common/cti/constants'; +import { SignalSourceHit } from '../types'; import { getThreatListItemMock } from './build_threat_mapping_filter.mock'; import { @@ -16,11 +17,7 @@ import { groupAndMergeSignalMatches, getSignalMatchesFromThreatList, } from './enrich_signal_threat_matches'; -import { - getNamedQueryMock, - getSignalHitMock, - getSignalsResponseMock, -} from './enrich_signal_threat_matches.mock'; +import { getNamedQueryMock, getSignalHitMock } from './enrich_signal_threat_matches.mock'; import { GetMatchedThreats, ThreatListItem, ThreatMatchNamedQuery } from './types'; import { encodeThreatMatchNamedQuery } from './utils'; @@ -507,14 +504,14 @@ describe('enrichSignalThreatMatches', () => { }); it('performs no enrichment if there are no signals', async () => { - const signals = getSignalsResponseMock([]); + const signals: SignalSourceHit[] = []; const enrichedSignals = await enrichSignalThreatMatches( signals, getMatchedThreats, indicatorPath ); - expect(enrichedSignals.hits.hits).toEqual([]); + expect(enrichedSignals).toEqual([]); }); it('preserves existing threat.enrichments objects on signals', async () => { @@ -526,13 +523,13 @@ describe('enrichSignalThreatMatches', () => { }, matched_queries: [matchedQuery], }); - const signals = getSignalsResponseMock([signalHit]); + const signals: SignalSourceHit[] = [signalHit]; const enrichedSignals = await enrichSignalThreatMatches( signals, getMatchedThreats, indicatorPath ); - const [enrichedHit] = enrichedSignals.hits.hits; + const [enrichedHit] = enrichedSignals; const enrichments = get(enrichedHit._source, ENRICHMENT_DESTINATION_PATH); expect(enrichments).toEqual([ @@ -560,13 +557,13 @@ describe('enrichSignalThreatMatches', () => { const signalHit = getSignalHitMock({ matched_queries: [matchedQuery], }); - const signals = getSignalsResponseMock([signalHit]); + const signals: SignalSourceHit[] = [signalHit]; const enrichedSignals = await enrichSignalThreatMatches( signals, getMatchedThreats, indicatorPath ); - const [enrichedHit] = enrichedSignals.hits.hits; + const [enrichedHit] = enrichedSignals; const enrichments = get(enrichedHit._source, ENRICHMENT_DESTINATION_PATH); expect(enrichments).toEqual([ @@ -598,13 +595,13 @@ describe('enrichSignalThreatMatches', () => { }, matched_queries: [matchedQuery], }); - const signals = getSignalsResponseMock([signalHit]); + const signals: SignalSourceHit[] = [signalHit]; const enrichedSignals = await enrichSignalThreatMatches( signals, getMatchedThreats, indicatorPath ); - const [enrichedHit] = enrichedSignals.hits.hits; + const [enrichedHit] = enrichedSignals; const enrichments = get(enrichedHit._source, ENRICHMENT_DESTINATION_PATH); expect(enrichments).toEqual([ @@ -637,7 +634,7 @@ describe('enrichSignalThreatMatches', () => { _source: { '@timestamp': 'mocked', threat: 'whoops' }, matched_queries: [matchedQuery], }); - const signals = getSignalsResponseMock([signalHit]); + const signals: SignalSourceHit[] = [signalHit]; await expect(() => enrichSignalThreatMatches(signals, getMatchedThreats, indicatorPath) ).rejects.toThrowError('Expected threat field to be an object, but found: whoops'); @@ -674,13 +671,13 @@ describe('enrichSignalThreatMatches', () => { }, matched_queries: [matchedQuery], }); - const signals = getSignalsResponseMock([signalHit]); + const signals: SignalSourceHit[] = [signalHit]; const enrichedSignals = await enrichSignalThreatMatches( signals, getMatchedThreats, 'custom_threat.custom_indicator' ); - const [enrichedHit] = enrichedSignals.hits.hits; + const [enrichedHit] = enrichedSignals; const enrichments = get(enrichedHit._source, ENRICHMENT_DESTINATION_PATH); expect(enrichments).toEqual([ @@ -748,16 +745,15 @@ describe('enrichSignalThreatMatches', () => { ), ], }); - const signals = getSignalsResponseMock([signalHit, otherSignalHit]); + const signals: SignalSourceHit[] = [signalHit, otherSignalHit]; const enrichedSignals = await enrichSignalThreatMatches( signals, getMatchedThreats, indicatorPath ); - expect(enrichedSignals.hits.total).toEqual(expect.objectContaining({ value: 1 })); - expect(enrichedSignals.hits.hits).toHaveLength(1); + expect(enrichedSignals).toHaveLength(1); - const [enrichedHit] = enrichedSignals.hits.hits; + const [enrichedHit] = enrichedSignals; const enrichments = get(enrichedHit._source, ENRICHMENT_DESTINATION_PATH); expect(enrichments).toEqual([ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/enrich_signal_threat_matches.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/enrich_signal_threat_matches.ts index c1fb88176fd4c..58a486068013f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/enrich_signal_threat_matches.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/enrich_signal_threat_matches.ts @@ -8,7 +8,7 @@ import { get, isObject } from 'lodash'; import { ENRICHMENT_TYPES, FEED_NAME_PATH } from '../../../../../common/cti/constants'; -import type { SignalSearchResponse, SignalSourceHit } from '../types'; +import type { SignalSourceHit } from '../types'; import type { GetMatchedThreats, ThreatEnrichment, @@ -109,17 +109,16 @@ export const buildEnrichments = ({ }); export const enrichSignalThreatMatches = async ( - signals: SignalSearchResponse, + signals: SignalSourceHit[], getMatchedThreats: GetMatchedThreats, indicatorPath: string, signalMatchesArg?: SignalMatch[] -): Promise => { - const signalHits = signals.hits.hits; - if (signalHits.length === 0) { +): Promise => { + if (signals.length === 0) { return signals; } - const uniqueHits = groupAndMergeSignalMatches(signalHits); + const uniqueHits = groupAndMergeSignalMatches(signals); const signalMatches: SignalMatch[] = signalMatchesArg ? signalMatchesArg : uniqueHits.map((signalHit) => ({ @@ -177,14 +176,5 @@ export const enrichSignalThreatMatches = async ( }; }); - return { - ...signals, - hits: { - ...signals.hits, - hits: enrichedSignals, - total: isObject(signals.hits.total) - ? { ...signals.hits.total, value: enrichedSignals.length } - : enrichedSignals.length, - }, - }; + return enrichedSignals; }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts index 235865a8b60a9..5dc19b1b257b8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts @@ -277,7 +277,7 @@ export interface AlertAttributes { export type BulkResponseErrorAggregation = Record; -export type SignalsEnrichment = (signals: SignalSearchResponse) => Promise; +export type SignalsEnrichment = (signals: SignalSourceHit[]) => Promise; export type BulkCreate = ( docs: Array> diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/tags/read_tags.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/tags/read_tags.test.ts index 3886a7dacc3b7..2154e672e0089 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/tags/read_tags.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/tags/read_tags.test.ts @@ -6,109 +6,23 @@ */ import { rulesClientMock } from '@kbn/alerting-plugin/server/mocks'; -import { getAlertMock, getFindResultWithMultiHits } from '../routes/__mocks__/request_responses'; -import { INTERNAL_RULE_ID_KEY, INTERNAL_IDENTIFIER } from '../../../../common/constants'; -import { readRawTags, readTags, convertTagsToSet, convertToTags, isTags } from './read_tags'; +import { getRuleMock, getFindResultWithMultiHits } from '../routes/__mocks__/request_responses'; +import { readTags, convertTagsToSet, convertToTags, isTags } from './read_tags'; import { getQueryRuleParams } from '../schemas/rule_schemas.mock'; -describe.each([ - ['Legacy', false], - ['RAC', true], -])('read_tags - %s', (_, isRuleRegistryEnabled) => { +describe('read_tags', () => { afterEach(() => { jest.resetAllMocks(); }); - describe('readRawTags', () => { - test('it should return the intersection of tags to where none are repeating', async () => { - const result1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - result1.id = '4baa53f8-96da-44ee-ad58-41bccb7f9f3d'; - result1.params.ruleId = 'rule-1'; - result1.tags = ['tag 1', 'tag 2', 'tag 3']; - - const result2 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - result2.id = '5baa53f8-96da-44ee-ad58-41bccb7f9f3d'; - result2.params.ruleId = 'rule-2'; - result2.tags = ['tag 1', 'tag 2', 'tag 3', 'tag 4']; - - const rulesClient = rulesClientMock.create(); - rulesClient.find.mockResolvedValue(getFindResultWithMultiHits({ data: [result1, result2] })); - - const tags = await readRawTags({ isRuleRegistryEnabled, rulesClient }); - expect(tags).toEqual(['tag 1', 'tag 2', 'tag 3', 'tag 4']); - }); - - test('it should return the intersection of tags to where some are repeating values', async () => { - const result1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - result1.id = '4baa53f8-96da-44ee-ad58-41bccb7f9f3d'; - result1.params.ruleId = 'rule-1'; - result1.tags = ['tag 1', 'tag 2', 'tag 2', 'tag 3']; - - const result2 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - result2.id = '5baa53f8-96da-44ee-ad58-41bccb7f9f3d'; - result2.params.ruleId = 'rule-2'; - result2.tags = ['tag 1', 'tag 2', 'tag 2', 'tag 3', 'tag 4']; - - const rulesClient = rulesClientMock.create(); - rulesClient.find.mockResolvedValue(getFindResultWithMultiHits({ data: [result1, result2] })); - - const tags = await readRawTags({ isRuleRegistryEnabled, rulesClient }); - expect(tags).toEqual(['tag 1', 'tag 2', 'tag 3', 'tag 4']); - }); - - test('it should work with no tags defined between two results', async () => { - const result1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - result1.id = '4baa53f8-96da-44ee-ad58-41bccb7f9f3d'; - result1.params.ruleId = 'rule-1'; - result1.tags = []; - - const result2 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - result2.id = '5baa53f8-96da-44ee-ad58-41bccb7f9f3d'; - result2.params.ruleId = 'rule-2'; - result2.tags = []; - - const rulesClient = rulesClientMock.create(); - rulesClient.find.mockResolvedValue(getFindResultWithMultiHits({ data: [result1, result2] })); - - const tags = await readRawTags({ isRuleRegistryEnabled, rulesClient }); - expect(tags).toEqual([]); - }); - - test('it should work with a single tag which has repeating values in it', async () => { - const result1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - result1.id = '4baa53f8-96da-44ee-ad58-41bccb7f9f3d'; - result1.params.ruleId = 'rule-1'; - result1.tags = ['tag 1', 'tag 1', 'tag 1', 'tag 2']; - - const rulesClient = rulesClientMock.create(); - rulesClient.find.mockResolvedValue(getFindResultWithMultiHits({ data: [result1] })); - - const tags = await readRawTags({ isRuleRegistryEnabled, rulesClient }); - expect(tags).toEqual(['tag 1', 'tag 2']); - }); - - test('it should work with a single tag which has empty tags', async () => { - const result1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - result1.id = '4baa53f8-96da-44ee-ad58-41bccb7f9f3d'; - result1.params.ruleId = 'rule-1'; - result1.tags = []; - - const rulesClient = rulesClientMock.create(); - rulesClient.find.mockResolvedValue(getFindResultWithMultiHits({ data: [result1] })); - - const tags = await readRawTags({ isRuleRegistryEnabled, rulesClient }); - expect(tags).toEqual([]); - }); - }); - describe('readTags', () => { test('it should return the intersection of tags to where none are repeating', async () => { - const result1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result1 = getRuleMock(getQueryRuleParams()); result1.id = '4baa53f8-96da-44ee-ad58-41bccb7f9f3d'; result1.params.ruleId = 'rule-1'; result1.tags = ['tag 1', 'tag 2', 'tag 3']; - const result2 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result2 = getRuleMock(getQueryRuleParams()); result2.id = '5baa53f8-96da-44ee-ad58-41bccb7f9f3d'; result2.params.ruleId = 'rule-2'; result2.tags = ['tag 1', 'tag 2', 'tag 3', 'tag 4']; @@ -116,17 +30,17 @@ describe.each([ const rulesClient = rulesClientMock.create(); rulesClient.find.mockResolvedValue(getFindResultWithMultiHits({ data: [result1, result2] })); - const tags = await readTags({ isRuleRegistryEnabled, rulesClient }); + const tags = await readTags({ rulesClient }); expect(tags).toEqual(['tag 1', 'tag 2', 'tag 3', 'tag 4']); }); test('it should return the intersection of tags to where some are repeating values', async () => { - const result1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result1 = getRuleMock(getQueryRuleParams()); result1.id = '4baa53f8-96da-44ee-ad58-41bccb7f9f3d'; result1.params.ruleId = 'rule-1'; result1.tags = ['tag 1', 'tag 2', 'tag 2', 'tag 3']; - const result2 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result2 = getRuleMock(getQueryRuleParams()); result2.id = '5baa53f8-96da-44ee-ad58-41bccb7f9f3d'; result2.params.ruleId = 'rule-2'; result2.tags = ['tag 1', 'tag 2', 'tag 2', 'tag 3', 'tag 4']; @@ -134,17 +48,17 @@ describe.each([ const rulesClient = rulesClientMock.create(); rulesClient.find.mockResolvedValue(getFindResultWithMultiHits({ data: [result1, result2] })); - const tags = await readTags({ isRuleRegistryEnabled, rulesClient }); + const tags = await readTags({ rulesClient }); expect(tags).toEqual(['tag 1', 'tag 2', 'tag 3', 'tag 4']); }); test('it should work with no tags defined between two results', async () => { - const result1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result1 = getRuleMock(getQueryRuleParams()); result1.id = '4baa53f8-96da-44ee-ad58-41bccb7f9f3d'; result1.params.ruleId = 'rule-1'; result1.tags = []; - const result2 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result2 = getRuleMock(getQueryRuleParams()); result2.id = '5baa53f8-96da-44ee-ad58-41bccb7f9f3d'; result2.params.ruleId = 'rule-2'; result2.tags = []; @@ -152,12 +66,12 @@ describe.each([ const rulesClient = rulesClientMock.create(); rulesClient.find.mockResolvedValue(getFindResultWithMultiHits({ data: [result1, result2] })); - const tags = await readTags({ isRuleRegistryEnabled, rulesClient }); + const tags = await readTags({ rulesClient }); expect(tags).toEqual([]); }); test('it should work with a single tag which has repeating values in it', async () => { - const result1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result1 = getRuleMock(getQueryRuleParams()); result1.id = '4baa53f8-96da-44ee-ad58-41bccb7f9f3d'; result1.params.ruleId = 'rule-1'; result1.tags = ['tag 1', 'tag 1', 'tag 1', 'tag 2']; @@ -165,12 +79,12 @@ describe.each([ const rulesClient = rulesClientMock.create(); rulesClient.find.mockResolvedValue(getFindResultWithMultiHits({ data: [result1] })); - const tags = await readTags({ isRuleRegistryEnabled, rulesClient }); + const tags = await readTags({ rulesClient }); expect(tags).toEqual(['tag 1', 'tag 2']); }); test('it should work with a single tag which has empty tags', async () => { - const result1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result1 = getRuleMock(getQueryRuleParams()); result1.id = '4baa53f8-96da-44ee-ad58-41bccb7f9f3d'; result1.params.ruleId = 'rule-1'; result1.tags = []; @@ -178,69 +92,19 @@ describe.each([ const rulesClient = rulesClientMock.create(); rulesClient.find.mockResolvedValue(getFindResultWithMultiHits({ data: [result1] })); - const tags = await readTags({ isRuleRegistryEnabled, rulesClient }); + const tags = await readTags({ rulesClient }); expect(tags).toEqual([]); }); - - test('it should filter out any __internal tags for things such as alert_id', async () => { - const result1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - result1.id = '4baa53f8-96da-44ee-ad58-41bccb7f9f3d'; - result1.params.ruleId = 'rule-1'; - result1.tags = [ - `${INTERNAL_IDENTIFIER}_some_value`, - `${INTERNAL_RULE_ID_KEY}_some_value`, - 'tag 1', - ]; - - const rulesClient = rulesClientMock.create(); - rulesClient.find.mockResolvedValue(getFindResultWithMultiHits({ data: [result1] })); - - const tags = await readTags({ isRuleRegistryEnabled, rulesClient }); - expect(tags).toEqual(['tag 1']); - }); - - test('it should filter out any __internal tags with two different results', async () => { - const result1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - result1.id = '4baa53f8-96da-44ee-ad58-41bccb7f9f3d'; - result1.params.ruleId = 'rule-1'; - result1.tags = [ - `${INTERNAL_IDENTIFIER}_some_value`, - `${INTERNAL_RULE_ID_KEY}_some_value`, - 'tag 1', - 'tag 2', - 'tag 3', - 'tag 4', - 'tag 5', - ]; - - const result2 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); - result2.id = '5baa53f8-96da-44ee-ad58-41bccb7f9f3d'; - result2.params.ruleId = 'rule-2'; - result2.tags = [ - `${INTERNAL_IDENTIFIER}_some_value`, - `${INTERNAL_RULE_ID_KEY}_some_value`, - 'tag 1', - 'tag 2', - 'tag 3', - 'tag 4', - ]; - - const rulesClient = rulesClientMock.create(); - rulesClient.find.mockResolvedValue(getFindResultWithMultiHits({ data: [result1] })); - - const tags = await readTags({ isRuleRegistryEnabled, rulesClient }); - expect(tags).toEqual(['tag 1', 'tag 2', 'tag 3', 'tag 4', 'tag 5']); - }); }); describe('convertTagsToSet', () => { test('it should convert the intersection of two tag systems without duplicates', () => { - const result1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result1 = getRuleMock(getQueryRuleParams()); result1.id = '4baa53f8-96da-44ee-ad58-41bccb7f9f3d'; result1.params.ruleId = 'rule-1'; result1.tags = ['tag 1', 'tag 2', 'tag 2', 'tag 3']; - const result2 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result2 = getRuleMock(getQueryRuleParams()); result2.id = '5baa53f8-96da-44ee-ad58-41bccb7f9f3d'; result2.params.ruleId = 'rule-2'; result2.tags = ['tag 1', 'tag 2', 'tag 2', 'tag 3', 'tag 4']; @@ -258,12 +122,12 @@ describe.each([ describe('convertToTags', () => { test('it should convert the two tag systems together with duplicates', () => { - const result1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result1 = getRuleMock(getQueryRuleParams()); result1.id = '4baa53f8-96da-44ee-ad58-41bccb7f9f3d'; result1.params.ruleId = 'rule-1'; result1.tags = ['tag 1', 'tag 2', 'tag 2', 'tag 3']; - const result2 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result2 = getRuleMock(getQueryRuleParams()); result2.id = '5baa53f8-96da-44ee-ad58-41bccb7f9f3d'; result2.params.ruleId = 'rule-2'; result2.tags = ['tag 1', 'tag 2', 'tag 2', 'tag 3', 'tag 4']; @@ -284,18 +148,18 @@ describe.each([ }); test('it should filter out anything that is not a tag', () => { - const result1 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result1 = getRuleMock(getQueryRuleParams()); result1.id = '4baa53f8-96da-44ee-ad58-41bccb7f9f3d'; result1.params.ruleId = 'rule-1'; result1.tags = ['tag 1', 'tag 2', 'tag 2', 'tag 3']; - const result2 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result2 = getRuleMock(getQueryRuleParams()); result2.id = '99979e67-19a7-455f-b452-8eded6135716'; result2.params.ruleId = 'rule-2'; // @ts-expect-error delete result2.tags; - const result3 = getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()); + const result3 = getRuleMock(getQueryRuleParams()); result3.id = '5baa53f8-96da-44ee-ad58-41bccb7f9f3d'; result3.params.ruleId = 'rule-2'; result3.tags = ['tag 1', 'tag 2', 'tag 2', 'tag 3', 'tag 4']; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/tags/read_tags.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/tags/read_tags.ts index da579ee306544..4ab3ccc831af1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/tags/read_tags.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/tags/read_tags.ts @@ -7,7 +7,6 @@ import { has } from 'lodash/fp'; import { RulesClient } from '@kbn/alerting-plugin/server'; -import { INTERNAL_IDENTIFIER } from '../../../../common/constants'; import { findRules } from '../rules/find_rules'; export interface TagType { @@ -20,11 +19,11 @@ export const isTags = (obj: object): obj is TagType => { }; export const convertToTags = (tagObjects: object[]): string[] => { - const tags = tagObjects.reduce((accum, tagObj) => { + const tags = tagObjects.reduce((acc, tagObj) => { if (isTags(tagObj)) { - return [...accum, ...tagObj.tags]; + return [...acc, ...tagObj.tags]; } else { - return accum; + return acc; } }, []); return tags; @@ -40,27 +39,13 @@ export const convertTagsToSet = (tagObjects: object[]): Set => { // then this should be replaced with a an aggregation call. // Ref: https://www.elastic.co/guide/en/kibana/master/saved-objects-api.html export const readTags = async ({ - isRuleRegistryEnabled, rulesClient, }: { - isRuleRegistryEnabled: boolean; - rulesClient: RulesClient; -}): Promise => { - const tags = await readRawTags({ isRuleRegistryEnabled, rulesClient }); - return tags.filter((tag) => !tag.startsWith(INTERNAL_IDENTIFIER)); -}; - -export const readRawTags = async ({ - isRuleRegistryEnabled, - rulesClient, -}: { - isRuleRegistryEnabled: boolean; rulesClient: RulesClient; perPage?: number; }): Promise => { // Get just one record so we can get the total count const firstTags = await findRules({ - isRuleRegistryEnabled, rulesClient, fields: ['tags'], perPage: 1, @@ -71,7 +56,6 @@ export const readRawTags = async ({ }); // Get all the rules to aggregate over all the tags of the rules const rules = await findRules({ - isRuleRegistryEnabled, rulesClient, fields: ['tags'], perPage: firstTags.total, diff --git a/x-pack/plugins/security_solution/server/lib/sourcerer/routes/index.test.ts b/x-pack/plugins/security_solution/server/lib/sourcerer/routes/index.test.ts index 08523d2e03340..232aba9d1ae3a 100644 --- a/x-pack/plugins/security_solution/server/lib/sourcerer/routes/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/sourcerer/routes/index.test.ts @@ -137,7 +137,10 @@ describe('sourcerer route', () => { }); test('returns sourcerer formatted Data Views when SIEM Data View does NOT exist', async () => { createSourcererDataViewRoute(server.router, getStartServicesNotSiem); - const response = await server.inject(getSourcererRequest(mockPatternList), context); + const response = await server.inject( + getSourcererRequest(mockPatternList), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual(mockDataViewsTransformed); }); @@ -163,7 +166,10 @@ describe('sourcerer route', () => { }, ] as unknown) as StartServicesAccessor; createSourcererDataViewRoute(server.router, getStartServicesSpecial); - const response = await server.inject(getSourcererRequest(mockPatternList), context); + const response = await server.inject( + getSourcererRequest(mockPatternList), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual(mockDataViewsTransformed); }); @@ -192,14 +198,20 @@ describe('sourcerer route', () => { }, ] as unknown) as StartServicesAccessor; createSourcererDataViewRoute(server.router, getStartServicesSpecial); - await server.inject(getSourcererRequest(mockPatternList), context); + await server.inject( + getSourcererRequest(mockPatternList), + requestContextMock.convertContext(context) + ); expect(mockCreateAndSave).toHaveBeenCalled(); expect(mockCreateAndSave.mock.calls[0][1]).toEqual(true); }); test('returns sourcerer formatted Data Views when SIEM Data View exists', async () => { createSourcererDataViewRoute(server.router, getStartServices); - const response = await server.inject(getSourcererRequest(mockPatternList), context); + const response = await server.inject( + getSourcererRequest(mockPatternList), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual(mockDataViewsTransformed); }); @@ -207,7 +219,10 @@ describe('sourcerer route', () => { test('returns sourcerer formatted Data Views when SIEM Data View exists and patternList input is changed', async () => { createSourcererDataViewRoute(server.router, getStartServices); mockPatternList.shift(); - const response = await server.inject(getSourcererRequest(mockPatternList), context); + const response = await server.inject( + getSourcererRequest(mockPatternList), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual({ defaultDataView: { diff --git a/x-pack/plugins/security_solution/server/lib/sourcerer/routes/index.ts b/x-pack/plugins/security_solution/server/lib/sourcerer/routes/index.ts index 4ce0f7be20956..bf69ed03fb79a 100644 --- a/x-pack/plugins/security_solution/server/lib/sourcerer/routes/index.ts +++ b/x-pack/plugins/security_solution/server/lib/sourcerer/routes/index.ts @@ -34,7 +34,8 @@ export const createSourcererDataViewRoute = ( }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); - const siemClient = context.securitySolution?.getAppClient(); + const coreContext = await context.core; + const siemClient = (await context.securitySolution)?.getAppClient(); const dataViewId = siemClient.getSourcererDataViewId(); try { @@ -46,8 +47,8 @@ export const createSourcererDataViewRoute = ( ] = await getStartServices(); const dataViewService = await indexPatterns.dataViewsServiceFactory( - context.core.savedObjects.client, - context.core.elasticsearch.client.asCurrentUser, + coreContext.savedObjects.client, + coreContext.elasticsearch.client.asCurrentUser, request, true ); @@ -103,7 +104,7 @@ export const createSourcererDataViewRoute = ( const defaultDataView = await buildSourcererDataView( siemDataView, - context.core.elasticsearch.client.asCurrentUser + coreContext.elasticsearch.client.asCurrentUser ); return response.ok({ body: { @@ -143,6 +144,7 @@ export const getSourcererDataViewRoute = ( }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); + const coreContext = await context.core; const { dataViewId } = request.query; try { const [ @@ -153,8 +155,8 @@ export const getSourcererDataViewRoute = ( ] = await getStartServices(); const dataViewService = await indexPatterns.dataViewsServiceFactory( - context.core.savedObjects.client, - context.core.elasticsearch.client.asCurrentUser, + coreContext.savedObjects.client, + coreContext.elasticsearch.client.asCurrentUser, request, true ); @@ -163,7 +165,7 @@ export const getSourcererDataViewRoute = ( const kibanaDataView = siemDataView ? await buildSourcererDataView( siemDataView, - context.core.elasticsearch.client.asCurrentUser + coreContext.elasticsearch.client.asCurrentUser ) : {}; diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/draft_timelines/clean_draft_timelines/index.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/draft_timelines/clean_draft_timelines/index.test.ts index 3d66a6507a67b..1a62b7604bfd7 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/draft_timelines/clean_draft_timelines/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/draft_timelines/clean_draft_timelines/index.test.ts @@ -82,7 +82,10 @@ describe('clean draft timelines', () => { timeline: [], }); - const response = await server.inject(cleanDraftTimelinesRequest(TimelineType.default), context); + const response = await server.inject( + cleanDraftTimelinesRequest(TimelineType.default), + requestContextMock.convertContext(context) + ); const req = cleanDraftTimelinesRequest(TimelineType.default); expect(mockPersistTimeline).toHaveBeenCalled(); expect(mockPersistTimeline.mock.calls[0][3]).toEqual({ @@ -106,7 +109,10 @@ describe('clean draft timelines', () => { mockResetTimeline.mockResolvedValue({}); mockGetTimeline.mockResolvedValue({ ...mockGetDraftTimelineValue }); - const response = await server.inject(cleanDraftTimelinesRequest(TimelineType.default), context); + const response = await server.inject( + cleanDraftTimelinesRequest(TimelineType.default), + requestContextMock.convertContext(context) + ); const req = cleanDraftTimelinesRequest(TimelineType.default); expect(mockPersistTimeline).not.toHaveBeenCalled(); diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/draft_timelines/get_draft_timelines/index.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/draft_timelines/get_draft_timelines/index.test.ts index 1911f964af4b1..cb488ef7d84ac 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/draft_timelines/get_draft_timelines/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/draft_timelines/get_draft_timelines/index.test.ts @@ -83,7 +83,7 @@ describe('get draft timelines', () => { timeline: [], }); const req = getDraftTimelinesRequest(TimelineType.default); - const response = await server.inject(req, context); + const response = await server.inject(req, requestContextMock.convertContext(context)); expect(mockPersistTimeline).toHaveBeenCalled(); expect(mockPersistTimeline.mock.calls[0][3]).toEqual({ ...draftTimelineDefaults, @@ -107,7 +107,7 @@ describe('get draft timelines', () => { const response = await server.inject( getDraftTimelinesRequest(TimelineType.default), - context + requestContextMock.convertContext(context) ); expect(mockPersistTimeline).not.toHaveBeenCalled(); expect(response.status).toEqual(200); diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/prepackaged_timelines/install_prepackaged_timelines/helpers.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/prepackaged_timelines/install_prepackaged_timelines/helpers.test.ts index 63e8d9afea9d8..4f0690cc288e6 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/prepackaged_timelines/install_prepackaged_timelines/helpers.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/prepackaged_timelines/install_prepackaged_timelines/helpers.test.ts @@ -26,10 +26,7 @@ import { ImportTimelineResultSchema } from '../../../../../../common/types/timel jest.mock('../../timelines/import_timelines/helpers'); -describe.each([ - ['Legacy', false], - ['RAC', true], -])('installPrepackagedTimelines - %s', (_, isRuleRegistryEnabled) => { +describe('installPrepackagedTimelines', () => { let securitySetup: SecurityPluginSetup; let frameworkRequest: FrameworkRequest; const spyInstallPrepackagedTimelines = jest.spyOn(helpers, 'installPrepackagedTimelines'); @@ -47,7 +44,7 @@ describe.each([ authz: {}, } as unknown as SecurityPluginSetup; - clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); + clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); jest.doMock('./helpers', () => { return { @@ -57,7 +54,11 @@ describe.each([ }); const request = addPrepackagedRulesRequest(); - frameworkRequest = await buildFrameworkRequest(context, securitySetup, request); + frameworkRequest = await buildFrameworkRequest( + requestContextMock.convertContext(context), + securitySetup, + request + ); }); afterEach(() => { diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/prepackaged_timelines/install_prepackaged_timelines/index.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/prepackaged_timelines/install_prepackaged_timelines/index.test.ts index 55f4a06326fe1..34a26b977e38e 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/prepackaged_timelines/install_prepackaged_timelines/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/prepackaged_timelines/install_prepackaged_timelines/index.test.ts @@ -64,7 +64,10 @@ describe('installPrepackagedTimelines', () => { mockCheckTimelinesStatusBeforeInstallResult ); - await server.inject(installPrepackedTimelinesRequest(), context); + await server.inject( + installPrepackedTimelinesRequest(), + requestContextMock.convertContext(context) + ); expect(installPrepackagedTimelines).toHaveBeenCalled(); }); @@ -81,7 +84,10 @@ describe('installPrepackagedTimelines', () => { timelines_updated: 0, }); - const result = await server.inject(installPrepackedTimelinesRequest(), context); + const result = await server.inject( + installPrepackedTimelinesRequest(), + requestContextMock.convertContext(context) + ); expect(result.body).toEqual({ errors: [], @@ -95,7 +101,10 @@ describe('installPrepackagedTimelines', () => { test('should not call installPrepackagedTimelines if it has nothing to install or update', async () => { (checkTimelinesStatus as jest.Mock).mockReturnValue(mockCheckTimelinesStatusAfterInstallResult); - await server.inject(installPrepackedTimelinesRequest(), context); + await server.inject( + installPrepackedTimelinesRequest(), + requestContextMock.convertContext(context) + ); expect(installPrepackagedTimelines).not.toHaveBeenCalled(); }); @@ -103,7 +112,10 @@ describe('installPrepackagedTimelines', () => { test('should return success if it has nothing to install or update', async () => { (checkTimelinesStatus as jest.Mock).mockReturnValue(mockCheckTimelinesStatusAfterInstallResult); - const result = await server.inject(installPrepackedTimelinesRequest(), context); + const result = await server.inject( + installPrepackedTimelinesRequest(), + requestContextMock.convertContext(context) + ); expect(result.body).toEqual({ errors: [], diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/helpers.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/helpers.test.ts index 0270d525ae779..be97cbd01e428 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/helpers.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/helpers.test.ts @@ -69,7 +69,11 @@ describe('createTimelines', () => { const { context } = requestContextMock.createTools(); const mockRequest = getCreateTimelinesRequest(createTimelineWithoutTimelineId); - frameworkRequest = await buildFrameworkRequest(context, securitySetup, mockRequest); + frameworkRequest = await buildFrameworkRequest( + requestContextMock.convertContext(context), + securitySetup, + mockRequest + ); Date.now = jest.fn().mockReturnValue(new Date('2020-11-04T11:37:31.655Z')); }); diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/index.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/index.test.ts index 5e066e419c4bb..9de715751ca7f 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/index.test.ts @@ -93,7 +93,7 @@ describe('create timelines', () => { createTimelinesRoute(server.router, createMockConfig(), securitySetup); const mockRequest = getCreateTimelinesRequest(createTimelineWithoutTimelineId); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); }); test('should Create a new timeline savedObject', async () => { @@ -123,7 +123,7 @@ describe('create timelines', () => { test('returns 200 when create timeline successfully', async () => { const response = await server.inject( getCreateTimelinesRequest(createTimelineWithoutTimelineId), - context + requestContextMock.convertContext(context) ); expect(response.status).toEqual(200); }); @@ -157,7 +157,7 @@ describe('create timelines', () => { test('returns error message', async () => { const response = await server.inject( getCreateTimelinesRequest(createTimelineWithTimelineId), - context + requestContextMock.convertContext(context) ); expect(response.body).toEqual({ message: CREATE_TIMELINE_ERROR_MESSAGE, @@ -195,7 +195,7 @@ describe('create timelines', () => { createTimelinesRoute(server.router, createMockConfig(), securitySetup); const mockRequest = getCreateTimelinesRequest(createTemplateTimelineWithoutTimelineId); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); }); test('should Create a new timeline template savedObject', async () => { @@ -227,7 +227,7 @@ describe('create timelines', () => { test('returns 200 when create timeline successfully', async () => { const response = await server.inject( getCreateTimelinesRequest(createTimelineWithoutTimelineId), - context + requestContextMock.convertContext(context) ); expect(response.status).toEqual(200); }); @@ -264,7 +264,7 @@ describe('create timelines', () => { test('returns error message', async () => { const response = await server.inject( getCreateTimelinesRequest(updateTemplateTimelineWithTimelineId), - context + requestContextMock.convertContext(context) ); expect(response.body).toEqual({ message: CREATE_TEMPLATE_TIMELINE_ERROR_MESSAGE, diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/export_timelines/index.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/export_timelines/index.test.ts index d117d3d0c1b47..cfd61beb4b174 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/export_timelines/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/export_timelines/index.test.ts @@ -71,14 +71,20 @@ describe('export timelines', () => { describe('status codes', () => { test('returns 200 when finding selected timelines', async () => { - const response = await server.inject(getExportTimelinesRequest(), context); + const response = await server.inject( + getExportTimelinesRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('catch error when status search throws error', async () => { clients.savedObjectsClient.bulkGet.mockReset(); clients.savedObjectsClient.bulkGet.mockRejectedValue(new Error('Test error')); - const response = await server.inject(getExportTimelinesRequest(), context); + const response = await server.inject( + getExportTimelinesRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/get_timeline/index.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/get_timeline/index.test.ts index 609b26f89be5c..c5c8ab6bfb7f2 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/get_timeline/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/get_timeline/index.test.ts @@ -49,7 +49,10 @@ describe('get timeline', () => { test('should call getTimelineTemplateOrNull if templateTimelineId is given', async () => { const templateTimelineId = '123'; - await server.inject(getTimelineRequest({ template_timeline_id: templateTimelineId }), context); + await server.inject( + getTimelineRequest({ template_timeline_id: templateTimelineId }), + requestContextMock.convertContext(context) + ); expect((getTimelineTemplateOrNull as jest.Mock).mock.calls[0][1]).toEqual(templateTimelineId); }); @@ -57,13 +60,16 @@ describe('get timeline', () => { test('should call getTimelineOrNull if id is given', async () => { const id = '456'; - await server.inject(getTimelineRequest({ id }), context); + await server.inject(getTimelineRequest({ id }), requestContextMock.convertContext(context)); expect((getTimelineOrNull as jest.Mock).mock.calls[0][1]).toEqual(id); }); test('should throw error message if nither templateTimelineId nor id is given', async () => { - const res = await server.inject(getTimelineRequest(), context); + const res = await server.inject( + getTimelineRequest(), + requestContextMock.convertContext(context) + ); expect(res.body.message).toEqual('please provide id or template_timeline_id'); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/get_timelines/index.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/get_timelines/index.test.ts index 0298a3f869bd4..208b804f222dc 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/get_timelines/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/get_timelines/index.test.ts @@ -46,13 +46,13 @@ describe('get all timelines', () => { }); test('should get the total count', async () => { - await server.inject(getTimelineRequest(), context); + await server.inject(getTimelineRequest(), requestContextMock.convertContext(context)); expect((getAllTimeline as jest.Mock).mock.calls[0][2]).toEqual({ pageSize: 1, pageIndex: 1 }); }); test('should get all timelines with total count', async () => { (getAllTimeline as jest.Mock).mockResolvedValue({ totalCount: 100 }); - await server.inject(getTimelineRequest(), context); + await server.inject(getTimelineRequest(), requestContextMock.convertContext(context)); expect((getAllTimeline as jest.Mock).mock.calls[1][2]).toEqual({ pageSize: 100, pageIndex: 1 }); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/import_timelines/index.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/import_timelines/index.test.ts index d92d82ea82fc2..9148c8f5441d1 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/import_timelines/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/import_timelines/index.test.ts @@ -158,31 +158,31 @@ describe('import timelines', () => { test('should use given timelineId to check if the timeline savedObject already exist', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockGetTimeline.mock.calls[0][1]).toEqual(mockUniqueParsedObjects[0].savedObjectId); }); test('should Create a new timeline savedObject', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline).toHaveBeenCalled(); }); test('should Create a new timeline savedObject without timelineId', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline.mock.calls[0][1]).toBeNull(); }); test('should Create a new timeline savedObject without timeline version', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline.mock.calls[0][2]).toBeNull(); }); test('should Create a new timeline savedObject with given timeline', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline.mock.calls[0][3]).toEqual({ ...mockParsedTimelineObject, status: TimelineStatus.active, @@ -202,7 +202,7 @@ describe('import timelines', () => { ], ]); const mockRequest = await getImportTimelinesRequest(); - const response = await server.inject(mockRequest, context); + const response = await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(response.body).toEqual({ success: false, success_count: 0, @@ -222,13 +222,13 @@ describe('import timelines', () => { test('should Create new pinned events', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistPinnedEventOnTimeline).toHaveBeenCalled(); }); test('should Create a new pinned event with new timeline id', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistPinnedEventOnTimeline.mock.calls[0][1]).toEqual( mockCreatedTimeline.savedObjectId ); @@ -236,7 +236,7 @@ describe('import timelines', () => { test('should Create a new pinned event with pinnedEventId', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistPinnedEventOnTimeline.mock.calls[0][2]).toEqual( mockUniqueParsedObjects[0].pinnedEventIds ); @@ -244,7 +244,7 @@ describe('import timelines', () => { test('should Check if note exists', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockGetNote.mock.calls[0][1]).toEqual( mockUniqueParsedObjects[0].globalNotes[0].noteId ); @@ -252,19 +252,19 @@ describe('import timelines', () => { test('should Create notes', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistNote).toHaveBeenCalled(); }); test('should provide no noteSavedObjectId when Creating notes for a timeline', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistNote.mock.calls[0][0].noteId).toBeNull(); }); test('should provide new notes with original author info when Creating notes for a timeline', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistNote.mock.calls[0][0].note).toEqual({ eventId: undefined, note: 'original note', @@ -299,7 +299,7 @@ describe('import timelines', () => { mockGetNote.mockRejectedValue(new Error()); const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistNote.mock.calls[0][0].note).toEqual({ created: mockUniqueParsedObjects[0].globalNotes[0].created, createdBy: mockUniqueParsedObjects[0].globalNotes[0].createdBy, @@ -331,7 +331,7 @@ describe('import timelines', () => { test('returns 200 when import timeline successfully', async () => { const mockRequest = await getImportTimelinesRequest(); - const response = await server.inject(mockRequest, context); + const response = await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); }); }); @@ -364,7 +364,7 @@ describe('import timelines', () => { test('returns error message', async () => { const mockRequest = await getImportTimelinesRequest(); - const response = await server.inject(mockRequest, context); + const response = await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(response.body).toEqual({ success: false, success_count: 0, @@ -393,7 +393,7 @@ describe('import timelines', () => { ], ]); const mockRequest = await getImportTimelinesRequest(); - const response = await server.inject(mockRequest, context); + const response = await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(response.body).toEqual({ success: false, success_count: 0, @@ -422,7 +422,7 @@ describe('import timelines', () => { ], ]); const mockRequest = await getImportTimelinesRequest(); - const response = await server.inject(mockRequest, context); + const response = await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(response.body).toEqual({ success: false, success_count: 0, @@ -582,7 +582,7 @@ describe('import timeline templates', () => { test('should use given timelineId to check if the timeline savedObject already exist', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockGetTimeline.mock.calls[0][1]).toEqual( mockUniqueParsedTemplateTimelineObjects[0].savedObjectId ); @@ -590,7 +590,7 @@ describe('import timeline templates', () => { test('should use given templateTimelineId to check if the timeline savedObject already exist', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockGetTemplateTimeline.mock.calls[0][1]).toEqual( mockUniqueParsedTemplateTimelineObjects[0].templateTimelineId ); @@ -598,25 +598,25 @@ describe('import timeline templates', () => { test('should Create a new timeline savedObject', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline).toHaveBeenCalled(); }); test('should Create a new timeline savedObject without timelineId', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline.mock.calls[0][1]).toBeNull(); }); test('should Create a new timeline savedObject without timeline version', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline.mock.calls[0][2]).toBeNull(); }); test('should Create a new timeline savedObject witn given timeline and skip the omitted fields', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline.mock.calls[0][3]).toEqual({ ...mockParsedTemplateTimelineObject, status: TimelineStatus.active, @@ -625,19 +625,19 @@ describe('import timeline templates', () => { test('should NOT Create new pinned events', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistPinnedEventOnTimeline).not.toHaveBeenCalled(); }); test('should provide no noteSavedObjectId when Creating notes for a timeline', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistNote.mock.calls[0][0].noteId).toBeNull(); }); test('should exclude event notes when creating notes', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistNote.mock.calls[0][0].note).toEqual({ eventId: undefined, note: mockUniqueParsedTemplateTimelineObjects[0].globalNotes[0].note, @@ -651,7 +651,7 @@ describe('import timeline templates', () => { test('returns 200 when import timeline successfully', async () => { const mockRequest = await getImportTimelinesRequest(); - const response = await server.inject(mockRequest, context); + const response = await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); }); @@ -666,7 +666,7 @@ describe('import timeline templates', () => { ], ]); const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline.mock.calls[0][3].templateTimelineId).toEqual( mockNewTemplateTimelineId ); @@ -684,7 +684,7 @@ describe('import timeline templates', () => { ], ]); const mockRequest = await getImportTimelinesRequest(); - const result = await server.inject(mockRequest, context); + const result = await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(result.body).toEqual({ errors: [], success: true, @@ -727,7 +727,7 @@ describe('import timeline templates', () => { test('should use given timelineId to check if the timeline savedObject already exist', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockGetTimeline.mock.calls[0][1]).toEqual( mockUniqueParsedTemplateTimelineObjects[0].savedObjectId ); @@ -735,7 +735,7 @@ describe('import timeline templates', () => { test('should use given templateTimelineId to check if the timeline savedObject already exist', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockGetTemplateTimeline.mock.calls[0][1]).toEqual( mockUniqueParsedTemplateTimelineObjects[0].templateTimelineId ); @@ -743,13 +743,13 @@ describe('import timeline templates', () => { test('should UPDATE timeline savedObject', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline).toHaveBeenCalled(); }); test('should UPDATE timeline savedObject with timelineId', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline.mock.calls[0][1]).toEqual( mockUniqueParsedTemplateTimelineObjects[0].savedObjectId ); @@ -757,7 +757,7 @@ describe('import timeline templates', () => { test('should UPDATE timeline savedObject without timeline version', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline.mock.calls[0][2]).toEqual( mockUniqueParsedTemplateTimelineObjects[0].version ); @@ -765,25 +765,25 @@ describe('import timeline templates', () => { test('should UPDATE a new timeline savedObject witn given timeline and skip the omitted fields', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline.mock.calls[0][3]).toEqual(mockParsedTemplateTimelineObject); }); test('should NOT Create new pinned events', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistPinnedEventOnTimeline).not.toHaveBeenCalled(); }); test('should provide noteSavedObjectId when Creating notes for a timeline', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistNote.mock.calls[0][0].noteId).toBeNull(); }); test('should exclude event notes when creating notes', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistNote.mock.calls[0][0].note).toEqual({ eventId: undefined, note: mockUniqueParsedTemplateTimelineObjects[0].globalNotes[0].note, @@ -797,7 +797,7 @@ describe('import timeline templates', () => { test('returns 200 when import timeline successfully', async () => { const mockRequest = await getImportTimelinesRequest(); - const response = await server.inject(mockRequest, context); + const response = await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); }); @@ -812,7 +812,7 @@ describe('import timeline templates', () => { ], ]); const mockRequest = await getImportTimelinesRequest(); - const response = await server.inject(mockRequest, context); + const response = await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(response.body).toEqual({ success: false, success_count: 0, @@ -841,7 +841,7 @@ describe('import timeline templates', () => { ], ]); const mockRequest = await getImportTimelinesRequest(); - const response = await server.inject(mockRequest, context); + const response = await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(response.body).toEqual({ success: false, success_count: 0, diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/import_timelines/index.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/import_timelines/index.ts index c06d99adf04d0..4336c9fd93418 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/import_timelines/index.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/import_timelines/index.ts @@ -46,7 +46,7 @@ export const importTimelinesRoute = ( async (context, request, response) => { try { const siemResponse = buildSiemResponse(response); - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; if (!savedObjectsClient) { return siemResponse.error({ statusCode: 404 }); } diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/patch_timelines/index.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/patch_timelines/index.test.ts index ca3482591407a..1c7ab73cc3809 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/patch_timelines/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/patch_timelines/index.test.ts @@ -90,7 +90,7 @@ describe('update timelines', () => { patchTimelinesRoute(server.router, createMockConfig(), securitySetup); const mockRequest = getUpdateTimelinesRequest(updateTimelineWithTimelineId); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); }); test('should Check if given timeline id exist', async () => { @@ -122,7 +122,7 @@ describe('update timelines', () => { test('returns 200 when create timeline successfully', async () => { const response = await server.inject( getUpdateTimelinesRequest(updateTimelineWithTimelineId), - context + requestContextMock.convertContext(context) ); expect(response.status).toEqual(200); }); @@ -157,7 +157,7 @@ describe('update timelines', () => { test('returns error message', async () => { const response = await server.inject( getUpdateTimelinesRequest(updateTimelineWithTimelineId), - context + requestContextMock.convertContext(context) ); expect(response.body).toEqual({ message: UPDATE_TIMELINE_ERROR_MESSAGE, @@ -198,7 +198,7 @@ describe('update timelines', () => { patchTimelinesRoute(server.router, createMockConfig(), securitySetup); const mockRequest = getUpdateTimelinesRequest(updateTemplateTimelineWithTimelineId); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); }); test('should Check if given timeline id exist', async () => { @@ -242,7 +242,7 @@ describe('update timelines', () => { test('returns 200 when create timeline template successfully', async () => { const response = await server.inject( getUpdateTimelinesRequest(updateTemplateTimelineWithTimelineId), - context + requestContextMock.convertContext(context) ); expect(response.status).toEqual(200); }); @@ -277,7 +277,7 @@ describe('update timelines', () => { test('returns error message', async () => { const response = await server.inject( getUpdateTimelinesRequest(updateTemplateTimelineWithTimelineId), - context + requestContextMock.convertContext(context) ); expect(response.body).toEqual({ message: UPDATE_TEMPLATE_TIMELINE_ERROR_MESSAGE, diff --git a/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/saved_object.ts b/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/saved_object.ts index ecf7b04bc1b1b..64820711d6685 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/saved_object.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/saved_object.ts @@ -34,7 +34,7 @@ import { timelineSavedObjectType } from '../../saved_object_mappings'; import { noteFieldsMigrator } from './field_migrator'; export const deleteNote = async (request: FrameworkRequest, noteIds: string[]) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; await Promise.all( noteIds.map((noteId) => savedObjectsClient.delete(noteSavedObjectType, noteId)) @@ -47,7 +47,7 @@ export const deleteNoteByTimelineId = async (request: FrameworkRequest, timeline hasReference: { type: timelineSavedObjectType, id: timelineId }, }; const notesToBeDeleted = await getAllSavedNote(request, options); - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; await Promise.all( notesToBeDeleted.notes.map((note) => @@ -159,7 +159,7 @@ const createNote = async ({ note: SavedNote; overrideOwner?: boolean; }) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const userInfo = request.user; const shallowCopyOfNote = { ...note }; @@ -217,7 +217,7 @@ const updateNote = async ({ note: SavedNote; overrideOwner?: boolean; }) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const userInfo = request.user; const existingNote = await savedObjectsClient.get( @@ -258,7 +258,7 @@ const updateNote = async ({ }; const getSavedNote = async (request: FrameworkRequest, NoteId: string) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const savedObject = await savedObjectsClient.get( noteSavedObjectType, NoteId @@ -270,7 +270,7 @@ const getSavedNote = async (request: FrameworkRequest, NoteId: string) => { }; const getAllSavedNote = async (request: FrameworkRequest, options: SavedObjectsFindOptions) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const savedObjects = await savedObjectsClient.find(options); return { diff --git a/x-pack/plugins/security_solution/server/lib/timeline/saved_object/pinned_events/index.ts b/x-pack/plugins/security_solution/server/lib/timeline/saved_object/pinned_events/index.ts index 3253deb0194c6..59d83ee93e5a2 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/saved_object/pinned_events/index.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/saved_object/pinned_events/index.ts @@ -70,7 +70,7 @@ export const deletePinnedEventOnTimeline = async ( request: FrameworkRequest, pinnedEventIds: string[] ) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; await Promise.all( pinnedEventIds.map((pinnedEventId) => @@ -83,7 +83,7 @@ export const deleteAllPinnedEventsOnTimeline = async ( request: FrameworkRequest, timelineId: string ) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const options: SavedObjectsFindOptions = { type: pinnedEventSavedObjectType, search: timelineId, @@ -186,7 +186,7 @@ const getValidTimelineIdAndVersion = async ( }; } - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; // create timeline because it didn't exist const { timeline: timelineResult } = await createTimeline({ @@ -224,7 +224,7 @@ const createPinnedEvent = async ({ timelineId: string; timelineVersion?: string; }) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const savedPinnedEvent: SavedPinnedEvent = { eventId, @@ -252,7 +252,7 @@ const createPinnedEvent = async ({ }; const getSavedPinnedEvent = async (request: FrameworkRequest, pinnedEventId: string) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const savedObject = await savedObjectsClient.get( pinnedEventSavedObjectType, pinnedEventId @@ -267,7 +267,7 @@ const getAllSavedPinnedEvents = async ( request: FrameworkRequest, options: SavedObjectsFindOptions ) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const savedObjects = await savedObjectsClient.find(options); return savedObjects.saved_objects.map((savedObject) => { diff --git a/x-pack/plugins/security_solution/server/lib/timeline/saved_object/timelines/index.ts b/x-pack/plugins/security_solution/server/lib/timeline/saved_object/timelines/index.ts index 2c573d72dd6e4..de7c31fb47a98 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/saved_object/timelines/index.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/saved_object/timelines/index.ts @@ -380,7 +380,7 @@ export const persistTimeline = async ( timeline: SavedTimeline, isImmutable?: boolean ): Promise => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const userInfo = isImmutable ? ({ username: 'Elastic' } as AuthenticatedUser) : request.user; try { if (timelineId == null) { @@ -498,7 +498,7 @@ const updatePartialSavedTimeline = async ( timelineId: string, timeline: SavedTimeline ) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const currentSavedTimeline = await savedObjectsClient.get( timelineSavedObjectType, timelineId @@ -563,7 +563,7 @@ export const resetTimeline = async ( }; export const deleteTimeline = async (request: FrameworkRequest, timelineIds: string[]) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; await Promise.all( timelineIds.map((timelineId) => @@ -577,7 +577,7 @@ export const deleteTimeline = async (request: FrameworkRequest, timelineIds: str }; const resolveBasicSavedTimeline = async (request: FrameworkRequest, timelineId: string) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const { saved_object: savedObject, ...resolveAttributes } = await savedObjectsClient.resolve( timelineSavedObjectType, @@ -615,7 +615,7 @@ const resolveSavedTimeline = async (request: FrameworkRequest, timelineId: strin }; const getBasicSavedTimeline = async (request: FrameworkRequest, timelineId: string) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const savedObject = await savedObjectsClient.get( timelineSavedObjectType, timelineId @@ -644,7 +644,7 @@ const getSavedTimeline = async (request: FrameworkRequest, timelineId: string) = const getAllSavedTimeline = async (request: FrameworkRequest, options: SavedObjectsFindOptions) => { const userName = request.user?.username ?? UNAUTHENTICATED_USER; - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const savedObjects = await savedObjectsClient.find(options); @@ -693,7 +693,7 @@ export const getSelectedTimelines = async ( request: FrameworkRequest, timelineIds?: string[] | null ) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; let exportedIds = timelineIds; if (timelineIds == null || timelineIds.length === 0) { const { timeline: savedAllTimelines } = await getAllTimeline( diff --git a/x-pack/plugins/security_solution/server/lib/timeline/utils/common.ts b/x-pack/plugins/security_solution/server/lib/timeline/utils/common.ts index 958a5bf061711..f05366264ece6 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/utils/common.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/utils/common.ts @@ -23,7 +23,7 @@ export const buildFrameworkRequest = async ( security: StartPlugins['security'] | SetupPlugins['security'] | undefined, request: KibanaRequest ): Promise => { - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; const user = await security?.authc.getCurrentUser(request); return set( diff --git a/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/blocklist_validator.ts b/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/blocklist_validator.ts index 45d080ab956ee..5510f352a414e 100644 --- a/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/blocklist_validator.ts +++ b/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/blocklist_validator.ts @@ -16,7 +16,7 @@ import { } from '@kbn/lists-plugin/server'; import { BaseValidator } from './base_validator'; import { ExceptionItemLikeOptions } from '../types'; -import { isValidHash } from '../../../../common/endpoint/service/trusted_apps/validations'; +import { isValidHash } from '../../../../common/endpoint/service/artifacts/validations'; import { EndpointArtifactExceptionValidationError } from './errors'; const allowedHashes: Readonly = ['file.hash.md5', 'file.hash.sha1', 'file.hash.sha256']; diff --git a/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/trusted_app_validator.ts b/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/trusted_app_validator.ts index b83e536cdee1e..af98ba7076535 100644 --- a/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/trusted_app_validator.ts +++ b/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/trusted_app_validator.ts @@ -19,7 +19,7 @@ import { TrustedAppConditionEntry as ConditionEntry } from '../../../../common/e import { getDuplicateFields, isValidHash, -} from '../../../../common/endpoint/service/trusted_apps/validations'; +} from '../../../../common/endpoint/service/artifacts/validations'; import { EndpointArtifactExceptionValidationError } from './errors'; const ProcessHashField = schema.oneOf([ diff --git a/x-pack/plugins/security_solution/server/plugin.ts b/x-pack/plugins/security_solution/server/plugin.ts index a313a0b86a246..cbf2a596e962d 100644 --- a/x-pack/plugins/security_solution/server/plugin.ts +++ b/x-pack/plugins/security_solution/server/plugin.ts @@ -8,7 +8,6 @@ import { Observable } from 'rxjs'; import LRU from 'lru-cache'; import { - SIGNALS_ID, QUERY_RULE_TYPE_ID, INDICATOR_RULE_TYPE_ID, ML_RULE_TYPE_ID, @@ -177,9 +176,6 @@ export class Plugin implements ISecuritySolutionPlugin { this.telemetryUsageCounter = plugins.usageCollection?.createUsageCounter(APP_ID); - // TODO: Once we are past experimental phase this check can be removed along with legacy registration of rules - const isRuleRegistryEnabled = experimentalFeatures.ruleRegistryEnabled; - const { ruleDataService } = plugins.ruleRegistry; let ruleDataClient: IRuleDataClient | null = null; let previewRuleDataClient: IRuleDataClient | null = null; @@ -271,7 +267,8 @@ export class Plugin implements ISecuritySolutionPlugin { registerPolicyRoutes(router, endpointContext); registerActionRoutes(router, endpointContext); - const racRuleTypes = [ + const ruleTypes = [ + LEGACY_NOTIFICATIONS_ID, EQL_RULE_TYPE_ID, INDICATOR_RULE_TYPE_ID, ML_RULE_TYPE_ID, @@ -279,11 +276,6 @@ export class Plugin implements ISecuritySolutionPlugin { SAVED_QUERY_RULE_TYPE_ID, THRESHOLD_RULE_TYPE_ID, ]; - const ruleTypes = [ - SIGNALS_ID, - LEGACY_NOTIFICATIONS_ID, - ...(isRuleRegistryEnabled ? racRuleTypes : []), - ]; plugins.features.registerKibanaFeature(getKibanaPrivilegesFeaturePrivileges(ruleTypes)); plugins.features.registerKibanaFeature(getCasesKibanaFeature()); diff --git a/x-pack/plugins/security_solution/server/request_context_factory.ts b/x-pack/plugins/security_solution/server/request_context_factory.ts index b0fe00485e2ad..9f6b950c46202 100644 --- a/x-pack/plugins/security_solution/server/request_context_factory.ts +++ b/x-pack/plugins/security_solution/server/request_context_factory.ts @@ -72,11 +72,14 @@ export class RequestContextFactory implements IRequestContextFactory { // If Fleet is enabled, then get its Authz if (startPlugins.fleet) { - fleetAuthz = context.fleet?.authz ?? (await startPlugins.fleet?.authz.fromRequest(request)); + fleetAuthz = + (await context.fleet)?.authz ?? (await startPlugins.fleet?.authz.fromRequest(request)); } + const coreContext = await context.core; + return { - core: context.core, + core: coreContext, get endpointAuthz(): Immutable { // Lazy getter of endpoint Authz. No point in defining it if it is never used. @@ -105,7 +108,7 @@ export class RequestContextFactory implements IRequestContextFactory { getRuleExecutionLog: memoize(() => ruleExecutionLogForRoutesFactory( - context.core.savedObjects.client, + coreContext.savedObjects.client, startPlugins.eventLog.getClient(request), logger ) @@ -117,7 +120,7 @@ export class RequestContextFactory implements IRequestContextFactory { } const username = security?.authc.getCurrentUser(request)?.username || 'elastic'; - return lists.getExceptionListClient(context.core.savedObjects.client, username); + return lists.getExceptionListClient(coreContext.savedObjects.client, username); }, }; } diff --git a/x-pack/plugins/security_solution/server/routes/index.ts b/x-pack/plugins/security_solution/server/routes/index.ts index fe093b0b31ee3..8763f2d00669e 100644 --- a/x-pack/plugins/security_solution/server/routes/index.ts +++ b/x-pack/plugins/security_solution/server/routes/index.ts @@ -86,15 +86,14 @@ export const initRoutes = ( previewRuleDataClient: IRuleDataClient, previewTelemetryReceiver: ITelemetryReceiver ) => { - const isRuleRegistryEnabled = ruleDataClient != null; // Detection Engine Rule routes that have the REST endpoints of /api/detection_engine/rules // All REST rule creation, deletion, updating, etc - createRulesRoute(router, ml, isRuleRegistryEnabled); - readRulesRoute(router, logger, isRuleRegistryEnabled); - updateRulesRoute(router, ml, isRuleRegistryEnabled); - patchRulesRoute(router, ml, isRuleRegistryEnabled); - deleteRulesRoute(router, isRuleRegistryEnabled); - findRulesRoute(router, logger, isRuleRegistryEnabled); + createRulesRoute(router, ml); + readRulesRoute(router, logger); + updateRulesRoute(router, ml); + patchRulesRoute(router, ml); + deleteRulesRoute(router); + findRulesRoute(router, logger); previewRulesRoute( router, config, @@ -110,19 +109,19 @@ export const initRoutes = ( legacyCreateLegacyNotificationRoute(router, logger); addPrepackedRulesRoute(router); - getPrepackagedRulesStatusRoute(router, config, security, isRuleRegistryEnabled); - createRulesBulkRoute(router, ml, isRuleRegistryEnabled, logger); - updateRulesBulkRoute(router, ml, isRuleRegistryEnabled, logger); - patchRulesBulkRoute(router, ml, isRuleRegistryEnabled, logger); - deleteRulesBulkRoute(router, isRuleRegistryEnabled, logger); - performBulkActionRoute(router, ml, logger, isRuleRegistryEnabled); + getPrepackagedRulesStatusRoute(router, config, security); + createRulesBulkRoute(router, ml, logger); + updateRulesBulkRoute(router, ml, logger); + patchRulesBulkRoute(router, ml, logger); + deleteRulesBulkRoute(router, logger); + performBulkActionRoute(router, ml, logger); getRuleExecutionEventsRoute(router); createTimelinesRoute(router, config, security); patchTimelinesRoute(router, config, security); - importRulesRoute(router, config, ml, isRuleRegistryEnabled); - exportRulesRoute(router, config, logger, isRuleRegistryEnabled); + importRulesRoute(router, config, ml); + exportRulesRoute(router, config, logger); importTimelinesRoute(router, config, security); exportTimelinesRoute(router, config, security); @@ -156,7 +155,7 @@ export const initRoutes = ( deleteIndexRoute(router); // Detection Engine tags routes that have the REST endpoints of /api/detection_engine/tags - readTagsRoute(router, isRuleRegistryEnabled); + readTagsRoute(router); // Privileges API to get the generic user privileges readPrivilegesRoute(router, hasEncryptionKey); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/__mocks__/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/__mocks__/index.ts index bc31f64fcc626..346c8845751ce 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/__mocks__/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/__mocks__/index.ts @@ -13,12 +13,6 @@ import { UsersFields } from '../../../../../../../common/search_strategy/securit export const mockOptions: UsersRequestOptions = { defaultIndex: ['test_indices*'], - docValueFields: [ - { - field: '@timestamp', - format: 'date_time', - }, - ], factoryQueryType: UsersQueries.users, filterQuery: '{"bool":{"must":[],"filter":[{"match_all":{}},{"match_phrase":{"user.name":{"query":"test_user"}}}],"should":[],"must_not":[]}}', @@ -78,10 +72,12 @@ export const mockSearchStrategyResponse: IEsSearchResponse = { _index: 'endgame-00001', _id: 'inT0934BjUd1_U2597Vf', _score: null, - _source: { - user: { - domain: 'ENDPOINT-W-8-03', - }, + fields: { + 'user.name': ['jose52'], + '@timestamp': ['2022-04-13T17:16:34.540Z'], + 'user.id': ['17'], + 'user.email': ['jose52@barrett.com'], + 'user.domain': ['ENDPOINT-W-8-03'], }, sort: [1644837532000], }, diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/__snapshots__/index.test.ts.snap b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/__snapshots__/index.test.ts.snap index b52d0b1fc1cfd..6383808293a9d 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/__snapshots__/index.test.ts.snap +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/__snapshots__/index.test.ts.snap @@ -3,7 +3,9 @@ exports[`allHosts search strategy parse should parse data correctly 1`] = ` Array [ Object { - "domain": "ENDPOINT-W-8-03", + "domain": Array [ + "ENDPOINT-W-8-03", + ], "lastSeen": "2022-02-14T11:18:52.000Z", "name": "vagrant", }, diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/__snapshots__/query.all_users.dsl.test.ts.snap b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/__snapshots__/query.all_users.dsl.test.ts.snap index 99f85724d2f5c..2b661fe355a13 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/__snapshots__/query.all_users.dsl.test.ts.snap +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/__snapshots__/query.all_users.dsl.test.ts.snap @@ -4,6 +4,7 @@ exports[`buildUsersQuery build query from options correctly 1`] = ` Object { "allow_no_indices": true, "body": Object { + "_source": false, "aggregations": Object { "user_count": Object { "cardinality": Object { @@ -14,11 +15,7 @@ Object { "aggs": Object { "domain": Object { "top_hits": Object { - "_source": Object { - "includes": Array [ - "user.domain", - ], - }, + "_source": false, "size": 1, "sort": Array [ Object { @@ -44,10 +41,12 @@ Object { }, }, }, - "docvalue_fields": Array [ + "fields": Array [ + "user.name", + "user.domain", Object { "field": "@timestamp", - "format": "date_time", + "format": "strict_date_optional_time", }, ], "query": Object { diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/index.ts index b8babe0b19845..9c62e55cc0bb1 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/index.ts @@ -50,7 +50,7 @@ export const allUsers: SecuritySolutionFactory = { (bucket: AllUsersAggEsItem) => ({ name: bucket.key, lastSeen: getOr(null, `lastSeen.value_as_string`, bucket), - domain: getOr(null, `domain.hits.hits[0]._source.user.domain`, bucket), + domain: getOr(null, `domain.hits.hits[0].fields['user.domain']`, bucket), }), {} ); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/query.all_users.dsl.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/query.all_users.dsl.ts index 82df1d2d97246..d7f8f7e50abe1 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/query.all_users.dsl.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/query.all_users.dsl.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { isEmpty } from 'lodash/fp'; import type { ISearchRequestParams } from '@kbn/data-plugin/common'; import { Direction } from '../../../../../../common/search_strategy'; import { createQueryFilterClauses } from '../../../../../utils/build_query'; @@ -18,7 +17,6 @@ import { assertUnreachable } from '../../../../../../common/utility_types'; export const buildUsersQuery = ({ defaultIndex, - docValueFields, filterQuery, pagination: { querySize }, sort, @@ -43,7 +41,6 @@ export const buildUsersQuery = ({ ignore_unavailable: true, track_total_hits: false, body: { - ...(!isEmpty(docValueFields) ? { docvalue_fields: docValueFields } : {}), aggregations: { user_count: { cardinality: { field: 'user.name' } }, user_data: { @@ -60,15 +57,22 @@ export const buildUsersQuery = ({ }, }, ], - _source: { - includes: ['user.domain'], - }, + _source: false, }, }, }, }, }, query: { bool: { filter } }, + _source: false, + fields: [ + 'user.name', + 'user.domain', + { + field: '@timestamp', + format: 'strict_date_optional_time', + }, + ], size: 0, }, }; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/__mocks__/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/__mocks__/index.ts index 487f4537cd50d..028ee4e4ba1b9 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/__mocks__/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/__mocks__/index.ts @@ -26,408 +26,6 @@ export const mockOptions: UserAuthenticationsRequestOptions = { 'winlogbeat-*', ], stackByField: AuthStackByField.userName, - docValueFields: [ - { - field: '@timestamp', - format: 'date_time', - }, - { - field: 'event.created', - format: 'date_time', - }, - { - field: 'event.end', - format: 'date_time', - }, - { - field: 'event.ingested', - format: 'date_time', - }, - { - field: 'event.start', - format: 'date_time', - }, - { - field: 'file.accessed', - format: 'date_time', - }, - { - field: 'file.created', - format: 'date_time', - }, - { - field: 'file.ctime', - format: 'date_time', - }, - { - field: 'file.mtime', - format: 'date_time', - }, - { - field: 'package.installed', - format: 'date_time', - }, - { - field: 'process.parent.start', - format: 'date_time', - }, - { - field: 'process.start', - format: 'date_time', - }, - { - field: 'system.audit.host.boottime', - format: 'date_time', - }, - { - field: 'system.audit.package.installtime', - format: 'date_time', - }, - { - field: 'system.audit.user.password.last_changed', - format: 'date_time', - }, - { - field: 'tls.client.not_after', - format: 'date_time', - }, - { - field: 'tls.client.not_before', - format: 'date_time', - }, - { - field: 'tls.server.not_after', - format: 'date_time', - }, - { - field: 'tls.server.not_before', - format: 'date_time', - }, - { - field: 'aws.cloudtrail.user_identity.session_context.creation_date', - format: 'date_time', - }, - { - field: 'azure.auditlogs.properties.activity_datetime', - format: 'date_time', - }, - { - field: 'azure.enqueued_time', - format: 'date_time', - }, - { - field: 'azure.signinlogs.properties.created_at', - format: 'date_time', - }, - { - field: 'cef.extensions.agentReceiptTime', - format: 'date_time', - }, - { - field: 'cef.extensions.deviceCustomDate1', - format: 'date_time', - }, - { - field: 'cef.extensions.deviceCustomDate2', - format: 'date_time', - }, - { - field: 'cef.extensions.deviceReceiptTime', - format: 'date_time', - }, - { - field: 'cef.extensions.endTime', - format: 'date_time', - }, - { - field: 'cef.extensions.fileCreateTime', - format: 'date_time', - }, - { - field: 'cef.extensions.fileModificationTime', - format: 'date_time', - }, - { - field: 'cef.extensions.flexDate1', - format: 'date_time', - }, - { - field: 'cef.extensions.managerReceiptTime', - format: 'date_time', - }, - { - field: 'cef.extensions.oldFileCreateTime', - format: 'date_time', - }, - { - field: 'cef.extensions.oldFileModificationTime', - format: 'date_time', - }, - { - field: 'cef.extensions.startTime', - format: 'date_time', - }, - { - field: 'checkpoint.subs_exp', - format: 'date_time', - }, - { - field: 'crowdstrike.event.EndTimestamp', - format: 'date_time', - }, - { - field: 'crowdstrike.event.IncidentEndTime', - format: 'date_time', - }, - { - field: 'crowdstrike.event.IncidentStartTime', - format: 'date_time', - }, - { - field: 'crowdstrike.event.ProcessEndTime', - format: 'date_time', - }, - { - field: 'crowdstrike.event.ProcessStartTime', - format: 'date_time', - }, - { - field: 'crowdstrike.event.StartTimestamp', - format: 'date_time', - }, - { - field: 'crowdstrike.event.Timestamp', - format: 'date_time', - }, - { - field: 'crowdstrike.event.UTCTimestamp', - format: 'date_time', - }, - { - field: 'crowdstrike.metadata.eventCreationTime', - format: 'date_time', - }, - { - field: 'gsuite.admin.email.log_search_filter.end_date', - format: 'date_time', - }, - { - field: 'gsuite.admin.email.log_search_filter.start_date', - format: 'date_time', - }, - { - field: 'gsuite.admin.user.birthdate', - format: 'date_time', - }, - { - field: 'kafka.block_timestamp', - format: 'date_time', - }, - { - field: 'microsoft.defender_atp.lastUpdateTime', - format: 'date_time', - }, - { - field: 'microsoft.defender_atp.resolvedTime', - format: 'date_time', - }, - { - field: 'misp.campaign.first_seen', - format: 'date_time', - }, - { - field: 'misp.campaign.last_seen', - format: 'date_time', - }, - { - field: 'misp.intrusion_set.first_seen', - format: 'date_time', - }, - { - field: 'misp.intrusion_set.last_seen', - format: 'date_time', - }, - { - field: 'misp.observed_data.first_observed', - format: 'date_time', - }, - { - field: 'misp.observed_data.last_observed', - format: 'date_time', - }, - { - field: 'misp.report.published', - format: 'date_time', - }, - { - field: 'misp.threat_indicator.valid_from', - format: 'date_time', - }, - { - field: 'misp.threat_indicator.valid_until', - format: 'date_time', - }, - { - field: 'netflow.collection_time_milliseconds', - format: 'date_time', - }, - { - field: 'netflow.exporter.timestamp', - format: 'date_time', - }, - { - field: 'netflow.flow_end_microseconds', - format: 'date_time', - }, - { - field: 'netflow.flow_end_milliseconds', - format: 'date_time', - }, - { - field: 'netflow.flow_end_nanoseconds', - format: 'date_time', - }, - { - field: 'netflow.flow_end_seconds', - format: 'date_time', - }, - { - field: 'netflow.flow_start_microseconds', - format: 'date_time', - }, - { - field: 'netflow.flow_start_milliseconds', - format: 'date_time', - }, - { - field: 'netflow.flow_start_nanoseconds', - format: 'date_time', - }, - { - field: 'netflow.flow_start_seconds', - format: 'date_time', - }, - { - field: 'netflow.max_export_seconds', - format: 'date_time', - }, - { - field: 'netflow.max_flow_end_microseconds', - format: 'date_time', - }, - { - field: 'netflow.max_flow_end_milliseconds', - format: 'date_time', - }, - { - field: 'netflow.max_flow_end_nanoseconds', - format: 'date_time', - }, - { - field: 'netflow.max_flow_end_seconds', - format: 'date_time', - }, - { - field: 'netflow.min_export_seconds', - format: 'date_time', - }, - { - field: 'netflow.min_flow_start_microseconds', - format: 'date_time', - }, - { - field: 'netflow.min_flow_start_milliseconds', - format: 'date_time', - }, - { - field: 'netflow.min_flow_start_nanoseconds', - format: 'date_time', - }, - { - field: 'netflow.min_flow_start_seconds', - format: 'date_time', - }, - { - field: 'netflow.monitoring_interval_end_milli_seconds', - format: 'date_time', - }, - { - field: 'netflow.monitoring_interval_start_milli_seconds', - format: 'date_time', - }, - { - field: 'netflow.observation_time_microseconds', - format: 'date_time', - }, - { - field: 'netflow.observation_time_milliseconds', - format: 'date_time', - }, - { - field: 'netflow.observation_time_nanoseconds', - format: 'date_time', - }, - { - field: 'netflow.observation_time_seconds', - format: 'date_time', - }, - { - field: 'netflow.system_init_time_milliseconds', - format: 'date_time', - }, - { - field: 'rsa.internal.lc_ctime', - format: 'date_time', - }, - { - field: 'rsa.internal.time', - format: 'date_time', - }, - { - field: 'rsa.time.effective_time', - format: 'date_time', - }, - { - field: 'rsa.time.endtime', - format: 'date_time', - }, - { - field: 'rsa.time.event_queue_time', - format: 'date_time', - }, - { - field: 'rsa.time.event_time', - format: 'date_time', - }, - { - field: 'rsa.time.expire_time', - format: 'date_time', - }, - { - field: 'rsa.time.recorded_time', - format: 'date_time', - }, - { - field: 'rsa.time.stamp', - format: 'date_time', - }, - { - field: 'rsa.time.starttime', - format: 'date_time', - }, - { - field: 'sophos.xg.date', - format: 'date_time', - }, - { - field: 'sophos.xg.eventtime', - format: 'date_time', - }, - { - field: 'sophos.xg.start_time', - format: 'date_time', - }, - ], factoryQueryType: UsersQueries.authentications, filterQuery: '{"bool":{"must":[],"filter":[{"match_all":{}}],"should":[],"must_not":[]}}', pagination: { @@ -481,106 +79,10 @@ export const mockSearchStrategyResponse: IEsSearchResponse = { _index: 'winlogbeat-8.0.0-2020.09.02-000001', _id: 'zqY7WXQBA6bGZw2uLeKI', _score: null, - _source: { - process: { - name: 'services.exe', - pid: 564, - executable: 'C:\\Windows\\System32\\services.exe', - }, - agent: { - build_date: '2020-07-16 09:16:27 +0000 UTC ', - name: 'siem-windows', - commit: '4dcbde39492bdc3843034bba8db811c68cb44b97 ', - id: '05e1bff7-d7a8-416a-8554-aa10288fa07d', - type: 'winlogbeat', - ephemeral_id: '655abd6c-6c33-435d-a2eb-79b2a01e6d61', - version: '8.0.0', - user: { name: 'inside_winlogbeat_user' }, - }, - winlog: { - computer_name: 'siem-windows', - process: { pid: 576, thread: { id: 880 } }, - keywords: ['Audit Success'], - logon: { id: '0x3e7', type: 'Service' }, - channel: 'Security', - event_data: { - LogonGuid: '{00000000-0000-0000-0000-000000000000}', - TargetOutboundDomainName: '-', - VirtualAccount: '%%1843', - LogonType: '5', - IpPort: '-', - TransmittedServices: '-', - SubjectLogonId: '0x3e7', - LmPackageName: '-', - TargetOutboundUserName: '-', - KeyLength: '0', - TargetLogonId: '0x3e7', - RestrictedAdminMode: '-', - SubjectUserName: 'SIEM-WINDOWS$', - TargetLinkedLogonId: '0x0', - ElevatedToken: '%%1842', - SubjectDomainName: 'WORKGROUP', - IpAddress: '-', - ImpersonationLevel: '%%1833', - TargetUserName: 'SYSTEM', - LogonProcessName: 'Advapi ', - TargetDomainName: 'NT AUTHORITY', - SubjectUserSid: 'S-1-5-18', - TargetUserSid: 'S-1-5-18', - AuthenticationPackageName: 'Negotiate', - }, - opcode: 'Info', - version: 2, - record_id: 57818, - task: 'Logon', - event_id: 4624, - provider_guid: '{54849625-5478-4994-a5ba-3e3b0328c30d}', - activity_id: '{d2485217-6bac-0000-8fbb-3f7e2571d601}', - api: 'wineventlog', - provider_name: 'Microsoft-Windows-Security-Auditing', - }, - log: { level: 'information' }, - source: { domain: '-' }, - message: - 'An account was successfully logged on.\n\nSubject:\n\tSecurity ID:\t\tS-1-5-18\n\tAccount Name:\t\tSIEM-WINDOWS$\n\tAccount Domain:\t\tWORKGROUP\n\tLogon ID:\t\t0x3E7\n\nLogon Information:\n\tLogon Type:\t\t5\n\tRestricted Admin Mode:\t-\n\tVirtual Account:\t\tNo\n\tElevated Token:\t\tYes\n\nImpersonation Level:\t\tImpersonation\n\nNew Logon:\n\tSecurity ID:\t\tS-1-5-18\n\tAccount Name:\t\tSYSTEM\n\tAccount Domain:\t\tNT AUTHORITY\n\tLogon ID:\t\t0x3E7\n\tLinked Logon ID:\t\t0x0\n\tNetwork Account Name:\t-\n\tNetwork Account Domain:\t-\n\tLogon GUID:\t\t{00000000-0000-0000-0000-000000000000}\n\nProcess Information:\n\tProcess ID:\t\t0x234\n\tProcess Name:\t\tC:\\Windows\\System32\\services.exe\n\nNetwork Information:\n\tWorkstation Name:\t-\n\tSource Network Address:\t-\n\tSource Port:\t\t-\n\nDetailed Authentication Information:\n\tLogon Process:\t\tAdvapi \n\tAuthentication Package:\tNegotiate\n\tTransited Services:\t-\n\tPackage Name (NTLM only):\t-\n\tKey Length:\t\t0\n\nThis event is generated when a logon session is created. It is generated on the computer that was accessed.\n\nThe subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe.\n\nThe logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network).\n\nThe New Logon fields indicate the account for whom the new logon was created, i.e. the account that was logged on.\n\nThe network fields indicate where a remote logon request originated. Workstation name is not always available and may be left blank in some cases.\n\nThe impersonation level field indicates the extent to which a process in the logon session can impersonate.\n\nThe authentication information fields provide detailed information about this specific logon request.\n\t- Logon GUID is a unique identifier that can be used to correlate this event with a KDC event.\n\t- Transited services indicate which intermediate services have participated in this logon request.\n\t- Package name indicates which sub-protocol was used among the NTLM protocols.\n\t- Key length indicates the length of the generated session key. This will be 0 if no session key was requested.', - cloud: { - availability_zone: 'us-central1-c', - instance: { name: 'siem-windows', id: '9156726559029788564' }, - provider: 'gcp', - machine: { type: 'g1-small' }, - project: { id: 'elastic-siem' }, - }, - '@timestamp': '2020-09-04T13:08:02.532Z', - related: { user: ['SYSTEM', 'SIEM-WINDOWS$'] }, - ecs: { version: '1.5.0' }, - host: { - hostname: 'siem-windows', - os: { - build: '17763.1397', - kernel: '10.0.17763.1397 (WinBuild.160101.0800)', - name: 'Windows Server 2019 Datacenter', - family: 'windows', - version: '10.0', - platform: 'windows', - }, - ip: ['fe80::ecf5:decc:3ec3:767e', '10.200.0.15'], - name: 'siem-windows', - id: 'ce1d3c9b-a815-4643-9641-ada0f2c00609', - mac: ['42:01:0a:c8:00:0f'], - architecture: 'x86_64', - }, - event: { - code: 4624, - provider: 'Microsoft-Windows-Security-Auditing', - created: '2020-09-04T13:08:03.638Z', - kind: 'event', - module: 'security', - action: 'logged-in', - category: 'authentication', - type: 'start', - outcome: 'success', - }, - user: { domain: 'NT AUTHORITY', name: 'SYSTEM', id: 'S-1-5-18' }, + fields: { + '@timestamp': ['2020-09-04T13:08:02.532Z'], + 'host.id': ['ce1d3c9b-a815-4643-9641-ada0f2c00609'], + 'host.name': ['siem-windows'], }, sort: [1599224882532], }, @@ -607,76 +109,11 @@ export const mockSearchStrategyResponse: IEsSearchResponse = { _index: '.ds-logs-system.auth-default-000001', _id: '9_sfWXQBc39KFIJbIsDh', _score: null, - _source: { - agent: { - hostname: 'siem-kibana', - name: 'siem-kibana', - id: 'aa3d9dc7-fef1-4c2f-a68d-25785d624e35', - ephemeral_id: 'e503bd85-11c7-4bc9-ae7d-70be1d919fb7', - type: 'filebeat', - version: '7.9.1', - }, - process: { name: 'sshd', pid: 20764 }, - log: { file: { path: '/var/log/auth.log' }, offset: 552463 }, - source: { - geo: { - continent_name: 'Europe', - region_iso_code: 'DE-BE', - city_name: 'Berlin', - country_iso_code: 'DE', - region_name: 'Land Berlin', - location: { lon: 13.3512, lat: 52.5727 }, - }, - as: { number: 6805, organization: { name: 'Telefonica Germany' } }, - port: 57457, - ip: '77.183.42.188', - }, - cloud: { - availability_zone: 'us-east1-b', - instance: { name: 'siem-kibana', id: '5412578377715150143' }, - provider: 'gcp', - machine: { type: 'n1-standard-2' }, - project: { id: 'elastic-beats' }, - }, - input: { type: 'log' }, - '@timestamp': '2020-09-04T11:49:21.000Z', - system: { - auth: { - ssh: { - method: 'publickey', - signature: 'RSA SHA256:vv64JNLzKZWYA9vonnGWuW7zxWhyZrL/BFxyIGbISx8', - event: 'Accepted', - }, - }, - }, - ecs: { version: '1.5.0' }, - data_stream: { namespace: 'default', type: 'logs', dataset: 'system.auth' }, - host: { - hostname: 'siem-kibana', - os: { - kernel: '4.9.0-8-amd64', - codename: 'stretch', - name: 'Debian GNU/Linux', - family: 'debian', - version: '9 (stretch)', - platform: 'debian', - }, - containerized: false, - ip: ['10.142.0.7', 'fe80::4001:aff:fe8e:7'], - name: 'siem-kibana', - id: 'aa7ca589f1b8220002f2fc61c64cfbf1', - mac: ['42:01:0a:8e:00:07'], - architecture: 'x86_64', - }, - event: { - timezone: '+00:00', - action: 'ssh_login', - type: 'authentication_success', - category: 'authentication', - dataset: 'system.auth', - outcome: 'success', - }, - user: { name: 'tsg' }, + fields: { + 'source.ip': ['77.183.42.188'], + 'host.id': ['aa7ca589f1b8220002f2fc61c64cfbf1'], + 'host.name': ['siem-kibana'], + '@timestamp': ['2020-09-04T11:49:21.000Z'], }, sort: [1599220161000], }, @@ -699,67 +136,11 @@ export const mockSearchStrategyResponse: IEsSearchResponse = { _index: '.ds-logs-system.auth-default-000001', _id: 'ZfxZWXQBc39KFIJbLN5U', _score: null, - _source: { - agent: { - hostname: 'siem-kibana', - name: 'siem-kibana', - id: 'aa3d9dc7-fef1-4c2f-a68d-25785d624e35', - ephemeral_id: 'e503bd85-11c7-4bc9-ae7d-70be1d919fb7', - type: 'filebeat', - version: '7.9.1', - }, - process: { name: 'sshd', pid: 22913 }, - log: { file: { path: '/var/log/auth.log' }, offset: 562910 }, - source: { - geo: { - continent_name: 'Asia', - region_iso_code: 'KR-28', - city_name: 'Incheon', - country_iso_code: 'KR', - region_name: 'Incheon', - location: { lon: 126.7288, lat: 37.4562 }, - }, - as: { number: 4766, organization: { name: 'Korea Telecom' } }, - ip: '59.15.3.197', - }, - cloud: { - availability_zone: 'us-east1-b', - instance: { name: 'siem-kibana', id: '5412578377715150143' }, - provider: 'gcp', - machine: { type: 'n1-standard-2' }, - project: { id: 'elastic-beats' }, - }, - input: { type: 'log' }, - '@timestamp': '2020-09-04T13:40:46.000Z', - system: { auth: { ssh: { event: 'Invalid' } } }, - ecs: { version: '1.5.0' }, - data_stream: { namespace: 'default', type: 'logs', dataset: 'system.auth' }, - host: { - hostname: 'siem-kibana', - os: { - kernel: '4.9.0-8-amd64', - codename: 'stretch', - name: 'Debian GNU/Linux', - family: 'debian', - version: '9 (stretch)', - platform: 'debian', - }, - containerized: false, - ip: ['10.142.0.7', 'fe80::4001:aff:fe8e:7'], - name: 'siem-kibana', - id: 'aa7ca589f1b8220002f2fc61c64cfbf1', - mac: ['42:01:0a:8e:00:07'], - architecture: 'x86_64', - }, - event: { - timezone: '+00:00', - action: 'ssh_login', - type: 'authentication_failure', - category: 'authentication', - dataset: 'system.auth', - outcome: 'failure', - }, - user: { name: 'admin' }, + fields: { + 'source.ip': ['59.15.3.197'], + 'host.id': ['aa7ca589f1b8220002f2fc61c64cfbf1'], + 'host.name': ['siem-kibana'], + '@timestamp': ['2020-09-04T13:40:46.000Z'], }, sort: [1599226846000], }, @@ -786,47 +167,10 @@ export const mockSearchStrategyResponse: IEsSearchResponse = { _index: 'filebeat-8.0.0-2020.09.02-000001', _id: 'M_xLWXQBc39KFIJbY7Cb', _score: null, - _source: { - agent: { - name: 'bastion00.siem.estc.dev', - id: 'f9a321c1-ec27-49fa-aacf-6a50ef6d836f', - type: 'filebeat', - ephemeral_id: '734ee3da-1a4f-4bc9-b400-e0cf0e5eeebc', - version: '8.0.0', - }, - process: { name: 'sshd', pid: 20671 }, - log: { file: { path: '/var/log/auth.log' }, offset: 1028103 }, - source: { - geo: { - continent_name: 'North America', - region_iso_code: 'US-NY', - city_name: 'New York', - country_iso_code: 'US', - region_name: 'New York', - location: { lon: -74, lat: 40.7157 }, - }, - ip: '64.227.88.245', - }, - fileset: { name: 'auth' }, - input: { type: 'log' }, - '@timestamp': '2020-09-04T13:25:43.000Z', - system: { auth: { ssh: { event: 'Invalid' } } }, - ecs: { version: '1.5.0' }, - related: { ip: ['64.227.88.245'], user: ['user'] }, - service: { type: 'system' }, - host: { hostname: 'bastion00', name: 'bastion00.siem.estc.dev' }, - event: { - ingested: '2020-09-04T13:25:47.034172Z', - timezone: '+00:00', - kind: 'event', - module: 'system', - action: 'ssh_login', - type: ['authentication_failure', 'info'], - category: ['authentication'], - dataset: 'system.auth', - outcome: 'failure', - }, - user: { name: 'user' }, + fields: { + 'source.ip': ['64.227.88.245'], + 'host.name': ['bastion00.siem.estc.dev'], + '@timestamp': ['2020-09-04T13:25:43.000Z'], }, sort: [1599225943000], }, @@ -853,47 +197,10 @@ export const mockSearchStrategyResponse: IEsSearchResponse = { _index: 'filebeat-8.0.0-2020.09.02-000001', _id: 'nPxKWXQBc39KFIJb7q4w', _score: null, - _source: { - agent: { - name: 'bastion00.siem.estc.dev', - id: 'f9a321c1-ec27-49fa-aacf-6a50ef6d836f', - ephemeral_id: '734ee3da-1a4f-4bc9-b400-e0cf0e5eeebc', - type: 'filebeat', - version: '8.0.0', - }, - process: { name: 'sshd', pid: 20665 }, - log: { file: { path: '/var/log/auth.log' }, offset: 1027372 }, - source: { - geo: { - continent_name: 'North America', - region_iso_code: 'US-NY', - city_name: 'New York', - country_iso_code: 'US', - region_name: 'New York', - location: { lon: -74, lat: 40.7157 }, - }, - ip: '64.227.88.245', - }, - fileset: { name: 'auth' }, - input: { type: 'log' }, - '@timestamp': '2020-09-04T13:25:07.000Z', - system: { auth: { ssh: { event: 'Invalid' } } }, - ecs: { version: '1.5.0' }, - related: { ip: ['64.227.88.245'], user: ['ubuntu'] }, - service: { type: 'system' }, - host: { hostname: 'bastion00', name: 'bastion00.siem.estc.dev' }, - event: { - ingested: '2020-09-04T13:25:16.974606Z', - timezone: '+00:00', - kind: 'event', - module: 'system', - action: 'ssh_login', - type: ['authentication_failure', 'info'], - category: ['authentication'], - dataset: 'system.auth', - outcome: 'failure', - }, - user: { name: 'ubuntu' }, + fields: { + 'source.ip': ['64.227.88.245'], + 'host.name': ['bastion00.siem.estc.dev'], + '@timestamp': ['2020-09-04T13:25:07.000Z'], }, sort: [1599225907000], }, @@ -920,67 +227,11 @@ export const mockSearchStrategyResponse: IEsSearchResponse = { _index: '.ds-logs-system.auth-default-000001', _id: 'mPsfWXQBc39KFIJbI8HI', _score: null, - _source: { - agent: { - hostname: 'siem-kibana', - name: 'siem-kibana', - id: 'aa3d9dc7-fef1-4c2f-a68d-25785d624e35', - type: 'filebeat', - ephemeral_id: 'e503bd85-11c7-4bc9-ae7d-70be1d919fb7', - version: '7.9.1', - }, - process: { name: 'sshd', pid: 21506 }, - log: { file: { path: '/var/log/auth.log' }, offset: 556761 }, - source: { - geo: { - continent_name: 'Asia', - region_iso_code: 'IN-DL', - city_name: 'New Delhi', - country_iso_code: 'IN', - region_name: 'National Capital Territory of Delhi', - location: { lon: 77.2245, lat: 28.6358 }, - }, - as: { number: 10029, organization: { name: 'SHYAM SPECTRA PVT LTD' } }, - ip: '180.151.228.166', - }, - cloud: { - availability_zone: 'us-east1-b', - instance: { name: 'siem-kibana', id: '5412578377715150143' }, - provider: 'gcp', - machine: { type: 'n1-standard-2' }, - project: { id: 'elastic-beats' }, - }, - input: { type: 'log' }, - '@timestamp': '2020-09-04T12:26:36.000Z', - system: { auth: { ssh: { event: 'Invalid' } } }, - ecs: { version: '1.5.0' }, - data_stream: { namespace: 'default', type: 'logs', dataset: 'system.auth' }, - host: { - hostname: 'siem-kibana', - os: { - kernel: '4.9.0-8-amd64', - codename: 'stretch', - name: 'Debian GNU/Linux', - family: 'debian', - version: '9 (stretch)', - platform: 'debian', - }, - containerized: false, - ip: ['10.142.0.7', 'fe80::4001:aff:fe8e:7'], - name: 'siem-kibana', - id: 'aa7ca589f1b8220002f2fc61c64cfbf1', - mac: ['42:01:0a:8e:00:07'], - architecture: 'x86_64', - }, - event: { - timezone: '+00:00', - action: 'ssh_login', - type: 'authentication_failure', - category: 'authentication', - dataset: 'system.auth', - outcome: 'failure', - }, - user: { name: 'odoo' }, + fields: { + 'source.ip': ['180.151.228.166'], + 'host.id': ['aa7ca589f1b8220002f2fc61c64cfbf1'], + 'host.name': ['siem-kibana'], + '@timestamp': ['2020-09-04T12:26:36.000Z'], }, sort: [1599222396000], }, @@ -1007,48 +258,10 @@ export const mockSearchStrategyResponse: IEsSearchResponse = { _index: 'filebeat-8.0.0-2020.09.02-000001', _id: 'aaToWHQBA6bGZw2uR-St', _score: null, - _source: { - agent: { - name: 'bastion00.siem.estc.dev', - id: 'f9a321c1-ec27-49fa-aacf-6a50ef6d836f', - type: 'filebeat', - ephemeral_id: '734ee3da-1a4f-4bc9-b400-e0cf0e5eeebc', - version: '8.0.0', - }, - process: { name: 'sshd', pid: 20475 }, - log: { file: { path: '/var/log/auth.log' }, offset: 1019218 }, - source: { - geo: { - continent_name: 'Europe', - region_iso_code: 'SE-AB', - city_name: 'Stockholm', - country_iso_code: 'SE', - region_name: 'Stockholm', - location: { lon: 17.7833, lat: 59.25 }, - }, - as: { number: 8473, organization: { name: 'Bahnhof AB' } }, - ip: '178.174.148.58', - }, - fileset: { name: 'auth' }, - input: { type: 'log' }, - '@timestamp': '2020-09-04T11:37:22.000Z', - system: { auth: { ssh: { event: 'Invalid' } } }, - ecs: { version: '1.5.0' }, - related: { ip: ['178.174.148.58'], user: ['pi'] }, - service: { type: 'system' }, - host: { hostname: 'bastion00', name: 'bastion00.siem.estc.dev' }, - event: { - ingested: '2020-09-04T11:37:31.797423Z', - timezone: '+00:00', - kind: 'event', - module: 'system', - action: 'ssh_login', - type: ['authentication_failure', 'info'], - category: ['authentication'], - dataset: 'system.auth', - outcome: 'failure', - }, - user: { name: 'pi' }, + fields: { + 'source.ip': ['178.174.148.58'], + 'host.name': ['bastion00.siem.estc.dev'], + '@timestamp': ['2020-09-04T11:37:22.000Z'], }, sort: [1599219442000], }, @@ -1075,48 +288,10 @@ export const mockSearchStrategyResponse: IEsSearchResponse = { _index: 'filebeat-8.0.0-2020.09.02-000001', _id: 'VaP_V3QBA6bGZw2upUbg', _score: null, - _source: { - agent: { - name: 'bastion00.siem.estc.dev', - id: 'f9a321c1-ec27-49fa-aacf-6a50ef6d836f', - type: 'filebeat', - ephemeral_id: '734ee3da-1a4f-4bc9-b400-e0cf0e5eeebc', - version: '8.0.0', - }, - process: { name: 'sshd', pid: 19849 }, - log: { file: { path: '/var/log/auth.log' }, offset: 981036 }, - source: { - geo: { - continent_name: 'Europe', - country_iso_code: 'HR', - location: { lon: 15.5, lat: 45.1667 }, - }, - as: { - number: 42864, - organization: { name: 'Giganet Internet Szolgaltato Kft' }, - }, - ip: '45.95.168.157', - }, - fileset: { name: 'auth' }, - input: { type: 'log' }, - '@timestamp': '2020-09-04T07:23:22.000Z', - system: { auth: { ssh: { event: 'Invalid' } } }, - ecs: { version: '1.5.0' }, - related: { ip: ['45.95.168.157'], user: ['demo'] }, - service: { type: 'system' }, - host: { hostname: 'bastion00', name: 'bastion00.siem.estc.dev' }, - event: { - ingested: '2020-09-04T07:23:26.046346Z', - timezone: '+00:00', - kind: 'event', - module: 'system', - action: 'ssh_login', - type: ['authentication_failure', 'info'], - category: ['authentication'], - dataset: 'system.auth', - outcome: 'failure', - }, - user: { name: 'demo' }, + fields: { + 'source.ip': ['45.95.168.157'], + 'host.name': ['bastion00.siem.estc.dev'], + '@timestamp': ['2020-09-04T07:23:22.000Z'], }, sort: [1599204202000], }, @@ -1143,72 +318,11 @@ export const mockSearchStrategyResponse: IEsSearchResponse = { _index: '.ds-logs-system.auth-default-000001', _id: 'PqYfWXQBA6bGZw2uIhVU', _score: null, - _source: { - agent: { - hostname: 'siem-kibana', - name: 'siem-kibana', - id: 'aa3d9dc7-fef1-4c2f-a68d-25785d624e35', - ephemeral_id: 'e503bd85-11c7-4bc9-ae7d-70be1d919fb7', - type: 'filebeat', - version: '7.9.1', - }, - process: { name: 'sshd', pid: 20396 }, - log: { file: { path: '/var/log/auth.log' }, offset: 550795 }, - source: { - geo: { - continent_name: 'Asia', - region_iso_code: 'CN-BJ', - city_name: 'Beijing', - country_iso_code: 'CN', - region_name: 'Beijing', - location: { lon: 116.3889, lat: 39.9288 }, - }, - as: { - number: 45090, - organization: { - name: 'Shenzhen Tencent Computer Systems Company Limited', - }, - }, - ip: '123.206.30.76', - }, - cloud: { - availability_zone: 'us-east1-b', - instance: { name: 'siem-kibana', id: '5412578377715150143' }, - provider: 'gcp', - machine: { type: 'n1-standard-2' }, - project: { id: 'elastic-beats' }, - }, - input: { type: 'log' }, - '@timestamp': '2020-09-04T11:20:26.000Z', - system: { auth: { ssh: { event: 'Invalid' } } }, - ecs: { version: '1.5.0' }, - data_stream: { namespace: 'default', type: 'logs', dataset: 'system.auth' }, - host: { - hostname: 'siem-kibana', - os: { - kernel: '4.9.0-8-amd64', - codename: 'stretch', - name: 'Debian GNU/Linux', - family: 'debian', - version: '9 (stretch)', - platform: 'debian', - }, - containerized: false, - ip: ['10.142.0.7', 'fe80::4001:aff:fe8e:7'], - name: 'siem-kibana', - id: 'aa7ca589f1b8220002f2fc61c64cfbf1', - mac: ['42:01:0a:8e:00:07'], - architecture: 'x86_64', - }, - event: { - timezone: '+00:00', - action: 'ssh_login', - type: 'authentication_failure', - category: 'authentication', - dataset: 'system.auth', - outcome: 'failure', - }, - user: { name: 'git' }, + fields: { + 'source.ip': ['123.206.30.76'], + 'host.id': ['aa7ca589f1b8220002f2fc61c64cfbf1'], + 'host.name': ['siem-kibana'], + '@timestamp': ['2020-09-04T11:20:26.000Z'], }, sort: [1599218426000], }, @@ -1235,48 +349,10 @@ export const mockSearchStrategyResponse: IEsSearchResponse = { _index: 'filebeat-8.0.0-2020.09.02-000001', _id: 'iMABWHQBB-gskclyitP-', _score: null, - _source: { - agent: { - name: 'bastion00.siem.estc.dev', - id: 'f9a321c1-ec27-49fa-aacf-6a50ef6d836f', - type: 'filebeat', - ephemeral_id: '734ee3da-1a4f-4bc9-b400-e0cf0e5eeebc', - version: '8.0.0', - }, - process: { name: 'sshd', pid: 19870 }, - log: { file: { path: '/var/log/auth.log' }, offset: 984133 }, - source: { - geo: { - continent_name: 'Europe', - country_iso_code: 'HR', - location: { lon: 15.5, lat: 45.1667 }, - }, - as: { - number: 42864, - organization: { name: 'Giganet Internet Szolgaltato Kft' }, - }, - ip: '45.95.168.157', - }, - fileset: { name: 'auth' }, - input: { type: 'log' }, - '@timestamp': '2020-09-04T07:25:28.000Z', - system: { auth: { ssh: { event: 'Invalid' } } }, - ecs: { version: '1.5.0' }, - related: { ip: ['45.95.168.157'], user: ['webadmin'] }, - service: { type: 'system' }, - host: { hostname: 'bastion00', name: 'bastion00.siem.estc.dev' }, - event: { - ingested: '2020-09-04T07:25:30.236651Z', - timezone: '+00:00', - kind: 'event', - module: 'system', - action: 'ssh_login', - type: ['authentication_failure', 'info'], - category: ['authentication'], - dataset: 'system.auth', - outcome: 'failure', - }, - user: { name: 'webadmin' }, + fields: { + 'source.ip': ['45.95.168.157'], + 'host.name': ['bastion00.siem.estc.dev'], + '@timestamp': ['2020-09-04T07:25:28.000Z'], }, sort: [1599204328000], }, @@ -1331,106 +407,10 @@ export const formattedSearchStrategyResponse = { _index: 'winlogbeat-8.0.0-2020.09.02-000001', _id: 'zqY7WXQBA6bGZw2uLeKI', _score: null, - _source: { - process: { - name: 'services.exe', - pid: 564, - executable: 'C:\\Windows\\System32\\services.exe', - }, - agent: { - build_date: '2020-07-16 09:16:27 +0000 UTC ', - name: 'siem-windows', - commit: '4dcbde39492bdc3843034bba8db811c68cb44b97 ', - id: '05e1bff7-d7a8-416a-8554-aa10288fa07d', - type: 'winlogbeat', - ephemeral_id: '655abd6c-6c33-435d-a2eb-79b2a01e6d61', - version: '8.0.0', - user: { name: 'inside_winlogbeat_user' }, - }, - winlog: { - computer_name: 'siem-windows', - process: { pid: 576, thread: { id: 880 } }, - keywords: ['Audit Success'], - logon: { id: '0x3e7', type: 'Service' }, - channel: 'Security', - event_data: { - LogonGuid: '{00000000-0000-0000-0000-000000000000}', - TargetOutboundDomainName: '-', - VirtualAccount: '%%1843', - LogonType: '5', - IpPort: '-', - TransmittedServices: '-', - SubjectLogonId: '0x3e7', - LmPackageName: '-', - TargetOutboundUserName: '-', - KeyLength: '0', - TargetLogonId: '0x3e7', - RestrictedAdminMode: '-', - SubjectUserName: 'SIEM-WINDOWS$', - TargetLinkedLogonId: '0x0', - ElevatedToken: '%%1842', - SubjectDomainName: 'WORKGROUP', - IpAddress: '-', - ImpersonationLevel: '%%1833', - TargetUserName: 'SYSTEM', - LogonProcessName: 'Advapi ', - TargetDomainName: 'NT AUTHORITY', - SubjectUserSid: 'S-1-5-18', - TargetUserSid: 'S-1-5-18', - AuthenticationPackageName: 'Negotiate', - }, - opcode: 'Info', - version: 2, - record_id: 57818, - task: 'Logon', - event_id: 4624, - provider_guid: '{54849625-5478-4994-a5ba-3e3b0328c30d}', - activity_id: '{d2485217-6bac-0000-8fbb-3f7e2571d601}', - api: 'wineventlog', - provider_name: 'Microsoft-Windows-Security-Auditing', - }, - log: { level: 'information' }, - source: { domain: '-' }, - message: - 'An account was successfully logged on.\n\nSubject:\n\tSecurity ID:\t\tS-1-5-18\n\tAccount Name:\t\tSIEM-WINDOWS$\n\tAccount Domain:\t\tWORKGROUP\n\tLogon ID:\t\t0x3E7\n\nLogon Information:\n\tLogon Type:\t\t5\n\tRestricted Admin Mode:\t-\n\tVirtual Account:\t\tNo\n\tElevated Token:\t\tYes\n\nImpersonation Level:\t\tImpersonation\n\nNew Logon:\n\tSecurity ID:\t\tS-1-5-18\n\tAccount Name:\t\tSYSTEM\n\tAccount Domain:\t\tNT AUTHORITY\n\tLogon ID:\t\t0x3E7\n\tLinked Logon ID:\t\t0x0\n\tNetwork Account Name:\t-\n\tNetwork Account Domain:\t-\n\tLogon GUID:\t\t{00000000-0000-0000-0000-000000000000}\n\nProcess Information:\n\tProcess ID:\t\t0x234\n\tProcess Name:\t\tC:\\Windows\\System32\\services.exe\n\nNetwork Information:\n\tWorkstation Name:\t-\n\tSource Network Address:\t-\n\tSource Port:\t\t-\n\nDetailed Authentication Information:\n\tLogon Process:\t\tAdvapi \n\tAuthentication Package:\tNegotiate\n\tTransited Services:\t-\n\tPackage Name (NTLM only):\t-\n\tKey Length:\t\t0\n\nThis event is generated when a logon session is created. It is generated on the computer that was accessed.\n\nThe subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe.\n\nThe logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network).\n\nThe New Logon fields indicate the account for whom the new logon was created, i.e. the account that was logged on.\n\nThe network fields indicate where a remote logon request originated. Workstation name is not always available and may be left blank in some cases.\n\nThe impersonation level field indicates the extent to which a process in the logon session can impersonate.\n\nThe authentication information fields provide detailed information about this specific logon request.\n\t- Logon GUID is a unique identifier that can be used to correlate this event with a KDC event.\n\t- Transited services indicate which intermediate services have participated in this logon request.\n\t- Package name indicates which sub-protocol was used among the NTLM protocols.\n\t- Key length indicates the length of the generated session key. This will be 0 if no session key was requested.', - cloud: { - availability_zone: 'us-central1-c', - instance: { name: 'siem-windows', id: '9156726559029788564' }, - provider: 'gcp', - machine: { type: 'g1-small' }, - project: { id: 'elastic-siem' }, - }, - '@timestamp': '2020-09-04T13:08:02.532Z', - related: { user: ['SYSTEM', 'SIEM-WINDOWS$'] }, - ecs: { version: '1.5.0' }, - host: { - hostname: 'siem-windows', - os: { - build: '17763.1397', - kernel: '10.0.17763.1397 (WinBuild.160101.0800)', - name: 'Windows Server 2019 Datacenter', - family: 'windows', - version: '10.0', - platform: 'windows', - }, - ip: ['fe80::ecf5:decc:3ec3:767e', '10.200.0.15'], - name: 'siem-windows', - id: 'ce1d3c9b-a815-4643-9641-ada0f2c00609', - mac: ['42:01:0a:c8:00:0f'], - architecture: 'x86_64', - }, - event: { - code: 4624, - provider: 'Microsoft-Windows-Security-Auditing', - created: '2020-09-04T13:08:03.638Z', - kind: 'event', - module: 'security', - action: 'logged-in', - category: 'authentication', - type: 'start', - outcome: 'success', - }, - user: { domain: 'NT AUTHORITY', name: 'SYSTEM', id: 'S-1-5-18' }, + fields: { + 'host.id': ['ce1d3c9b-a815-4643-9641-ada0f2c00609'], + 'host.name': ['siem-windows'], + '@timestamp': ['2020-09-04T13:08:02.532Z'], }, sort: [1599224882532], }, @@ -1457,76 +437,11 @@ export const formattedSearchStrategyResponse = { _index: '.ds-logs-system.auth-default-000001', _id: '9_sfWXQBc39KFIJbIsDh', _score: null, - _source: { - agent: { - hostname: 'siem-kibana', - name: 'siem-kibana', - id: 'aa3d9dc7-fef1-4c2f-a68d-25785d624e35', - ephemeral_id: 'e503bd85-11c7-4bc9-ae7d-70be1d919fb7', - type: 'filebeat', - version: '7.9.1', - }, - process: { name: 'sshd', pid: 20764 }, - log: { file: { path: '/var/log/auth.log' }, offset: 552463 }, - source: { - geo: { - continent_name: 'Europe', - region_iso_code: 'DE-BE', - city_name: 'Berlin', - country_iso_code: 'DE', - region_name: 'Land Berlin', - location: { lon: 13.3512, lat: 52.5727 }, - }, - as: { number: 6805, organization: { name: 'Telefonica Germany' } }, - port: 57457, - ip: '77.183.42.188', - }, - cloud: { - availability_zone: 'us-east1-b', - instance: { name: 'siem-kibana', id: '5412578377715150143' }, - provider: 'gcp', - machine: { type: 'n1-standard-2' }, - project: { id: 'elastic-beats' }, - }, - input: { type: 'log' }, - '@timestamp': '2020-09-04T11:49:21.000Z', - system: { - auth: { - ssh: { - method: 'publickey', - signature: 'RSA SHA256:vv64JNLzKZWYA9vonnGWuW7zxWhyZrL/BFxyIGbISx8', - event: 'Accepted', - }, - }, - }, - ecs: { version: '1.5.0' }, - data_stream: { namespace: 'default', type: 'logs', dataset: 'system.auth' }, - host: { - hostname: 'siem-kibana', - os: { - kernel: '4.9.0-8-amd64', - codename: 'stretch', - name: 'Debian GNU/Linux', - family: 'debian', - version: '9 (stretch)', - platform: 'debian', - }, - containerized: false, - ip: ['10.142.0.7', 'fe80::4001:aff:fe8e:7'], - name: 'siem-kibana', - id: 'aa7ca589f1b8220002f2fc61c64cfbf1', - mac: ['42:01:0a:8e:00:07'], - architecture: 'x86_64', - }, - event: { - timezone: '+00:00', - action: 'ssh_login', - type: 'authentication_success', - category: 'authentication', - dataset: 'system.auth', - outcome: 'success', - }, - user: { name: 'tsg' }, + fields: { + 'source.ip': ['77.183.42.188'], + 'host.id': ['aa7ca589f1b8220002f2fc61c64cfbf1'], + 'host.name': ['siem-kibana'], + '@timestamp': ['2020-09-04T11:49:21.000Z'], }, sort: [1599220161000], }, @@ -1549,67 +464,11 @@ export const formattedSearchStrategyResponse = { _index: '.ds-logs-system.auth-default-000001', _id: 'ZfxZWXQBc39KFIJbLN5U', _score: null, - _source: { - agent: { - hostname: 'siem-kibana', - name: 'siem-kibana', - id: 'aa3d9dc7-fef1-4c2f-a68d-25785d624e35', - ephemeral_id: 'e503bd85-11c7-4bc9-ae7d-70be1d919fb7', - type: 'filebeat', - version: '7.9.1', - }, - process: { name: 'sshd', pid: 22913 }, - log: { file: { path: '/var/log/auth.log' }, offset: 562910 }, - source: { - geo: { - continent_name: 'Asia', - region_iso_code: 'KR-28', - city_name: 'Incheon', - country_iso_code: 'KR', - region_name: 'Incheon', - location: { lon: 126.7288, lat: 37.4562 }, - }, - as: { number: 4766, organization: { name: 'Korea Telecom' } }, - ip: '59.15.3.197', - }, - cloud: { - availability_zone: 'us-east1-b', - instance: { name: 'siem-kibana', id: '5412578377715150143' }, - provider: 'gcp', - machine: { type: 'n1-standard-2' }, - project: { id: 'elastic-beats' }, - }, - input: { type: 'log' }, - '@timestamp': '2020-09-04T13:40:46.000Z', - system: { auth: { ssh: { event: 'Invalid' } } }, - ecs: { version: '1.5.0' }, - data_stream: { namespace: 'default', type: 'logs', dataset: 'system.auth' }, - host: { - hostname: 'siem-kibana', - os: { - kernel: '4.9.0-8-amd64', - codename: 'stretch', - name: 'Debian GNU/Linux', - family: 'debian', - version: '9 (stretch)', - platform: 'debian', - }, - containerized: false, - ip: ['10.142.0.7', 'fe80::4001:aff:fe8e:7'], - name: 'siem-kibana', - id: 'aa7ca589f1b8220002f2fc61c64cfbf1', - mac: ['42:01:0a:8e:00:07'], - architecture: 'x86_64', - }, - event: { - timezone: '+00:00', - action: 'ssh_login', - type: 'authentication_failure', - category: 'authentication', - dataset: 'system.auth', - outcome: 'failure', - }, - user: { name: 'admin' }, + fields: { + 'source.ip': ['59.15.3.197'], + 'host.id': ['aa7ca589f1b8220002f2fc61c64cfbf1'], + 'host.name': ['siem-kibana'], + '@timestamp': ['2020-09-04T13:40:46.000Z'], }, sort: [1599226846000], }, @@ -1636,47 +495,10 @@ export const formattedSearchStrategyResponse = { _index: 'filebeat-8.0.0-2020.09.02-000001', _id: 'M_xLWXQBc39KFIJbY7Cb', _score: null, - _source: { - agent: { - name: 'bastion00.siem.estc.dev', - id: 'f9a321c1-ec27-49fa-aacf-6a50ef6d836f', - type: 'filebeat', - ephemeral_id: '734ee3da-1a4f-4bc9-b400-e0cf0e5eeebc', - version: '8.0.0', - }, - process: { name: 'sshd', pid: 20671 }, - log: { file: { path: '/var/log/auth.log' }, offset: 1028103 }, - source: { - geo: { - continent_name: 'North America', - region_iso_code: 'US-NY', - city_name: 'New York', - country_iso_code: 'US', - region_name: 'New York', - location: { lon: -74, lat: 40.7157 }, - }, - ip: '64.227.88.245', - }, - fileset: { name: 'auth' }, - input: { type: 'log' }, - '@timestamp': '2020-09-04T13:25:43.000Z', - system: { auth: { ssh: { event: 'Invalid' } } }, - ecs: { version: '1.5.0' }, - related: { ip: ['64.227.88.245'], user: ['user'] }, - service: { type: 'system' }, - host: { hostname: 'bastion00', name: 'bastion00.siem.estc.dev' }, - event: { - ingested: '2020-09-04T13:25:47.034172Z', - timezone: '+00:00', - kind: 'event', - module: 'system', - action: 'ssh_login', - type: ['authentication_failure', 'info'], - category: ['authentication'], - dataset: 'system.auth', - outcome: 'failure', - }, - user: { name: 'user' }, + fields: { + 'source.ip': ['64.227.88.245'], + 'host.name': ['bastion00.siem.estc.dev'], + '@timestamp': ['2020-09-04T13:25:43.000Z'], }, sort: [1599225943000], }, @@ -1703,47 +525,10 @@ export const formattedSearchStrategyResponse = { _index: 'filebeat-8.0.0-2020.09.02-000001', _id: 'nPxKWXQBc39KFIJb7q4w', _score: null, - _source: { - agent: { - name: 'bastion00.siem.estc.dev', - id: 'f9a321c1-ec27-49fa-aacf-6a50ef6d836f', - ephemeral_id: '734ee3da-1a4f-4bc9-b400-e0cf0e5eeebc', - type: 'filebeat', - version: '8.0.0', - }, - process: { name: 'sshd', pid: 20665 }, - log: { file: { path: '/var/log/auth.log' }, offset: 1027372 }, - source: { - geo: { - continent_name: 'North America', - region_iso_code: 'US-NY', - city_name: 'New York', - country_iso_code: 'US', - region_name: 'New York', - location: { lon: -74, lat: 40.7157 }, - }, - ip: '64.227.88.245', - }, - fileset: { name: 'auth' }, - input: { type: 'log' }, - '@timestamp': '2020-09-04T13:25:07.000Z', - system: { auth: { ssh: { event: 'Invalid' } } }, - ecs: { version: '1.5.0' }, - related: { ip: ['64.227.88.245'], user: ['ubuntu'] }, - service: { type: 'system' }, - host: { hostname: 'bastion00', name: 'bastion00.siem.estc.dev' }, - event: { - ingested: '2020-09-04T13:25:16.974606Z', - timezone: '+00:00', - kind: 'event', - module: 'system', - action: 'ssh_login', - type: ['authentication_failure', 'info'], - category: ['authentication'], - dataset: 'system.auth', - outcome: 'failure', - }, - user: { name: 'ubuntu' }, + fields: { + 'source.ip': ['64.227.88.245'], + 'host.name': ['bastion00.siem.estc.dev'], + '@timestamp': ['2020-09-04T13:25:07.000Z'], }, sort: [1599225907000], }, @@ -1770,67 +555,11 @@ export const formattedSearchStrategyResponse = { _index: '.ds-logs-system.auth-default-000001', _id: 'mPsfWXQBc39KFIJbI8HI', _score: null, - _source: { - agent: { - hostname: 'siem-kibana', - name: 'siem-kibana', - id: 'aa3d9dc7-fef1-4c2f-a68d-25785d624e35', - type: 'filebeat', - ephemeral_id: 'e503bd85-11c7-4bc9-ae7d-70be1d919fb7', - version: '7.9.1', - }, - process: { name: 'sshd', pid: 21506 }, - log: { file: { path: '/var/log/auth.log' }, offset: 556761 }, - source: { - geo: { - continent_name: 'Asia', - region_iso_code: 'IN-DL', - city_name: 'New Delhi', - country_iso_code: 'IN', - region_name: 'National Capital Territory of Delhi', - location: { lon: 77.2245, lat: 28.6358 }, - }, - as: { number: 10029, organization: { name: 'SHYAM SPECTRA PVT LTD' } }, - ip: '180.151.228.166', - }, - cloud: { - availability_zone: 'us-east1-b', - instance: { name: 'siem-kibana', id: '5412578377715150143' }, - provider: 'gcp', - machine: { type: 'n1-standard-2' }, - project: { id: 'elastic-beats' }, - }, - input: { type: 'log' }, - '@timestamp': '2020-09-04T12:26:36.000Z', - system: { auth: { ssh: { event: 'Invalid' } } }, - ecs: { version: '1.5.0' }, - data_stream: { namespace: 'default', type: 'logs', dataset: 'system.auth' }, - host: { - hostname: 'siem-kibana', - os: { - kernel: '4.9.0-8-amd64', - codename: 'stretch', - name: 'Debian GNU/Linux', - family: 'debian', - version: '9 (stretch)', - platform: 'debian', - }, - containerized: false, - ip: ['10.142.0.7', 'fe80::4001:aff:fe8e:7'], - name: 'siem-kibana', - id: 'aa7ca589f1b8220002f2fc61c64cfbf1', - mac: ['42:01:0a:8e:00:07'], - architecture: 'x86_64', - }, - event: { - timezone: '+00:00', - action: 'ssh_login', - type: 'authentication_failure', - category: 'authentication', - dataset: 'system.auth', - outcome: 'failure', - }, - user: { name: 'odoo' }, + fields: { + 'source.ip': ['180.151.228.166'], + 'host.id': ['aa7ca589f1b8220002f2fc61c64cfbf1'], + 'host.name': ['siem-kibana'], + '@timestamp': ['2020-09-04T12:26:36.000Z'], }, sort: [1599222396000], }, @@ -1857,48 +586,10 @@ export const formattedSearchStrategyResponse = { _index: 'filebeat-8.0.0-2020.09.02-000001', _id: 'aaToWHQBA6bGZw2uR-St', _score: null, - _source: { - agent: { - name: 'bastion00.siem.estc.dev', - id: 'f9a321c1-ec27-49fa-aacf-6a50ef6d836f', - type: 'filebeat', - ephemeral_id: '734ee3da-1a4f-4bc9-b400-e0cf0e5eeebc', - version: '8.0.0', - }, - process: { name: 'sshd', pid: 20475 }, - log: { file: { path: '/var/log/auth.log' }, offset: 1019218 }, - source: { - geo: { - continent_name: 'Europe', - region_iso_code: 'SE-AB', - city_name: 'Stockholm', - country_iso_code: 'SE', - region_name: 'Stockholm', - location: { lon: 17.7833, lat: 59.25 }, - }, - as: { number: 8473, organization: { name: 'Bahnhof AB' } }, - ip: '178.174.148.58', - }, - fileset: { name: 'auth' }, - input: { type: 'log' }, - '@timestamp': '2020-09-04T11:37:22.000Z', - system: { auth: { ssh: { event: 'Invalid' } } }, - ecs: { version: '1.5.0' }, - related: { ip: ['178.174.148.58'], user: ['pi'] }, - service: { type: 'system' }, - host: { hostname: 'bastion00', name: 'bastion00.siem.estc.dev' }, - event: { - ingested: '2020-09-04T11:37:31.797423Z', - timezone: '+00:00', - kind: 'event', - module: 'system', - action: 'ssh_login', - type: ['authentication_failure', 'info'], - category: ['authentication'], - dataset: 'system.auth', - outcome: 'failure', - }, - user: { name: 'pi' }, + fields: { + 'source.ip': ['178.174.148.58'], + 'host.name': ['bastion00.siem.estc.dev'], + '@timestamp': ['2020-09-04T11:37:22.000Z'], }, sort: [1599219442000], }, @@ -1925,48 +616,10 @@ export const formattedSearchStrategyResponse = { _index: 'filebeat-8.0.0-2020.09.02-000001', _id: 'VaP_V3QBA6bGZw2upUbg', _score: null, - _source: { - agent: { - name: 'bastion00.siem.estc.dev', - id: 'f9a321c1-ec27-49fa-aacf-6a50ef6d836f', - type: 'filebeat', - ephemeral_id: '734ee3da-1a4f-4bc9-b400-e0cf0e5eeebc', - version: '8.0.0', - }, - process: { name: 'sshd', pid: 19849 }, - log: { file: { path: '/var/log/auth.log' }, offset: 981036 }, - source: { - geo: { - continent_name: 'Europe', - country_iso_code: 'HR', - location: { lon: 15.5, lat: 45.1667 }, - }, - as: { - number: 42864, - organization: { name: 'Giganet Internet Szolgaltato Kft' }, - }, - ip: '45.95.168.157', - }, - fileset: { name: 'auth' }, - input: { type: 'log' }, - '@timestamp': '2020-09-04T07:23:22.000Z', - system: { auth: { ssh: { event: 'Invalid' } } }, - ecs: { version: '1.5.0' }, - related: { ip: ['45.95.168.157'], user: ['demo'] }, - service: { type: 'system' }, - host: { hostname: 'bastion00', name: 'bastion00.siem.estc.dev' }, - event: { - ingested: '2020-09-04T07:23:26.046346Z', - timezone: '+00:00', - kind: 'event', - module: 'system', - action: 'ssh_login', - type: ['authentication_failure', 'info'], - category: ['authentication'], - dataset: 'system.auth', - outcome: 'failure', - }, - user: { name: 'demo' }, + fields: { + 'source.ip': ['45.95.168.157'], + 'host.name': ['bastion00.siem.estc.dev'], + '@timestamp': ['2020-09-04T07:23:22.000Z'], }, sort: [1599204202000], }, @@ -1993,72 +646,11 @@ export const formattedSearchStrategyResponse = { _index: '.ds-logs-system.auth-default-000001', _id: 'PqYfWXQBA6bGZw2uIhVU', _score: null, - _source: { - agent: { - hostname: 'siem-kibana', - name: 'siem-kibana', - id: 'aa3d9dc7-fef1-4c2f-a68d-25785d624e35', - ephemeral_id: 'e503bd85-11c7-4bc9-ae7d-70be1d919fb7', - type: 'filebeat', - version: '7.9.1', - }, - process: { name: 'sshd', pid: 20396 }, - log: { file: { path: '/var/log/auth.log' }, offset: 550795 }, - source: { - geo: { - continent_name: 'Asia', - region_iso_code: 'CN-BJ', - city_name: 'Beijing', - country_iso_code: 'CN', - region_name: 'Beijing', - location: { lon: 116.3889, lat: 39.9288 }, - }, - as: { - number: 45090, - organization: { - name: 'Shenzhen Tencent Computer Systems Company Limited', - }, - }, - ip: '123.206.30.76', - }, - cloud: { - availability_zone: 'us-east1-b', - instance: { name: 'siem-kibana', id: '5412578377715150143' }, - provider: 'gcp', - machine: { type: 'n1-standard-2' }, - project: { id: 'elastic-beats' }, - }, - input: { type: 'log' }, - '@timestamp': '2020-09-04T11:20:26.000Z', - system: { auth: { ssh: { event: 'Invalid' } } }, - ecs: { version: '1.5.0' }, - data_stream: { namespace: 'default', type: 'logs', dataset: 'system.auth' }, - host: { - hostname: 'siem-kibana', - os: { - kernel: '4.9.0-8-amd64', - codename: 'stretch', - name: 'Debian GNU/Linux', - family: 'debian', - version: '9 (stretch)', - platform: 'debian', - }, - containerized: false, - ip: ['10.142.0.7', 'fe80::4001:aff:fe8e:7'], - name: 'siem-kibana', - id: 'aa7ca589f1b8220002f2fc61c64cfbf1', - mac: ['42:01:0a:8e:00:07'], - architecture: 'x86_64', - }, - event: { - timezone: '+00:00', - action: 'ssh_login', - type: 'authentication_failure', - category: 'authentication', - dataset: 'system.auth', - outcome: 'failure', - }, - user: { name: 'git' }, + fields: { + 'source.ip': ['123.206.30.76'], + 'host.id': ['aa7ca589f1b8220002f2fc61c64cfbf1'], + 'host.name': ['siem-kibana'], + '@timestamp': ['2020-09-04T11:20:26.000Z'], }, sort: [1599218426000], }, @@ -2085,48 +677,10 @@ export const formattedSearchStrategyResponse = { _index: 'filebeat-8.0.0-2020.09.02-000001', _id: 'iMABWHQBB-gskclyitP-', _score: null, - _source: { - agent: { - name: 'bastion00.siem.estc.dev', - id: 'f9a321c1-ec27-49fa-aacf-6a50ef6d836f', - type: 'filebeat', - ephemeral_id: '734ee3da-1a4f-4bc9-b400-e0cf0e5eeebc', - version: '8.0.0', - }, - process: { name: 'sshd', pid: 19870 }, - log: { file: { path: '/var/log/auth.log' }, offset: 984133 }, - source: { - geo: { - continent_name: 'Europe', - country_iso_code: 'HR', - location: { lon: 15.5, lat: 45.1667 }, - }, - as: { - number: 42864, - organization: { name: 'Giganet Internet Szolgaltato Kft' }, - }, - ip: '45.95.168.157', - }, - fileset: { name: 'auth' }, - input: { type: 'log' }, - '@timestamp': '2020-09-04T07:25:28.000Z', - system: { auth: { ssh: { event: 'Invalid' } } }, - ecs: { version: '1.5.0' }, - related: { ip: ['45.95.168.157'], user: ['webadmin'] }, - service: { type: 'system' }, - host: { hostname: 'bastion00', name: 'bastion00.siem.estc.dev' }, - event: { - ingested: '2020-09-04T07:25:30.236651Z', - timezone: '+00:00', - kind: 'event', - module: 'system', - action: 'ssh_login', - type: ['authentication_failure', 'info'], - category: ['authentication'], - dataset: 'system.auth', - outcome: 'failure', - }, - user: { name: 'webadmin' }, + fields: { + 'source.ip': ['45.95.168.157'], + 'host.name': ['bastion00.siem.estc.dev'], + '@timestamp': ['2020-09-04T07:25:28.000Z'], }, sort: [1599204328000], }, @@ -2163,7 +717,6 @@ export const formattedSearchStrategyResponse = { ], ignore_unavailable: true, body: { - docvalue_fields: mockOptions.docValueFields, aggregations: { stack_by_count: { cardinality: { field: 'user.name' } }, stack_by: { @@ -2179,7 +732,7 @@ export const formattedSearchStrategyResponse = { lastFailure: { top_hits: { size: 1, - _source: [], + _source: false, sort: [{ '@timestamp': { order: 'desc' } }], }, }, @@ -2191,7 +744,7 @@ export const formattedSearchStrategyResponse = { lastSuccess: { top_hits: { size: 1, - _source: [], + _source: false, sort: [{ '@timestamp': { order: 'desc' } }], }, }, @@ -2218,6 +771,16 @@ export const formattedSearchStrategyResponse = { }, }, size: 0, + _source: false, + fields: [ + 'source.ip', + 'host.id', + 'host.name', + { + field: '@timestamp', + format: 'strict_date_optional_time', + }, + ], }, track_total_hits: false, }, @@ -2238,7 +801,7 @@ export const formattedSearchStrategyResponse = { host: { id: ['ce1d3c9b-a815-4643-9641-ada0f2c00609'], name: ['siem-windows'] }, }, }, - cursor: { value: '', tiebreaker: null }, + cursor: { value: undefined, tiebreaker: null }, }, { node: { @@ -2252,13 +815,13 @@ export const formattedSearchStrategyResponse = { host: { id: ['aa7ca589f1b8220002f2fc61c64cfbf1'], name: ['siem-kibana'] }, }, }, - cursor: { value: '', tiebreaker: null }, + cursor: { value: undefined, tiebreaker: null }, }, { node: { failures: 23, successes: 0, - _id: 'admin+23', + _id: 'ZfxZWXQBc39KFIJbLN5U', stackedValue: ['admin'], lastFailure: { timestamp: ['2020-09-04T13:40:46.000Z'], @@ -2266,13 +829,13 @@ export const formattedSearchStrategyResponse = { host: { id: ['aa7ca589f1b8220002f2fc61c64cfbf1'], name: ['siem-kibana'] }, }, }, - cursor: { value: '', tiebreaker: null }, + cursor: { value: undefined, tiebreaker: null }, }, { node: { failures: 21, successes: 0, - _id: 'user+21', + _id: 'M_xLWXQBc39KFIJbY7Cb', stackedValue: ['user'], lastFailure: { timestamp: ['2020-09-04T13:25:43.000Z'], @@ -2280,13 +843,13 @@ export const formattedSearchStrategyResponse = { host: { name: ['bastion00.siem.estc.dev'] }, }, }, - cursor: { value: '', tiebreaker: null }, + cursor: { value: undefined, tiebreaker: null }, }, { node: { failures: 18, successes: 0, - _id: 'ubuntu+18', + _id: 'nPxKWXQBc39KFIJb7q4w', stackedValue: ['ubuntu'], lastFailure: { timestamp: ['2020-09-04T13:25:07.000Z'], @@ -2294,13 +857,13 @@ export const formattedSearchStrategyResponse = { host: { name: ['bastion00.siem.estc.dev'] }, }, }, - cursor: { value: '', tiebreaker: null }, + cursor: { value: undefined, tiebreaker: null }, }, { node: { failures: 17, successes: 0, - _id: 'odoo+17', + _id: 'mPsfWXQBc39KFIJbI8HI', stackedValue: ['odoo'], lastFailure: { timestamp: ['2020-09-04T12:26:36.000Z'], @@ -2308,13 +871,13 @@ export const formattedSearchStrategyResponse = { host: { id: ['aa7ca589f1b8220002f2fc61c64cfbf1'], name: ['siem-kibana'] }, }, }, - cursor: { value: '', tiebreaker: null }, + cursor: { value: undefined, tiebreaker: null }, }, { node: { failures: 17, successes: 0, - _id: 'pi+17', + _id: 'aaToWHQBA6bGZw2uR-St', stackedValue: ['pi'], lastFailure: { timestamp: ['2020-09-04T11:37:22.000Z'], @@ -2322,13 +885,13 @@ export const formattedSearchStrategyResponse = { host: { name: ['bastion00.siem.estc.dev'] }, }, }, - cursor: { value: '', tiebreaker: null }, + cursor: { value: undefined, tiebreaker: null }, }, { node: { failures: 14, successes: 0, - _id: 'demo+14', + _id: 'VaP_V3QBA6bGZw2upUbg', stackedValue: ['demo'], lastFailure: { timestamp: ['2020-09-04T07:23:22.000Z'], @@ -2336,13 +899,13 @@ export const formattedSearchStrategyResponse = { host: { name: ['bastion00.siem.estc.dev'] }, }, }, - cursor: { value: '', tiebreaker: null }, + cursor: { value: undefined, tiebreaker: null }, }, { node: { failures: 13, successes: 0, - _id: 'git+13', + _id: 'PqYfWXQBA6bGZw2uIhVU', stackedValue: ['git'], lastFailure: { timestamp: ['2020-09-04T11:20:26.000Z'], @@ -2350,13 +913,13 @@ export const formattedSearchStrategyResponse = { host: { id: ['aa7ca589f1b8220002f2fc61c64cfbf1'], name: ['siem-kibana'] }, }, }, - cursor: { value: '', tiebreaker: null }, + cursor: { value: undefined, tiebreaker: null }, }, { node: { failures: 13, successes: 0, - _id: 'webadmin+13', + _id: 'iMABWHQBB-gskclyitP-', stackedValue: ['webadmin'], lastFailure: { timestamp: ['2020-09-04T07:25:28.000Z'], @@ -2364,7 +927,7 @@ export const formattedSearchStrategyResponse = { host: { name: ['bastion00.siem.estc.dev'] }, }, }, - cursor: { value: '', tiebreaker: null }, + cursor: { value: undefined, tiebreaker: null }, }, ], totalCount: 188, @@ -2385,7 +948,6 @@ export const expectedDsl = { ], ignore_unavailable: true, body: { - docvalue_fields: mockOptions.docValueFields, aggregations: { stack_by_count: { cardinality: { field: 'user.name' } }, stack_by: { @@ -2399,7 +961,7 @@ export const expectedDsl = { filter: { term: { 'event.outcome': 'failure' } }, aggs: { lastFailure: { - top_hits: { size: 1, _source: [], sort: [{ '@timestamp': { order: 'desc' } }] }, + top_hits: { size: 1, _source: false, sort: [{ '@timestamp': { order: 'desc' } }] }, }, }, }, @@ -2407,7 +969,7 @@ export const expectedDsl = { filter: { term: { 'event.outcome': 'success' } }, aggs: { lastSuccess: { - top_hits: { size: 1, _source: [], sort: [{ '@timestamp': { order: 'desc' } }] }, + top_hits: { size: 1, _source: false, sort: [{ '@timestamp': { order: 'desc' } }] }, }, }, }, @@ -2431,6 +993,16 @@ export const expectedDsl = { ], }, }, + _source: false, + fields: [ + 'source.ip', + 'host.id', + 'host.name', + { + field: '@timestamp', + format: 'strict_date_optional_time', + }, + ], size: 0, }, track_total_hits: false, @@ -2441,7 +1013,7 @@ export const mockHit: AuthenticationHit = { _type: 'type-123', _id: 'id-123', _score: 10, - _source: { + fields: { '@timestamp': 'time-1', }, cursor: 'cursor-1', diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/dsl/query.dsl.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/dsl/query.dsl.ts index e018716d4c216..3c32ae3f85944 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/dsl/query.dsl.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/dsl/query.dsl.ts @@ -5,26 +5,10 @@ * 2.0. */ -import { isEmpty } from 'lodash/fp'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { UserAuthenticationsRequestOptions } from '../../../../../../../common/search_strategy/security_solution/users/authentications'; -import { sourceFieldsMap, hostFieldsMap } from '../../../../../../../common/ecs/ecs_fields'; - import { createQueryFilterClauses } from '../../../../../../utils/build_query'; -import { reduceFields } from '../../../../../../utils/build_query/reduce_fields'; - import { authenticationsFields } from '../helpers'; -import { extendMap } from '../../../../../../../common/ecs/ecs_fields/extend_map'; - -export const auditdFieldsMap: Readonly> = { - latest: '@timestamp', - 'lastSuccess.timestamp': 'lastSuccess.@timestamp', - 'lastFailure.timestamp': 'lastFailure.@timestamp', - ...{ ...extendMap('lastSuccess', sourceFieldsMap) }, - ...{ ...extendMap('lastSuccess', hostFieldsMap) }, - ...{ ...extendMap('lastFailure', sourceFieldsMap) }, - ...{ ...extendMap('lastFailure', hostFieldsMap) }, -}; export const buildQuery = ({ filterQuery, @@ -32,13 +16,7 @@ export const buildQuery = ({ timerange: { from, to }, pagination: { querySize }, defaultIndex, - docValueFields, }: UserAuthenticationsRequestOptions) => { - const esFields = reduceFields(authenticationsFields, { - ...hostFieldsMap, - ...sourceFieldsMap, - }) as string[]; - const filter = [ ...createQueryFilterClauses(filterQuery), { term: { 'event.category': 'authentication' } }, @@ -52,13 +30,13 @@ export const buildQuery = ({ }, }, ]; + const queryFields = authenticationsFields.filter((field) => field !== 'timestamp'); const dslQuery = { allow_no_indices: true, index: defaultIndex, ignore_unavailable: true, body: { - ...(!isEmpty(docValueFields) ? { docvalue_fields: docValueFields } : {}), aggregations: { stack_by_count: { cardinality: { @@ -85,7 +63,7 @@ export const buildQuery = ({ lastFailure: { top_hits: { size: 1, - _source: esFields, + _source: false, sort: [{ '@timestamp': { order: 'desc' as const } }], }, }, @@ -101,7 +79,7 @@ export const buildQuery = ({ lastSuccess: { top_hits: { size: 1, - _source: esFields, + _source: false, sort: [{ '@timestamp': { order: 'desc' as const } }], }, }, @@ -116,6 +94,14 @@ export const buildQuery = ({ }, }, size: 0, + _source: false, + fields: [ + ...queryFields, + { + field: '@timestamp', + format: 'strict_date_optional_time', + }, + ], }, track_total_hits: false, }; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/helpers.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/helpers.test.ts index 1e745ffcbf2ed..a8eea076ae1be 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/helpers.test.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/helpers.test.ts @@ -6,15 +6,12 @@ */ import { AuthenticationsEdges } from '../../../../../../common/search_strategy'; -import { auditdFieldsMap } from './dsl/query.dsl'; - import { formatAuthenticationData } from './helpers'; import { mockHit } from './__mocks__'; describe('#formatAuthenticationsData', () => { test('it formats a authentication with an empty set', () => { - const fields: readonly string[] = ['']; - const data = formatAuthenticationData(fields, mockHit, auditdFieldsMap); + const data = formatAuthenticationData(mockHit); const expected: AuthenticationsEdges = { cursor: { tiebreaker: null, @@ -32,8 +29,7 @@ describe('#formatAuthenticationsData', () => { }); test('it formats a authentications with a source ip correctly', () => { - const fields: readonly string[] = ['lastSuccess.source.ip']; - const data = formatAuthenticationData(fields, mockHit, auditdFieldsMap); + const data = formatAuthenticationData(mockHit); const expected: AuthenticationsEdges = { cursor: { tiebreaker: null, @@ -51,8 +47,7 @@ describe('#formatAuthenticationsData', () => { }); test('it formats a authentications with a host name only', () => { - const fields: readonly string[] = ['lastSuccess.host.name']; - const data = formatAuthenticationData(fields, mockHit, auditdFieldsMap); + const data = formatAuthenticationData(mockHit); const expected: AuthenticationsEdges = { cursor: { tiebreaker: null, @@ -70,8 +65,7 @@ describe('#formatAuthenticationsData', () => { }); test('it formats a authentications with a host id only', () => { - const fields: readonly string[] = ['lastSuccess.host.id']; - const data = formatAuthenticationData(fields, mockHit, auditdFieldsMap); + const data = formatAuthenticationData(mockHit); const expected: AuthenticationsEdges = { cursor: { tiebreaker: null, @@ -89,8 +83,7 @@ describe('#formatAuthenticationsData', () => { }); test('it formats a authentications with a host name and id correctly', () => { - const fields: readonly string[] = ['lastSuccess.host.name', 'lastSuccess.host.id']; - const data = formatAuthenticationData(fields, mockHit, auditdFieldsMap); + const data = formatAuthenticationData(mockHit); const expected: AuthenticationsEdges = { cursor: { tiebreaker: null, diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/helpers.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/helpers.ts index 43baa4aadea14..46c0a83a3b572 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/helpers.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/helpers.ts @@ -7,8 +7,8 @@ import { get, getOr, isEmpty } from 'lodash/fp'; import { set } from '@elastic/safer-lodash-set/fp'; -import { mergeFieldsWithHit } from '../../../../../utils/build_query'; import { toObjectArrayOfStrings } from '../../../../../../common/utils/to_array'; +import { sourceFieldsMap, hostFieldsMap } from '../../../../../../common/ecs/ecs_fields'; import { AuthenticationsEdges, AuthenticationHit, @@ -17,78 +17,79 @@ import { StrategyResponseType, } from '../../../../../../common/search_strategy/security_solution'; -export const authenticationsFields = [ - '_id', - 'failures', - 'successes', - 'stackedValue', - 'lastSuccess.timestamp', - 'lastSuccess.source.ip', - 'lastSuccess.host.id', - 'lastSuccess.host.name', - 'lastFailure.timestamp', - 'lastFailure.source.ip', - 'lastFailure.host.id', - 'lastFailure.host.name', -]; +export const authenticationsFields = ['timestamp', 'source.ip', 'host.id', 'host.name']; +export const authenticationsFieldsMap: Readonly> = { + latest: '@timestamp', + lastSuccess: { + timestamp: '@timestamp', + ...sourceFieldsMap, + ...hostFieldsMap, + }, + lastFailure: { + timestamp: '@timestamp', + ...sourceFieldsMap, + ...hostFieldsMap, + }, +}; -export const formatAuthenticationData = ( - fields: readonly string[] = authenticationsFields, - hit: AuthenticationHit, - fieldMap: Readonly> -): AuthenticationsEdges => - fields.reduce( - (flattenedFields, fieldName) => { - if (hit.cursor) { - flattenedFields.cursor.value = hit.cursor; - } - flattenedFields.node = { - ...flattenedFields.node, - ...{ - _id: hit._id, - stackedValue: [hit.stackedValue], - failures: hit.failures, - successes: hit.successes, - }, - }; - const mergedResult = mergeFieldsWithHit(fieldName, flattenedFields, fieldMap, hit); - const fieldPath = `node.${fieldName}`; - const fieldValue = get(fieldPath, mergedResult); +export const formatAuthenticationData = (hit: AuthenticationHit): AuthenticationsEdges => { + let flattenedFields = { + node: { + _id: hit._id, + stackedValue: [hit.stackedValue], + failures: hit.failures, + successes: hit.successes, + }, + cursor: { + value: hit.cursor, + tiebreaker: null, + }, + }; + + const lastSuccessFields = getAuthenticationFields(authenticationsFields, hit, 'lastSuccess'); + if (Object.keys(lastSuccessFields).length > 0) { + flattenedFields = set('node.lastSuccess', lastSuccessFields, flattenedFields); + } + + const lastFailureFields = getAuthenticationFields(authenticationsFields, hit, 'lastFailure'); + if (Object.keys(lastFailureFields).length > 0) { + flattenedFields = set('node.lastFailure', lastFailureFields, flattenedFields); + } + + return flattenedFields; +}; + +const getAuthenticationFields = (fields: string[], hit: AuthenticationHit, parentField: string) => { + return fields.reduce((flattenedFields, fieldName) => { + const fieldPath = `${fieldName}`; + const esField = get(`${parentField}['${fieldName}']`, authenticationsFieldsMap); + + if (!isEmpty(esField)) { + const fieldValue = get(`${parentField}['${esField}']`, hit.fields); if (!isEmpty(fieldValue)) { return set( fieldPath, toObjectArrayOfStrings(fieldValue).map(({ str }) => str), - mergedResult + flattenedFields ); - } else { - return mergedResult; } - }, - { - node: { - failures: 0, - successes: 0, - _id: '', - stackedValue: [''], - }, - cursor: { - value: '', - tiebreaker: null, - }, } - ); + + return flattenedFields; + }, {}); +}; export const getHits = (response: StrategyResponseType) => getOr([], 'aggregations.stack_by.buckets', response.rawResponse).map( (bucket: AuthenticationBucket) => ({ _id: getOr( `${bucket.key}+${bucket.doc_count}`, - 'failures.lastFailure.hits.hits[0].id', + 'failures.lastFailure.hits.hits[0]._id', bucket ), - _source: { - lastSuccess: getOr(null, 'successes.lastSuccess.hits.hits[0]._source', bucket), - lastFailure: getOr(null, 'failures.lastFailure.hits.hits[0]._source', bucket), + fields: { + lastSuccess: getOr(null, 'successes.lastSuccess.hits.hits[0].fields', bucket), + lastFailure: getOr(null, 'failures.lastFailure.hits.hits[0].fields', bucket), }, stackedValue: bucket.key, failures: bucket.failures.doc_count, diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/index.tsx b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/index.tsx index 5bb62f685ce4b..f2483b78dc3ef 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/index.tsx +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/index.tsx @@ -20,9 +20,9 @@ import { UsersQueries } from '../../../../../../common/search_strategy/security_ import { inspectStringifyObject } from '../../../../../utils/build_query'; import { SecuritySolutionFactory } from '../../types'; -import { auditdFieldsMap, buildQuery as buildAuthenticationQuery } from './dsl/query.dsl'; +import { buildQuery as buildAuthenticationQuery } from './dsl/query.dsl'; -import { authenticationsFields, formatAuthenticationData, getHits } from './helpers'; +import { formatAuthenticationData, getHits } from './helpers'; export const authentications: SecuritySolutionFactory = { buildDsl: (options: UserAuthenticationsRequestOptions) => { @@ -42,7 +42,7 @@ export const authentications: SecuritySolutionFactory - formatAuthenticationData(authenticationsFields, hit, auditdFieldsMap) + formatAuthenticationData(hit) ); const edges = authenticationEdges.splice(cursorStart, querySize - cursorStart); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/details/__mocks__/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/details/__mocks__/index.ts index 33760eec4556e..5b54ffaf8dff8 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/details/__mocks__/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/details/__mocks__/index.ts @@ -12,12 +12,6 @@ import { UserDetailsRequestOptions } from '../../../../../../../common/search_st export const mockOptions: UserDetailsRequestOptions = { defaultIndex: ['test_indices*'], - docValueFields: [ - { - field: '@timestamp', - format: 'date_time', - }, - ], factoryQueryType: UsersQueries.details, filterQuery: '{"bool":{"must":[],"filter":[{"match_all":{}},{"match_phrase":{"user.name":{"query":"test_user"}}}],"should":[],"must_not":[]}}', diff --git a/x-pack/plugins/security_solution/server/types.ts b/x-pack/plugins/security_solution/server/types.ts index c0e496ba4e647..b1bf51439a3f6 100644 --- a/x-pack/plugins/security_solution/server/types.ts +++ b/x-pack/plugins/security_solution/server/types.ts @@ -5,7 +5,11 @@ * 2.0. */ -import type { IRouter, RequestHandlerContext } from '@kbn/core/server'; +import type { + IRouter, + CustomRequestHandlerContext, + CoreRequestHandlerContext, +} from '@kbn/core/server'; import type { ActionsApiRequestHandlerContext } from '@kbn/actions-plugin/server'; import type { AlertingApiRequestHandlerContext } from '@kbn/alerting-plugin/server'; import type { FleetRequestHandlerContext } from '@kbn/fleet-plugin/server'; @@ -21,7 +25,8 @@ import { EndpointAuthz } from '../common/endpoint/types/authz'; export { AppClient }; -export interface SecuritySolutionApiRequestHandlerContext extends RequestHandlerContext { +export interface SecuritySolutionApiRequestHandlerContext { + core: CoreRequestHandlerContext; endpointAuthz: EndpointAuthz; getConfig: () => ConfigType; getFrameworkRequest: () => FrameworkRequest; @@ -32,13 +37,13 @@ export interface SecuritySolutionApiRequestHandlerContext extends RequestHandler getExceptionListClient: () => ExceptionListClient | null; } -export interface SecuritySolutionRequestHandlerContext extends RequestHandlerContext { +export type SecuritySolutionRequestHandlerContext = CustomRequestHandlerContext<{ securitySolution: SecuritySolutionApiRequestHandlerContext; actions: ActionsApiRequestHandlerContext; alerting: AlertingApiRequestHandlerContext; licensing: LicensingApiRequestHandlerContext; lists?: ListsApiRequestHandlerContext; fleet?: FleetRequestHandlerContext['fleet']; -} +}>; export type SecuritySolutionPluginRouter = IRouter; diff --git a/x-pack/plugins/security_solution/server/usage/detections/get_metrics.test.ts b/x-pack/plugins/security_solution/server/usage/detections/get_metrics.test.ts index 4e782f914df70..9c40d662544c1 100644 --- a/x-pack/plugins/security_solution/server/usage/detections/get_metrics.test.ts +++ b/x-pack/plugins/security_solution/server/usage/detections/get_metrics.test.ts @@ -131,7 +131,7 @@ describe('Detections Usage and Metrics', () => { esClient.search.mockResponseOnce(getEventLogElasticRules()); esClient.search.mockResponseOnce(getElasticLogCustomRules()); esClient.search.mockResponseOnce(getMockRuleAlertsResponse(800)); - savedObjectsClient.find.mockResolvedValueOnce(getMockRuleSearchResponse('not_immutable')); + savedObjectsClient.find.mockResolvedValueOnce(getMockRuleSearchResponse(false)); savedObjectsClient.find.mockResolvedValueOnce(getMockAlertCaseCommentsResponse()); // Get empty saved object for legacy notification system. savedObjectsClient.find.mockResolvedValueOnce(getEmptySavedObjectResponse()); diff --git a/x-pack/plugins/security_solution/server/usage/detections/ml_jobs/get_metrics.mocks.ts b/x-pack/plugins/security_solution/server/usage/detections/ml_jobs/get_metrics.mocks.ts index 0863ca6cef411..4ad8f2213a682 100644 --- a/x-pack/plugins/security_solution/server/usage/detections/ml_jobs/get_metrics.mocks.ts +++ b/x-pack/plugins/security_solution/server/usage/detections/ml_jobs/get_metrics.mocks.ts @@ -291,7 +291,7 @@ export const getMockMlDatafeedStatsResponse = () => ({ }); export const getMockRuleSearchResponse = ( - immutableTag: string = '__internal_immutable:true' + immutable: boolean = true ): SavedObjectsFindResponse => ({ page: 1, @@ -304,16 +304,7 @@ export const getMockRuleSearchResponse = ( namespaces: ['default'], attributes: { name: 'Azure Diagnostic Settings Deletion', - tags: [ - 'Elastic', - 'Cloud', - 'Azure', - 'Continuous Monitoring', - 'SecOps', - 'Monitoring', - '__internal_rule_id:5370d4cd-2bb3-4d71-abf5-1e1d0ff5a2de', - `${immutableTag}`, - ], + tags: ['Elastic', 'Cloud', 'Azure', 'Continuous Monitoring', 'SecOps', 'Monitoring'], alertTypeId: 'siem.queryRule', consumer: 'siem', params: { @@ -326,7 +317,7 @@ export const getMockRuleSearchResponse = ( 'Deletion of diagnostic settings may be done by a system or network administrator. Verify whether the username, hostname, and/or resource name should be making changes in your environment. Diagnostic settings deletion from unfamiliar users or hosts should be investigated. If known behavior is causing false positives, it can be exempted from the rule.', ], from: 'now-25m', - immutable: true, + immutable, query: 'event.dataset:azure.activitylogs and azure.activitylogs.operation_name:"MICROSOFT.INSIGHTS/DIAGNOSTICSETTINGS/DELETE" and event.outcome:(Success or success)', language: 'kuery', diff --git a/x-pack/plugins/security_solution/server/usage/detections/rules/transform_utils/get_rule_object_correlations.ts b/x-pack/plugins/security_solution/server/usage/detections/rules/transform_utils/get_rule_object_correlations.ts index 169cb502521df..5387c63aace3e 100644 --- a/x-pack/plugins/security_solution/server/usage/detections/rules/transform_utils/get_rule_object_correlations.ts +++ b/x-pack/plugins/security_solution/server/usage/detections/rules/transform_utils/get_rule_object_correlations.ts @@ -9,8 +9,6 @@ import type { SavedObjectsFindResult } from '@kbn/core/server'; import type { RuleMetric } from '../types'; import type { RuleSearchResult } from '../../../types'; -import { isElasticRule } from '../../../queries/utils/is_elastic_rule'; - export interface RuleObjectCorrelationsOptions { ruleResults: Array>; legacyNotificationRuleIds: Map< @@ -32,7 +30,6 @@ export const getRuleObjectCorrelations = ({ return ruleResults.map((result) => { const ruleId = result.id; const { attributes } = result; - const isElastic = isElasticRule(attributes.tags); // Even if the legacy notification is set to "no_actions" we still count the rule as having a legacy notification that is not migrated yet. const hasLegacyNotification = legacyNotificationRuleIds.get(ruleId) != null; @@ -50,7 +47,8 @@ export const getRuleObjectCorrelations = ({ rule_type: attributes.params.type, rule_version: attributes.params.version, enabled: attributes.enabled, - elastic_rule: isElastic, + // if rule immutable, it's Elastic/prebuilt + elastic_rule: attributes.params.immutable, created_on: attributes.createdAt, updated_on: attributes.updatedAt, alert_count_daily: alertsCounts.get(ruleId) || 0, diff --git a/x-pack/plugins/security_solution/server/usage/queries/utils/is_elastic_rule.ts b/x-pack/plugins/security_solution/server/usage/queries/utils/is_elastic_rule.ts deleted file mode 100644 index f08959702b290..0000000000000 --- a/x-pack/plugins/security_solution/server/usage/queries/utils/is_elastic_rule.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { INTERNAL_IMMUTABLE_KEY } from '../../../../common/constants'; - -export const isElasticRule = (tags: string[] = []) => - tags.includes(`${INTERNAL_IMMUTABLE_KEY}:true`); diff --git a/x-pack/plugins/security_solution/tsconfig.json b/x-pack/plugins/security_solution/tsconfig.json index 95aaeffad7f71..cc1656ace3c65 100644 --- a/x-pack/plugins/security_solution/tsconfig.json +++ b/x-pack/plugins/security_solution/tsconfig.json @@ -32,7 +32,6 @@ { "path": "../actions/tsconfig.json" }, { "path": "../alerting/tsconfig.json" }, { "path": "../cases/tsconfig.json" }, - { "path": "../data_enhanced/tsconfig.json" }, { "path": "../encrypted_saved_objects/tsconfig.json" }, { "path": "../features/tsconfig.json" }, { "path": "../fleet/tsconfig.json" }, diff --git a/x-pack/plugins/session_view/common/constants.ts b/x-pack/plugins/session_view/common/constants.ts index 0e1a7c16172f2..98c27bd4f86e1 100644 --- a/x-pack/plugins/session_view/common/constants.ts +++ b/x-pack/plugins/session_view/common/constants.ts @@ -13,7 +13,7 @@ export const PROCESS_EVENTS_INDEX = 'logs-endpoint.events.process-*'; export const PREVIEW_ALERTS_INDEX = '.preview.alerts-security.alerts-default'; export const ENTRY_SESSION_ENTITY_ID_PROPERTY = 'process.entry_leader.entity_id'; export const ALERT_UUID_PROPERTY = 'kibana.alert.uuid'; -export const KIBANA_DATE_FORMAT = 'MMM DD, YYYY @ hh:mm:ss.SSS'; +export const KIBANA_DATE_FORMAT = 'MMM DD, YYYY @ HH:mm:ss.SSS'; export const ALERT_STATUS = { OPEN: 'open', ACKNOWLEDGED: 'acknowledged', diff --git a/x-pack/plugins/session_view/common/mocks/constants/session_view_process.mock.ts b/x-pack/plugins/session_view/common/mocks/constants/session_view_process.mock.ts index 6def7c7bcbd47..76f954d1fe72e 100644 --- a/x-pack/plugins/session_view/common/mocks/constants/session_view_process.mock.ts +++ b/x-pack/plugins/session_view/common/mocks/constants/session_view_process.mock.ts @@ -819,8 +819,8 @@ export const mockAlerts: ProcessEvent[] = [ architecture: 'x86_64', hostname: 'james-fleet-714-2', id: '48c1b3f1ac5da4e0057fc9f60f4d1d5d', - ip: '127.0.0.1,::1,10.132.0.50,fe80::7d39:3147:4d9a:f809', - mac: '42:01:0a:84:00:32', + ip: ['127.0.0.1', '::1', '10.132.0.50', 'fe80::7d39:3147:4d9a:f809'], + mac: ['42:01:0a:84:00:32'], name: 'james-fleet-714-2', os: { family: 'centos', @@ -1006,8 +1006,8 @@ export const mockAlerts: ProcessEvent[] = [ architecture: 'x86_64', hostname: 'james-fleet-714-2', id: '48c1b3f1ac5da4e0057fc9f60f4d1d5d', - ip: '127.0.0.1,::1,10.132.0.50,fe80::7d39:3147:4d9a:f809', - mac: '42:01:0a:84:00:32', + ip: ['127.0.0.1', '::1', '10.132.0.50', 'fe80::7d39:3147:4d9a:f809'], + mac: ['42:01:0a:84:00:32'], name: 'james-fleet-714-2', os: { family: 'centos', @@ -1285,8 +1285,8 @@ export const childProcessMock: Process = { architecture: 'x86_64', hostname: 'james-fleet-714-2', id: '48c1b3f1ac5da4e0057fc9f60f4d1d5d', - ip: '127.0.0.1,::1,10.132.0.50,fe80::7d39:3147:4d9a:f809', - mac: '42:01:0a:84:00:32', + ip: ['127.0.0.1', '::1', '10.132.0.50', 'fe80::7d39:3147:4d9a:f809'], + mac: ['42:01:0a:84:00:32'], name: 'james-fleet-714-2', os: { family: 'centos', @@ -1370,8 +1370,8 @@ export const processMock: Process = { architecture: 'x86_64', hostname: 'james-fleet-714-2', id: '48c1b3f1ac5da4e0057fc9f60f4d1d5d', - ip: '127.0.0.1,::1,10.132.0.50,fe80::7d39:3147:4d9a:f809', - mac: '42:01:0a:84:00:32', + ip: ['127.0.0.1', '::1', '10.132.0.50', 'fe80::7d39:3147:4d9a:f809'], + mac: ['42:01:0a:84:00:32'], name: 'james-fleet-714-2', os: { family: 'centos', diff --git a/x-pack/plugins/session_view/common/mocks/responses/session_view_process_events.mock.ts b/x-pack/plugins/session_view/common/mocks/responses/session_view_process_events.mock.ts index 47849f859ba9c..78206cc1a6320 100644 --- a/x-pack/plugins/session_view/common/mocks/responses/session_view_process_events.mock.ts +++ b/x-pack/plugins/session_view/common/mocks/responses/session_view_process_events.mock.ts @@ -24,8 +24,8 @@ export const sessionViewProcessEventsMock: ProcessEventResults = { architecture: 'x86_64', hostname: 'james-fleet-714-2', id: '48c1b3f1ac5da4e0057fc9f60f4d1d5d', - ip: '127.0.0.1,::1,10.132.0.50,fe80::7d39:3147:4d9a:f809', - mac: '42:01:0a:84:00:32', + ip: ['127.0.0.1', '::1', '10.132.0.50', 'fe80::7d39:3147:4d9a:f809'], + mac: ['42:01:0a:84:00:32'], name: 'james-fleet-714-2', os: { Ext: { @@ -427,8 +427,8 @@ export const sessionViewProcessEventsMock: ProcessEventResults = { architecture: 'x86_64', hostname: 'james-fleet-714-2', id: '48c1b3f1ac5da4e0057fc9f60f4d1d5d', - ip: '127.0.0.1,::1,10.132.0.50,fe80::7d39:3147:4d9a:f809', - mac: '42:01:0a:84:00:32', + ip: ['127.0.0.1', '::1', '10.132.0.50', 'fe80::7d39:3147:4d9a:f809'], + mac: ['42:01:0a:84:00:32'], name: 'james-fleet-714-2', os: { Ext: { @@ -836,8 +836,8 @@ export const sessionViewProcessEventsMock: ProcessEventResults = { architecture: 'x86_64', hostname: 'james-fleet-714-2', id: '48c1b3f1ac5da4e0057fc9f60f4d1d5d', - ip: '127.0.0.1,::1,10.132.0.50,fe80::7d39:3147:4d9a:f809', - mac: '42:01:0a:84:00:32', + ip: ['127.0.0.1', '::1', '10.132.0.50', 'fe80::7d39:3147:4d9a:f809'], + mac: ['42:01:0a:84:00:32'], name: 'james-fleet-714-2', os: { Ext: { diff --git a/x-pack/plugins/session_view/common/types/process_tree/index.ts b/x-pack/plugins/session_view/common/types/process_tree/index.ts index 11f5aeb2ffac2..f337b6a38c742 100644 --- a/x-pack/plugins/session_view/common/types/process_tree/index.ts +++ b/x-pack/plugins/session_view/common/types/process_tree/index.ts @@ -97,8 +97,8 @@ export interface ProcessEventHost { architecture?: string; hostname?: string; id?: string; - ip?: string; - mac?: string; + ip?: string[]; + mac?: string[]; name?: string; os?: { family?: string; diff --git a/x-pack/plugins/session_view/public/components/back_to_investigated_alert/index.tsx b/x-pack/plugins/session_view/public/components/back_to_investigated_alert/index.tsx index 6252335c29f61..78ce2f4d871ea 100644 --- a/x-pack/plugins/session_view/public/components/back_to_investigated_alert/index.tsx +++ b/x-pack/plugins/session_view/public/components/back_to_investigated_alert/index.tsx @@ -29,7 +29,7 @@ export const BackToInvestigatedAlert = ({ return (
{ - const { euiTheme } = useEuiTheme(); + const { euiTheme, euiVars } = useEuiTheme(); const cached = useMemo(() => { - const { size, colors, font } = euiTheme; + const { size, font } = euiTheme; - const buttonBackgroundColor = colors.primary; + const buttonStyle = { + color: euiLightVars.euiColorEmptyShade, + backgroundColor: euiLightVars.euiColorPrimaryText, + }; const container: CSSObject = { position: 'absolute', @@ -41,18 +44,18 @@ export const useStyles = ({ isDisplayedAbove }: StylesDeps) => { if (isDisplayedAbove) { container.top = 0; - container.background = `linear-gradient(180deg, ${theme.euiColorLightestShade} 0%, transparent 100%)`; + container.background = `linear-gradient(180deg, ${euiVars.euiColorLightestShade} 0%, transparent 100%)`; } else { container.bottom = 0; - container.background = `linear-gradient(360deg, ${theme.euiColorLightestShade} 0%, transparent 100%)`; + container.background = `linear-gradient(360deg, ${euiVars.euiColorLightestShade} 0%, transparent 100%)`; } return { container, jumpBackBadge, - buttonBackgroundColor, + buttonStyle, }; - }, [isDisplayedAbove, euiTheme]); + }, [isDisplayedAbove, euiTheme, euiVars]); return cached; }; diff --git a/x-pack/plugins/session_view/public/components/detail_panel_alert_group_item/index.tsx b/x-pack/plugins/session_view/public/components/detail_panel_alert_group_item/index.tsx index a83e41d793e23..562bd013ebd60 100644 --- a/x-pack/plugins/session_view/public/components/detail_panel_alert_group_item/index.tsx +++ b/x-pack/plugins/session_view/public/components/detail_panel_alert_group_item/index.tsx @@ -66,6 +66,7 @@ export const DetailPanelAlertGroupItem = ({ data-test-subj={ALERT_GROUP_ITEM_COUNT_TEST_ID} className="eui-alignCenter" size="m" + css={styles.alertCountArrowPad} > {alertsCount} diff --git a/x-pack/plugins/session_view/public/components/detail_panel_alert_list_item/index.tsx b/x-pack/plugins/session_view/public/components/detail_panel_alert_list_item/index.tsx index 1c6dd0a57b7e7..26fd2af6b69d6 100644 --- a/x-pack/plugins/session_view/public/components/detail_panel_alert_list_item/index.tsx +++ b/x-pack/plugins/session_view/public/components/detail_panel_alert_list_item/index.tsx @@ -59,7 +59,7 @@ export const DetailPanelAlertListItem = ({ const forceState = !isInvestigated ? 'open' : undefined; return minimal ? ( -
+
diff --git a/x-pack/plugins/session_view/public/components/detail_panel_alert_list_item/styles.ts b/x-pack/plugins/session_view/public/components/detail_panel_alert_list_item/styles.ts index 403c6d3e2cacb..4cd77e48c2c4d 100644 --- a/x-pack/plugins/session_view/public/components/detail_panel_alert_list_item/styles.ts +++ b/x-pack/plugins/session_view/public/components/detail_panel_alert_list_item/styles.ts @@ -79,6 +79,10 @@ export const useStyles = (minimal = false, isInvestigated = false) => { minWidth: 0, }; + const alertCountArrowPad: CSSObject = { + marginRight: size.xs, + }; + const processPanel: CSSObject = { border: `${borderThickness} solid ${colors.lightShade}`, fontFamily: font.familyCode, @@ -103,6 +107,12 @@ export const useStyles = (minimal = false, isInvestigated = false) => { float: 'right', }; + const firstAlertPad: CSSObject = { + '&:first-child': { + paddingTop: size.base, + }, + }; + const minimalHR: CSSObject = { marginBottom: 0, }; @@ -114,9 +124,11 @@ export const useStyles = (minimal = false, isInvestigated = false) => { alertTitle, alertIcon, alertAccordionButton, + alertCountArrowPad, processPanel, investigatedLabel, minimalContextMenu, + firstAlertPad, minimalHR, }; }, [euiTheme, isInvestigated, minimal]); diff --git a/x-pack/plugins/session_view/public/components/detail_panel_alert_tab/styles.ts b/x-pack/plugins/session_view/public/components/detail_panel_alert_tab/styles.ts index a906744cdafb2..702d4f20f3554 100644 --- a/x-pack/plugins/session_view/public/components/detail_panel_alert_tab/styles.ts +++ b/x-pack/plugins/session_view/public/components/detail_panel_alert_tab/styles.ts @@ -24,12 +24,10 @@ export const useStyles = () => { top: 0, zIndex: 1, backgroundColor: colors.emptyShade, - paddingTop: size.base, }; const viewMode: CSSObject = { margin: size.base, - marginBottom: 0, }; return { diff --git a/x-pack/plugins/session_view/public/components/detail_panel_copy/__snapshots__/index.test.tsx.snap b/x-pack/plugins/session_view/public/components/detail_panel_copy/__snapshots__/index.test.tsx.snap new file mode 100644 index 0000000000000..ea9f03408af67 --- /dev/null +++ b/x-pack/plugins/session_view/public/components/detail_panel_copy/__snapshots__/index.test.tsx.snap @@ -0,0 +1,88 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`DetailPanelCopy component When DetailPanelCopy is mounted renders DetailPanelCopy correctly 1`] = ` +Object { + "asFragment": [Function], + "baseElement": +
+
+ + + copy component test + + +
+
+ , + "container":
+
+ + + copy component test + + +
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; diff --git a/x-pack/plugins/session_view/public/components/detail_panel_copy/index.test.tsx b/x-pack/plugins/session_view/public/components/detail_panel_copy/index.test.tsx index 4d3c5e16e1bb7..2b1f53c9ab8ab 100644 --- a/x-pack/plugins/session_view/public/components/detail_panel_copy/index.test.tsx +++ b/x-pack/plugins/session_view/public/components/detail_panel_copy/index.test.tsx @@ -24,10 +24,13 @@ describe('DetailPanelCopy component', () => { describe('When DetailPanelCopy is mounted', () => { it('renders DetailPanelCopy correctly', async () => { renderResult = mockedContext.render( - {TEST_CHILD} + + {TEST_CHILD} + ); expect(renderResult.queryByText(TEST_TEXT_COPY)).toBeVisible(); + expect(renderResult).toMatchSnapshot(); }); }); }); diff --git a/x-pack/plugins/session_view/public/components/detail_panel_copy/index.tsx b/x-pack/plugins/session_view/public/components/detail_panel_copy/index.tsx index 0716ded33a7db..72febd9ea25ea 100644 --- a/x-pack/plugins/session_view/public/components/detail_panel_copy/index.tsx +++ b/x-pack/plugins/session_view/public/components/detail_panel_copy/index.tsx @@ -5,15 +5,15 @@ * 2.0. */ import React, { ReactNode } from 'react'; -import { EuiButtonIcon, EuiCopy } from '@elastic/eui'; +import { EuiButtonIcon, EuiCopy, EuiToolTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { DetailPanelListItem } from '../detail_panel_list_item'; -import { dataOrDash } from '../../utils/data_or_dash'; import { useStyles } from './styles'; interface DetailPanelCopyDeps { children: ReactNode; - textToCopy: string | number | undefined; + textToCopy: string; + tooltipContent: ReactNode; display?: 'inlineBlock' | 'block' | undefined; } @@ -28,13 +28,14 @@ interface DetailPanelListItemProps { export const DetailPanelCopy = ({ children, textToCopy, + tooltipContent, display = 'inlineBlock', }: DetailPanelCopyDeps) => { const styles = useStyles(); const props: DetailPanelListItemProps = { copy: ( - + {(copy) => ( {children}; + return ( + + + <>{children} + + + ); }; diff --git a/x-pack/plugins/session_view/public/components/detail_panel_description_list/styles.ts b/x-pack/plugins/session_view/public/components/detail_panel_description_list/styles.ts index d1f3198a10c85..be847e52562b5 100644 --- a/x-pack/plugins/session_view/public/components/detail_panel_description_list/styles.ts +++ b/x-pack/plugins/session_view/public/components/detail_panel_description_list/styles.ts @@ -20,14 +20,14 @@ export const useStyles = () => { const tabListTitle = { width: '40%', display: 'flex', - alignItems: 'center', + alignItems: 'baseline', marginTop: '0px', }; const tabListDescription = { width: '60%', display: 'flex', - alignItems: 'center', + alignItems: 'baseline', marginTop: '0px', }; diff --git a/x-pack/plugins/session_view/public/components/detail_panel_host_tab/helpers.test.ts b/x-pack/plugins/session_view/public/components/detail_panel_host_tab/helpers.test.ts new file mode 100644 index 0000000000000..a2d096d91310e --- /dev/null +++ b/x-pack/plugins/session_view/public/components/detail_panel_host_tab/helpers.test.ts @@ -0,0 +1,85 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { ProcessEventHost } from '../../../common/types/process_tree'; +import { DASH } from '../../constants'; +import { getHostData } from './helpers'; + +const MOCK_HOST_DATA: ProcessEventHost = { + architecture: 'x86_64', + hostname: 'james-fleet-714-2', + id: '48c1b3f1ac5da4e0057fc9f60f4d1d5d', + ip: ['127.0.0.1', '::1', '10.132.0.50', 'fe80::7d39:3147:4d9a:f809'], + mac: ['42:01:0a:84:00:32'], + name: 'james-fleet-714-2', + os: { + family: 'centos', + full: 'CentOS 7.9.2009', + kernel: '3.10.0-1160.31.1.el7.x86_64 #1 SMP Thu Jun 10 13:32:12 UTC 2021', + name: 'Linux', + platform: 'centos', + version: '7.9.2009', + }, +}; + +describe('detail panel host tab helpers tests', () => { + it('getHostData returns fields with a dash with undefined host', () => { + const result = getHostData(undefined); + expect(result.architecture).toEqual(DASH); + expect(result.hostname).toEqual(DASH); + expect(result.id).toEqual(DASH); + expect(result.ip).toEqual(DASH); + expect(result.mac).toEqual(DASH); + expect(result.name).toEqual(DASH); + expect(result.os.family).toEqual(DASH); + expect(result.os.full).toEqual(DASH); + expect(result.os.kernel).toEqual(DASH); + expect(result.os.name).toEqual(DASH); + expect(result.os.platform).toEqual(DASH); + expect(result.os.version).toEqual(DASH); + }); + + it('getHostData returns dashes for missing fields', () => { + const result = getHostData({ + ...MOCK_HOST_DATA, + ip: ['127.0.0.1', '', '', 'fe80::7d39:3147:4d9a:f809'], + name: undefined, + os: { + ...MOCK_HOST_DATA.os, + full: undefined, + platform: undefined, + }, + }); + expect(result.architecture).toEqual(MOCK_HOST_DATA.architecture); + expect(result.hostname).toEqual(MOCK_HOST_DATA.hostname); + expect(result.id).toEqual(MOCK_HOST_DATA.id); + expect(result.ip).toEqual(['127.0.0.1', DASH, DASH, 'fe80::7d39:3147:4d9a:f809'].join(', ')); + expect(result.mac).toEqual(MOCK_HOST_DATA.mac?.join(', ')); + expect(result.name).toEqual(DASH); + expect(result.os.family).toEqual(MOCK_HOST_DATA.os?.family); + expect(result.os.full).toEqual(DASH); + expect(result.os.kernel).toEqual(MOCK_HOST_DATA.os?.kernel); + expect(result.os.name).toEqual(MOCK_HOST_DATA.os?.name); + expect(result.os.platform).toEqual(DASH); + expect(result.os.version).toEqual(MOCK_HOST_DATA.os?.version); + }); + + it('getHostData returns all data provided', () => { + const result = getHostData(MOCK_HOST_DATA); + expect(result.architecture).toEqual(MOCK_HOST_DATA.architecture); + expect(result.hostname).toEqual(MOCK_HOST_DATA.hostname); + expect(result.id).toEqual(MOCK_HOST_DATA.id); + expect(result.ip).toEqual(MOCK_HOST_DATA.ip?.join(', ')); + expect(result.mac).toEqual(MOCK_HOST_DATA.mac?.join(', ')); + expect(result.name).toEqual(MOCK_HOST_DATA.name); + expect(result.os.family).toEqual(MOCK_HOST_DATA.os?.family); + expect(result.os.full).toEqual(MOCK_HOST_DATA.os?.full); + expect(result.os.kernel).toEqual(MOCK_HOST_DATA.os?.kernel); + expect(result.os.name).toEqual(MOCK_HOST_DATA.os?.name); + expect(result.os.platform).toEqual(MOCK_HOST_DATA.os?.platform); + expect(result.os.version).toEqual(MOCK_HOST_DATA.os?.version); + }); +}); diff --git a/x-pack/plugins/session_view/public/components/detail_panel_host_tab/helpers.ts b/x-pack/plugins/session_view/public/components/detail_panel_host_tab/helpers.ts new file mode 100644 index 0000000000000..72565f5885e37 --- /dev/null +++ b/x-pack/plugins/session_view/public/components/detail_panel_host_tab/helpers.ts @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ProcessEventHost } from '../../../common/types/process_tree'; +import { DASH } from '../../constants'; +import { DetailPanelHost } from '../../types'; +import { dataOrDash } from '../../utils/data_or_dash'; + +export const getHostData = (host: ProcessEventHost | undefined): DetailPanelHost => { + const detailPanelHost: DetailPanelHost = { + architecture: DASH, + hostname: DASH, + id: DASH, + ip: DASH, + mac: DASH, + name: DASH, + os: { + family: DASH, + full: DASH, + kernel: DASH, + name: DASH, + platform: DASH, + version: DASH, + }, + }; + + if (!host) { + return detailPanelHost; + } + + detailPanelHost.hostname = dataOrDash(host.hostname).toString(); + detailPanelHost.id = dataOrDash(host.id).toString(); + detailPanelHost.ip = host.ip?.map?.((ip) => dataOrDash(ip)).join(', ') ?? DASH; + detailPanelHost.mac = host.mac?.map?.((mac) => dataOrDash(mac)).join(', ') ?? DASH; + detailPanelHost.name = dataOrDash(host.name).toString(); + detailPanelHost.architecture = dataOrDash(host.architecture).toString(); + detailPanelHost.os.family = dataOrDash(host.os?.family).toString(); + detailPanelHost.os.full = dataOrDash(host.os?.full).toString(); + detailPanelHost.os.kernel = dataOrDash(host.os?.kernel).toString(); + detailPanelHost.os.name = dataOrDash(host.os?.name).toString(); + detailPanelHost.os.platform = dataOrDash(host.os?.platform).toString(); + detailPanelHost.os.version = dataOrDash(host.os?.version).toString(); + + return detailPanelHost; +}; diff --git a/x-pack/plugins/session_view/public/components/detail_panel_host_tab/index.test.tsx b/x-pack/plugins/session_view/public/components/detail_panel_host_tab/index.test.tsx index 17e9102fb8ed9..41a5ada524974 100644 --- a/x-pack/plugins/session_view/public/components/detail_panel_host_tab/index.test.tsx +++ b/x-pack/plugins/session_view/public/components/detail_panel_host_tab/index.test.tsx @@ -13,8 +13,8 @@ import { DetailPanelHostTab } from '.'; const TEST_ARCHITECTURE = 'x86_64'; const TEST_HOSTNAME = 'host-james-fleet-714-2'; const TEST_ID = '48c1b3f1ac5da4e0057fc9f60f4d1d5d'; -const TEST_IP = '127.0.0.1,::1,10.132.0.50,fe80::7d39:3147:4d9a:f809'; -const TEST_MAC = '42:01:0a:84:00:32'; +const TEST_IP = ['127.0.0.1', '::1', '10.132.0.50', 'fe80::7d39:3147:4d9a:f809']; +const TEST_MAC = ['42:01:0a:84:00:32']; const TEST_NAME = 'name-james-fleet-714-2'; const TEST_OS_FAMILY = 'family-centos'; const TEST_OS_FULL = 'full-CentOS 7.9.2009'; @@ -62,8 +62,8 @@ describe('DetailPanelHostTab component', () => { expect(renderResult.queryByText(TEST_ARCHITECTURE)).toBeVisible(); expect(renderResult.queryByText(TEST_HOSTNAME)).toBeVisible(); expect(renderResult.queryByText(TEST_ID)).toBeVisible(); - expect(renderResult.queryByText(TEST_IP)).toBeVisible(); - expect(renderResult.queryByText(TEST_MAC)).toBeVisible(); + expect(renderResult.queryByText(TEST_IP.join(', '))).toBeVisible(); + expect(renderResult.queryByText(TEST_MAC.join(', '))).toBeVisible(); expect(renderResult.queryByText(TEST_NAME)).toBeVisible(); // expand host os accordion diff --git a/x-pack/plugins/session_view/public/components/detail_panel_host_tab/index.tsx b/x-pack/plugins/session_view/public/components/detail_panel_host_tab/index.tsx index b2869f6c4e24b..2b1c2f97fa738 100644 --- a/x-pack/plugins/session_view/public/components/detail_panel_host_tab/index.tsx +++ b/x-pack/plugins/session_view/public/components/detail_panel_host_tab/index.tsx @@ -4,15 +4,15 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React from 'react'; +import React, { useMemo } from 'react'; import { EuiTextColor } from '@elastic/eui'; import { ProcessEventHost } from '../../../common/types/process_tree'; import { DetailPanelAccordion } from '../detail_panel_accordion'; import { DetailPanelCopy } from '../detail_panel_copy'; import { DetailPanelDescriptionList } from '../detail_panel_description_list'; import { DetailPanelListItem } from '../detail_panel_list_item'; -import { dataOrDash } from '../../utils/data_or_dash'; import { useStyles } from '../detail_panel_process_tab/styles'; +import { getHostData } from './helpers'; interface DetailPanelHostTabDeps { processHost?: ProcessEventHost; @@ -23,6 +23,7 @@ interface DetailPanelHostTabDeps { */ export const DetailPanelHostTab = ({ processHost }: DetailPanelHostTabDeps) => { const styles = useStyles(); + const hostData = useMemo(() => getHostData(processHost), [processHost]); return ( <> @@ -31,9 +32,12 @@ export const DetailPanelHostTab = ({ processHost }: DetailPanelHostTabDeps) => { { title: hostname, description: ( - + - {dataOrDash(processHost?.hostname)} + {hostData.hostname} ), @@ -41,9 +45,12 @@ export const DetailPanelHostTab = ({ processHost }: DetailPanelHostTabDeps) => { { title: id, description: ( - + - {dataOrDash(processHost?.id)} + {hostData.id} ), @@ -51,9 +58,12 @@ export const DetailPanelHostTab = ({ processHost }: DetailPanelHostTabDeps) => { { title: ip, description: ( - + - {dataOrDash(processHost?.ip)} + {hostData.ip} ), @@ -61,9 +71,12 @@ export const DetailPanelHostTab = ({ processHost }: DetailPanelHostTabDeps) => { { title: mac, description: ( - + - {dataOrDash(processHost?.mac)} + {hostData.mac} ), @@ -71,9 +84,12 @@ export const DetailPanelHostTab = ({ processHost }: DetailPanelHostTabDeps) => { { title: name, description: ( - + - {dataOrDash(processHost?.name)} + {hostData.name} ), @@ -87,9 +103,12 @@ export const DetailPanelHostTab = ({ processHost }: DetailPanelHostTabDeps) => { { title: architecture, description: ( - + - {dataOrDash(processHost?.architecture)} + {hostData.architecture} ), @@ -97,9 +116,12 @@ export const DetailPanelHostTab = ({ processHost }: DetailPanelHostTabDeps) => { { title: os.family, description: ( - + - {dataOrDash(processHost?.os?.family)} + {hostData.os.family} ), @@ -107,9 +129,12 @@ export const DetailPanelHostTab = ({ processHost }: DetailPanelHostTabDeps) => { { title: os.full, description: ( - + - {dataOrDash(processHost?.os?.full)} + {hostData.os.full} ), @@ -117,9 +142,12 @@ export const DetailPanelHostTab = ({ processHost }: DetailPanelHostTabDeps) => { { title: os.kernel, description: ( - + - {dataOrDash(processHost?.os?.kernel)} + {hostData.os.kernel} ), @@ -127,9 +155,12 @@ export const DetailPanelHostTab = ({ processHost }: DetailPanelHostTabDeps) => { { title: os.name, description: ( - + - {dataOrDash(processHost?.os?.name)} + {hostData.os.name} ), @@ -137,9 +168,12 @@ export const DetailPanelHostTab = ({ processHost }: DetailPanelHostTabDeps) => { { title: os.platform, description: ( - + - {dataOrDash(processHost?.os?.platform)} + {hostData.os.platform} ), @@ -147,9 +181,12 @@ export const DetailPanelHostTab = ({ processHost }: DetailPanelHostTabDeps) => { { title: os.version, description: ( - + - {dataOrDash(processHost?.os?.version)} + {hostData.os.version} ), diff --git a/x-pack/plugins/session_view/public/components/detail_panel_list_item/index.tsx b/x-pack/plugins/session_view/public/components/detail_panel_list_item/index.tsx index 93a6554bbe54a..3ba8dee8965fd 100644 --- a/x-pack/plugins/session_view/public/components/detail_panel_list_item/index.tsx +++ b/x-pack/plugins/session_view/public/components/detail_panel_list_item/index.tsx @@ -27,7 +27,7 @@ interface EuiTextPropsCss extends EuiTextProps { export const DetailPanelListItem = ({ children, copy, - display = 'flex', + display = 'grid', }: DetailPanelListItemDeps) => { const [isHovered, setIsHovered] = useState(false); const styles = useStyles({ display }); diff --git a/x-pack/plugins/session_view/public/components/detail_panel_list_item/styles.ts b/x-pack/plugins/session_view/public/components/detail_panel_list_item/styles.ts index 22f5e6782288f..48a8dba781ee4 100644 --- a/x-pack/plugins/session_view/public/components/detail_panel_list_item/styles.ts +++ b/x-pack/plugins/session_view/public/components/detail_panel_list_item/styles.ts @@ -19,14 +19,21 @@ export const useStyles = ({ display }: StylesDeps) => { const cached = useMemo(() => { const item: CSSObject = { display, - alignItems: 'center', - padding: `0px ${euiTheme.size.s} `, + alignContent: 'center', + padding: `${euiTheme.size.xs} ${euiTheme.size.s} `, width: '100%', fontWeight: 'inherit', - height: euiTheme.size.xl, - lineHeight: euiTheme.size.l, + height: 'max-content', + minHeight: euiTheme.size.l, letterSpacing: '0px', textAlign: 'left', + + '& .euiToolTipAnchor': { + width: `calc(100% - ${euiTheme.size.xl})`, + whiteSpace: 'nowrap', + overflow: 'hidden', + textOverflow: 'ellipsis', + }, }; const copiableItem: CSSObject = { @@ -36,7 +43,7 @@ export const useStyles = ({ display }: StylesDeps) => { '&:hover': { background: transparentize(euiTheme.colors.primary, 0.1), }, - height: '100%', + height: 'fit-content', }; return { diff --git a/x-pack/plugins/session_view/public/components/detail_panel_process_tab/helpers.test.ts b/x-pack/plugins/session_view/public/components/detail_panel_process_tab/helpers.test.ts index de5339fa2bbbe..a50c6e73e198d 100644 --- a/x-pack/plugins/session_view/public/components/detail_panel_process_tab/helpers.test.ts +++ b/x-pack/plugins/session_view/public/components/detail_panel_process_tab/helpers.test.ts @@ -4,6 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import { DASH } from '../../constants'; import { getProcessExecutableCopyText, formatProcessArgs, getIsInterativeString } from './helpers'; describe('detail panel process tab helpers tests', () => { @@ -36,7 +37,7 @@ describe('detail panel process tab helpers tests', () => { it("formatProcessArgs returns '-' when given empty args array", () => { const result = formatProcessArgs([]); - expect(result).toEqual('-'); + expect(result).toEqual(DASH); }); it('formatProcessArgs returns formatted args string', () => { diff --git a/x-pack/plugins/session_view/public/components/detail_panel_process_tab/helpers.ts b/x-pack/plugins/session_view/public/components/detail_panel_process_tab/helpers.ts index 4584e7fb217dd..4417a5329a752 100644 --- a/x-pack/plugins/session_view/public/components/detail_panel_process_tab/helpers.ts +++ b/x-pack/plugins/session_view/public/components/detail_panel_process_tab/helpers.ts @@ -5,7 +5,29 @@ * 2.0. */ -import { Teletype } from '../../../common/types/process_tree'; +import { EventAction, Process, ProcessFields, Teletype } from '../../../common/types/process_tree'; +import { DetailPanelProcess, DetailPanelProcessLeader } from '../../types'; +import { DASH } from '../../constants'; +import { dataOrDash } from '../../utils/data_or_dash'; + +const FILTER_FORKS_EXECS = [EventAction.fork, EventAction.exec]; + +const DEFAULT_PROCESS_DATA: DetailPanelProcessLeader = { + id: DASH, + name: DASH, + start: DASH, + end: DASH, + exitCode: DASH, + userName: DASH, + groupName: DASH, + workingDirectory: DASH, + interactive: DASH, + args: DASH, + pid: DASH, + entryMetaType: DASH, + entryMetaSourceIp: DASH, + executable: [[DASH]], +}; /** * Serialize an array of executable tuples to a copyable text. @@ -32,11 +54,11 @@ export const getProcessExecutableCopyText = (executable: string[][]): string => /** * Format an array of args for display. * - * @param {String[]} args + * @param {String[] | undefined} args * @return {String} formatted string of process args */ -export const formatProcessArgs = (args: string[]): string => - args.length ? `[${args.map((arg) => `'${arg}'`).join(', ')}]` : '-'; +export const formatProcessArgs = (args: string[] | undefined): string => + args && args.length && args.map ? `[${args.map((arg) => `'${arg}'`).join(', ')}]` : DASH; /** * Get isInteractive boolean string from tty. @@ -46,3 +68,86 @@ export const formatProcessArgs = (args: string[]): string => */ export const getIsInterativeString = (tty: Teletype | undefined): string => !!tty ? 'True' : 'False'; + +const getDetailPanelProcessLeader = ( + leader: ProcessFields | undefined +): DetailPanelProcessLeader => ({ + ...leader, + id: leader?.entity_id ?? DEFAULT_PROCESS_DATA.id, + name: leader?.name ?? DEFAULT_PROCESS_DATA.name, + start: leader?.start ?? DEFAULT_PROCESS_DATA.start, + end: leader?.end ?? DEFAULT_PROCESS_DATA.end, + exitCode: leader?.exit_code?.toString() ?? DEFAULT_PROCESS_DATA.exitCode, + interactive: getIsInterativeString(leader?.tty), + userName: leader?.user?.name ?? DEFAULT_PROCESS_DATA.userName, + groupName: leader?.group?.name ?? DEFAULT_PROCESS_DATA.groupName, + workingDirectory: leader?.working_directory ?? DEFAULT_PROCESS_DATA.workingDirectory, + args: formatProcessArgs(leader?.args) ?? DEFAULT_PROCESS_DATA.args, + pid: leader?.pid?.toString() ?? DEFAULT_PROCESS_DATA.pid, + // TODO: get the event action of leader + executable: leader?.executable ? [[leader?.executable]] : DEFAULT_PROCESS_DATA.executable, + entryMetaType: leader?.entry_meta?.type ?? DEFAULT_PROCESS_DATA.entryMetaType, + entryMetaSourceIp: leader?.entry_meta?.source?.ip ?? DEFAULT_PROCESS_DATA.entryMetaSourceIp, +}); + +export const getDetailPanelProcess = (process: Process | null): DetailPanelProcess => { + const processData = { + id: DEFAULT_PROCESS_DATA.id, + start: DEFAULT_PROCESS_DATA.start, + end: DEFAULT_PROCESS_DATA.end, + exitCode: DEFAULT_PROCESS_DATA.exitCode, + interactive: DEFAULT_PROCESS_DATA.interactive, + userName: DEFAULT_PROCESS_DATA.userName, + groupName: DEFAULT_PROCESS_DATA.groupName, + args: DEFAULT_PROCESS_DATA.args, + pid: DEFAULT_PROCESS_DATA.pid, + executable: DEFAULT_PROCESS_DATA.executable, + workingDirectory: DEFAULT_PROCESS_DATA.workingDirectory, + entryLeader: DEFAULT_PROCESS_DATA, + sessionLeader: DEFAULT_PROCESS_DATA, + groupLeader: DEFAULT_PROCESS_DATA, + parent: DEFAULT_PROCESS_DATA, + } as DetailPanelProcess; + if (!process) { + return processData; + } + + const details = process.getDetails(); + + processData.id = `${dataOrDash(process.id)}`; + processData.start = `${dataOrDash(details.process?.start)}`; + processData.end = `${dataOrDash(process.getEndTime())}`; + processData.exitCode = `${dataOrDash(details.process?.exit_code)}`; + processData.interactive = getIsInterativeString(details.process?.tty); + processData.userName = `${dataOrDash(details.process?.user?.name)}`; + processData.groupName = `${dataOrDash(details.process?.group?.name)}`; + processData.pid = `${dataOrDash(details.process?.pid)}`; + processData.workingDirectory = `${dataOrDash(details.process?.working_directory)}`; + if (details.process?.args) { + processData.args = formatProcessArgs(details.process.args); + } + + // we grab the executable from each process lifecycle event to give an indication + // of the processes journey. Processes can sometimes exec multiple times, so it's good + // information to have. + processData.executable = []; + process.events.forEach((event) => { + if ( + event.process?.executable && + event.event?.action && + FILTER_FORKS_EXECS.includes(event.event.action) + ) { + processData.executable.push([event.process.executable, `(${event.event.action})`]); + } + }); + if (!processData.executable.length) { + processData.executable = DEFAULT_PROCESS_DATA.executable; + } + + processData.entryLeader = getDetailPanelProcessLeader(details?.process?.entry_leader); + processData.sessionLeader = getDetailPanelProcessLeader(details?.process?.session_leader); + processData.groupLeader = getDetailPanelProcessLeader(details?.process?.group_leader); + processData.parent = getDetailPanelProcessLeader(details?.process?.parent); + + return processData; +}; diff --git a/x-pack/plugins/session_view/public/components/detail_panel_process_tab/index.test.tsx b/x-pack/plugins/session_view/public/components/detail_panel_process_tab/index.test.tsx index 7daaf997e2af8..488d83ca9880e 100644 --- a/x-pack/plugins/session_view/public/components/detail_panel_process_tab/index.test.tsx +++ b/x-pack/plugins/session_view/public/components/detail_panel_process_tab/index.test.tsx @@ -7,60 +7,15 @@ import React from 'react'; import { AppContextTestRender, createAppRootMockRenderer } from '../../test'; -import { DetailPanelProcess, DetailPanelProcessLeader } from '../../types'; +import { sessionViewBasicProcessMock } from '../../../common/mocks/constants/session_view_process.mock'; import { DetailPanelProcessTab } from '.'; -const getLeaderDetail = (leader: string): DetailPanelProcessLeader => ({ - id: `${leader}-id`, - name: `${leader}-name`, - start: new Date('2022-02-24').toISOString(), - entryMetaType: 'sshd', - working_directory: '/home/jack', - tty: { - char_device: { - major: 8, - minor: 1, - }, - }, - args: ['ls'], - userName: `${leader}-jack`, - groupName: `${leader}-jack-group`, - pid: 1234, - entryMetaSourceIp: '10.132.0.50', - executable: '/usr/bin/bash', -}); - -const TEST_PROCESS_DETAIL: DetailPanelProcess = { - id: 'process-id', - start: new Date('2022-02-22').toISOString(), - end: new Date('2022-02-23').toISOString(), - exit_code: 137, - userName: 'process-jack', - groupName: 'process-jack-group', - args: ['vi', 'test.txt'], - executable: [ - ['test-executable-cmd', '(fork)'], - ['test-executable-cmd', '(exec)'], - ['test-executable-cmd', '(end)'], - ], - working_directory: '/home/jack', - tty: { - char_device: { - major: 8, - minor: 1, - }, - }, - pid: 1233, - entryLeader: getLeaderDetail('entryLeader'), - sessionLeader: getLeaderDetail('sessionLeader'), - groupLeader: getLeaderDetail('groupLeader'), - parent: getLeaderDetail('parent'), -}; - describe('DetailPanelProcessTab component', () => { let render: () => ReturnType; let renderResult: ReturnType; let mockedContext: AppContextTestRender; + const processDetail = sessionViewBasicProcessMock.getDetails(); + const MOCK_PROCESS_END = '2021-11-24T15:25:04.210Z'; beforeEach(() => { mockedContext = createAppRootMockRenderer(); @@ -69,21 +24,29 @@ describe('DetailPanelProcessTab component', () => { describe('When DetailPanelProcessTab is mounted', () => { it('renders DetailPanelProcessTab correctly', async () => { renderResult = mockedContext.render( - + MOCK_PROCESS_END, + }} + /> ); // Process detail rendered correctly - expect(renderResult.queryByText(TEST_PROCESS_DETAIL.id)).toBeVisible(); - expect(renderResult.queryByText(TEST_PROCESS_DETAIL.start)).toBeVisible(); - expect(renderResult.queryByText(TEST_PROCESS_DETAIL.end)).toBeVisible(); - expect(renderResult.queryByText(TEST_PROCESS_DETAIL.exit_code!)).toBeVisible(); - expect(renderResult.queryByText(TEST_PROCESS_DETAIL.userName)).toBeVisible(); - expect(renderResult.queryByText(`['vi', 'test.txt']`)).toBeVisible(); - expect(renderResult.queryAllByText('test-executable-cmd')).toHaveLength(3); + expect(renderResult.queryByText(processDetail!.process!.entity_id!)).toBeVisible(); + expect(renderResult.queryByText(processDetail!.process!.start!)).toBeVisible(); + expect(renderResult.queryByText(MOCK_PROCESS_END)).toBeVisible(); + expect(renderResult.queryByText(processDetail!.process!.exit_code!)).toBeVisible(); + expect(renderResult.queryAllByText(processDetail!.process!.user!.name!)).toHaveLength(10); + expect(renderResult.queryAllByText(processDetail!.process!.working_directory!)).toHaveLength( + 5 + ); + expect(renderResult.queryByText(`['bash']`)).toBeVisible(); + expect(renderResult.queryAllByText('/usr/bin/bash')).toHaveLength(5); + expect(renderResult.queryByText('/usr/bin/vi')).toBeVisible(); expect(renderResult.queryByText('(fork)')).toBeVisible(); expect(renderResult.queryByText('(exec)')).toBeVisible(); - expect(renderResult.queryByText('(end)')).toBeVisible(); - expect(renderResult.queryByText(TEST_PROCESS_DETAIL.pid!)).toBeVisible(); + expect(renderResult.queryByText(processDetail!.process!.pid!)).toBeVisible(); // Process tab accordions rendered correctly // TODO: revert back when we have jump to leaders button working diff --git a/x-pack/plugins/session_view/public/components/detail_panel_process_tab/index.tsx b/x-pack/plugins/session_view/public/components/detail_panel_process_tab/index.tsx index b148fc99ef7a7..f62c6188203a2 100644 --- a/x-pack/plugins/session_view/public/components/detail_panel_process_tab/index.tsx +++ b/x-pack/plugins/session_view/public/components/detail_panel_process_tab/index.tsx @@ -4,20 +4,20 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React, { ReactNode } from 'react'; +import React, { ReactNode, useCallback, useMemo } from 'react'; import { EuiTextColor } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { DetailPanelProcess } from '../../types'; +import { Process } from '../../../common/types/process_tree'; import { DetailPanelAccordion } from '../detail_panel_accordion'; import { DetailPanelCopy } from '../detail_panel_copy'; import { DetailPanelDescriptionList } from '../detail_panel_description_list'; import { DetailPanelListItem } from '../detail_panel_list_item'; import { dataOrDash } from '../../utils/data_or_dash'; -import { getProcessExecutableCopyText, formatProcessArgs, getIsInterativeString } from './helpers'; +import { getProcessExecutableCopyText, getDetailPanelProcess } from './helpers'; import { useStyles } from './styles'; interface DetailPanelProcessTabDeps { - processDetail: DetailPanelProcess; + selectedProcess: Process | null; } type ListItems = Array<{ @@ -59,11 +59,41 @@ const leaderDescriptionListInfo = [ }, ]; +const PROCESS_FIELD_PREFIX = 'process'; +const LEADER_FIELD_PREFIX = [ + `${PROCESS_FIELD_PREFIX}.entry_leader`, + `${PROCESS_FIELD_PREFIX}.session_leader`, + `${PROCESS_FIELD_PREFIX}.group_leader`, + `${PROCESS_FIELD_PREFIX}.parent`, +]; + /** * Detail panel in the session view. */ -export const DetailPanelProcessTab = ({ processDetail }: DetailPanelProcessTabDeps) => { +export const DetailPanelProcessTab = ({ selectedProcess }: DetailPanelProcessTabDeps) => { const styles = useStyles(); + + const processDetail = useMemo(() => getDetailPanelProcess(selectedProcess), [selectedProcess]); + const renderExecs = useCallback( + (executable: string[][]) => + executable.map((execTuple, idx) => { + const [exec, eventAction] = execTuple; + return ( +
+ + {exec} + + {eventAction && ( + + {eventAction} + + )} +
+ ); + }), + [styles.descriptionSemibold, styles.ellipsis, styles.executableAction] + ); + const leaderListItems = [ processDetail.entryLeader, processDetail.sessionLeader, @@ -74,25 +104,29 @@ export const DetailPanelProcessTab = ({ processDetail }: DetailPanelProcessTabDe id, start, end, - exit_code: exitCode, + exitCode, entryMetaType, - tty, - working_directory: workingDirectory, + interactive, + workingDirectory, args, + executable, pid, userName, groupName, entryMetaSourceIp, } = leader; - const leaderArgs = formatProcessArgs(args); - const isLeaderInteractive = getIsInterativeString(tty); + + const leaderExecutableText = getProcessExecutableCopyText(executable); const listItems: ListItems = [ { title: entity_id, description: ( - + - {dataOrDash(id)} + {id} ), @@ -100,17 +134,34 @@ export const DetailPanelProcessTab = ({ processDetail }: DetailPanelProcessTabDe { title: args, description: ( - - {leaderArgs} + + {args} + + ), + }, + { + title: executable, + description: ( + + {renderExecs(executable)} ), }, { title: interactive, description: ( - + - {isLeaderInteractive} + {interactive} ), @@ -118,9 +169,12 @@ export const DetailPanelProcessTab = ({ processDetail }: DetailPanelProcessTabDe { title: working_directory, description: ( - + - {dataOrDash(workingDirectory)} + {workingDirectory} ), @@ -128,9 +182,12 @@ export const DetailPanelProcessTab = ({ processDetail }: DetailPanelProcessTabDe { title: pid, description: ( - + - {dataOrDash(pid)} + {pid} ), @@ -138,25 +195,34 @@ export const DetailPanelProcessTab = ({ processDetail }: DetailPanelProcessTabDe { title: start, description: ( - - {dataOrDash(start)} + + {start} ), }, { title: end, description: ( - - {dataOrDash(end)} + + {end} ), }, { title: exit_code, description: ( - + - {dataOrDash(exitCode)} + {exitCode} ), @@ -164,16 +230,22 @@ export const DetailPanelProcessTab = ({ processDetail }: DetailPanelProcessTabDe { title: user.name, description: ( - - {dataOrDash(userName)} + + {userName} ), }, { title: group.name, description: ( - - {dataOrDash(groupName)} + + {groupName} ), }, @@ -184,9 +256,12 @@ export const DetailPanelProcessTab = ({ processDetail }: DetailPanelProcessTabDe { title: entry_meta.type, description: ( - + - {dataOrDash(entryMetaType)} + {entryMetaType} ), @@ -194,8 +269,11 @@ export const DetailPanelProcessTab = ({ processDetail }: DetailPanelProcessTabDe { title: entry_meta.source.ip, description: ( - - {dataOrDash(entryMetaSourceIp)} + + {dataOrDash(entryMetaSourceIp)} ), } @@ -214,17 +292,15 @@ export const DetailPanelProcessTab = ({ processDetail }: DetailPanelProcessTabDe start, end, executable, - exit_code: exitCode, + exitCode, pid, - working_directory: workingDirectory, - tty, + workingDirectory, + interactive, userName, groupName, args, } = processDetail; - - const isInteractive = getIsInterativeString(tty); - const processArgs = formatProcessArgs(args); + const executableText = getProcessExecutableCopyText(executable); return ( <> @@ -233,9 +309,12 @@ export const DetailPanelProcessTab = ({ processDetail }: DetailPanelProcessTabDe { title: entity_id, description: ( - + - {dataOrDash(id)} + {id} ), @@ -243,8 +322,11 @@ export const DetailPanelProcessTab = ({ processDetail }: DetailPanelProcessTabDe { title: args, description: ( - - {processArgs} + + {args} ), }, @@ -252,31 +334,23 @@ export const DetailPanelProcessTab = ({ processDetail }: DetailPanelProcessTabDe title: executable, description: ( - {executable.map((execTuple, idx) => { - const [exec, eventAction] = execTuple; - return ( -
- - {dataOrDash(exec)} - - - {eventAction} - -
- ); - })} + {renderExecs(executable)}
), }, { title: interactive, description: ( - + - {isInteractive} + {interactive} ), @@ -284,9 +358,12 @@ export const DetailPanelProcessTab = ({ processDetail }: DetailPanelProcessTabDe { title: working_directory, description: ( - + - {dataOrDash(workingDirectory)} + {workingDirectory} ), @@ -294,9 +371,12 @@ export const DetailPanelProcessTab = ({ processDetail }: DetailPanelProcessTabDe { title: pid, description: ( - + - {dataOrDash(pid)} + {pid} ), @@ -304,25 +384,34 @@ export const DetailPanelProcessTab = ({ processDetail }: DetailPanelProcessTabDe { title: start, description: ( - - {dataOrDash(start)} + + {start} ), }, { title: end, description: ( - - {dataOrDash(end)} + + {end} ), }, { title: exit_code, description: ( - + - {dataOrDash(exitCode)} + {exitCode} ), @@ -330,16 +419,22 @@ export const DetailPanelProcessTab = ({ processDetail }: DetailPanelProcessTabDe { title: user.name, description: ( - - {dataOrDash(userName)} + + {userName} ), }, { title: group.name, description: ( - - {dataOrDash(groupName)} + + {groupName} ), }, diff --git a/x-pack/plugins/session_view/public/components/detail_panel_process_tab/styles.ts b/x-pack/plugins/session_view/public/components/detail_panel_process_tab/styles.ts index 8c1154f0c0076..e1bc139ba5d8a 100644 --- a/x-pack/plugins/session_view/public/components/detail_panel_process_tab/styles.ts +++ b/x-pack/plugins/session_view/public/components/detail_panel_process_tab/styles.ts @@ -13,15 +13,7 @@ export const useStyles = () => { const { euiTheme } = useEuiTheme(); const cached = useMemo(() => { - const description: CSSObject = { - width: `calc(100% - ${euiTheme.size.xl})`, - whiteSpace: 'nowrap', - overflow: 'hidden', - textOverflow: 'ellipsis', - }; - const descriptionSemibold: CSSObject = { - ...description, fontWeight: euiTheme.font.weight.medium, }; @@ -30,10 +22,15 @@ export const useStyles = () => { paddingLeft: euiTheme.size.xs, }; + const ellipsis: CSSObject = { + overflow: 'hidden', + textOverflow: 'ellipsis', + }; + return { - description, descriptionSemibold, executableAction, + ellipsis, }; }, [euiTheme]); diff --git a/x-pack/plugins/session_view/public/components/process_tree/index.tsx b/x-pack/plugins/session_view/public/components/process_tree/index.tsx index f2b5fef85002c..8a06ec769b7a9 100644 --- a/x-pack/plugins/session_view/public/components/process_tree/index.tsx +++ b/x-pack/plugins/session_view/public/components/process_tree/index.tsx @@ -160,7 +160,7 @@ export const ProcessTree = ({ <>
{sessionLeader && ( diff --git a/x-pack/plugins/session_view/public/components/process_tree/styles.ts b/x-pack/plugins/session_view/public/components/process_tree/styles.ts index 490829cad440b..04f8a22890c28 100644 --- a/x-pack/plugins/session_view/public/components/process_tree/styles.ts +++ b/x-pack/plugins/session_view/public/components/process_tree/styles.ts @@ -6,23 +6,23 @@ */ import { useMemo } from 'react'; -import { transparentize, useEuiTheme } from '@elastic/eui'; +import { transparentize } from '@elastic/eui'; import { CSSObject } from '@emotion/react'; -import { euiLightVars } from '@kbn/ui-theme'; // using this temporarily until the euiTheme hook is updated to include proper hex values +import { useEuiTheme } from '../../hooks'; export const useStyles = () => { - const { euiTheme } = useEuiTheme(); + const { euiTheme, euiVars } = useEuiTheme(); const cached = useMemo(() => { const { colors, font, size } = euiTheme; const defaultSelectionColor = colors.primary; - const scroller: CSSObject = { + const sessionViewProcessTree: CSSObject = { position: 'relative', fontFamily: font.familyCode, overflow: 'auto', height: '100%', - backgroundColor: euiLightVars.euiColorLightestShade, + backgroundColor: euiVars.euiColorLightestShade, paddingTop: size.base, paddingLeft: size.s, }; @@ -43,12 +43,12 @@ export const useStyles = () => { const alertSelected = transparentize(colors.danger, 0.008); return { - scroller, + sessionViewProcessTree, selectionArea, defaultSelected, alertSelected, }; - }, [euiTheme]); + }, [euiTheme, euiVars]); return cached; }; diff --git a/x-pack/plugins/session_view/public/components/process_tree_alert/__snapshots__/index.test.tsx.snap b/x-pack/plugins/session_view/public/components/process_tree_alert/__snapshots__/index.test.tsx.snap index e9f66ea10d66e..9614bb1267ea5 100644 --- a/x-pack/plugins/session_view/public/components/process_tree_alert/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/session_view/public/components/process_tree_alert/__snapshots__/index.test.tsx.snap @@ -6,13 +6,13 @@ Object { "baseElement":
cmd test alert
@@ -53,13 +52,13 @@ Object { , "container":
cmd test alert
diff --git a/x-pack/plugins/session_view/public/components/process_tree_alert/index.tsx b/x-pack/plugins/session_view/public/components/process_tree_alert/index.tsx index 95618123d709f..954492782ab93 100644 --- a/x-pack/plugins/session_view/public/components/process_tree_alert/index.tsx +++ b/x-pack/plugins/session_view/public/components/process_tree_alert/index.tsx @@ -69,14 +69,11 @@ export const ProcessTreeAlert = ({ - - - {dataOrDash(name)} - + + {dataOrDash(name)} {dataOrDash(status)} diff --git a/x-pack/plugins/session_view/public/components/process_tree_alert/styles.ts b/x-pack/plugins/session_view/public/components/process_tree_alert/styles.ts index bcd47edf56db8..db06be06cc2aa 100644 --- a/x-pack/plugins/session_view/public/components/process_tree_alert/styles.ts +++ b/x-pack/plugins/session_view/public/components/process_tree_alert/styles.ts @@ -43,6 +43,7 @@ export const useStyles = ({ isInvestigated, isSelected }: StylesDeps) => { const alert: CSSObject = { fontFamily: font.family, display: 'flex', + gap: size.s, alignItems: 'center', minHeight: '20px', padding: `${size.xs} ${size.base}`, @@ -55,34 +56,18 @@ export const useStyles = ({ isInvestigated, isSelected }: StylesDeps) => { '&:hover': { background: hoverBgColor, }, - }; - - const alertRowItem: CSSObject = { - '&:first-of-type': { - marginRight: size.m, - }, - '&:not(:first-of-type)': { + button: { + flexShrink: 0, marginRight: size.s, }, }; - const alertRuleName: CSSObject = { - ...alertRowItem, - maxWidth: '70%', - }; - const alertStatus: CSSObject = { - ...alertRowItem, textTransform: 'capitalize', - '&, span': { - cursor: 'pointer !important', - }, }; return { alert, - alertRowItem, - alertRuleName, alertStatus, }; }, [euiTheme, isInvestigated, isSelected]); diff --git a/x-pack/plugins/session_view/public/components/process_tree_node/buttons.tsx b/x-pack/plugins/session_view/public/components/process_tree_node/buttons.tsx index b4a2472f11dab..9cc842aac7668 100644 --- a/x-pack/plugins/session_view/public/components/process_tree_node/buttons.tsx +++ b/x-pack/plugins/session_view/public/components/process_tree_node/buttons.tsx @@ -9,6 +9,8 @@ import { EuiButton, EuiIcon } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { useButtonStyles } from './use_button_styles'; +const MAX_ALERT_COUNT = 99; + export const ChildrenProcessesButton = ({ onToggle, isExpanded, @@ -16,17 +18,18 @@ export const ChildrenProcessesButton = ({ onToggle: () => void; isExpanded: boolean; }) => { - const { button, buttonArrow, expandedIcon } = useButtonStyles({ isExpanded }); + const { button, buttonArrow } = useButtonStyles(); return ( - + ); }; @@ -40,12 +43,11 @@ export const AlertButton = ({ onToggle: () => void; alertsCount: number; }) => { - const { alertButton, alertsCountNumber, buttonArrow, expandedIcon } = useButtonStyles({ - isExpanded, - }); + const { alertButton, buttonArrow } = useButtonStyles(); return ( )} - {alertsCount > 1 && ( - ({alertsCount > 99 ? '99+' : alertsCount}) - )} - + {alertsCount > 1 && + (alertsCount > MAX_ALERT_COUNT ? ` (${MAX_ALERT_COUNT}+)` : ` (${alertsCount})`)} + ); }; diff --git a/x-pack/plugins/session_view/public/components/process_tree_node/index.test.tsx b/x-pack/plugins/session_view/public/components/process_tree_node/index.test.tsx index a5e0305595187..7daceaa366c43 100644 --- a/x-pack/plugins/session_view/public/components/process_tree_node/index.test.tsx +++ b/x-pack/plugins/session_view/public/components/process_tree_node/index.test.tsx @@ -216,7 +216,7 @@ describe('ProcessTreeNode component', () => { expect(renderResult.queryByTestId('processTreeNodeAlertButton')).toBeTruthy(); expect(renderResult.queryByTestId('processTreeNodeAlertButton')?.textContent).toBe( - `Alerts(${sessionViewAlertProcessMock.getAlerts().length})` + `Alerts (${sessionViewAlertProcessMock.getAlerts().length})` ); }); it('renders Alerts button with 99+ when process has more than 99 alerts', async () => { @@ -234,7 +234,7 @@ describe('ProcessTreeNode component', () => { expect(renderResult.queryByTestId('processTreeNodeAlertButton')).toBeTruthy(); expect(renderResult.queryByTestId('processTreeNodeAlertButton')?.textContent).toBe( - 'Alerts(99+)' + 'Alerts (99+)' ); }); it('toggle Alert Details button when Alert button is clicked', async () => { diff --git a/x-pack/plugins/session_view/public/components/process_tree_node/index.tsx b/x-pack/plugins/session_view/public/components/process_tree_node/index.tsx index d1b0fded615f6..d868dee04cbf5 100644 --- a/x-pack/plugins/session_view/public/components/process_tree_node/index.tsx +++ b/x-pack/plugins/session_view/public/components/process_tree_node/index.tsx @@ -104,8 +104,8 @@ export function ProcessTreeNode({ [hasAlerts, alerts, investigatedAlertId] ); const isSelected = selectedProcess?.id === process.id; - const styles = useStyles({ depth, hasAlerts, hasInvestigatedAlert, isSelected }); - const buttonStyles = useButtonStyles({}); + const styles = useStyles({ depth, hasAlerts, hasInvestigatedAlert, isSelected, isSessionLeader }); + const buttonStyles = useButtonStyles(); const nodeRef = useVisible({ viewPortEl: scrollerRef.current, @@ -256,7 +256,7 @@ export function ProcessTreeNode({ > {isSessionLeader ? ( <> - {' '} + {' '} {dataOrDash(name || args?.[0])}{' '} {' '} {dataOrDash(user?.name)} @@ -269,7 +269,7 @@ export function ProcessTreeNode({ )} - + {' '} {dataOrDash(workingDirectory)}  @@ -308,7 +308,7 @@ export function ProcessTreeNode({ diff --git a/x-pack/plugins/session_view/public/components/process_tree_node/styles.ts b/x-pack/plugins/session_view/public/components/process_tree_node/styles.ts index 6503f373240ad..e328c28be8bad 100644 --- a/x-pack/plugins/session_view/public/components/process_tree_node/styles.ts +++ b/x-pack/plugins/session_view/public/components/process_tree_node/styles.ts @@ -6,18 +6,26 @@ */ import { useMemo } from 'react'; -import { useEuiTheme, transparentize } from '@elastic/eui'; +import { transparentize } from '@elastic/eui'; import { CSSObject } from '@emotion/react'; +import { useEuiTheme } from '../../hooks'; interface StylesDeps { depth: number; hasAlerts: boolean; hasInvestigatedAlert: boolean; isSelected: boolean; + isSessionLeader: boolean; } -export const useStyles = ({ depth, hasAlerts, hasInvestigatedAlert, isSelected }: StylesDeps) => { - const { euiTheme } = useEuiTheme(); +export const useStyles = ({ + depth, + hasAlerts, + hasInvestigatedAlert, + isSelected, + isSessionLeader, +}: StylesDeps) => { + const { euiTheme, euiVars } = useEuiTheme(); const cached = useMemo(() => { const { colors, border, size, font } = euiTheme; @@ -40,12 +48,16 @@ export const useStyles = ({ depth, hasAlerts, hasInvestigatedAlert, isSelected } borderLeft: border.editable, }; + const icon: CSSObject = { + color: euiVars.euiColorDarkShade, + }; + /** * gets border, bg and hover colors for a process */ const getHighlightColors = () => { let bgColor = 'none'; - const hoverColor = transparentize(colors.primary, 0.04); + let hoverColor = transparentize(colors.primary, 0.04); let borderColor = 'transparent'; let searchResColor = transparentize(colors.warning, 0.32); @@ -55,11 +67,16 @@ export const useStyles = ({ depth, hasAlerts, hasInvestigatedAlert, isSelected } if (isSelected) { searchResColor = colors.warning; - bgColor = `${transparentize(colors.primary, 0.1)}!important`; + bgColor = transparentize(colors.primary, 0.08); + hoverColor = transparentize(colors.primary, 0.12); } if (hasInvestigatedAlert) { - bgColor = `${transparentize(colors.danger, 0.04)}!important`; + bgColor = transparentize(colors.danger, 0.04); + hoverColor = transparentize(colors.danger, 0.12); + if (isSelected) { + bgColor = transparentize(colors.danger, 0.08); + } } return { bgColor, borderColor, hoverColor, searchResColor }; @@ -72,6 +89,7 @@ export const useStyles = ({ depth, hasAlerts, hasInvestigatedAlert, isSelected } cursor: 'pointer', position: 'relative', padding: `${size.xs} 0px`, + marginBottom: isSessionLeader ? size.s : '0px', '&:hover:before': { backgroundColor: hoverColor, transform: `translateY(-${size.xs})`, @@ -99,7 +117,7 @@ export const useStyles = ({ depth, hasAlerts, hasInvestigatedAlert, isSelected } paddingLeft: size.s, position: 'relative', verticalAlign: 'middle', - color: colors.mediumShade, + color: euiVars.euiTextSubduedColor, wordBreak: 'break-all', minHeight: `calc(${size.l} - ${size.xxs})`, lineHeight: `calc(${size.l} - ${size.xxs})`, @@ -108,7 +126,7 @@ export const useStyles = ({ depth, hasAlerts, hasInvestigatedAlert, isSelected } const workingDir: CSSObject = { color: colors.successText, fontFamily: font.familyCode, - fontWeight: font.weight.medium, + fontWeight: font.weight.regular, paddingLeft: size.s, paddingRight: size.xxs, }; @@ -138,8 +156,9 @@ export const useStyles = ({ depth, hasAlerts, hasInvestigatedAlert, isSelected } workingDir, timeStamp, alertDetails, + icon, }; - }, [depth, euiTheme, hasAlerts, hasInvestigatedAlert, isSelected]); + }, [depth, euiTheme, hasAlerts, hasInvestigatedAlert, isSelected, euiVars, isSessionLeader]); return cached; }; diff --git a/x-pack/plugins/session_view/public/components/process_tree_node/use_button_styles.ts b/x-pack/plugins/session_view/public/components/process_tree_node/use_button_styles.ts index 67883b12e2bba..04d3eb793bfda 100644 --- a/x-pack/plugins/session_view/public/components/process_tree_node/use_button_styles.ts +++ b/x-pack/plugins/session_view/public/components/process_tree_node/use_button_styles.ts @@ -6,36 +6,48 @@ */ import { useMemo } from 'react'; -import { useEuiTheme, transparentize, shade } from '@elastic/eui'; -import { euiLightVars as theme } from '@kbn/ui-theme'; +import { transparentize } from '@elastic/eui'; import { CSSObject } from '@emotion/react'; +import { useEuiTheme } from '../../hooks'; -interface ButtonStylesDeps { - isExpanded?: boolean; -} - -export const useButtonStyles = ({ isExpanded }: ButtonStylesDeps) => { - const { euiTheme } = useEuiTheme(); +export const useButtonStyles = () => { + const { euiTheme, euiVars } = useEuiTheme(); const cached = useMemo(() => { - const { colors, border, size, font } = euiTheme; + const { border, colors, size, font } = euiTheme; const button: CSSObject = { - background: transparentize(theme.euiColorVis6, 0.04), - border: `${border.width.thin} solid ${transparentize(theme.euiColorVis6, 0.48)}`, lineHeight: '18px', height: '20px', fontSize: size.m, fontFamily: font.family, fontWeight: font.weight.medium, borderRadius: border.radius.small, - color: shade(theme.euiColorVis6, 0.25), marginLeft: size.xs, marginRight: size.xs, minWidth: 0, padding: `${size.s} ${size.xxs}`, - span: { - padding: `0px ${size.xxs} !important`, + color: euiVars.euiColorVis6_asText, + background: transparentize(euiVars.euiColorVis6, 0.04), + border: `${border.width.thin} solid ${transparentize(euiVars.euiColorVis6, 0.48)}`, + '&& > span': { + padding: `0px ${size.xxs}`, + svg: { + transition: `transform ${euiTheme.animation.extraFast}`, + }, + }, + '&&:hover, &&:focus': { + background: transparentize(euiVars.euiColorVis6, 0.04), + }, + '&.isExpanded > span svg': { + transform: `rotate(180deg)`, + }, + '&.isExpanded': { + color: colors.ghost, + background: euiVars.euiColorVis6, + '&:hover, &:focus': { + background: euiVars.euiColorVis6, + }, }, }; @@ -45,52 +57,48 @@ export const useButtonStyles = ({ isExpanded }: ButtonStylesDeps) => { const alertButton: CSSObject = { ...button, - color: colors.dangerText, - background: transparentize(colors.dangerText, 0.04), - border: `${border.width.thin} solid ${transparentize(colors.dangerText, 0.48)}`, - }; - - const alertsCountNumber: CSSObject = { - paddingLeft: size.xs, + color: euiVars.euiColorDanger, + background: transparentize(euiVars.euiColorDanger, 0.04), + border: `${border.width.thin} solid ${transparentize(euiVars.euiColorDanger, 0.48)}`, + '&&:hover, &&:focus': { + background: transparentize(euiVars.euiColorDanger, 0.04), + }, + '&.isExpanded': { + color: colors.ghost, + background: euiVars.euiColorDanger, + '&:hover, &:focus': { + background: `${euiVars.euiColorDanger}`, + }, + }, }; - if (isExpanded) { - button.color = colors.ghost; - button.background = theme.euiColorVis6; - button['&:hover, &:focus'] = { - backgroundColor: `${theme.euiColorVis6} !important`, - }; - - alertButton.color = colors.ghost; - alertButton.background = colors.dangerText; - alertButton['&:hover, &:focus'] = { - backgroundColor: `${colors.dangerText} !important`, - }; - } - const userChangedButton: CSSObject = { ...button, - color: theme.euiColorVis3, - background: transparentize(theme.euiColorVis3, 0.04), - border: `${border.width.thin} solid ${transparentize(theme.euiColorVis3, 0.48)}`, + cursor: 'default', + color: euiVars.euiColorGhost, + background: euiVars.euiColorVis3, + border: `${border.width.thin} solid ${transparentize(euiVars.euiColorVis3, 0.48)}`, + '&&:hover, &&:focus': { + color: euiVars.euiColorGhost, + background: euiVars.euiColorVis3, + textDecoration: 'none', + transform: 'none', + animation: 'none', + }, }; const buttonSize: CSSObject = { padding: `0px ${euiTheme.size.xs}`, }; - const expandedIcon = isExpanded ? 'arrowUp' : 'arrowDown'; - return { buttonArrow, button, alertButton, - alertsCountNumber, userChangedButton, buttonSize, - expandedIcon, }; - }, [euiTheme, isExpanded]); + }, [euiTheme, euiVars]); return cached; }; diff --git a/x-pack/plugins/session_view/public/components/session_view/index.tsx b/x-pack/plugins/session_view/public/components/session_view/index.tsx index b1678a5265ee2..5fe3e2365cc58 100644 --- a/x-pack/plugins/session_view/public/components/session_view/index.tsx +++ b/x-pack/plugins/session_view/public/components/session_view/index.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React, { useState, useCallback, useEffect, useMemo } from 'react'; +import React, { useState, useCallback, useEffect, useMemo, useRef } from 'react'; import { EuiEmptyPrompt, EuiButton, @@ -78,6 +78,8 @@ export const SessionView = ({ const styles = useStyles({ height, isFullScreen }); + const detailPanelCollapseFn = useRef(() => {}); + // to give an indication to the user that there may be more search results if they turn on verbose mode. const showVerboseSearchTooltip = useMemo(() => { return !!(!displayOptions?.verboseMode && searchQuery && searchResults?.length === 0); @@ -122,7 +124,6 @@ export const SessionView = ({ const hasData = alerts && data && data.pages?.[0].events.length > 0; const hasError = error || alertsError; const renderIsLoading = (isFetching || alertsFetching) && !(data && alerts); - const renderDetails = isDetailOpen && selectedProcess; const { data: newUpdatedAlertsStatus } = useFetchAlertStatus( updatedAlertsStatus, fetchAlertStatus[0] ?? '' @@ -141,6 +142,7 @@ export const SessionView = ({ }, []); const toggleDetailPanel = useCallback(() => { + detailPanelCollapseFn.current(); setIsDetailOpen(!isDetailOpen); }, [isDetailOpen]); @@ -198,15 +200,12 @@ export const SessionView = ({ return ( <>
- + - + - {(EuiResizablePanel, EuiResizableButton) => ( - <> - - {hasError && ( - - - - } - body={ -

- -

- } - /> - )} + {(EuiResizablePanel, EuiResizableButton, { togglePanel }) => { + detailPanelCollapseFn.current = () => { + togglePanel?.('session-detail-panel', { direction: 'left' }); + }; - {hasData && ( -
- + + {hasError && ( + + + + } + body={ +

+ +

+ } /> -
- )} -
+ )} - {renderDetails ? ( - <> - - - - - - ) : ( - <> - {/* Returning an empty element here (instead of false) to avoid a bug in EuiResizableContainer */} - - )} - - )} + {hasData && ( +
+ +
+ )} + + + + + + + + ); + }}
diff --git a/x-pack/plugins/session_view/public/components/session_view/styles.ts b/x-pack/plugins/session_view/public/components/session_view/styles.ts index d8cccebe9738a..0b05f3b9d9c9b 100644 --- a/x-pack/plugins/session_view/public/components/session_view/styles.ts +++ b/x-pack/plugins/session_view/public/components/session_view/styles.ts @@ -6,9 +6,8 @@ */ import { useMemo } from 'react'; -import { useEuiTheme } from '@elastic/eui'; import { CSSObject } from '@emotion/react'; -import { euiLightVars } from '@kbn/ui-theme'; // using this temporarily until the euiTheme hook is updated to include proper hex values +import { useEuiTheme } from '../../hooks'; interface StylesDeps { height?: number; @@ -16,7 +15,7 @@ interface StylesDeps { } export const useStyles = ({ height = 500, isFullScreen }: StylesDeps) => { - const { euiTheme } = useEuiTheme(); + const { euiTheme, euiVars } = useEuiTheme(); const cached = useMemo(() => { const { border, colors, size } = euiTheme; @@ -45,21 +44,14 @@ export const useStyles = ({ height = 500, isFullScreen }: StylesDeps) => { flexGrow: 0, alignItems: 'stretch', }; - const searchBar: CSSObject = { - position: 'relative', - input: { - backgroundColor: colors.emptyShade, - }, - }; const sessionViewerComponent: CSSObject = { border: border.thin, borderRadius: border.radius.medium, - }; - - const toolBar: CSSObject = { - backgroundColor: `${euiLightVars.euiFormBackgroundDisabledColor} !important`, // important used since euipanel overrides this - padding: `${size.m} ${size.base}`, + '.sessionViewerToolbar': { + backgroundColor: `${euiVars.euiFormBackgroundDisabledColor}`, + padding: `${size.m} ${size.base}`, + }, }; const betaBadge: CSSObject = { @@ -71,12 +63,10 @@ export const useStyles = ({ height = 500, isFullScreen }: StylesDeps) => { detailPanel, nonGrowGroup, resizeHandle, - searchBar, sessionViewerComponent, - toolBar, betaBadge, }; - }, [euiTheme, isFullScreen, height]); + }, [euiTheme, isFullScreen, height, euiVars]); return cached; }; diff --git a/x-pack/plugins/session_view/public/components/session_view_detail_panel/helpers.test.ts b/x-pack/plugins/session_view/public/components/session_view_detail_panel/helpers.test.ts new file mode 100644 index 0000000000000..70b0fe7ec272f --- /dev/null +++ b/x-pack/plugins/session_view/public/components/session_view_detail_panel/helpers.test.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { getSelectedTabContent } from './helpers'; +import { EuiTabProps } from '../../types'; + +const TABS: EuiTabProps[] = [ + { + id: '1', + name: 'Process', + content: 'process content', + }, + { + id: '2', + name: 'Host', + content: 'host content', + }, + { + id: '3', + name: 'Alert', + content: 'alert content', + }, +]; + +describe('session view detail panel helpers tests', () => { + it('getSelectedTabContent works', () => { + const result = getSelectedTabContent(TABS, '1'); + expect(result).toBe(TABS[0].content); + }); + + it('getSelectedTabContent returns null if tab id not found', () => { + const result = getSelectedTabContent(TABS, 'process'); + expect(result).toBeNull(); + }); +}); diff --git a/x-pack/plugins/session_view/public/components/session_view_detail_panel/helpers.ts b/x-pack/plugins/session_view/public/components/session_view_detail_panel/helpers.ts index 083bc35ac49d4..755c24f83361a 100644 --- a/x-pack/plugins/session_view/public/components/session_view_detail_panel/helpers.ts +++ b/x-pack/plugins/session_view/public/components/session_view_detail_panel/helpers.ts @@ -4,108 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { EventAction, Process, ProcessFields } from '../../../common/types/process_tree'; -import { DetailPanelProcess, EuiTabProps } from '../../types'; - -const FILTER_FORKS_EXECS = [EventAction.fork, EventAction.exec]; - -const DEFAULT_PROCESS_DATA = { - id: '', - name: '', - start: '', - end: '', - userName: '', - groupName: '', - working_directory: '', - args: [], - entryMetaType: '', - entryMetaSourceIp: '', - executable: '', -}; - -const getDetailPanelProcessLeader = (leader: ProcessFields | undefined) => ({ - ...leader, - name: leader?.name ?? DEFAULT_PROCESS_DATA.name, - start: leader?.start ?? DEFAULT_PROCESS_DATA.start, - working_directory: leader?.working_directory ?? DEFAULT_PROCESS_DATA.working_directory, - args: leader?.args ?? DEFAULT_PROCESS_DATA.args, - executable: leader?.executable ?? DEFAULT_PROCESS_DATA.executable, - id: leader?.entity_id ?? DEFAULT_PROCESS_DATA.id, - entryMetaType: leader?.entry_meta?.type ?? DEFAULT_PROCESS_DATA.entryMetaType, - userName: leader?.user?.name ?? DEFAULT_PROCESS_DATA.userName, - groupName: leader?.group?.name ?? DEFAULT_PROCESS_DATA.groupName, - entryMetaSourceIp: leader?.entry_meta?.source?.ip ?? DEFAULT_PROCESS_DATA.entryMetaSourceIp, -}); - -export const getDetailPanelProcess = (process: Process | undefined) => { - const processData = {} as DetailPanelProcess; - if (!process) { - return { - id: DEFAULT_PROCESS_DATA.id, - start: DEFAULT_PROCESS_DATA.start, - end: DEFAULT_PROCESS_DATA.end, - userName: DEFAULT_PROCESS_DATA.userName, - groupName: DEFAULT_PROCESS_DATA.groupName, - args: DEFAULT_PROCESS_DATA.args, - executable: [], - working_directory: DEFAULT_PROCESS_DATA.working_directory, - entryLeader: DEFAULT_PROCESS_DATA, - sessionLeader: DEFAULT_PROCESS_DATA, - groupLeader: DEFAULT_PROCESS_DATA, - parent: DEFAULT_PROCESS_DATA, - }; - } - - const details = process.getDetails(); - - processData.id = process.id; - processData.start = details.process?.start ?? ''; - processData.args = []; - processData.executable = []; - - if (!processData.userName) { - processData.userName = details.process?.user?.name ?? ''; - } - if (!processData.groupName) { - processData.groupName = details.process?.group?.name ?? ''; - } - if (!processData.pid) { - processData.pid = details.process?.pid; - } - if (!processData.working_directory) { - processData.working_directory = details.process?.working_directory ?? ''; - } - if (!processData.tty) { - processData.tty = details.process?.tty; - } - if (details.process?.args && details.process.args.length > 0) { - processData.args = details.process.args; - } - if (details.process?.exit_code !== undefined) { - processData.exit_code = details.process.exit_code; - } - - // we grab the executable from each process lifecycle event to give an indication - // of the processes journey. Processes can sometimes exec multiple times, so it's good - // information to have. - process.events.forEach((event) => { - if ( - event.process?.executable && - event.event?.action && - FILTER_FORKS_EXECS.includes(event.event.action) - ) { - processData.executable.push([event.process.executable, `(${event.event.action})`]); - } - }); - - processData.end = process.getEndTime(); - processData.entryLeader = getDetailPanelProcessLeader(details?.process?.entry_leader); - processData.sessionLeader = getDetailPanelProcessLeader(details?.process?.session_leader); - processData.groupLeader = getDetailPanelProcessLeader(details?.process?.group_leader); - processData.parent = getDetailPanelProcessLeader(details?.process?.parent); - - return processData; -}; +import { EuiTabProps } from '../../types'; export const getSelectedTabContent = (tabs: EuiTabProps[], selectedTabId: string) => { const selectedTab = tabs.find((tab) => tab.id === selectedTabId); diff --git a/x-pack/plugins/session_view/public/components/session_view_detail_panel/index.test.tsx b/x-pack/plugins/session_view/public/components/session_view_detail_panel/index.test.tsx index f2d7249e43c90..9ddefa25cea07 100644 --- a/x-pack/plugins/session_view/public/components/session_view_detail_panel/index.test.tsx +++ b/x-pack/plugins/session_view/public/components/session_view_detail_panel/index.test.tsx @@ -38,10 +38,10 @@ describe('SessionView component', () => { expect(renderResult.queryByText('8e4daeb2-4a4e-56c4-980e-f0dcfdbc3726')).toBeVisible(); }); - it('should should default state with selectedProcess undefined', async () => { + it('should should default state with selectedProcess null', async () => { renderResult = mockedContext.render( diff --git a/x-pack/plugins/session_view/public/components/session_view_detail_panel/index.tsx b/x-pack/plugins/session_view/public/components/session_view_detail_panel/index.tsx index 86cfacfb72d06..a22ad026c4395 100644 --- a/x-pack/plugins/session_view/public/components/session_view_detail_panel/index.tsx +++ b/x-pack/plugins/session_view/public/components/session_view_detail_panel/index.tsx @@ -9,7 +9,7 @@ import { EuiTabs, EuiTab, EuiNotificationBadge } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { EuiTabProps } from '../../types'; import { Process, ProcessEvent } from '../../../common/types/process_tree'; -import { getDetailPanelProcess, getSelectedTabContent } from './helpers'; +import { getSelectedTabContent } from './helpers'; import { DetailPanelProcessTab } from '../detail_panel_process_tab'; import { DetailPanelHostTab } from '../detail_panel_host_tab'; import { useStyles } from './styles'; @@ -17,7 +17,7 @@ import { DetailPanelAlertTab } from '../detail_panel_alert_tab'; import { ALERT_COUNT_THRESHOLD } from '../../../common/constants'; interface SessionViewDetailPanelDeps { - selectedProcess: Process | undefined; + selectedProcess: Process | null; alerts?: ProcessEvent[]; investigatedAlertId?: string; onJumpToEvent: (event: ProcessEvent) => void; @@ -35,7 +35,6 @@ export const SessionViewDetailPanel = ({ onShowAlertDetails, }: SessionViewDetailPanelDeps) => { const [selectedTabId, setSelectedTabId] = useState('process'); - const processDetail = useMemo(() => getDetailPanelProcess(selectedProcess), [selectedProcess]); const alertsCount = useMemo(() => { if (!alerts) { @@ -54,7 +53,7 @@ export const SessionViewDetailPanel = ({ name: i18n.translate('xpack.sessionView.detailsPanel.process', { defaultMessage: 'Process', }), - content: , + content: , }, { id: 'host', @@ -85,12 +84,11 @@ export const SessionViewDetailPanel = ({ ]; }, [ alerts, + selectedProcess, alertsCount, - processDetail, - selectedProcess?.events, + onJumpToEvent, onShowAlertDetails, investigatedAlertId, - onJumpToEvent, ]); const onSelectedTabChanged = useCallback((id: string) => { diff --git a/x-pack/plugins/session_view/public/components/session_view_search_bar/index.test.tsx b/x-pack/plugins/session_view/public/components/session_view_search_bar/index.test.tsx index 67347f2138f0a..dd758529530ba 100644 --- a/x-pack/plugins/session_view/public/components/session_view_search_bar/index.test.tsx +++ b/x-pack/plugins/session_view/public/components/session_view_search_bar/index.test.tsx @@ -34,7 +34,7 @@ describe('SessionViewSearchBar component', () => { /> ); - const searchInput = renderResult.getByTestId('sessionView:searchInput').querySelector('input'); + const searchInput = renderResult.getByTestId('sessionView:searchBar').querySelector('input'); expect(searchInput?.value).toEqual('ls'); @@ -73,7 +73,7 @@ describe('SessionViewSearchBar component', () => { userEvent.click(renderResult.getByTestId('pagination-button-next')); expect(searchPagination.querySelector(paginationTextClass)?.textContent).toEqual('2 of 3'); - const searchInput = renderResult.getByTestId('sessionView:searchInput').querySelector('input'); + const searchInput = renderResult.getByTestId('sessionView:searchBar').querySelector('input'); if (searchInput) { userEvent.type(searchInput, ' -la'); diff --git a/x-pack/plugins/session_view/public/components/session_view_search_bar/index.tsx b/x-pack/plugins/session_view/public/components/session_view_search_bar/index.tsx index 9c24f6b94199c..0cac43f39a8ec 100644 --- a/x-pack/plugins/session_view/public/components/session_view_search_bar/index.tsx +++ b/x-pack/plugins/session_view/public/components/session_view_search_bar/index.tsx @@ -65,7 +65,7 @@ export const SessionViewSearchBar = ({ }, [searchResults, onProcessSelected, selectedResult]); return ( -
+
{noResults && {NO_RESULTS}} {showPagination && ( diff --git a/x-pack/plugins/session_view/public/components/session_view_search_bar/styles.ts b/x-pack/plugins/session_view/public/components/session_view_search_bar/styles.ts index ebb1b8f7b340b..6e7c717e2816b 100644 --- a/x-pack/plugins/session_view/public/components/session_view_search_bar/styles.ts +++ b/x-pack/plugins/session_view/public/components/session_view_search_bar/styles.ts @@ -6,15 +6,15 @@ */ import { useMemo } from 'react'; -import { useEuiTheme } from '@elastic/eui'; import { CSSObject } from '@emotion/react'; +import { useEuiTheme } from '../../hooks'; interface StylesDeps { hasSearchResults: boolean; } export const useStyles = ({ hasSearchResults }: StylesDeps) => { - const { euiTheme } = useEuiTheme(); + const { euiTheme, euiVars } = useEuiTheme(); const cached = useMemo(() => { const pagination: CSSObject = { @@ -36,19 +36,20 @@ export const useStyles = ({ hasSearchResults }: StylesDeps) => { right: euiTheme.size.xxl, }; - const searchBarWithResult: CSSObject = { + const searchBar: CSSObject = { position: 'relative', - 'input.euiFieldSearch.euiFieldSearch-isClearable': { + backgroundColor: euiVars.euiFormBackgroundColor, + input: { paddingRight: hasSearchResults ? '200px' : euiTheme.size.xxl, }, }; return { pagination, - searchBarWithResult, + searchBar, noResults, }; - }, [euiTheme, hasSearchResults]); + }, [euiTheme, euiVars, hasSearchResults]); return cached; }; diff --git a/x-pack/plugins/session_view/public/constants.ts b/x-pack/plugins/session_view/public/constants.ts new file mode 100644 index 0000000000000..2f7306bf3e4a8 --- /dev/null +++ b/x-pack/plugins/session_view/public/constants.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const DASH = '-'; diff --git a/x-pack/plugins/session_view/public/hooks/index.ts b/x-pack/plugins/session_view/public/hooks/index.ts new file mode 100644 index 0000000000000..8db231cd2bc64 --- /dev/null +++ b/x-pack/plugins/session_view/public/hooks/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { useEuiTheme } from './use_eui_theme'; diff --git a/x-pack/plugins/session_view/public/hooks/use_eui_theme.ts b/x-pack/plugins/session_view/public/hooks/use_eui_theme.ts new file mode 100644 index 0000000000000..f7021f6146f09 --- /dev/null +++ b/x-pack/plugins/session_view/public/hooks/use_eui_theme.ts @@ -0,0 +1,44 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { shade, useEuiTheme as useEuiThemeHook } from '@elastic/eui'; +import { euiLightVars, euiDarkVars } from '@kbn/ui-theme'; +import { useMemo } from 'react'; + +type EuiThemeProps = Parameters; +type ExtraEuiVars = { + // eslint-disable-next-line @typescript-eslint/naming-convention + euiColorVis6_asText: string; +}; +type EuiVars = typeof euiLightVars & ExtraEuiVars; +type EuiThemeReturn = ReturnType & { euiVars: EuiVars }; + +// Not all Eui Tokens were fully migrated to @elastic/eui/useEuiTheme yet, so +// this hook overrides the default useEuiTheme hook to provide a custom hook that +// allows the use the euiVars tokens from the euiLightVars and euiDarkVars +export const useEuiTheme = (...props: EuiThemeProps): EuiThemeReturn => { + const euiThemeHook = useEuiThemeHook(...props); + + const euiVars = useMemo(() => { + const themeVars = euiThemeHook.colorMode === 'DARK' ? euiDarkVars : euiLightVars; + + const extraEuiVars: ExtraEuiVars = { + // eslint-disable-next-line @typescript-eslint/naming-convention + euiColorVis6_asText: shade(themeVars.euiColorVis6, 0.335), + }; + + return { + ...themeVars, + ...extraEuiVars, + }; + }, [euiThemeHook.colorMode]); + + return { + ...euiThemeHook, + euiVars, + }; +}; diff --git a/x-pack/plugins/session_view/public/types.ts b/x-pack/plugins/session_view/public/types.ts index 8e5b9a7ed83f2..1f90ae05b0791 100644 --- a/x-pack/plugins/session_view/public/types.ts +++ b/x-pack/plugins/session_view/public/types.ts @@ -6,7 +6,6 @@ */ import { ReactNode } from 'react'; import { CoreStart } from '@kbn/core/public'; -import { Teletype } from '../common/types/process_tree'; export type SessionViewServices = CoreStart; @@ -43,14 +42,14 @@ export interface DetailPanelProcess { id: string; start: string; end: string; - exit_code?: number; + exitCode: string; userName: string; groupName: string; - args: string[]; + args: string; executable: string[][]; - working_directory: string; - tty?: Teletype; - pid?: number; + workingDirectory: string; + interactive: string; + pid: string; entryLeader: DetailPanelProcessLeader; sessionLeader: DetailPanelProcessLeader; groupLeader: DetailPanelProcessLeader; @@ -61,17 +60,34 @@ export interface DetailPanelProcessLeader { id: string; name: string; start: string; - end?: string; - exit_code?: number; + end: string; + exitCode: string; userName: string; groupName: string; - working_directory: string; - tty?: Teletype; - args: string[]; - pid?: number; + workingDirectory: string; + interactive: string; + args: string; + pid: string; entryMetaType: string; entryMetaSourceIp: string; - executable: string; + executable: string[][]; +} + +export interface DetailPanelHost { + architecture: string; + hostname: string; + id: string; + ip: string; + mac: string; + name: string; + os: { + family: string; + full: string; + kernel: string; + name: string; + platform: string; + version: string; + }; } export interface SessionViewStart { diff --git a/x-pack/plugins/session_view/public/utils/data_or_dash.test.ts b/x-pack/plugins/session_view/public/utils/data_or_dash.test.ts index 12ef44cf1d708..c4950bb8d20b0 100644 --- a/x-pack/plugins/session_view/public/utils/data_or_dash.test.ts +++ b/x-pack/plugins/session_view/public/utils/data_or_dash.test.ts @@ -5,11 +5,11 @@ * 2.0. */ +import { DASH } from '../constants'; import { dataOrDash } from './data_or_dash'; const TEST_STRING = '123'; const TEST_NUMBER = 123; -const DASH = '-'; describe('dataOrDash(data)', () => { it('works for a valid string', () => { diff --git a/x-pack/plugins/session_view/public/utils/data_or_dash.ts b/x-pack/plugins/session_view/public/utils/data_or_dash.ts index ff6c2fb9bc1ff..15c82b47220d2 100644 --- a/x-pack/plugins/session_view/public/utils/data_or_dash.ts +++ b/x-pack/plugins/session_view/public/utils/data_or_dash.ts @@ -5,6 +5,8 @@ * 2.0. */ +import { DASH } from '../constants'; + /** * Returns a dash ('-') if data is undefined, and empty string, or a NaN. * @@ -15,7 +17,7 @@ */ export const dataOrDash = (data: string | number | undefined): string | number => { if (data === undefined || data === '' || (typeof data === 'number' && isNaN(data))) { - return '-'; + return DASH; } return data; diff --git a/x-pack/plugins/session_view/server/routes/process_events_route.ts b/x-pack/plugins/session_view/server/routes/process_events_route.ts index c75bdc3fb6ed8..7341f8238f9af 100644 --- a/x-pack/plugins/session_view/server/routes/process_events_route.ts +++ b/x-pack/plugins/session_view/server/routes/process_events_route.ts @@ -27,7 +27,7 @@ export const registerProcessEventsRoute = (router: IRouter) => { }, }, async (context, request, response) => { - const client = context.core.elasticsearch.client.asCurrentUser; + const client = (await context.core).elasticsearch.client.asCurrentUser; const { sessionEntityId, cursor, forward = true } = request.query; const body = await doSearch(client, sessionEntityId, cursor, forward); diff --git a/x-pack/plugins/session_view/server/routes/session_entry_leaders_route.ts b/x-pack/plugins/session_view/server/routes/session_entry_leaders_route.ts index 186195c342a48..c8fd28334f18e 100644 --- a/x-pack/plugins/session_view/server/routes/session_entry_leaders_route.ts +++ b/x-pack/plugins/session_view/server/routes/session_entry_leaders_route.ts @@ -19,7 +19,7 @@ export const sessionEntryLeadersRoute = (router: IRouter) => { }, }, async (context, request, response) => { - const client = context.core.elasticsearch.client.asCurrentUser; + const client = (await context.core).elasticsearch.client.asCurrentUser; const { id } = request.query; const result = await client.get({ diff --git a/x-pack/plugins/snapshot_restore/server/routes/api/app.ts b/x-pack/plugins/snapshot_restore/server/routes/api/app.ts index 21938eaecf605..702a7633f7cc7 100644 --- a/x-pack/plugins/snapshot_restore/server/routes/api/app.ts +++ b/x-pack/plugins/snapshot_restore/server/routes/api/app.ts @@ -32,7 +32,7 @@ export function registerAppRoutes({ router.get( { path: addBasePath('privileges'), validate: false }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const privilegesResult: Privileges = { hasAllPrivileges: true, diff --git a/x-pack/plugins/snapshot_restore/server/routes/api/policy.ts b/x-pack/plugins/snapshot_restore/server/routes/api/policy.ts index 57cb81ca13b9b..8068c64ec77b6 100644 --- a/x-pack/plugins/snapshot_restore/server/routes/api/policy.ts +++ b/x-pack/plugins/snapshot_restore/server/routes/api/policy.ts @@ -23,7 +23,7 @@ export function registerPolicyRoutes({ router.get( { path: addBasePath('policies'), validate: false }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const managedPolicies = await getManagedPolicyNames(clusterClient.asCurrentUser); @@ -53,7 +53,7 @@ export function registerPolicyRoutes({ router.get( { path: addBasePath('policy/{name}'), validate: { params: nameParameterSchema } }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = req.params as TypeOf; try { @@ -80,7 +80,7 @@ export function registerPolicyRoutes({ router.post( { path: addBasePath('policies'), validate: { body: policySchema } }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const policy = req.body as TypeOf; const { name } = policy; @@ -120,7 +120,7 @@ export function registerPolicyRoutes({ validate: { params: nameParameterSchema, body: policySchema }, }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = req.params as TypeOf; const policy = req.body as TypeOf; @@ -147,7 +147,7 @@ export function registerPolicyRoutes({ router.delete( { path: addBasePath('policies/{name}'), validate: { params: nameParameterSchema } }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = req.params as TypeOf; const policyNames = name.split(','); @@ -178,7 +178,7 @@ export function registerPolicyRoutes({ router.post( { path: addBasePath('policy/{name}/run'), validate: { params: nameParameterSchema } }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = req.params as TypeOf; try { @@ -197,7 +197,7 @@ export function registerPolicyRoutes({ router.get( { path: addBasePath('policies/indices'), validate: false }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; try { const response = await clusterClient.asCurrentUser.indices.resolveIndex({ @@ -227,7 +227,7 @@ export function registerPolicyRoutes({ router.get( { path: addBasePath('policies/retention_settings'), validate: false }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { persistent, transient, defaults } = await clusterClient.asCurrentUser.cluster.getSettings({ filter_path: '**.slm.retention*', @@ -257,7 +257,7 @@ export function registerPolicyRoutes({ validate: { body: retentionSettingsSchema }, }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { retentionSchedule } = req.body as TypeOf; try { @@ -282,7 +282,7 @@ export function registerPolicyRoutes({ router.post( { path: addBasePath('policies/retention'), validate: false }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const response = await clusterClient.asCurrentUser.slm.executeRetention(); return res.ok({ body: response }); }) diff --git a/x-pack/plugins/snapshot_restore/server/routes/api/repositories.ts b/x-pack/plugins/snapshot_restore/server/routes/api/repositories.ts index 4666870133f1f..4e86de4036d53 100644 --- a/x-pack/plugins/snapshot_restore/server/routes/api/repositories.ts +++ b/x-pack/plugins/snapshot_restore/server/routes/api/repositories.ts @@ -43,7 +43,7 @@ export function registerRepositoriesRoutes({ router.get( { path: addBasePath('repositories'), validate: false }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const managedRepositoryName = await getManagedRepositoryName(clusterClient.asCurrentUser); let repositoryNames: string[] | undefined; @@ -102,7 +102,7 @@ export function registerRepositoriesRoutes({ router.get( { path: addBasePath('repositories/{name}'), validate: { params: nameParameterSchema } }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = req.params as TypeOf; const managedRepository = await getManagedRepositoryName(clusterClient.asCurrentUser); @@ -157,7 +157,7 @@ export function registerRepositoriesRoutes({ router.get( { path: addBasePath('repository_types'), validate: false }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; // module repo types are available everywhere out of the box // on-prem repo types are not available on Cloud const types: RepositoryType[] = isCloudEnabled @@ -198,7 +198,7 @@ export function registerRepositoriesRoutes({ validate: { params: nameParameterSchema }, }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = req.params as TypeOf; try { @@ -232,7 +232,7 @@ export function registerRepositoriesRoutes({ validate: { params: nameParameterSchema }, }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = req.params as TypeOf; try { @@ -274,7 +274,7 @@ export function registerRepositoriesRoutes({ router.put( { path: addBasePath('repositories'), validate: { body: repositorySchema } }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name = '', type = '', settings = {} } = req.body as TypeOf; // Check that repository with the same name doesn't already exist @@ -313,7 +313,7 @@ export function registerRepositoriesRoutes({ validate: { body: repositorySchema, params: nameParameterSchema }, }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = req.params as TypeOf; const { type = '', settings = {} } = req.body as TypeOf; @@ -345,7 +345,7 @@ export function registerRepositoriesRoutes({ router.delete( { path: addBasePath('repositories/{name}'), validate: { params: nameParameterSchema } }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = req.params as TypeOf; const repositoryNames = name.split(','); diff --git a/x-pack/plugins/snapshot_restore/server/routes/api/restore.ts b/x-pack/plugins/snapshot_restore/server/routes/api/restore.ts index ea688273781ed..e97a64f26a123 100644 --- a/x-pack/plugins/snapshot_restore/server/routes/api/restore.ts +++ b/x-pack/plugins/snapshot_restore/server/routes/api/restore.ts @@ -24,7 +24,7 @@ export function registerRestoreRoutes({ router.get( { path: addBasePath('restores'), validate: false }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; try { const snapshotRestores: SnapshotRestore[] = []; @@ -99,7 +99,7 @@ export function registerRestoreRoutes({ validate: { body: restoreSettingsSchema, params: restoreParamsSchema }, }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { repository, snapshot } = req.params as TypeOf; const restoreSettings = req.body as TypeOf; diff --git a/x-pack/plugins/snapshot_restore/server/routes/api/snapshots.ts b/x-pack/plugins/snapshot_restore/server/routes/api/snapshots.ts index 7425ad0c272c6..c486180424da5 100644 --- a/x-pack/plugins/snapshot_restore/server/routes/api/snapshots.ts +++ b/x-pack/plugins/snapshot_restore/server/routes/api/snapshots.ts @@ -47,7 +47,7 @@ export function registerSnapshotsRoutes({ router.get( { path: addBasePath('snapshots'), validate: { query: snapshotListSchema } }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const sortField = sortFieldToESParams[(req.query as TypeOf).sortField]; const sortDirection = (req.query as TypeOf).sortDirection; @@ -176,7 +176,7 @@ export function registerSnapshotsRoutes({ validate: { params: getOneParamsSchema }, }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { repository, snapshot } = req.params as TypeOf; const managedRepository = await getManagedRepositoryName(clusterClient.asCurrentUser); @@ -232,7 +232,7 @@ export function registerSnapshotsRoutes({ router.post( { path: addBasePath('snapshots/bulk_delete'), validate: { body: deleteSchema } }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const response: { itemsDeleted: Array<{ snapshot: string; repository: string }>; diff --git a/x-pack/plugins/snapshot_restore/server/types.ts b/x-pack/plugins/snapshot_restore/server/types.ts index 9e7d97aed39ef..d5710bb39d4c9 100644 --- a/x-pack/plugins/snapshot_restore/server/types.ts +++ b/x-pack/plugins/snapshot_restore/server/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { IRouter, RequestHandlerContext, IScopedClusterClient } from '@kbn/core/server'; +import type { IRouter, CustomRequestHandlerContext, IScopedClusterClient } from '@kbn/core/server'; import { LicensingPluginSetup } from '@kbn/licensing-plugin/server'; import { SecurityPluginSetup } from '@kbn/security-plugin/server'; import { CloudSetup } from '@kbn/cloud-plugin/server'; @@ -63,6 +63,6 @@ export interface SnapshotRestoreContext { /** * @internal */ -export interface SnapshotRestoreRequestHandlerContext extends RequestHandlerContext { +export type SnapshotRestoreRequestHandlerContext = CustomRequestHandlerContext<{ snapshotRestore: SnapshotRestoreContext; -} +}>; diff --git a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/resolve_all_conflicts.test.tsx b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/resolve_all_conflicts.test.tsx index ad183196039c6..639323fb5467c 100644 --- a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/resolve_all_conflicts.test.tsx +++ b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/resolve_all_conflicts.test.tsx @@ -109,7 +109,6 @@ describe('ResolveAllConflicts', () => { panelPaddingSize="none" > { key={`spcMenuList`} data-search-term={searchTerm} className="spcMenu__spacesList" - hasFocus={this.state.allowSpacesListFocus} initialFocusedItemIndex={this.state.allowSpacesListFocus ? 0 : undefined} items={items} /> diff --git a/x-pack/plugins/spaces/server/routes/lib/licensed_route_handler.ts b/x-pack/plugins/spaces/server/routes/lib/licensed_route_handler.ts index 19b163e31e31f..254130cc1c51b 100644 --- a/x-pack/plugins/spaces/server/routes/lib/licensed_route_handler.ts +++ b/x-pack/plugins/spaces/server/routes/lib/licensed_route_handler.ts @@ -5,23 +5,23 @@ * 2.0. */ -import type { RequestHandler, RequestHandlerContext } from '@kbn/core/server'; +import type { CustomRequestHandlerContext, RequestHandler } from '@kbn/core/server'; import type { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server'; export const createLicensedRouteHandler = < P, Q, B, - Context extends RequestHandlerContext & { licensing: LicensingApiRequestHandlerContext } + Context extends CustomRequestHandlerContext<{ licensing: LicensingApiRequestHandlerContext }> >( handler: RequestHandler ) => { - const licensedRouteHandler: RequestHandler = ( + const licensedRouteHandler: RequestHandler = async ( context, request, responseToolkit ) => { - const { license } = context.licensing; + const { license } = await context.licensing; const licenseCheck = license.check('spaces', 'basic'); if (licenseCheck.state === 'unavailable' || licenseCheck.state === 'invalid') { return responseToolkit.forbidden({ body: { message: licenseCheck.message! } }); diff --git a/x-pack/plugins/spaces/server/routes/views/index.ts b/x-pack/plugins/spaces/server/routes/views/index.ts index de33027f5be45..d0cff27e85433 100644 --- a/x-pack/plugins/spaces/server/routes/views/index.ts +++ b/x-pack/plugins/spaces/server/routes/views/index.ts @@ -26,7 +26,8 @@ export function initSpacesViewsRoutes(deps: ViewRouteDeps) { { path: ENTER_SPACE_PATH, validate: false }, async (context, request, response) => { try { - const defaultRoute = await context.core.uiSettings.client.get('defaultRoute'); + const { uiSettings } = await context.core; + const defaultRoute = await uiSettings.client.get('defaultRoute'); const basePath = deps.basePath.get(request); const url = `${basePath}${defaultRoute}`; diff --git a/x-pack/plugins/spaces/server/types.ts b/x-pack/plugins/spaces/server/types.ts index 789f66fe2cbda..267e7b51377a7 100644 --- a/x-pack/plugins/spaces/server/types.ts +++ b/x-pack/plugins/spaces/server/types.ts @@ -5,15 +5,15 @@ * 2.0. */ -import type { IRouter, RequestHandlerContext } from '@kbn/core/server'; +import type { CustomRequestHandlerContext, IRouter } from '@kbn/core/server'; import type { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server'; /** * @internal */ -export interface SpacesRequestHandlerContext extends RequestHandlerContext { +export type SpacesRequestHandlerContext = CustomRequestHandlerContext<{ licensing: LicensingApiRequestHandlerContext; -} +}>; /** * @internal diff --git a/x-pack/plugins/synthetics/common/constants/alerts.ts b/x-pack/plugins/synthetics/common/constants/alerts.ts index ff3cda7887ef7..a265d13fb71d8 100644 --- a/x-pack/plugins/synthetics/common/constants/alerts.ts +++ b/x-pack/plugins/synthetics/common/constants/alerts.ts @@ -52,3 +52,10 @@ export const CLIENT_ALERT_TYPES = { TLS: 'xpack.uptime.alerts.tlsCertificate', DURATION_ANOMALY: 'xpack.uptime.alerts.durationAnomaly', }; + +export const UPTIME_RULE_TYPES = [ + 'xpack.uptime.alerts.tls', + 'xpack.uptime.alerts.tlsCertificate', + 'xpack.uptime.alerts.monitorStatus', + 'xpack.uptime.alerts.durationAnomaly', +]; diff --git a/x-pack/plugins/synthetics/common/constants/index.ts b/x-pack/plugins/synthetics/common/constants/index.ts index c7649d73b8af3..b85cfb0a0d9b6 100644 --- a/x-pack/plugins/synthetics/common/constants/index.ts +++ b/x-pack/plugins/synthetics/common/constants/index.ts @@ -13,4 +13,3 @@ export * from './settings_defaults'; export { QUERY } from './query'; export * from './ui'; export * from './rest_api'; -export const DEFAULT_NAMESPACE_STRING = 'default'; diff --git a/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts b/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts new file mode 100644 index 0000000000000..e7f79fc2086a2 --- /dev/null +++ b/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts @@ -0,0 +1,167 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { + BrowserAdvancedFields, + BrowserSimpleFields, + CommonFields, + DataStream, + HTTPAdvancedFields, + HTTPMethod, + HTTPSimpleFields, + ICMPSimpleFields, + Mode, + MonitorDefaults, + ResponseBodyIndexPolicy, + ScheduleUnit, + ScreenshotOption, + TCPAdvancedFields, + TCPSimpleFields, + TLSFields, + TLSVersion, + VerificationMode, +} from '../runtime_types/monitor_management'; +import { ConfigKey } from './monitor_management'; + +export const DEFAULT_NAMESPACE_STRING = 'default'; + +export const DEFAULT_COMMON_FIELDS: CommonFields = { + [ConfigKey.MONITOR_TYPE]: DataStream.HTTP, + [ConfigKey.ENABLED]: true, + [ConfigKey.SCHEDULE]: { + number: '3', + unit: ScheduleUnit.MINUTES, + }, + [ConfigKey.APM_SERVICE_NAME]: '', + [ConfigKey.TAGS]: [], + [ConfigKey.TIMEOUT]: '16', + [ConfigKey.NAME]: '', + [ConfigKey.LOCATIONS]: [], + [ConfigKey.NAMESPACE]: DEFAULT_NAMESPACE_STRING, +}; + +export const DEFAULT_BROWSER_ADVANCED_FIELDS: BrowserAdvancedFields = { + [ConfigKey.SCREENSHOTS]: ScreenshotOption.ON, + [ConfigKey.SYNTHETICS_ARGS]: [], + [ConfigKey.JOURNEY_FILTERS_MATCH]: '', + [ConfigKey.JOURNEY_FILTERS_TAGS]: [], + [ConfigKey.IGNORE_HTTPS_ERRORS]: false, + [ConfigKey.IS_THROTTLING_ENABLED]: true, + [ConfigKey.DOWNLOAD_SPEED]: '5', + [ConfigKey.UPLOAD_SPEED]: '3', + [ConfigKey.LATENCY]: '20', + [ConfigKey.THROTTLING_CONFIG]: '5d/3u/20l', +}; + +export const DEFAULT_BROWSER_SIMPLE_FIELDS: BrowserSimpleFields = { + ...DEFAULT_COMMON_FIELDS, + [ConfigKey.SCHEDULE]: { + unit: ScheduleUnit.MINUTES, + number: '10', + }, + [ConfigKey.METADATA]: { + script_source: { + is_generated_script: false, + file_name: '', + }, + is_zip_url_tls_enabled: false, + }, + [ConfigKey.MONITOR_TYPE]: DataStream.BROWSER, + [ConfigKey.SOURCE_INLINE]: '', + [ConfigKey.SOURCE_ZIP_URL]: '', + [ConfigKey.SOURCE_ZIP_USERNAME]: '', + [ConfigKey.SOURCE_ZIP_PASSWORD]: '', + [ConfigKey.SOURCE_ZIP_FOLDER]: '', + [ConfigKey.SOURCE_ZIP_PROXY_URL]: '', + [ConfigKey.PARAMS]: '', + [ConfigKey.ZIP_URL_TLS_CERTIFICATE_AUTHORITIES]: undefined, + [ConfigKey.ZIP_URL_TLS_CERTIFICATE]: undefined, + [ConfigKey.ZIP_URL_TLS_KEY]: undefined, + [ConfigKey.ZIP_URL_TLS_KEY_PASSPHRASE]: undefined, + [ConfigKey.ZIP_URL_TLS_VERIFICATION_MODE]: undefined, + [ConfigKey.ZIP_URL_TLS_VERSION]: undefined, + [ConfigKey.URLS]: undefined, + [ConfigKey.PORT]: undefined, +}; + +export const DEFAULT_HTTP_SIMPLE_FIELDS: HTTPSimpleFields = { + ...DEFAULT_COMMON_FIELDS, + [ConfigKey.METADATA]: { + is_tls_enabled: false, + }, + [ConfigKey.URLS]: '', + [ConfigKey.MAX_REDIRECTS]: '0', + [ConfigKey.MONITOR_TYPE]: DataStream.HTTP, +}; + +export const DEFAULT_HTTP_ADVANCED_FIELDS: HTTPAdvancedFields = { + [ConfigKey.PASSWORD]: '', + [ConfigKey.PROXY_URL]: '', + [ConfigKey.RESPONSE_BODY_CHECK_NEGATIVE]: [], + [ConfigKey.RESPONSE_BODY_CHECK_POSITIVE]: [], + [ConfigKey.RESPONSE_BODY_INDEX]: ResponseBodyIndexPolicy.ON_ERROR, + [ConfigKey.RESPONSE_HEADERS_CHECK]: {}, + [ConfigKey.RESPONSE_HEADERS_INDEX]: true, + [ConfigKey.RESPONSE_STATUS_CHECK]: [], + [ConfigKey.REQUEST_BODY_CHECK]: { + value: '', + type: Mode.PLAINTEXT, + }, + [ConfigKey.REQUEST_HEADERS_CHECK]: {}, + [ConfigKey.REQUEST_METHOD_CHECK]: HTTPMethod.GET, + [ConfigKey.USERNAME]: '', +}; + +export const DEFAULT_ICMP_SIMPLE_FIELDS: ICMPSimpleFields = { + ...DEFAULT_COMMON_FIELDS, + [ConfigKey.HOSTS]: '', + [ConfigKey.MONITOR_TYPE]: DataStream.ICMP, + [ConfigKey.WAIT]: '1', +}; + +export const DEFAULT_TCP_SIMPLE_FIELDS: TCPSimpleFields = { + ...DEFAULT_COMMON_FIELDS, + [ConfigKey.METADATA]: { + is_tls_enabled: false, + }, + [ConfigKey.HOSTS]: '', + [ConfigKey.MONITOR_TYPE]: DataStream.TCP, +}; + +export const DEFAULT_TCP_ADVANCED_FIELDS: TCPAdvancedFields = { + [ConfigKey.PROXY_URL]: '', + [ConfigKey.PROXY_USE_LOCAL_RESOLVER]: false, + [ConfigKey.RESPONSE_RECEIVE_CHECK]: '', + [ConfigKey.REQUEST_SEND_CHECK]: '', +}; + +export const DEFAULT_TLS_FIELDS: TLSFields = { + [ConfigKey.TLS_CERTIFICATE_AUTHORITIES]: '', + [ConfigKey.TLS_CERTIFICATE]: '', + [ConfigKey.TLS_KEY]: '', + [ConfigKey.TLS_KEY_PASSPHRASE]: '', + [ConfigKey.TLS_VERIFICATION_MODE]: VerificationMode.FULL, + [ConfigKey.TLS_VERSION]: [TLSVersion.ONE_ONE, TLSVersion.ONE_TWO, TLSVersion.ONE_THREE], +}; + +export const DEFAULT_FIELDS: MonitorDefaults = { + [DataStream.HTTP]: { + ...DEFAULT_HTTP_SIMPLE_FIELDS, + ...DEFAULT_HTTP_ADVANCED_FIELDS, + ...DEFAULT_TLS_FIELDS, + }, + [DataStream.TCP]: { + ...DEFAULT_TCP_SIMPLE_FIELDS, + ...DEFAULT_TCP_ADVANCED_FIELDS, + ...DEFAULT_TLS_FIELDS, + }, + [DataStream.ICMP]: DEFAULT_ICMP_SIMPLE_FIELDS, + [DataStream.BROWSER]: { + ...DEFAULT_BROWSER_SIMPLE_FIELDS, + ...DEFAULT_BROWSER_ADVANCED_FIELDS, + ...DEFAULT_TLS_FIELDS, + }, +}; diff --git a/x-pack/plugins/synthetics/common/constants/plugin.ts b/x-pack/plugins/synthetics/common/constants/plugin.ts index 8c1506621ba8c..c0a6ed02477f5 100644 --- a/x-pack/plugins/synthetics/common/constants/plugin.ts +++ b/x-pack/plugins/synthetics/common/constants/plugin.ts @@ -9,16 +9,19 @@ import { i18n } from '@kbn/i18n'; export const PLUGIN = { APP_ROOT_ID: 'react-uptime-root', - DESCRIPTION: i18n.translate('xpack.uptime.pluginDescription', { + DESCRIPTION: i18n.translate('xpack.synthetics.pluginDescription', { defaultMessage: 'Synthetics monitoring', description: 'The description text that will appear in the feature catalogue.', }), ID: 'uptime', - LOCAL_STORAGE_KEY: 'xpack.uptime', - NAME: i18n.translate('xpack.uptime.featureRegistry.syntheticsFeatureName', { + LOCAL_STORAGE_KEY: 'xpack.synthetics.', + NAME: i18n.translate('xpack.synthetics.featureRegistry.syntheticsFeatureName', { defaultMessage: 'Synthetics and Uptime', }), - TITLE: i18n.translate('xpack.uptime.uptimeFeatureCatalogueTitle', { + TITLE: i18n.translate('xpack.synthetics.uptimeFeatureCatalogueTitle', { defaultMessage: 'Uptime', }), + SYNTHETICS: i18n.translate('xpack.synthetics.syntheticsFeatureCatalogueTitle', { + defaultMessage: 'Synthetics', + }), }; diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts index c093705e858d8..0e96b8b9de6e2 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts @@ -10,6 +10,7 @@ import { secretKeys } from '../../constants/monitor_management'; import { ConfigKey } from './config_key'; import { MonitorServiceLocationsCodec, ServiceLocationErrors } from './locations'; import { + DataStream, DataStreamCodec, ModeCodec, ResponseBodyIndexPolicyCodec, @@ -308,6 +309,15 @@ export type EncryptedSyntheticsMonitorWithId = t.TypeOf< typeof EncryptedSyntheticsMonitorWithIdCodec >; +export const MonitorDefaultsCodec = t.interface({ + [DataStream.HTTP]: HTTPFieldsCodec, + [DataStream.TCP]: TCPFieldsCodec, + [DataStream.ICMP]: ICMPSimpleFieldsCodec, + [DataStream.BROWSER]: BrowserFieldsCodec, +}); + +export type MonitorDefaults = t.TypeOf; + export const MonitorManagementListResultCodec = t.type({ monitors: t.array( t.interface({ diff --git a/x-pack/plugins/synthetics/common/translations.ts b/x-pack/plugins/synthetics/common/translations.ts index 2b95732badafb..9bef65bd9dad6 100644 --- a/x-pack/plugins/synthetics/common/translations.ts +++ b/x-pack/plugins/synthetics/common/translations.ts @@ -8,38 +8,44 @@ import { i18n } from '@kbn/i18n'; export const VALUE_MUST_BE_GREATER_THAN_ZERO = i18n.translate( - 'xpack.uptime.settings.invalid.error', + 'xpack.synthetics.settings.invalid.error', { defaultMessage: 'Value must be greater than 0.', } ); -export const VALUE_MUST_BE_AN_INTEGER = i18n.translate('xpack.uptime.settings.invalid.nanError', { - defaultMessage: 'Value must be an integer.', -}); +export const VALUE_MUST_BE_AN_INTEGER = i18n.translate( + 'xpack.synthetics.settings.invalid.nanError', + { + defaultMessage: 'Value must be an integer.', + } +); export const MonitorStatusTranslations = { - defaultActionMessage: i18n.translate('xpack.uptime.alerts.monitorStatus.defaultActionMessage', { - defaultMessage: - 'Monitor {monitorName} with url {monitorUrl} from {observerLocation} {statusMessage} The latest error message is {latestErrorMessage}', - values: { - monitorName: '{{state.monitorName}}', - monitorUrl: '{{{state.monitorUrl}}}', - statusMessage: '{{{state.statusMessage}}}', - latestErrorMessage: '{{{state.latestErrorMessage}}}', - observerLocation: '{{state.observerLocation}}', - }, - }), - name: i18n.translate('xpack.uptime.alerts.monitorStatus.clientName', { + defaultActionMessage: i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.defaultActionMessage', + { + defaultMessage: + 'Monitor {monitorName} with url {monitorUrl} from {observerLocation} {statusMessage} The latest error message is {latestErrorMessage}', + values: { + monitorName: '{{state.monitorName}}', + monitorUrl: '{{{state.monitorUrl}}}', + statusMessage: '{{{state.statusMessage}}}', + latestErrorMessage: '{{{state.latestErrorMessage}}}', + observerLocation: '{{state.observerLocation}}', + }, + } + ), + name: i18n.translate('xpack.synthetics.alerts.monitorStatus.clientName', { defaultMessage: 'Uptime monitor status', }), - description: i18n.translate('xpack.uptime.alerts.monitorStatus.description', { + description: i18n.translate('xpack.synthetics.alerts.monitorStatus.description', { defaultMessage: 'Alert when a monitor is down or an availability threshold is breached.', }), }; export const TlsTranslations = { - defaultActionMessage: i18n.translate('xpack.uptime.alerts.tls.defaultActionMessage', { + defaultActionMessage: i18n.translate('xpack.synthetics.alerts.tls.defaultActionMessage', { defaultMessage: `Detected TLS certificate {commonName} from issuer {issuer} is {status}. Certificate {summary} `, values: { @@ -49,16 +55,16 @@ export const TlsTranslations = { status: '{{state.status}}', }, }), - name: i18n.translate('xpack.uptime.alerts.tls.clientName', { + name: i18n.translate('xpack.synthetics.alerts.tls.clientName', { defaultMessage: 'Uptime TLS', }), - description: i18n.translate('xpack.uptime.alerts.tls.description', { + description: i18n.translate('xpack.synthetics.alerts.tls.description', { defaultMessage: 'Alert when the TLS certificate of an Uptime monitor is about to expire.', }), }; export const TlsTranslationsLegacy = { - defaultActionMessage: i18n.translate('xpack.uptime.alerts.tls.legacy.defaultActionMessage', { + defaultActionMessage: i18n.translate('xpack.synthetics.alerts.tls.legacy.defaultActionMessage', { defaultMessage: `Detected {count} TLS certificates expiring or becoming too old. {expiringConditionalOpen} Expiring cert count: {expiringCount} @@ -81,34 +87,37 @@ Aging Certificates: {agingCommonNameAndDate} agingConditionalClose: '{{/state.hasAging}}', }, }), - name: i18n.translate('xpack.uptime.alerts.tls.legacy.clientName', { + name: i18n.translate('xpack.synthetics.alerts.tls.legacy.clientName', { defaultMessage: 'Uptime TLS (Legacy)', }), - description: i18n.translate('xpack.uptime.alerts.tls.legacy.description', { + description: i18n.translate('xpack.synthetics.alerts.tls.legacy.description', { defaultMessage: 'Alert when the TLS certificate of an Uptime monitor is about to expire. This alert will be deprecated in a future version.', }), }; export const DurationAnomalyTranslations = { - defaultActionMessage: i18n.translate('xpack.uptime.alerts.durationAnomaly.defaultActionMessage', { - defaultMessage: `Abnormal ({severity} level) response time detected on {monitor} with url {monitorUrl} at {anomalyStartTimestamp}. Anomaly severity score is {severityScore}. + defaultActionMessage: i18n.translate( + 'xpack.synthetics.alerts.durationAnomaly.defaultActionMessage', + { + defaultMessage: `Abnormal ({severity} level) response time detected on {monitor} with url {monitorUrl} at {anomalyStartTimestamp}. Anomaly severity score is {severityScore}. Response times as high as {slowestAnomalyResponse} have been detected from location {observerLocation}. Expected response time is {expectedResponseTime}.`, - values: { - severity: '{{state.severity}}', - anomalyStartTimestamp: '{{state.anomalyStartTimestamp}}', - monitor: '{{state.monitor}}', - monitorUrl: '{{{state.monitorUrl}}}', - slowestAnomalyResponse: '{{state.slowestAnomalyResponse}}', - expectedResponseTime: '{{state.expectedResponseTime}}', - severityScore: '{{state.severityScore}}', - observerLocation: '{{state.observerLocation}}', - }, - }), - name: i18n.translate('xpack.uptime.alerts.durationAnomaly.clientName', { + values: { + severity: '{{state.severity}}', + anomalyStartTimestamp: '{{state.anomalyStartTimestamp}}', + monitor: '{{state.monitor}}', + monitorUrl: '{{{state.monitorUrl}}}', + slowestAnomalyResponse: '{{state.slowestAnomalyResponse}}', + expectedResponseTime: '{{state.expectedResponseTime}}', + severityScore: '{{state.severityScore}}', + observerLocation: '{{state.observerLocation}}', + }, + } + ), + name: i18n.translate('xpack.synthetics.alerts.durationAnomaly.clientName', { defaultMessage: 'Uptime Duration Anomaly', }), - description: i18n.translate('xpack.uptime.alerts.durationAnomaly.description', { + description: i18n.translate('xpack.synthetics.alerts.durationAnomaly.description', { defaultMessage: 'Alert when the Uptime monitor duration is anomalous.', }), }; diff --git a/x-pack/plugins/synthetics/e2e/journeys/alerts/status_alert_flyouts_in_alerting_app.ts b/x-pack/plugins/synthetics/e2e/journeys/alerts/status_alert_flyouts_in_alerting_app.ts index 5346d0de33c28..321c68a8c3350 100644 --- a/x-pack/plugins/synthetics/e2e/journeys/alerts/status_alert_flyouts_in_alerting_app.ts +++ b/x-pack/plugins/synthetics/e2e/journeys/alerts/status_alert_flyouts_in_alerting_app.ts @@ -27,7 +27,7 @@ journey('StatusFlyoutInAlertingApp', async ({ page, params }) => { step('Open monitor status flyout', async () => { await page.click(byTestId('createFirstRuleButton')); await waitForLoadingToFinish({ page }); - await page.click(byTestId('"xpack.uptime.alerts.monitorStatus-SelectOption"')); + await page.click(byTestId('"xpack.synthetics.alerts.monitorStatus-SelectOption"')); await waitForLoadingToFinish({ page }); await assertText({ page, text: 'This alert will apply to approximately 0 monitors.' }); }); @@ -39,9 +39,12 @@ journey('StatusFlyoutInAlertingApp', async ({ page, params }) => { }); step('can open query bar', async () => { - await page.click(byTestId('"xpack.uptime.alerts.monitorStatus.filterBar"')); + await page.click(byTestId('"xpack.synthetics.alerts.monitorStatus.filterBar"')); - await page.fill(byTestId('"xpack.uptime.alerts.monitorStatus.filterBar"'), 'monitor.type : '); + await page.fill( + byTestId('"xpack.synthetics.alerts.monitorStatus.filterBar"'), + 'monitor.type : ' + ); await waitForLoadingToFinish({ page }); @@ -58,7 +61,7 @@ journey('StatusFlyoutInAlertingApp', async ({ page, params }) => { step('Open tls alert flyout', async () => { await page.click(byTestId('createFirstRuleButton')); await waitForLoadingToFinish({ page }); - await page.click(byTestId('"xpack.uptime.alerts.tlsCertificate-SelectOption"')); + await page.click(byTestId('"xpack.synthetics.alerts.tlsCertificate-SelectOption"')); await waitForLoadingToFinish({ page }); await assertText({ page, text: 'has a certificate expiring within' }); }); diff --git a/x-pack/plugins/synthetics/e2e/journeys/alerts/tls_alert_flyouts_in_alerting_app.ts b/x-pack/plugins/synthetics/e2e/journeys/alerts/tls_alert_flyouts_in_alerting_app.ts index 873d10c0a21bb..5cf1d1a6c9ff5 100644 --- a/x-pack/plugins/synthetics/e2e/journeys/alerts/tls_alert_flyouts_in_alerting_app.ts +++ b/x-pack/plugins/synthetics/e2e/journeys/alerts/tls_alert_flyouts_in_alerting_app.ts @@ -27,7 +27,7 @@ journey('TlsFlyoutInAlertingApp', async ({ page, params }) => { step('Open tls alert flyout', async () => { await page.click(byTestId('createFirstRuleButton')); await waitForLoadingToFinish({ page }); - await page.click(byTestId('"xpack.uptime.alerts.tlsCertificate-SelectOption"')); + await page.click(byTestId('"xpack.synthetics.alerts.tlsCertificate-SelectOption"')); await waitForLoadingToFinish({ page }); await assertText({ page, text: 'has a certificate expiring within' }); }); diff --git a/x-pack/plugins/synthetics/e2e/journeys/monitor_details/monitor_details.journey.ts b/x-pack/plugins/synthetics/e2e/journeys/monitor_details/monitor_details.journey.ts index 2965c1acf2c2b..b061942e0bb3f 100644 --- a/x-pack/plugins/synthetics/e2e/journeys/monitor_details/monitor_details.journey.ts +++ b/x-pack/plugins/synthetics/e2e/journeys/monitor_details/monitor_details.journey.ts @@ -54,7 +54,7 @@ journey('MonitorDetails', async ({ page, params }: { page: Page; params: any }) 'k5tlHm0B0I9WX_CzaNxm', 'NZtkHm0B0I9WX_Cz89w9', 'zJtkHm0B0I9WX_CzftsN', - ].map((id) => page.waitForSelector(byTestId(`"xpack.uptime.pingList.ping-${id}"`))) + ].map((id) => page.waitForSelector(byTestId(`"xpack.synthetics.pingList.ping-${id}"`))) ); }); }); diff --git a/x-pack/plugins/synthetics/e2e/page_objects/monitor_details.tsx b/x-pack/plugins/synthetics/e2e/page_objects/monitor_details.tsx index 7cce2c061fa82..02395674d0cdd 100644 --- a/x-pack/plugins/synthetics/e2e/page_objects/monitor_details.tsx +++ b/x-pack/plugins/synthetics/e2e/page_objects/monitor_details.tsx @@ -40,11 +40,11 @@ export function monitorDetailsPageProvider({ page, kibanaUrl }: { page: Page; ki }, async setStatusFilterUp() { - await page.click('[data-test-subj="xpack.uptime.filterBar.filterStatusUp"]'); + await page.click('[data-test-subj="xpack.synthetics.filterBar.filterStatusUp"]'); }, async setStatusFilterDown() { - await page.click('[data-test-subj="xpack.uptime.filterBar.filterStatusDown"]'); + await page.click('[data-test-subj="xpack.synthetics.filterBar.filterStatusDown"]'); }, async refreshFromES() { diff --git a/x-pack/plugins/synthetics/kibana.json b/x-pack/plugins/synthetics/kibana.json index 7eaccbbb0817f..bb827019fc70a 100644 --- a/x-pack/plugins/synthetics/kibana.json +++ b/x-pack/plugins/synthetics/kibana.json @@ -8,6 +8,7 @@ "cases", "embeddable", "discover", + "dataViews", "encryptedSavedObjects", "features", "inspector", @@ -18,7 +19,8 @@ "share", "taskManager", "triggersActionsUi", - "usageCollection" + "usageCollection", + "unifiedSearch" ], "server": true, "ui": true, diff --git a/x-pack/plugins/synthetics/public/apps/plugin.ts b/x-pack/plugins/synthetics/public/apps/plugin.ts deleted file mode 100644 index ab2ae07e1c454..0000000000000 --- a/x-pack/plugins/synthetics/public/apps/plugin.ts +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - CoreSetup, - CoreStart, - Plugin, - PluginInitializerContext, - AppMountParameters, -} from '@kbn/core/public'; -import { from } from 'rxjs'; -import { map } from 'rxjs/operators'; -import { i18n } from '@kbn/i18n'; -import { SharePluginSetup, SharePluginStart } from '@kbn/share-plugin/public'; -import { DiscoverStart } from '@kbn/discover-plugin/public'; -import { DEFAULT_APP_CATEGORIES } from '@kbn/core/public'; - -import type { HomePublicPluginSetup } from '@kbn/home-plugin/public'; -import { EmbeddableStart } from '@kbn/embeddable-plugin/public'; -import { - TriggersAndActionsUIPublicPluginSetup, - TriggersAndActionsUIPublicPluginStart, -} from '@kbn/triggers-actions-ui-plugin/public'; -import { DataPublicPluginSetup, DataPublicPluginStart } from '@kbn/data-plugin/public'; - -import { FleetStart } from '@kbn/fleet-plugin/public'; -import { - FetchDataParams, - ObservabilityPublicSetup, - ObservabilityPublicStart, -} from '@kbn/observability-plugin/public'; -import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; -import { Start as InspectorPluginStart } from '@kbn/inspector-plugin/public'; -import { CasesUiStart } from '@kbn/cases-plugin/public'; -import { CloudSetup } from '@kbn/cloud-plugin/public'; -import { PLUGIN } from '../../common/constants/plugin'; -import { - LazySyntheticsPolicyCreateExtension, - LazySyntheticsPolicyEditExtension, -} from '../components/fleet_package'; -import { LazySyntheticsCustomAssetsExtension } from '../components/fleet_package/lazy_synthetics_custom_assets_extension'; -import { uptimeOverviewNavigatorParams } from './locators/overview'; -import { alertTypeInitializers, legacyAlertTypeInitializers } from '../lib/alert_types'; - -export interface ClientPluginsSetup { - home?: HomePublicPluginSetup; - data: DataPublicPluginSetup; - observability: ObservabilityPublicSetup; - share: SharePluginSetup; - triggersActionsUi: TriggersAndActionsUIPublicPluginSetup; - cloud?: CloudSetup; -} - -export interface ClientPluginsStart { - fleet?: FleetStart; - data: DataPublicPluginStart; - discover: DiscoverStart; - inspector: InspectorPluginStart; - embeddable: EmbeddableStart; - observability: ObservabilityPublicStart; - share: SharePluginStart; - triggersActionsUi: TriggersAndActionsUIPublicPluginStart; - cases: CasesUiStart; -} - -export interface UptimePluginServices extends Partial { - embeddable: EmbeddableStart; - data: DataPublicPluginStart; - triggersActionsUi: TriggersAndActionsUIPublicPluginStart; - storage: IStorageWrapper; -} - -export type ClientSetup = void; -export type ClientStart = void; - -export class UptimePlugin - implements Plugin -{ - constructor(private readonly initContext: PluginInitializerContext) {} - - public setup(core: CoreSetup, plugins: ClientPluginsSetup): void { - if (plugins.home) { - plugins.home.featureCatalogue.register({ - id: PLUGIN.ID, - title: PLUGIN.TITLE, - description: PLUGIN.DESCRIPTION, - icon: 'uptimeApp', - path: '/app/uptime', - showOnHomePage: false, - category: 'data', - }); - } - const getUptimeDataHelper = async () => { - const [coreStart] = await core.getStartServices(); - const { UptimeDataHelper } = await import('./uptime_overview_fetcher'); - - return UptimeDataHelper(coreStart); - }; - - plugins.share.url.locators.create(uptimeOverviewNavigatorParams); - - plugins.observability.dashboard.register({ - appName: 'synthetics', - hasData: async () => { - const dataHelper = await getUptimeDataHelper(); - const status = await dataHelper.indexStatus(); - return { hasData: status.docCount > 0, indices: status.indices }; - }, - fetchData: async (params: FetchDataParams) => { - const dataHelper = await getUptimeDataHelper(); - return await dataHelper.overviewData(params); - }, - }); - - plugins.observability.navigation.registerSections( - from(core.getStartServices()).pipe( - map(([coreStart]) => { - if (coreStart.application.capabilities.uptime.show) { - return [ - { - label: 'Uptime', - sortKey: 500, - entries: [ - { - label: i18n.translate('xpack.uptime.overview.heading', { - defaultMessage: 'Monitors', - }), - app: 'uptime', - path: '/', - matchFullPath: true, - ignoreTrailingSlash: true, - }, - { - label: i18n.translate('xpack.uptime.certificatesPage.heading', { - defaultMessage: 'TLS Certificates', - }), - app: 'uptime', - path: '/certificates', - matchFullPath: true, - }, - ], - }, - ]; - } - - return []; - }) - ) - ); - - const { observabilityRuleTypeRegistry } = plugins.observability; - - core.getStartServices().then(([coreStart, clientPluginsStart]) => { - alertTypeInitializers.forEach((init) => { - const alertInitializer = init({ - core: coreStart, - plugins: clientPluginsStart, - }); - if ( - clientPluginsStart.triggersActionsUi && - !clientPluginsStart.triggersActionsUi.ruleTypeRegistry.has(alertInitializer.id) - ) { - observabilityRuleTypeRegistry.register(alertInitializer); - } - }); - - legacyAlertTypeInitializers.forEach((init) => { - const alertInitializer = init({ - core: coreStart, - plugins: clientPluginsStart, - }); - if ( - clientPluginsStart.triggersActionsUi && - !clientPluginsStart.triggersActionsUi.ruleTypeRegistry.has(alertInitializer.id) - ) { - plugins.triggersActionsUi.ruleTypeRegistry.register(alertInitializer); - } - }); - }); - - core.application.register({ - id: PLUGIN.ID, - euiIconType: 'logoObservability', - order: 8400, - title: PLUGIN.TITLE, - category: DEFAULT_APP_CATEGORIES.observability, - keywords: [ - 'Synthetics', - 'pings', - 'checks', - 'availability', - 'response duration', - 'response time', - 'outside in', - 'reachability', - 'reachable', - 'digital', - 'performance', - 'web performance', - 'web perf', - ], - deepLinks: [ - { id: 'Down monitors', title: 'Down monitors', path: '/?statusFilter=down' }, - { id: 'Certificates', title: 'TLS Certificates', path: '/certificates' }, - { id: 'Settings', title: 'Settings', path: '/settings' }, - ], - mount: async (params: AppMountParameters) => { - const [coreStart, corePlugins] = await core.getStartServices(); - - const { renderApp } = await import('./render_app'); - return renderApp(coreStart, plugins, corePlugins, params, this.initContext.env.mode.dev); - }, - }); - } - - public start(start: CoreStart, plugins: ClientPluginsStart): void { - if (plugins.fleet) { - const { registerExtension } = plugins.fleet; - - registerExtension({ - package: 'synthetics', - view: 'package-policy-create', - Component: LazySyntheticsPolicyCreateExtension, - }); - - registerExtension({ - package: 'synthetics', - view: 'package-policy-edit', - useLatestPackageVersion: true, - Component: LazySyntheticsPolicyEditExtension, - }); - - registerExtension({ - package: 'synthetics', - view: 'package-detail-assets', - Component: LazySyntheticsCustomAssetsExtension, - }); - } - } - - public stop(): void {} -} diff --git a/x-pack/plugins/synthetics/public/apps/render_app.tsx b/x-pack/plugins/synthetics/public/apps/render_app.tsx deleted file mode 100644 index 9a64fe9e18621..0000000000000 --- a/x-pack/plugins/synthetics/public/apps/render_app.tsx +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import ReactDOM from 'react-dom'; -import { i18n as i18nFormatter } from '@kbn/i18n'; -import { AppMountParameters, CoreStart } from '@kbn/core/public'; -import { getIntegratedAppAvailability } from '../lib/adapters/framework/capabilities_adapter'; -import { - DEFAULT_DARK_MODE, - DEFAULT_TIMEPICKER_QUICK_RANGES, - INTEGRATED_SOLUTIONS, -} from '../../common/constants'; -import { UptimeApp, UptimeAppProps } from './uptime_app'; -import { ClientPluginsSetup, ClientPluginsStart } from './plugin'; - -export function renderApp( - core: CoreStart, - plugins: ClientPluginsSetup, - startPlugins: ClientPluginsStart, - appMountParameters: AppMountParameters, - isDev: boolean -) { - const { - application: { capabilities }, - chrome: { setBadge, setHelpExtension }, - docLinks, - http: { basePath }, - i18n, - } = core; - - const { apm, infrastructure, logs } = getIntegratedAppAvailability( - capabilities, - INTEGRATED_SOLUTIONS - ); - - const canSave = (capabilities.uptime.save ?? false) as boolean; - - const props: UptimeAppProps = { - isDev, - plugins, - canSave, - core, - i18n, - startPlugins, - basePath: basePath.get(), - darkMode: core.uiSettings.get(DEFAULT_DARK_MODE), - commonlyUsedRanges: core.uiSettings.get(DEFAULT_TIMEPICKER_QUICK_RANGES), - isApmAvailable: apm, - isInfraAvailable: infrastructure, - isLogsAvailable: logs, - renderGlobalHelpControls: () => - setHelpExtension({ - appName: i18nFormatter.translate('xpack.uptime.header.appName', { - defaultMessage: 'Uptime', - }), - links: [ - { - linkType: 'documentation', - href: `${docLinks.links.observability.monitorUptime}`, - }, - { - linkType: 'discuss', - href: 'https://discuss.elastic.co/c/uptime', - }, - ], - }), - setBadge, - appMountParameters, - setBreadcrumbs: core.chrome.setBreadcrumbs, - }; - - ReactDOM.render(, appMountParameters.element); - - return () => { - ReactDOM.unmountComponentAtNode(appMountParameters.element); - }; -} diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/render_app.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/render_app.tsx new file mode 100644 index 0000000000000..c4b05ea7a2e0c --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/render_app.tsx @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import ReactDOM from 'react-dom'; +import { AppMountParameters, CoreStart } from '@kbn/core/public'; +import { ClientPluginsSetup, ClientPluginsStart } from '../../plugin'; +import { SyntheticsApp } from '../synthetics_app'; + +export function renderApp( + core: CoreStart, + plugins: ClientPluginsSetup, + startPlugins: ClientPluginsStart, + appMountParameters: AppMountParameters, + isDev: boolean +) { + ReactDOM.render(, appMountParameters.element); + + return () => { + ReactDOM.unmountComponentAtNode(appMountParameters.element); + }; +} diff --git a/x-pack/plugins/synthetics/public/apps/synthetics_app.tsx b/x-pack/plugins/synthetics/public/apps/synthetics_app.tsx new file mode 100644 index 0000000000000..92531041157a7 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics_app.tsx @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; + +export const SyntheticsApp = () => { + return
Synthetics App
; +}; diff --git a/x-pack/plugins/synthetics/public/badge.ts b/x-pack/plugins/synthetics/public/badge.ts deleted file mode 100644 index a42eaa58a7943..0000000000000 --- a/x-pack/plugins/synthetics/public/badge.ts +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { ChromeBadge } from '@kbn/core/public'; -export type UMBadge = ChromeBadge | undefined; diff --git a/x-pack/plugins/synthetics/public/components/certificates/translations.ts b/x-pack/plugins/synthetics/public/components/certificates/translations.ts deleted file mode 100644 index 45ea2bf9c47cf..0000000000000 --- a/x-pack/plugins/synthetics/public/components/certificates/translations.ts +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const OK = i18n.translate('xpack.uptime.certs.ok', { - defaultMessage: 'OK', -}); - -export const EXPIRED = i18n.translate('xpack.uptime.certs.expired', { - defaultMessage: 'Expired', -}); - -export const EXPIRES_SOON = i18n.translate('xpack.uptime.certs.expireSoon', { - defaultMessage: 'Expires soon', -}); - -export const EXPIRES = i18n.translate('xpack.uptime.certs.expires', { - defaultMessage: 'Expires', -}); - -export const SEARCH_CERTS = i18n.translate('xpack.uptime.certs.searchCerts', { - defaultMessage: 'Search certificates', -}); - -export const STATUS_COL = i18n.translate('xpack.uptime.certs.list.status', { - defaultMessage: 'Status', -}); - -export const TOO_OLD = i18n.translate('xpack.uptime.certs.list.status.old', { - defaultMessage: 'Too old', -}); - -export const COMMON_NAME_COL = i18n.translate('xpack.uptime.certs.list.commonName', { - defaultMessage: 'Common name', -}); - -export const MONITORS_COL = i18n.translate('xpack.uptime.certs.list.monitors', { - defaultMessage: 'Monitors', -}); - -export const ISSUED_BY_COL = i18n.translate('xpack.uptime.certs.list.issuedBy', { - defaultMessage: 'Issued by', -}); - -export const VALID_UNTIL_COL = i18n.translate('xpack.uptime.certs.list.validUntil', { - defaultMessage: 'Valid until', -}); - -export const AGE_COL = i18n.translate('xpack.uptime.certs.list.ageCol', { - defaultMessage: 'Age', -}); - -export const DAYS = i18n.translate('xpack.uptime.certs.list.days', { - defaultMessage: 'days', -}); - -export const FINGERPRINTS_COL = i18n.translate('xpack.uptime.certs.list.expirationDate', { - defaultMessage: 'Fingerprints', -}); - -export const COPY_FINGERPRINT = i18n.translate('xpack.uptime.certs.list.copyFingerprint', { - defaultMessage: 'Click to copy fingerprint value', -}); - -export const NO_CERTS_AVAILABLE = i18n.translate('xpack.uptime.certs.list.empty', { - defaultMessage: 'No Certificates found. Note: Certificates are only visible for Heartbeat 7.8+', -}); - -export const LOADING_CERTIFICATES = i18n.translate('xpack.uptime.certificates.loading', { - defaultMessage: 'Loading certificates ...', -}); diff --git a/x-pack/plugins/synthetics/public/components/common/charts/donut_chart_legend.test.tsx b/x-pack/plugins/synthetics/public/components/common/charts/donut_chart_legend.test.tsx deleted file mode 100644 index 3e5a5c2539680..0000000000000 --- a/x-pack/plugins/synthetics/public/components/common/charts/donut_chart_legend.test.tsx +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { renderWithIntl } from '@kbn/test-jest-helpers'; - -import { DonutChartLegend } from './donut_chart_legend'; - -import { STATUS_DOWN_LABEL, STATUS_UP_LABEL } from '../translations'; - -describe('DonutChartLegend', () => { - it('applies valid props as expected', () => { - const up = 45; - const down = 23; - const component = renderWithIntl(); - - expect( - component.find('[data-test-subj="xpack.uptime.snapshot.donutChart.up.label"]').text() - ).toBe(STATUS_UP_LABEL); - expect(component.find('[data-test-subj="xpack.uptime.snapshot.donutChart.up"]').text()).toBe( - `${up}` - ); - expect( - component.find('[data-test-subj="xpack.uptime.snapshot.donutChart.down.label"]').text() - ).toBe(STATUS_DOWN_LABEL); - expect(component.find('[data-test-subj="xpack.uptime.snapshot.donutChart.down"]').text()).toBe( - `${down}` - ); - }); -}); diff --git a/x-pack/plugins/synthetics/public/components/common/translations.ts b/x-pack/plugins/synthetics/public/components/common/translations.ts deleted file mode 100644 index db772d8bed9d7..0000000000000 --- a/x-pack/plugins/synthetics/public/components/common/translations.ts +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const URL_LABEL = i18n.translate('xpack.uptime.monitorList.table.url.name', { - defaultMessage: 'Url', -}); - -export const TAGS_LABEL = i18n.translate('xpack.uptime.monitorList.table.tags.name', { - defaultMessage: 'Tags', -}); - -export const STATUS_UP_LABEL = i18n.translate('xpack.uptime.monitorList.statusColumn.upLabel', { - defaultMessage: 'Up', -}); - -export const STATUS_DOWN_LABEL = i18n.translate('xpack.uptime.monitorList.statusColumn.downLabel', { - defaultMessage: 'Down', -}); - -export const STATUS_COMPLETE_LABEL = i18n.translate( - 'xpack.uptime.monitorList.statusColumn.completeLabel', - { - defaultMessage: 'Complete', - } -); - -export const STATUS_FAILED_LABEL = i18n.translate( - 'xpack.uptime.monitorList.statusColumn.failedLabel', - { - defaultMessage: 'Failed', - } -); - -export const SECONDS_LABEL = i18n.translate('xpack.uptime.seconds.label', { - defaultMessage: 'seconds', -}); - -export const SEC_LABEL = i18n.translate('xpack.uptime.seconds.shortForm.label', { - defaultMessage: 'sec', -}); - -export const MS_LABEL = i18n.translate('xpack.uptime.millisecond.abbreviation.label', { - defaultMessage: 'ms', -}); diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/browser/advanced_fields.tsx b/x-pack/plugins/synthetics/public/components/fleet_package/browser/advanced_fields.tsx deleted file mode 100644 index 5db5aabd791ee..0000000000000 --- a/x-pack/plugins/synthetics/public/components/fleet_package/browser/advanced_fields.tsx +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { memo, useCallback } from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { - EuiAccordion, - EuiSelect, - EuiFieldText, - EuiCheckbox, - EuiFormRow, - EuiSpacer, -} from '@elastic/eui'; -import { ComboBox } from '../combo_box'; -import { DescribedFormGroupWithWrap } from '../common/described_form_group_with_wrap'; - -import { useBrowserAdvancedFieldsContext, useBrowserSimpleFieldsContext } from '../contexts'; - -import { ConfigKey, Validation, ScreenshotOption } from '../types'; - -import { OptionalLabel } from '../optional_label'; -import { ThrottlingFields } from './throttling_fields'; - -interface Props { - validate: Validation; - children?: React.ReactNode; - minColumnWidth?: string; - onFieldBlur?: (field: ConfigKey) => void; -} - -export const BrowserAdvancedFields = memo( - ({ validate, children, minColumnWidth, onFieldBlur }) => { - const { fields, setFields } = useBrowserAdvancedFieldsContext(); - const { fields: simpleFields } = useBrowserSimpleFieldsContext(); - - const handleInputChange = useCallback( - ({ value, configKey }: { value: unknown; configKey: ConfigKey }) => { - setFields((prevFields) => ({ ...prevFields, [configKey]: value })); - }, - [setFields] - ); - - return ( - - - {simpleFields[ConfigKey.SOURCE_ZIP_URL] && ( - - - - } - description={ - - } - > - - - } - labelAppend={} - helpText={ - - } - > - - handleInputChange({ - value: event.target.value, - configKey: ConfigKey.JOURNEY_FILTERS_MATCH, - }) - } - onBlur={() => onFieldBlur?.(ConfigKey.JOURNEY_FILTERS_MATCH)} - data-test-subj="syntheticsBrowserJourneyFiltersMatch" - /> - - - } - labelAppend={} - helpText={ - - } - > - - handleInputChange({ value, configKey: ConfigKey.JOURNEY_FILTERS_TAGS }) - } - onBlur={() => onFieldBlur?.(ConfigKey.JOURNEY_FILTERS_TAGS)} - data-test-subj="syntheticsBrowserJourneyFiltersTags" - /> - - - )} - - - - } - description={ - - } - > - - - - - } - data-test-subj="syntheticsBrowserIgnoreHttpsErrors" - > - - } - onChange={(event) => - handleInputChange({ - value: event.target.checked, - configKey: ConfigKey.IGNORE_HTTPS_ERRORS, - }) - } - onBlur={() => onFieldBlur?.(ConfigKey.IGNORE_HTTPS_ERRORS)} - /> - - - - } - labelAppend={} - helpText={ - - } - > - - handleInputChange({ - value: event.target.value, - configKey: ConfigKey.SCREENSHOTS, - }) - } - onBlur={() => onFieldBlur?.(ConfigKey.SCREENSHOTS)} - data-test-subj="syntheticsBrowserScreenshots" - /> - - - } - labelAppend={} - helpText={ - - } - > - - handleInputChange({ value, configKey: ConfigKey.SYNTHETICS_ARGS }) - } - onBlur={() => onFieldBlur?.(ConfigKey.SYNTHETICS_ARGS)} - data-test-subj="syntheticsBrowserSyntheticsArgs" - /> - - - - - {children} - - ); - } -); - -const requestMethodOptions = Object.values(ScreenshotOption).map((option) => ({ - value: option, - text: option.replace(/-/g, ' '), -})); diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/browser/simple_fields.tsx b/x-pack/plugins/synthetics/public/components/fleet_package/browser/simple_fields.tsx deleted file mode 100644 index ddf8f5699b5f9..0000000000000 --- a/x-pack/plugins/synthetics/public/components/fleet_package/browser/simple_fields.tsx +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { memo, useMemo, useCallback } from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { EuiFormRow } from '@elastic/eui'; -import { Validation } from '../types'; -import { ConfigKey } from '../types'; -import { useBrowserSimpleFieldsContext } from '../contexts'; -import { ScheduleField } from '../schedule_field'; -import { SourceField } from './source_field'; -import { SimpleFieldsWrapper } from '../common/simple_fields_wrapper'; - -interface Props { - validate: Validation; - onFieldBlur: (field: ConfigKey) => void; // To propagate blurred state up to parents -} - -export const BrowserSimpleFields = memo(({ validate, onFieldBlur }) => { - const { fields, setFields, defaultValues } = useBrowserSimpleFieldsContext(); - const handleInputChange = useCallback( - ({ value, configKey }: { value: unknown; configKey: ConfigKey }) => { - setFields((prevFields) => ({ ...prevFields, [configKey]: value })); - }, - [setFields] - ); - const onChangeSourceField = useCallback( - ({ - zipUrl, - folder, - username, - password, - inlineScript, - params, - proxyUrl, - isGeneratedScript, - fileName, - }) => { - setFields((prevFields) => ({ - ...prevFields, - [ConfigKey.SOURCE_ZIP_URL]: zipUrl, - [ConfigKey.SOURCE_ZIP_PROXY_URL]: proxyUrl, - [ConfigKey.SOURCE_ZIP_FOLDER]: folder, - [ConfigKey.SOURCE_ZIP_USERNAME]: username, - [ConfigKey.SOURCE_ZIP_PASSWORD]: password, - [ConfigKey.SOURCE_INLINE]: inlineScript, - [ConfigKey.PARAMS]: params, - [ConfigKey.METADATA]: { - ...prevFields[ConfigKey.METADATA], - script_source: { - is_generated_script: isGeneratedScript, - file_name: fileName, - }, - }, - })); - }, - [setFields] - ); - - return ( - - - } - isInvalid={!!validate[ConfigKey.SCHEDULE]?.(fields)} - error={ - - } - > - - handleInputChange({ - value: schedule, - configKey: ConfigKey.SCHEDULE, - }) - } - onBlur={() => onFieldBlur(ConfigKey.SCHEDULE)} - number={fields[ConfigKey.SCHEDULE].number} - unit={fields[ConfigKey.SCHEDULE].unit} - /> - - - } - > - ({ - zipUrl: defaultValues[ConfigKey.SOURCE_ZIP_URL], - proxyUrl: defaultValues[ConfigKey.SOURCE_ZIP_PROXY_URL], - folder: defaultValues[ConfigKey.SOURCE_ZIP_FOLDER], - username: defaultValues[ConfigKey.SOURCE_ZIP_USERNAME], - password: defaultValues[ConfigKey.SOURCE_ZIP_PASSWORD], - inlineScript: defaultValues[ConfigKey.SOURCE_INLINE], - params: defaultValues[ConfigKey.PARAMS], - isGeneratedScript: - defaultValues[ConfigKey.METADATA].script_source?.is_generated_script, - fileName: defaultValues[ConfigKey.METADATA].script_source?.file_name, - }), - [defaultValues] - )} - /> - - - ); -}); diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/common/default_values.ts b/x-pack/plugins/synthetics/public/components/fleet_package/common/default_values.ts deleted file mode 100644 index 54c6969833cf1..0000000000000 --- a/x-pack/plugins/synthetics/public/components/fleet_package/common/default_values.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { DEFAULT_NAMESPACE_STRING } from '../../../../common/constants'; -import { CommonFields, ConfigKey, ScheduleUnit, DataStream } from '../types'; - -export const defaultValues: CommonFields = { - [ConfigKey.MONITOR_TYPE]: DataStream.HTTP, - [ConfigKey.LOCATIONS]: [], - [ConfigKey.ENABLED]: true, - [ConfigKey.SCHEDULE]: { - number: '3', - unit: ScheduleUnit.MINUTES, - }, - [ConfigKey.APM_SERVICE_NAME]: '', - [ConfigKey.TAGS]: [], - [ConfigKey.TIMEOUT]: '16', - [ConfigKey.NAME]: '', - [ConfigKey.LOCATIONS]: [], - [ConfigKey.NAMESPACE]: DEFAULT_NAMESPACE_STRING, -}; diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/browser_context.tsx b/x-pack/plugins/synthetics/public/components/fleet_package/contexts/browser_context.tsx deleted file mode 100644 index f7b67488e4bcc..0000000000000 --- a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/browser_context.tsx +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { createContext, useContext, useMemo, useState } from 'react'; -import { BrowserSimpleFields, ConfigKey, DataStream, ScheduleUnit } from '../types'; -import { defaultValues as commonDefaultValues } from '../common/default_values'; - -interface BrowserSimpleFieldsContext { - setFields: React.Dispatch>; - fields: BrowserSimpleFields; - defaultValues: BrowserSimpleFields; -} - -interface BrowserSimpleFieldsContextProvider { - children: React.ReactNode; - defaultValues?: BrowserSimpleFields; -} - -export const initialValues: BrowserSimpleFields = { - ...commonDefaultValues, - [ConfigKey.SCHEDULE]: { - unit: ScheduleUnit.MINUTES, - number: '10', - }, - [ConfigKey.METADATA]: { - script_source: { - is_generated_script: false, - file_name: '', - }, - is_zip_url_tls_enabled: false, - }, - [ConfigKey.MONITOR_TYPE]: DataStream.BROWSER, - [ConfigKey.SOURCE_ZIP_URL]: '', - [ConfigKey.SOURCE_ZIP_USERNAME]: '', - [ConfigKey.SOURCE_ZIP_PASSWORD]: '', - [ConfigKey.SOURCE_ZIP_FOLDER]: '', - [ConfigKey.SOURCE_ZIP_PROXY_URL]: '', - [ConfigKey.SOURCE_INLINE]: '', - [ConfigKey.PARAMS]: '', - [ConfigKey.ZIP_URL_TLS_CERTIFICATE_AUTHORITIES]: undefined, - [ConfigKey.ZIP_URL_TLS_CERTIFICATE]: undefined, - [ConfigKey.ZIP_URL_TLS_KEY]: undefined, - [ConfigKey.ZIP_URL_TLS_KEY_PASSPHRASE]: undefined, - [ConfigKey.ZIP_URL_TLS_VERIFICATION_MODE]: undefined, - [ConfigKey.ZIP_URL_TLS_VERSION]: undefined, - [ConfigKey.URLS]: undefined, - [ConfigKey.PORT]: undefined, -}; - -const defaultContext: BrowserSimpleFieldsContext = { - setFields: (_fields: React.SetStateAction) => { - throw new Error( - 'setFields was not initialized for Browser Simple Fields, set it when you invoke the context' - ); - }, - fields: initialValues, // mutable - defaultValues: initialValues, // immutable -}; - -export const BrowserSimpleFieldsContext = createContext(defaultContext); - -export const BrowserSimpleFieldsContextProvider = ({ - children, - defaultValues = initialValues, -}: BrowserSimpleFieldsContextProvider) => { - const [fields, setFields] = useState(defaultValues); - - const value = useMemo(() => { - return { fields, setFields, defaultValues }; - }, [fields, defaultValues]); - - return ; -}; - -export const useBrowserSimpleFieldsContext = () => useContext(BrowserSimpleFieldsContext); diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/http_context_advanced.tsx b/x-pack/plugins/synthetics/public/components/fleet_package/contexts/http_context_advanced.tsx deleted file mode 100644 index 4d64bd3cf1ad4..0000000000000 --- a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/http_context_advanced.tsx +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { createContext, useContext, useMemo, useState } from 'react'; -import { HTTPAdvancedFields, ConfigKey, Mode, ResponseBodyIndexPolicy, HTTPMethod } from '../types'; - -interface HTTPAdvancedFieldsContext { - setFields: React.Dispatch>; - fields: HTTPAdvancedFields; - defaultValues: HTTPAdvancedFields; -} - -interface HTTPAdvancedFieldsContextProvider { - children: React.ReactNode; - defaultValues?: HTTPAdvancedFields; -} - -export const initialValues: HTTPAdvancedFields = { - [ConfigKey.PASSWORD]: '', - [ConfigKey.PROXY_URL]: '', - [ConfigKey.RESPONSE_BODY_CHECK_NEGATIVE]: [], - [ConfigKey.RESPONSE_BODY_CHECK_POSITIVE]: [], - [ConfigKey.RESPONSE_BODY_INDEX]: ResponseBodyIndexPolicy.ON_ERROR, - [ConfigKey.RESPONSE_HEADERS_CHECK]: {}, - [ConfigKey.RESPONSE_HEADERS_INDEX]: true, - [ConfigKey.RESPONSE_STATUS_CHECK]: [], - [ConfigKey.REQUEST_BODY_CHECK]: { - value: '', - type: Mode.PLAINTEXT, - }, - [ConfigKey.REQUEST_HEADERS_CHECK]: {}, - [ConfigKey.REQUEST_METHOD_CHECK]: HTTPMethod.GET, - [ConfigKey.USERNAME]: '', -}; - -export const defaultContext: HTTPAdvancedFieldsContext = { - setFields: (_fields: React.SetStateAction) => { - throw new Error('setFields was not initialized, set it when you invoke the context'); - }, - fields: initialValues, - defaultValues: initialValues, -}; - -export const HTTPAdvancedFieldsContext = createContext(defaultContext); - -export const HTTPAdvancedFieldsContextProvider = ({ - children, - defaultValues = initialValues, -}: HTTPAdvancedFieldsContextProvider) => { - const [fields, setFields] = useState(defaultValues); - - const value = useMemo(() => { - return { fields, setFields, defaultValues }; - }, [fields, defaultValues]); - - return ; -}; - -export const useHTTPAdvancedFieldsContext = () => useContext(HTTPAdvancedFieldsContext); diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/index.ts b/x-pack/plugins/synthetics/public/components/fleet_package/contexts/index.ts deleted file mode 100644 index 3f392c42983b6..0000000000000 --- a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/index.ts +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { DataStream, PolicyConfig } from '../types'; -import { initialValues as defaultHTTPSimpleFields } from './http_context'; -import { initialValues as defaultHTTPAdvancedFields } from './http_context_advanced'; -import { initialValues as defaultTCPSimpleFields } from './tcp_context'; -import { initialValues as defaultICMPSimpleFields } from './icmp_context'; -import { initialValues as defaultTCPAdvancedFields } from './tcp_context_advanced'; -import { initialValues as defaultBrowserSimpleFields } from './browser_context'; -import { initialValues as defaultBrowserAdvancedFields } from './browser_context_advanced'; -import { initialValues as defaultTLSFields } from './tls_fields_context'; - -export type { IPolicyConfigContextProvider } from './policy_config_context'; -export { - PolicyConfigContext, - PolicyConfigContextProvider, - initialValue as defaultPolicyConfig, - defaultContext as defaultPolicyConfigValues, - usePolicyConfigContext, -} from './policy_config_context'; -export { - HTTPSimpleFieldsContext, - HTTPSimpleFieldsContextProvider, - initialValues as defaultHTTPSimpleFields, - useHTTPSimpleFieldsContext, -} from './http_context'; -export { - HTTPAdvancedFieldsContext, - HTTPAdvancedFieldsContextProvider, - initialValues as defaultHTTPAdvancedFields, - useHTTPAdvancedFieldsContext, -} from './http_context_advanced'; -export { - TCPSimpleFieldsContext, - TCPSimpleFieldsContextProvider, - initialValues as defaultTCPSimpleFields, - useTCPSimpleFieldsContext, -} from './tcp_context'; -export { - ICMPSimpleFieldsContext, - ICMPSimpleFieldsContextProvider, - initialValues as defaultICMPSimpleFields, - useICMPSimpleFieldsContext, -} from './icmp_context'; -export { - TCPAdvancedFieldsContext, - TCPAdvancedFieldsContextProvider, - initialValues as defaultTCPAdvancedFields, - useTCPAdvancedFieldsContext, -} from './tcp_context_advanced'; -export { - BrowserSimpleFieldsContext, - BrowserSimpleFieldsContextProvider, - initialValues as defaultBrowserSimpleFields, - useBrowserSimpleFieldsContext, -} from './browser_context'; -export { - BrowserAdvancedFieldsContext, - BrowserAdvancedFieldsContextProvider, - initialValues as defaultBrowserAdvancedFields, - useBrowserAdvancedFieldsContext, -} from './browser_context_advanced'; -export { - TLSFieldsContext, - TLSFieldsContextProvider, - initialValues as defaultTLSFields, - useTLSFieldsContext, -} from './tls_fields_context'; -export { HTTPContextProvider } from './http_provider'; -export { TCPContextProvider } from './tcp_provider'; -export { BrowserContextProvider } from './browser_provider'; -export { SyntheticsProviders } from './synthetics_context_providers'; - -export const defaultConfig: PolicyConfig = { - [DataStream.HTTP]: { - ...defaultHTTPSimpleFields, - ...defaultHTTPAdvancedFields, - ...defaultTLSFields, - }, - [DataStream.TCP]: { - ...defaultTCPSimpleFields, - ...defaultTCPAdvancedFields, - ...defaultTLSFields, - }, - [DataStream.ICMP]: defaultICMPSimpleFields, - [DataStream.BROWSER]: { - ...defaultBrowserSimpleFields, - ...defaultBrowserAdvancedFields, - ...defaultTLSFields, - }, -}; diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/http/advanced_fields.tsx b/x-pack/plugins/synthetics/public/components/fleet_package/http/advanced_fields.tsx deleted file mode 100644 index c9396ac69fbac..0000000000000 --- a/x-pack/plugins/synthetics/public/components/fleet_package/http/advanced_fields.tsx +++ /dev/null @@ -1,492 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useCallback, memo } from 'react'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { - EuiAccordion, - EuiCode, - EuiFieldText, - EuiFormRow, - EuiSelect, - EuiCheckbox, - EuiSpacer, - EuiFieldPassword, -} from '@elastic/eui'; -import { DescribedFormGroupWithWrap } from '../common/described_form_group_with_wrap'; - -import { useHTTPAdvancedFieldsContext } from '../contexts'; - -import { ConfigKey, HTTPMethod, Validation } from '../types'; - -import { OptionalLabel } from '../optional_label'; -import { HeaderField } from '../header_field'; -import { RequestBodyField } from '../request_body_field'; -import { ResponseBodyIndexField } from '../index_response_body_field'; -import { ComboBox } from '../combo_box'; - -interface Props { - validate: Validation; - children?: React.ReactNode; - minColumnWidth?: string; - onFieldBlur?: (field: ConfigKey) => void; -} - -export const HTTPAdvancedFields = memo( - ({ validate, children, minColumnWidth, onFieldBlur }) => { - const { fields, setFields } = useHTTPAdvancedFieldsContext(); - const handleInputChange = useCallback( - ({ value, configKey }: { value: unknown; configKey: ConfigKey }) => { - setFields((prevFields) => ({ ...prevFields, [configKey]: value })); - }, - [setFields] - ); - - return ( - - } - data-test-subj="syntheticsHTTPAdvancedFieldsAccordion" - > - - - - - } - description={ - - } - data-test-subj="httpAdvancedFieldsSection" - > - - - } - labelAppend={} - helpText={ - - } - > - - handleInputChange({ - value: event.target.value, - configKey: ConfigKey.USERNAME, - }) - } - onBlur={() => onFieldBlur?.(ConfigKey.USERNAME)} - data-test-subj="syntheticsUsername" - /> - - - } - labelAppend={} - helpText={ - - } - > - - handleInputChange({ - value: event.target.value, - configKey: ConfigKey.PASSWORD, - }) - } - onBlur={() => onFieldBlur?.(ConfigKey.PASSWORD)} - data-test-subj="syntheticsPassword" - /> - - - } - labelAppend={} - helpText={ - - } - > - - handleInputChange({ - value: event.target.value, - configKey: ConfigKey.PROXY_URL, - }) - } - onBlur={() => onFieldBlur?.(ConfigKey.PROXY_URL)} - data-test-subj="syntheticsProxyUrl" - /> - - - } - helpText={ - - } - > - - handleInputChange({ - value: event.target.value, - configKey: ConfigKey.REQUEST_METHOD_CHECK, - }) - } - onBlur={() => onFieldBlur?.(ConfigKey.REQUEST_METHOD_CHECK)} - data-test-subj="syntheticsRequestMethod" - /> - - - } - labelAppend={} - isInvalid={!!validate[ConfigKey.REQUEST_HEADERS_CHECK]?.(fields)} - error={ - - } - helpText={ - - } - > - - handleInputChange({ - value, - configKey: ConfigKey.REQUEST_HEADERS_CHECK, - }), - [handleInputChange] - )} - onBlur={() => onFieldBlur?.(ConfigKey.REQUEST_HEADERS_CHECK)} - data-test-subj="syntheticsRequestHeaders" - /> - - - } - labelAppend={} - helpText={ - - } - fullWidth - > - - handleInputChange({ - value, - configKey: ConfigKey.REQUEST_BODY_CHECK, - }), - [handleInputChange] - )} - onBlur={() => onFieldBlur?.(ConfigKey.REQUEST_BODY_CHECK)} - /> - - - - - - - } - description={ - - } - > - - - - http.response.body.headers - - } - data-test-subj="syntheticsIndexResponseHeaders" - > - - } - onChange={(event) => - handleInputChange({ - value: event.target.checked, - configKey: ConfigKey.RESPONSE_HEADERS_INDEX, - }) - } - onBlur={() => onFieldBlur?.(ConfigKey.RESPONSE_HEADERS_INDEX)} - /> - - - - http.response.body.contents - - } - > - - handleInputChange({ value: policy, configKey: ConfigKey.RESPONSE_BODY_INDEX }), - [handleInputChange] - )} - onBlur={() => onFieldBlur?.(ConfigKey.RESPONSE_BODY_INDEX)} - /> - - - - - - } - description={ - - } - > - - } - labelAppend={} - isInvalid={!!validate[ConfigKey.RESPONSE_STATUS_CHECK]?.(fields)} - error={ - - } - helpText={i18n.translate( - 'xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.responseStatusCheck.helpText', - { - defaultMessage: - 'A list of expected status codes. Press enter to add a new code. 4xx and 5xx codes are considered down by default. Other codes are considered up.', - } - )} - > - - handleInputChange({ - value, - configKey: ConfigKey.RESPONSE_STATUS_CHECK, - }) - } - onBlur={() => onFieldBlur?.(ConfigKey.RESPONSE_STATUS_CHECK)} - data-test-subj="syntheticsResponseStatusCheck" - /> - - - } - labelAppend={} - isInvalid={!!validate[ConfigKey.RESPONSE_HEADERS_CHECK]?.(fields)} - error={[ - , - ]} - helpText={ - - } - > - - handleInputChange({ - value, - configKey: ConfigKey.RESPONSE_HEADERS_CHECK, - }), - [handleInputChange] - )} - onBlur={() => onFieldBlur?.(ConfigKey.RESPONSE_HEADERS_CHECK)} - data-test-subj="syntheticsResponseHeaders" - /> - - - } - labelAppend={} - helpText={i18n.translate( - 'xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseBodyCheckPositive.helpText', - { - defaultMessage: - 'A list of regular expressions to match the body output. Press enter to add a new expression. Only a single expression needs to match.', - } - )} - > - - handleInputChange({ - value, - configKey: ConfigKey.RESPONSE_BODY_CHECK_POSITIVE, - }), - [handleInputChange] - )} - onBlur={() => onFieldBlur?.(ConfigKey.RESPONSE_BODY_CHECK_POSITIVE)} - data-test-subj="syntheticsResponseBodyCheckPositive" - /> - - - } - labelAppend={} - helpText={i18n.translate( - 'xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseBodyCheckNegative.helpText', - { - defaultMessage: - 'A list of regular expressions to match the the body output negatively. Press enter to add a new expression. Return match failed if single expression matches.', - } - )} - > - - handleInputChange({ - value, - configKey: ConfigKey.RESPONSE_BODY_CHECK_NEGATIVE, - }), - [handleInputChange] - )} - onBlur={() => onFieldBlur?.(ConfigKey.RESPONSE_BODY_CHECK_NEGATIVE)} - data-test-subj="syntheticsResponseBodyCheckNegative" - /> - - - {children} - - ); - } -); - -const requestMethodOptions = Object.values(HTTPMethod).map((method) => ({ - value: method, - text: method, -})); diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/http/simple_fields.tsx b/x-pack/plugins/synthetics/public/components/fleet_package/http/simple_fields.tsx deleted file mode 100644 index 56245856f5aed..0000000000000 --- a/x-pack/plugins/synthetics/public/components/fleet_package/http/simple_fields.tsx +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiFieldNumber, EuiFieldText, EuiFormRow } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n-react'; -import React, { memo, useCallback } from 'react'; -import { SimpleFieldsWrapper } from '../common/simple_fields_wrapper'; -import { useHTTPSimpleFieldsContext } from '../contexts'; -import { OptionalLabel } from '../optional_label'; -import { ScheduleField } from '../schedule_field'; -import { ConfigKey, Validation } from '../types'; - -interface Props { - validate: Validation; - onFieldBlur: (field: ConfigKey) => void; // To propagate blurred state up to parents -} - -export const HTTPSimpleFields = memo(({ validate, onFieldBlur }) => { - const { fields, setFields } = useHTTPSimpleFieldsContext(); - const handleInputChange = useCallback( - ({ value, configKey }: { value: unknown; configKey: ConfigKey }) => { - setFields((prevFields) => ({ ...prevFields, [configKey]: value })); - }, - [setFields] - ); - - return ( - - - } - isInvalid={!!validate[ConfigKey.URLS]?.(fields)} - error={ - - } - > - - handleInputChange({ value: event.target.value, configKey: ConfigKey.URLS }) - } - onBlur={() => onFieldBlur(ConfigKey.URLS)} - data-test-subj="syntheticsUrlField" - /> - - - } - isInvalid={!!validate[ConfigKey.SCHEDULE]?.(fields)} - error={ - - } - > - - handleInputChange({ - value: schedule, - configKey: ConfigKey.SCHEDULE, - }) - } - onBlur={() => onFieldBlur(ConfigKey.SCHEDULE)} - number={fields[ConfigKey.SCHEDULE].number} - unit={fields[ConfigKey.SCHEDULE].unit} - /> - - - } - isInvalid={!!validate[ConfigKey.MAX_REDIRECTS]?.(fields)} - error={ - - } - labelAppend={} - helpText={ - - } - > - - handleInputChange({ - value: event.target.value, - configKey: ConfigKey.MAX_REDIRECTS, - }) - } - onBlur={() => onFieldBlur(ConfigKey.MAX_REDIRECTS)} - /> - - - ); -}); diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/icmp/advanced_fields.tsx b/x-pack/plugins/synthetics/public/components/fleet_package/icmp/advanced_fields.tsx deleted file mode 100644 index ed08443b2a9fc..0000000000000 --- a/x-pack/plugins/synthetics/public/components/fleet_package/icmp/advanced_fields.tsx +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiAccordion, EuiSpacer } from '@elastic/eui'; -import React from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; - -export const ICMPAdvancedFields = ({ children }: { children?: React.ReactNode }) => { - if (!!children) { - return ( - - } - data-test-subj="syntheticsICMPAdvancedFieldsAccordion" - > - - {children} - - ); - } - - return <>; -}; diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/icmp/simple_fields.tsx b/x-pack/plugins/synthetics/public/components/fleet_package/icmp/simple_fields.tsx deleted file mode 100644 index 76058d5cc3248..0000000000000 --- a/x-pack/plugins/synthetics/public/components/fleet_package/icmp/simple_fields.tsx +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { memo, useCallback } from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { EuiFormRow, EuiFieldText, EuiFieldNumber } from '@elastic/eui'; -import { ConfigKey, Validation } from '../types'; -import { useICMPSimpleFieldsContext } from '../contexts'; -import { OptionalLabel } from '../optional_label'; -import { ScheduleField } from '../schedule_field'; -import { SimpleFieldsWrapper } from '../common/simple_fields_wrapper'; - -interface Props { - validate: Validation; - onFieldBlur: (field: ConfigKey) => void; // To propagate blurred state up to parents -} - -export const ICMPSimpleFields = memo(({ validate, onFieldBlur }) => { - const { fields, setFields } = useICMPSimpleFieldsContext(); - const handleInputChange = useCallback( - ({ value, configKey }: { value: unknown; configKey: ConfigKey }) => { - setFields((prevFields) => ({ ...prevFields, [configKey]: value })); - }, - [setFields] - ); - - return ( - - - } - isInvalid={!!validate[ConfigKey.HOSTS]?.(fields)} - error={ - - } - > - - handleInputChange({ - value: event.target.value, - configKey: ConfigKey.HOSTS, - }) - } - onBlur={() => onFieldBlur(ConfigKey.HOSTS)} - data-test-subj="syntheticsICMPHostField" - /> - - - } - isInvalid={!!validate[ConfigKey.SCHEDULE]?.(fields)} - error={ - - } - > - - handleInputChange({ - value: schedule, - configKey: ConfigKey.SCHEDULE, - }) - } - onBlur={() => onFieldBlur(ConfigKey.SCHEDULE)} - number={fields[ConfigKey.SCHEDULE].number} - unit={fields[ConfigKey.SCHEDULE].unit} - /> - - - } - isInvalid={!!validate[ConfigKey.WAIT]?.(fields)} - error={ - - } - labelAppend={} - helpText={ - - } - > - - handleInputChange({ - value: event.target.value, - configKey: ConfigKey.WAIT, - }) - } - onBlur={() => onFieldBlur(ConfigKey.WAIT)} - step={'any'} - /> - - - ); -}); diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/tcp/advanced_fields.tsx b/x-pack/plugins/synthetics/public/components/fleet_package/tcp/advanced_fields.tsx deleted file mode 100644 index 7598f1ec0734c..0000000000000 --- a/x-pack/plugins/synthetics/public/components/fleet_package/tcp/advanced_fields.tsx +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { memo, useCallback } from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { EuiAccordion, EuiCheckbox, EuiFormRow, EuiFieldText, EuiSpacer } from '@elastic/eui'; -import { DescribedFormGroupWithWrap } from '../common/described_form_group_with_wrap'; - -import { useTCPAdvancedFieldsContext } from '../contexts'; - -import { ConfigKey } from '../types'; - -import { OptionalLabel } from '../optional_label'; - -interface Props { - children?: React.ReactNode; - minColumnWidth?: string; - onFieldBlur?: (field: ConfigKey) => void; -} - -export const TCPAdvancedFields = memo(({ children, minColumnWidth, onFieldBlur }) => { - const { fields, setFields } = useTCPAdvancedFieldsContext(); - - const handleInputChange = useCallback( - ({ value, configKey }: { value: unknown; configKey: ConfigKey }) => { - setFields((prevFields) => ({ ...prevFields, [configKey]: value })); - }, - [setFields] - ); - - return ( - - - - - - } - description={ - - } - > - - - } - labelAppend={} - helpText={ - - } - > - - handleInputChange({ - value: event.target.value, - configKey: ConfigKey.PROXY_URL, - }) - } - onBlur={() => onFieldBlur?.(ConfigKey.PROXY_URL)} - data-test-subj="syntheticsProxyUrl" - /> - - {!!fields[ConfigKey.PROXY_URL] && ( - - - } - onChange={(event) => - handleInputChange({ - value: event.target.checked, - configKey: ConfigKey.PROXY_USE_LOCAL_RESOLVER, - }) - } - /> - - )} - - } - labelAppend={} - helpText={ - - } - > - - handleInputChange({ - value: event.target.value, - configKey: ConfigKey.REQUEST_SEND_CHECK, - }), - [handleInputChange] - )} - onBlur={() => onFieldBlur?.(ConfigKey.REQUEST_SEND_CHECK)} - data-test-subj="syntheticsTCPRequestSendCheck" - /> - - - - - - } - description={ - - } - > - - } - labelAppend={} - helpText={ - - } - > - - handleInputChange({ - value: event.target.value, - configKey: ConfigKey.RESPONSE_RECEIVE_CHECK, - }), - [handleInputChange] - )} - onBlur={() => onFieldBlur?.(ConfigKey.RESPONSE_RECEIVE_CHECK)} - data-test-subj="syntheticsTCPResponseReceiveCheck" - /> - - - {children} - - ); -}); diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/tcp/simple_fields.tsx b/x-pack/plugins/synthetics/public/components/fleet_package/tcp/simple_fields.tsx deleted file mode 100644 index 4eb4ed05e073b..0000000000000 --- a/x-pack/plugins/synthetics/public/components/fleet_package/tcp/simple_fields.tsx +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { memo, useCallback } from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { EuiFormRow, EuiFieldText } from '@elastic/eui'; -import { ConfigKey, Validation } from '../types'; -import { useTCPSimpleFieldsContext } from '../contexts'; -import { ScheduleField } from '../schedule_field'; -import { SimpleFieldsWrapper } from '../common/simple_fields_wrapper'; - -interface Props { - validate: Validation; - onFieldBlur: (field: ConfigKey) => void; // To propagate blurred state up to parents -} - -export const TCPSimpleFields = memo(({ validate, onFieldBlur }) => { - const { fields, setFields } = useTCPSimpleFieldsContext(); - const handleInputChange = useCallback( - ({ value, configKey }: { value: unknown; configKey: ConfigKey }) => { - setFields((prevFields) => ({ ...prevFields, [configKey]: value })); - }, - [setFields] - ); - - return ( - - - } - isInvalid={!!validate[ConfigKey.HOSTS]?.(fields)} - error={ - - } - > - - handleInputChange({ - value: event.target.value, - configKey: ConfigKey.HOSTS, - }) - } - onBlur={() => onFieldBlur(ConfigKey.HOSTS)} - data-test-subj="syntheticsTCPHostField" - /> - - - - } - isInvalid={!!validate[ConfigKey.SCHEDULE]?.(fields)} - error={ - - } - > - - handleInputChange({ - value: schedule, - configKey: ConfigKey.SCHEDULE, - }) - } - onBlur={() => onFieldBlur(ConfigKey.SCHEDULE)} - number={fields[ConfigKey.SCHEDULE].number} - unit={fields[ConfigKey.SCHEDULE].unit} - /> - - - ); -}); diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/tls/default_values.ts b/x-pack/plugins/synthetics/public/components/fleet_package/tls/default_values.ts deleted file mode 100644 index 18f291ce20f35..0000000000000 --- a/x-pack/plugins/synthetics/public/components/fleet_package/tls/default_values.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { TLSFields, ConfigKey, VerificationMode, TLSVersion } from '../types'; - -export const defaultValues: TLSFields = { - [ConfigKey.TLS_CERTIFICATE_AUTHORITIES]: '', - [ConfigKey.TLS_CERTIFICATE]: '', - [ConfigKey.TLS_KEY]: '', - [ConfigKey.TLS_KEY_PASSPHRASE]: '', - [ConfigKey.TLS_VERIFICATION_MODE]: VerificationMode.FULL, - [ConfigKey.TLS_VERSION]: [TLSVersion.ONE_ONE, TLSVersion.ONE_TWO, TLSVersion.ONE_THREE], -}; diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/types.tsx b/x-pack/plugins/synthetics/public/components/fleet_package/types.tsx deleted file mode 100644 index d3df3a1926887..0000000000000 --- a/x-pack/plugins/synthetics/public/components/fleet_package/types.tsx +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { - HTTPFields, - TCPFields, - ICMPFields, - BrowserFields, - ConfigKey, - ContentType, - DataStream, - Mode, - ThrottlingConfigKey, - ThrottlingSuffix, - ThrottlingSuffixType, -} from '../../../common/runtime_types'; -export * from '../../../common/runtime_types/monitor_management'; -export * from '../../../common/types/monitor_validation'; - -export interface PolicyConfig { - [DataStream.HTTP]: HTTPFields; - [DataStream.TCP]: TCPFields; - [DataStream.ICMP]: ICMPFields; - [DataStream.BROWSER]: BrowserFields; -} - -export const contentTypesToMode = { - [ContentType.FORM]: Mode.FORM, - [ContentType.JSON]: Mode.JSON, - [ContentType.TEXT]: Mode.PLAINTEXT, - [ContentType.XML]: Mode.XML, -}; - -export const configKeyToThrottlingSuffix: Record = { - [ConfigKey.DOWNLOAD_SPEED]: ThrottlingSuffix.DOWNLOAD, - [ConfigKey.UPLOAD_SPEED]: ThrottlingSuffix.UPLOAD, - [ConfigKey.LATENCY]: ThrottlingSuffix.LATENCY, -}; diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/validation.test.ts b/x-pack/plugins/synthetics/public/components/fleet_package/validation.test.ts deleted file mode 100644 index 3495b163b9845..0000000000000 --- a/x-pack/plugins/synthetics/public/components/fleet_package/validation.test.ts +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - ConfigKey, - DataStream, - HTTPFields, - BrowserFields, - MonitorFields, - ScheduleUnit, -} from '../../../common/runtime_types'; -import { validate } from './validation'; - -describe('[Monitor Management] validation', () => { - const commonPropsValid: Partial = { - [ConfigKey.SCHEDULE]: { number: '5', unit: ScheduleUnit.MINUTES }, - [ConfigKey.TIMEOUT]: '3m', - }; - - describe('HTTP', () => { - const httpPropsValid: Partial = { - ...commonPropsValid, - [ConfigKey.RESPONSE_STATUS_CHECK]: ['200', '204'], - [ConfigKey.RESPONSE_HEADERS_CHECK]: { 'Content-Type': 'application/json' }, - [ConfigKey.REQUEST_HEADERS_CHECK]: { 'Accept-Language': 'en-GB,en-US;q=0.9,en;q=0.8' }, - [ConfigKey.MAX_REDIRECTS]: '3', - [ConfigKey.URLS]: 'https:// example-url.com', - }; - - it('should return false for all valid props', () => { - const validators = validate[DataStream.HTTP]; - const keysToValidate = [ - ConfigKey.SCHEDULE, - ConfigKey.TIMEOUT, - ConfigKey.RESPONSE_STATUS_CHECK, - ConfigKey.RESPONSE_HEADERS_CHECK, - ConfigKey.REQUEST_HEADERS_CHECK, - ConfigKey.MAX_REDIRECTS, - ConfigKey.URLS, - ]; - const validatorFns = keysToValidate.map((key) => validators[key]); - const result = validatorFns.map((fn) => fn?.(httpPropsValid) ?? true); - - expect(result).not.toEqual(expect.arrayContaining([true])); - }); - }); - - describe.each([ - [ConfigKey.SOURCE_INLINE, 'step(() => {});'], - [ConfigKey.SOURCE_ZIP_URL, 'https://test.zip'], - ])('Browser', (configKey, value) => { - const browserProps: Partial = { - ...commonPropsValid, - [ConfigKey.MONITOR_TYPE]: DataStream.BROWSER, - [ConfigKey.TIMEOUT]: null, - [configKey]: value, - }; - - it('should return false for all valid props', () => { - const validators = validate[DataStream.BROWSER]; - const keysToValidate = [ConfigKey.SCHEDULE, ConfigKey.TIMEOUT, configKey]; - const validatorFns = keysToValidate.map((key) => validators[key]); - const result = validatorFns.map((fn) => fn?.(browserProps) ?? true); - - expect(result).not.toEqual(expect.arrayContaining([true])); - }); - }); - - // TODO: Add test for other monitor types if needed -}); diff --git a/x-pack/plugins/synthetics/public/components/monitor/ml/translations.tsx b/x-pack/plugins/synthetics/public/components/monitor/ml/translations.tsx deleted file mode 100644 index 6816dea66c180..0000000000000 --- a/x-pack/plugins/synthetics/public/components/monitor/ml/translations.tsx +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const JOB_CREATED_SUCCESS_TITLE = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreatedNotificationTitle', - { - defaultMessage: 'Job successfully created', - } -); - -export const JOB_CREATED_SUCCESS_MESSAGE = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreatedNotificationText', - { - defaultMessage: - 'The analysis is now running for response duration chart. It might take a while before results are added to the response times graph.', - } -); - -export const JOB_CREATED_LAZY_SUCCESS_MESSAGE = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreatedLazyNotificationText', - { - defaultMessage: - 'The analysis is waiting for an ML node to become available. It might take a while before results are added to the response times graph.', - } -); - -export const JOB_CREATION_FAILED = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreationFailedNotificationTitle', - { - defaultMessage: 'Job creation failed', - } -); - -export const JOB_CREATION_FAILED_MESSAGE = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreationFailedNotificationText', - { - defaultMessage: - 'Your current license may not allow for creating machine learning jobs, or this job may already exist.', - } -); - -export const JOB_DELETION = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.jobDeletionNotificationTitle', - { - defaultMessage: 'Job deleted', - } -); - -export const JOB_DELETION_SUCCESS = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.jobDeletionSuccessNotificationText', - { - defaultMessage: 'Job is successfully deleted', - } -); - -export const JOB_DELETION_CONFIRMATION = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.jobDeletionConfirmLabel', - { - defaultMessage: 'Delete anomaly detection job?', - } -); - -export const VIEW_JOB = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreatedNotificationText.viewJobLinkText', - { - defaultMessage: 'View job', - } -); - -export const EXPLORE_IN_ML_APP = i18n.translate('xpack.uptime.ml.durationChart.exploreInMlApp', { - defaultMessage: 'Explore in ML App', -}); - -export const ENABLE_ANOMALY_DETECTION = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.enableAnomalyDetectionTitle', - { - defaultMessage: 'Enable anomaly detection', - } -); - -export const ANOMALY_DETECTION = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.anomalyDetectionTitle', - { - defaultMessage: 'Anomaly detection', - } -); - -export const DISABLE_ANOMALY_DETECTION = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.disableAnomalyDetectionTitle', - { - defaultMessage: 'Disable anomaly detection', - } -); - -export const ENABLE_ANOMALY_ALERT = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.enableAnomalyAlert', - { - defaultMessage: 'Enable anomaly alert', - } -); - -export const ENABLE_ANOMALY_NO_PERMISSIONS_TOOLTIP = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.noPermissionsTooltip', - { - defaultMessage: 'You need read-write access to Uptime to create anomaly alerts.', - } -); - -export const DISABLE_ANOMALY_ALERT = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.disableAnomalyAlert', - { - defaultMessage: 'Disable anomaly alert', - } -); - -export const MANAGE_ANOMALY_DETECTION = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.manageAnomalyDetectionTitle', - { - defaultMessage: 'Manage anomaly detection', - } -); - -export const ML_MANAGEMENT_PAGE = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.manageMLJobDescription.mlJobsPageLinkText', - { - defaultMessage: 'Machine Learning jobs management page', - } -); - -export const TAKE_SOME_TIME_TEXT = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.manageMLJobDescription.noteText', - { - defaultMessage: 'Note: It might take a few minutes for the job to begin calculating results.', - } -); - -export const CREATE_NEW_JOB = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.createNewJobButtonLabel', - { - defaultMessage: 'Create new job', - } -); - -export const CANCEL_LABEL = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.cancelLabel', - { - defaultMessage: 'Cancel', - } -); - -export const CREAT_ML_JOB_DESC = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.createMLJobDescription', - { - defaultMessage: `Here you can create a machine learning job to calculate anomaly scores on - response durations for Uptime Monitor. Once enabled, the monitor duration chart on the details page - will show the expected bounds and annotate the graph with anomalies. You can also potentially - identify periods of increased latency across geographical regions.`, - } -); - -export const START_TRAIL = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.startTrial', - { - defaultMessage: 'Start free 14-day trial', - } -); - -export const START_TRAIL_DESC = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.startTrialDesc', - { - defaultMessage: - 'In order to access duration anomaly detection, you have to be subscribed to an Elastic Platinum license.', - } -); - -export const ENABLE_MANAGE_JOB = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.enable_or_manage_job', - { - defaultMessage: - 'You can enable anomaly detection job or if job is already there you can manage the job or alert.', - } -); - -export const ADD_JOB_PERMISSIONS_NEEDED = i18n.translate( - 'xpack.uptime.ml.enableAnomalyDetectionPanel.add_job_permissions_needed', - { - defaultMessage: 'Permissions needed', - } -); diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/translations.ts b/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/translations.ts deleted file mode 100644 index f781610745ced..0000000000000 --- a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/translations.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const prevAriaLabel = i18n.translate('xpack.uptime.synthetics.prevStepButton.airaLabel', { - defaultMessage: 'Previous step', -}); - -export const nextAriaLabel = i18n.translate('xpack.uptime.synthetics.nextStepButton.ariaLabel', { - defaultMessage: 'Next step', -}); - -export const imageLoadingSpinnerAriaLabel = i18n.translate( - 'xpack.uptime.synthetics.imageLoadingSpinner.ariaLabel', - { - defaultMessage: 'An animated spinner indicating the image is loading', - } -); - -export const fullSizeImageAlt = i18n.translate('xpack.uptime.synthetics.thumbnail.fullSize.alt', { - defaultMessage: `A larger version of the screenshot for this journey step's thumbnail.`, -}); - -export const formatCaptionContent = (stepNumber: number, totalSteps?: number) => - i18n.translate('xpack.uptime.synthetics.pingTimestamp.captionContent', { - defaultMessage: 'Step: {stepNumber} of {totalSteps}', - values: { - stepNumber, - totalSteps, - }, - }); diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/translations.ts b/x-pack/plugins/synthetics/public/components/monitor/ping_list/translations.ts deleted file mode 100644 index 674b5c32332b4..0000000000000 --- a/x-pack/plugins/synthetics/public/components/monitor/ping_list/translations.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const STATUS_LABEL = i18n.translate('xpack.uptime.pingList.statusColumnLabel', { - defaultMessage: 'Status', -}); - -export const RES_CODE_LABEL = i18n.translate('xpack.uptime.pingList.responseCodeColumnLabel', { - defaultMessage: 'Response code', -}); -export const ERROR_TYPE_LABEL = i18n.translate('xpack.uptime.pingList.errorTypeColumnLabel', { - defaultMessage: 'Error type', -}); -export const ERROR_LABEL = i18n.translate('xpack.uptime.pingList.errorColumnLabel', { - defaultMessage: 'Error', -}); - -export const LOCATION_LABEL = i18n.translate('xpack.uptime.pingList.locationNameColumnLabel', { - defaultMessage: 'Location', -}); - -export const TIMESTAMP_LABEL = i18n.translate('xpack.uptime.pingList.timestampColumnLabel', { - defaultMessage: 'Timestamp', -}); diff --git a/x-pack/plugins/synthetics/public/components/monitor/status_details/translations.ts b/x-pack/plugins/synthetics/public/components/monitor/status_details/translations.ts deleted file mode 100644 index 39225fab2c560..0000000000000 --- a/x-pack/plugins/synthetics/public/components/monitor/status_details/translations.ts +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const healthStatusMessageAriaLabel = i18n.translate( - 'xpack.uptime.monitorStatusBar.healthStatusMessageAriaLabel', - { - defaultMessage: 'Monitor status', - } -); - -export const typeLabel = i18n.translate('xpack.uptime.monitorStatusBar.type.label', { - defaultMessage: 'Type', -}); - -export const typeAriaLabel = i18n.translate('xpack.uptime.monitorStatusBar.type.ariaLabel', { - defaultMessage: 'Monitor type', -}); - -export const monitorUrlLinkAriaLabel = i18n.translate( - 'xpack.uptime.monitorStatusBar.monitorUrlLinkAriaLabel', - { - defaultMessage: 'Monitor URL link', - } -); - -export const durationTextAriaLabel = i18n.translate( - 'xpack.uptime.monitorStatusBar.durationTextAriaLabel', - { - defaultMessage: 'Monitor duration in milliseconds', - } -); - -export const timestampFromNowTextAriaLabel = i18n.translate( - 'xpack.uptime.monitorStatusBar.timestampFromNowTextAriaLabel', - { - defaultMessage: 'Time since last check', - } -); - -export const loadingMessage = i18n.translate('xpack.uptime.monitorStatusBar.loadingMessage', { - defaultMessage: 'Loading…', -}); - -export const MonitorIDLabel = i18n.translate('xpack.uptime.monitorStatusBar.monitor.id', { - defaultMessage: 'Monitor ID', -}); - -export const OverallAvailability = i18n.translate( - 'xpack.uptime.monitorStatusBar.monitor.availability', - { - defaultMessage: 'Overall availability', - } -); - -export const MonitoringFrom = i18n.translate( - 'xpack.uptime.monitorStatusBar.monitor.monitoringFrom', - { - defaultMessage: 'Monitoring from', - } -); - -export const ChangeToMapView = i18n.translate( - 'xpack.uptime.monitorStatusBar.monitor.monitoringFrom.listToMap', - { - defaultMessage: 'Change to map view to check availability by location.', - } -); - -export const ChangeToListView = i18n.translate( - 'xpack.uptime.monitorStatusBar.monitor.monitoringFrom.MapToList', - { - defaultMessage: 'Change to list view to check availability by location.', - } -); - -export const LocationLabel = i18n.translate( - 'xpack.uptime.monitorStatusBar.monitor.availabilityReport.location', - { - defaultMessage: 'Location', - } -); - -export const AvailabilityLabel = i18n.translate( - 'xpack.uptime.monitorStatusBar.monitor.availabilityReport.availability', - { - defaultMessage: 'Availability', - } -); - -export const LastCheckLabel = i18n.translate( - 'xpack.uptime.monitorStatusBar.monitor.availabilityReport.lastCheck', - { - defaultMessage: 'Last check', - } -); diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/types.ts b/x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/types.ts deleted file mode 100644 index e356297fdae38..0000000000000 --- a/x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/types.ts +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; -import { NetworkEvent } from '../../../../../../common/runtime_types'; - -export enum Timings { - Blocked = 'blocked', - Dns = 'dns', - Connect = 'connect', - Ssl = 'ssl', - Send = 'send', - Wait = 'wait', - Receive = 'receive', -} - -export enum Metadata { - Status = 'status', - ResourceSize = 'resourceSize', - TransferSize = 'transferSize', - CertificateIssuer = 'certificateIssuer', - CertificateIssueDate = 'certificateIssueDate', - CertificateExpiryDate = 'certificateExpiryDate', - CertificateSubject = 'certificateSubject', - IP = 'ip', - MimeType = 'mimeType', - RequestStart = 'requestStart', -} - -export const FriendlyTimingLabels = { - [Timings.Blocked]: i18n.translate( - 'xpack.uptime.synthetics.waterfallChart.labels.timings.blocked', - { - defaultMessage: 'Queued / Blocked', - } - ), - [Timings.Dns]: i18n.translate('xpack.uptime.synthetics.waterfallChart.labels.timings.dns', { - defaultMessage: 'DNS', - }), - [Timings.Connect]: i18n.translate( - 'xpack.uptime.synthetics.waterfallChart.labels.timings.connect', - { - defaultMessage: 'Connecting', - } - ), - [Timings.Ssl]: i18n.translate('xpack.uptime.synthetics.waterfallChart.labels.timings.ssl', { - defaultMessage: 'TLS', - }), - [Timings.Send]: i18n.translate('xpack.uptime.synthetics.waterfallChart.labels.timings.send', { - defaultMessage: 'Sending request', - }), - [Timings.Wait]: i18n.translate('xpack.uptime.synthetics.waterfallChart.labels.timings.wait', { - defaultMessage: 'Waiting (TTFB)', - }), - [Timings.Receive]: i18n.translate( - 'xpack.uptime.synthetics.waterfallChart.labels.timings.receive', - { - defaultMessage: 'Content downloading', - } - ), -}; - -export const FriendlyFlyoutLabels = { - [Metadata.Status]: i18n.translate( - 'xpack.uptime.synthetics.waterfallChart.labels.metadata.status', - { - defaultMessage: 'Status', - } - ), - [Metadata.MimeType]: i18n.translate( - 'xpack.uptime.synthetics.waterfallChart.labels.metadata.contentType', - { - defaultMessage: 'Content type', - } - ), - [Metadata.RequestStart]: i18n.translate( - 'xpack.uptime.synthetics.waterfallChart.labels.metadata.requestStart', - { - defaultMessage: 'Request start', - } - ), - [Metadata.ResourceSize]: i18n.translate( - 'xpack.uptime.synthetics.waterfallChart.labels.metadata.resourceSize', - { - defaultMessage: 'Resource size', - } - ), - [Metadata.TransferSize]: i18n.translate( - 'xpack.uptime.synthetics.waterfallChart.labels.metadata.transferSize', - { - defaultMessage: 'Transfer size', - } - ), - [Metadata.CertificateIssuer]: i18n.translate( - 'xpack.uptime.synthetics.waterfallChart.labels.metadata.certificateIssuer', - { - defaultMessage: 'Issuer', - } - ), - [Metadata.CertificateIssueDate]: i18n.translate( - 'xpack.uptime.synthetics.waterfallChart.labels.metadata.certificateIssueDate', - { - defaultMessage: 'Valid from', - } - ), - [Metadata.CertificateExpiryDate]: i18n.translate( - 'xpack.uptime.synthetics.waterfallChart.labels.metadata.certificateExpiryDate', - { - defaultMessage: 'Valid until', - } - ), - [Metadata.CertificateSubject]: i18n.translate( - 'xpack.uptime.synthetics.waterfallChart.labels.metadata.certificateSubject', - { - defaultMessage: 'Common name', - } - ), - [Metadata.IP]: i18n.translate('xpack.uptime.synthetics.waterfallChart.labels.metadata.ip', { - defaultMessage: 'IP', - }), -}; - -export const TIMING_ORDER = [ - Timings.Blocked, - Timings.Dns, - Timings.Connect, - Timings.Ssl, - Timings.Send, - Timings.Wait, - Timings.Receive, -] as const; - -export const META_DATA_ORDER_FLYOUT = [ - Metadata.MimeType, - Timings.Dns, - Timings.Connect, - Timings.Ssl, - Timings.Wait, - Timings.Receive, -] as const; - -export type CalculatedTimings = { - [K in Timings]?: number; -}; - -export enum MimeType { - Html = 'html', - Script = 'script', - Stylesheet = 'stylesheet', - Media = 'media', - Font = 'font', - XHR = 'xhr', - Other = 'other', -} - -export const FriendlyMimetypeLabels = { - [MimeType.Html]: i18n.translate('xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.html', { - defaultMessage: 'HTML', - }), - [MimeType.Script]: i18n.translate( - 'xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.script', - { - defaultMessage: 'JS', - } - ), - [MimeType.Stylesheet]: i18n.translate( - 'xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.stylesheet', - { - defaultMessage: 'CSS', - } - ), - [MimeType.Media]: i18n.translate( - 'xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.media', - { - defaultMessage: 'Media', - } - ), - [MimeType.Font]: i18n.translate('xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.font', { - defaultMessage: 'Font', - }), - [MimeType.XHR]: i18n.translate('xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.xhr', { - defaultMessage: 'XHR', - }), - [MimeType.Other]: i18n.translate( - 'xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.other', - { - defaultMessage: 'Other', - } - ), -}; - -// NOTE: This list tries to cover the standard spec compliant mime types, -// and a few popular non-standard ones, but it isn't exhaustive. -export const MimeTypesMap: Record = { - 'text/html': MimeType.Html, - 'application/javascript': MimeType.Script, - 'text/javascript': MimeType.Script, - 'text/css': MimeType.Stylesheet, - // Images - 'image/apng': MimeType.Media, - 'image/bmp': MimeType.Media, - 'image/gif': MimeType.Media, - 'image/x-icon': MimeType.Media, - 'image/jpeg': MimeType.Media, - 'image/png': MimeType.Media, - 'image/svg+xml': MimeType.Media, - 'image/tiff': MimeType.Media, - 'image/webp': MimeType.Media, - // Common audio / video formats - 'audio/wave': MimeType.Media, - 'audio/wav': MimeType.Media, - 'audio/x-wav': MimeType.Media, - 'audio/x-pn-wav': MimeType.Media, - 'audio/webm': MimeType.Media, - 'video/webm': MimeType.Media, - 'video/mp4': MimeType.Media, - 'audio/ogg': MimeType.Media, - 'video/ogg': MimeType.Media, - 'application/ogg': MimeType.Media, - // Fonts - 'font/otf': MimeType.Font, - 'font/ttf': MimeType.Font, - 'font/woff': MimeType.Font, - 'font/woff2': MimeType.Font, - 'application/x-font-opentype': MimeType.Font, - 'application/font-woff': MimeType.Font, - 'application/font-woff2': MimeType.Font, - 'application/vnd.ms-fontobject': MimeType.Font, - 'application/font-sfnt': MimeType.Font, - - // XHR - 'application/json': MimeType.XHR, -}; - -export type NetworkItem = NetworkEvent; -export type NetworkItems = NetworkItem[]; - -export type SidebarItem = Pick & { - isHighlighted: boolean; - index: number; - offsetIndex: number; -}; -export type SidebarItems = SidebarItem[]; - -export interface LegendItem { - name: string; - colour: string; -} -export type LegendItems = LegendItem[]; diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/translations.ts b/x-pack/plugins/synthetics/public/components/monitor/synthetics/translations.ts deleted file mode 100644 index bc9bfb5fb352f..0000000000000 --- a/x-pack/plugins/synthetics/public/components/monitor/synthetics/translations.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const VIEW_PERFORMANCE = i18n.translate( - 'xpack.uptime.pingList.synthetics.performanceBreakDown', - { - defaultMessage: 'View performance breakdown', - } -); diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/translations.ts b/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/translations.ts deleted file mode 100644 index b63ffacaadd2e..0000000000000 --- a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/translations.ts +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const FILTER_REQUESTS_LABEL = i18n.translate( - 'xpack.uptime.synthetics.waterfall.searchBox.placeholder', - { - defaultMessage: 'Filter network requests', - } -); - -export const FILTER_SCREENREADER_LABEL = i18n.translate( - 'xpack.uptime.synthetics.waterfall.filterGroup.filterScreenreaderLabel', - { - defaultMessage: 'Filter by', - } -); - -export const FILTER_REMOVE_SCREENREADER_LABEL = i18n.translate( - 'xpack.uptime.synthetics.waterfall.filterGroup.removeFilterScreenReaderLabel', - { - defaultMessage: 'Remove filter by', - } -); - -export const FILTER_POPOVER_OPEN_LABEL = i18n.translate( - 'xpack.uptime.pingList.synthetics.waterfall.filters.popover', - { - defaultMessage: 'Click to open waterfall filters', - } -); - -export const FILTER_COLLAPSE_REQUESTS_LABEL = i18n.translate( - 'xpack.uptime.pingList.synthetics.waterfall.filters.collapseRequestsLabel', - { - defaultMessage: 'Collapse to only show matching requests', - } -); - -export const SIDEBAR_FILTER_MATCHES_SCREENREADER_LABEL = i18n.translate( - 'xpack.uptime.synthetics.waterfall.sidebar.filterMatchesScreenReaderLabel', - { - defaultMessage: 'Resource matches filter', - } -); diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/content/index.ts b/x-pack/plugins/synthetics/public/components/monitor_management/content/index.ts deleted file mode 100644 index 369506a12b3d9..0000000000000 --- a/x-pack/plugins/synthetics/public/components/monitor_management/content/index.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const SYNTHETICS_ENABLE_FAILURE = i18n.translate( - 'xpack.uptime.monitorManagement.syntheticsEnabledFailure', - { - defaultMessage: 'Monitor Management was not able to be enabled. Please contact support.', - } -); - -export const SYNTHETICS_DISABLE_FAILURE = i18n.translate( - 'xpack.uptime.monitorManagement.syntheticsDisabledFailure', - { - defaultMessage: 'Monitor Management was not able to be disabled. Please contact support.', - } -); - -export const SYNTHETICS_ENABLE_SUCCESS = i18n.translate( - 'xpack.uptime.monitorManagement.syntheticsEnableSuccess', - { - defaultMessage: 'Monitor Management enabled successfully.', - } -); - -export const SYNTHETICS_DISABLE_SUCCESS = i18n.translate( - 'xpack.uptime.monitorManagement.syntheticsDisabledSuccess', - { - defaultMessage: 'Monitor Management disabled successfully.', - } -); diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_list.test.tsx b/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_list.test.tsx deleted file mode 100644 index a641f7a76f3a7..0000000000000 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_list.test.tsx +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { screen } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; -import React from 'react'; -import { - ConfigKey, - DataStream, - HTTPFields, - ScheduleUnit, - DEFAULT_THROTTLING, -} from '../../../../common/runtime_types'; -import { render } from '../../../lib/helper/rtl_helpers'; -import { MonitorManagementList as MonitorManagementListState } from '../../../state/reducers/monitor_management'; -import { MonitorManagementList, MonitorManagementListPageState } from './monitor_list'; - -describe('', () => { - const onUpdate = jest.fn(); - const onPageStateChange = jest.fn(); - const monitors = []; - for (let i = 0; i < 12; i++) { - monitors.push({ - id: `test-monitor-id-${i}`, - updated_at: '123', - attributes: { - name: `test-monitor-${i}`, - enabled: true, - schedule: { - unit: ScheduleUnit.MINUTES, - number: `${i * 10}`, - }, - urls: `https://test-${i}.co`, - type: DataStream.HTTP, - tags: [`tag-${i}`], - } as HTTPFields, - }); - } - const state = { - monitorManagementList: { - throttling: DEFAULT_THROTTLING, - list: { - perPage: 5, - page: 1, - total: 6, - monitors, - syncErrors: null, - }, - locations: [], - enablement: null, - error: { - serviceLocations: null, - monitorList: null, - enablement: null, - }, - loading: { - monitorList: true, - serviceLocations: false, - enablement: false, - }, - syntheticsService: { - loading: false, - signupUrl: null, - }, - } as MonitorManagementListState, - }; - - const pageState: MonitorManagementListPageState = { - pageIndex: 1, - pageSize: 10, - sortField: `${ConfigKey.NAME}.keyword`, - sortOrder: 'asc', - }; - - it.each(monitors)('navigates to edit monitor flow on edit pencil', (monitor) => { - render( - , - { state } - ); - - expect(screen.getByText(monitor.attributes.name)).toBeInTheDocument(); - expect(screen.getByText(monitor.attributes.urls)).toBeInTheDocument(); - monitor.attributes.tags.forEach((tag) => { - expect(screen.getByText(tag)).toBeInTheDocument(); - }); - expect(screen.getByText(monitor.attributes.schedule.number)).toBeInTheDocument(); - }); - - it('handles changing per page', () => { - render( - , - { state } - ); - - userEvent.click(screen.getByTestId('tablePaginationPopoverButton')); - - userEvent.click(screen.getByText('10 rows')); - - expect(onPageStateChange).toBeCalledWith(expect.objectContaining({ pageSize: 10 })); - }); - - it('handles refreshing and changing page when navigating to the next page', async () => { - const { getByTestId } = render( - , - { state } - ); - - userEvent.click(getByTestId('pagination-button-next')); - - expect(onPageStateChange).toBeCalledWith(expect.objectContaining({ pageIndex: 2 })); - }); -}); diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_list.tsx b/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_list.tsx deleted file mode 100644 index e38dad1c10d46..0000000000000 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_list.tsx +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { - Criteria, - EuiBasicTable, - EuiBasicTableColumn, - EuiLink, - EuiPanel, - EuiSpacer, -} from '@elastic/eui'; -import { EuiTableSortingType } from '@elastic/eui/src/components/basic_table/table_types'; -import { i18n } from '@kbn/i18n'; -import React, { useCallback, useContext, useMemo } from 'react'; -import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { - CommonFields, - ConfigKey, - FetchMonitorManagementListQueryArgs, - ICMPSimpleFields, - Ping, - ServiceLocations, - EncryptedSyntheticsMonitorWithId, - TCPSimpleFields, -} from '../../../../common/runtime_types'; -import { UptimeSettingsContext } from '../../../contexts'; -import { useBreakpoints } from '../../../hooks'; -import { MonitorManagementList as MonitorManagementListState } from '../../../state/reducers/monitor_management'; -import * as labels from '../../overview/monitor_list/translations'; -import { Actions } from './actions'; -import { MonitorEnabled } from './monitor_enabled'; -import { MonitorLocations } from './monitor_locations'; -import { MonitorTags } from './tags'; - -export interface MonitorManagementListPageState { - pageIndex: number; - pageSize: number; - sortField: - | `${ConfigKey.URLS}.keyword` - | `${ConfigKey.NAME}.keyword` - | `${ConfigKey.MONITOR_TYPE}.keyword`; - sortOrder: NonNullable; -} - -interface Props { - pageState: MonitorManagementListPageState; - monitorList: MonitorManagementListState; - onPageStateChange: (state: MonitorManagementListPageState) => void; - onUpdate: () => void; - errorSummaries?: Ping[]; -} - -export const MonitorManagementList = ({ - pageState: { pageIndex, pageSize, sortField, sortOrder }, - monitorList: { - list, - error: { monitorList: error }, - loading: { monitorList: loading }, - }, - onPageStateChange, - onUpdate, - errorSummaries, -}: Props) => { - const { basePath } = useContext(UptimeSettingsContext); - const isXl = useBreakpoints().up('xl'); - - const { total } = list as MonitorManagementListState['list']; - const monitors: EncryptedSyntheticsMonitorWithId[] = useMemo( - () => - list.monitors.map((monitor) => ({ - ...monitor.attributes, - id: monitor.id, - })), - [list.monitors] - ); - - const handleOnChange = useCallback( - ({ - page = { index: 0, size: 10 }, - sort = { field: ConfigKey.NAME, direction: 'asc' }, - }: Criteria) => { - const { index, size } = page; - const { field, direction } = sort; - - onPageStateChange({ - pageIndex: index + 1, // page index for Saved Objects is base 1 - pageSize: size, - sortField: `${field}.keyword` as MonitorManagementListPageState['sortField'], - sortOrder: direction, - }); - }, - [onPageStateChange] - ); - - const pagination = { - pageIndex: pageIndex - 1, // page index for EuiBasicTable is base 0 - pageSize, - totalItemCount: total || 0, - pageSizeOptions: [5, 10, 25, 50, 100], - }; - - const sorting: EuiTableSortingType = { - sort: { - field: sortField.replace('.keyword', '') as keyof EncryptedSyntheticsMonitorWithId, - direction: sortOrder, - }, - }; - - const canEdit: boolean = !!useKibana().services?.application?.capabilities.uptime.save; - - const columns = [ - { - align: 'left' as const, - field: ConfigKey.NAME as string, - name: i18n.translate('xpack.uptime.monitorManagement.monitorList.monitorName', { - defaultMessage: 'Monitor name', - }), - sortable: true, - render: (name: string, { id }: EncryptedSyntheticsMonitorWithId) => ( - - {name} - - ), - }, - { - align: 'left' as const, - field: ConfigKey.MONITOR_TYPE, - name: i18n.translate('xpack.uptime.monitorManagement.monitorList.monitorType', { - defaultMessage: 'Monitor type', - }), - sortable: true, - }, - { - align: 'left' as const, - field: ConfigKey.TAGS, - name: i18n.translate('xpack.uptime.monitorManagement.monitorList.tags', { - defaultMessage: 'Tags', - }), - render: (tags: string[]) => (tags ? : null), - }, - { - align: 'left' as const, - field: ConfigKey.LOCATIONS, - name: i18n.translate('xpack.uptime.monitorManagement.monitorList.locations', { - defaultMessage: 'Locations', - }), - render: (locations: ServiceLocations) => - locations ? : null, - }, - { - align: 'left' as const, - field: ConfigKey.SCHEDULE, - name: i18n.translate('xpack.uptime.monitorManagement.monitorList.schedule', { - defaultMessage: 'Frequency (min)', - }), - render: (schedule: CommonFields[ConfigKey.SCHEDULE]) => schedule?.number, - }, - { - align: 'left' as const, - field: ConfigKey.URLS, - name: i18n.translate('xpack.uptime.monitorManagement.monitorList.URL', { - defaultMessage: 'URL', - }), - sortable: true, - render: (urls: string, { hosts }: TCPSimpleFields | ICMPSimpleFields) => urls || hosts, - truncateText: true, - textOnly: true, - }, - { - align: 'left' as const, - field: ConfigKey.ENABLED as string, - name: i18n.translate('xpack.uptime.monitorManagement.monitorList.enabled', { - defaultMessage: 'Enabled', - }), - render: (_enabled: boolean, monitor: EncryptedSyntheticsMonitorWithId) => ( - - ), - }, - { - align: 'left' as const, - name: i18n.translate('xpack.uptime.monitorManagement.monitorList.actions', { - defaultMessage: 'Actions', - }), - render: (fields: EncryptedSyntheticsMonitorWithId) => ( - - ), - }, - ] as Array>; - - return ( - - - - - ); -}; diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_list_container.tsx b/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_list_container.tsx deleted file mode 100644 index 92b61cf1d744d..0000000000000 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_list_container.tsx +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useEffect, useReducer, useCallback, Reducer } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import { useParams } from 'react-router-dom'; -import { useTrackPageview } from '@kbn/observability-plugin/public'; -import { ConfigKey } from '../../../../common/runtime_types'; -import { getMonitors } from '../../../state/actions'; -import { monitorManagementListSelector } from '../../../state/selectors'; -import { MonitorManagementListPageState } from './monitor_list'; -import { MonitorAsyncError } from './monitor_async_error'; -import { useInlineErrors } from '../hooks/use_inline_errors'; -import { MonitorListTabs } from './list_tabs'; -import { AllMonitors } from './all_monitors'; -import { InvalidMonitors } from './invalid_monitors'; -import { useInvalidMonitors } from '../hooks/use_invalid_monitors'; - -export const MonitorListContainer: React.FC = () => { - const [pageState, dispatchPageAction] = useReducer( - monitorManagementPageReducer, - { - pageIndex: 1, // saved objects page index is base 1 - pageSize: 10, - sortOrder: 'asc', - sortField: `${ConfigKey.NAME}.keyword`, - } - ); - - const onPageStateChange = useCallback( - (state) => { - dispatchPageAction({ type: 'update', payload: state }); - }, - [dispatchPageAction] - ); - - const onUpdate = useCallback(() => { - dispatchPageAction({ type: 'refresh' }); - }, [dispatchPageAction]); - - useTrackPageview({ app: 'uptime', path: 'manage-monitors' }); - useTrackPageview({ app: 'uptime', path: 'manage-monitors', delay: 15000 }); - - const dispatch = useDispatch(); - const monitorList = useSelector(monitorManagementListSelector); - - const { pageIndex, pageSize, sortField, sortOrder } = pageState as MonitorManagementListPageState; - - const { type: viewType } = useParams<{ type: 'all' | 'invalid' }>(); - const { errorSummaries, loading, count } = useInlineErrors({ - onlyInvalidMonitors: viewType === 'invalid', - sortField: pageState.sortField, - sortOrder: pageState.sortOrder, - }); - - useEffect(() => { - if (viewType === 'all') { - dispatch(getMonitors({ page: pageIndex, perPage: pageSize, sortField, sortOrder })); - } - }, [dispatch, pageState, pageIndex, pageSize, sortField, sortOrder, viewType]); - - const { data: monitorSavedObjects, loading: objectsLoading } = useInvalidMonitors(errorSummaries); - - return ( - <> - - - {viewType === 'all' ? ( - - ) : ( - - )} - - ); -}; - -type MonitorManagementPageAction = - | { - type: 'update'; - payload: MonitorManagementListPageState; - } - | { type: 'refresh' }; - -const monitorManagementPageReducer: Reducer< - MonitorManagementListPageState, - MonitorManagementPageAction -> = (state: MonitorManagementListPageState, action: MonitorManagementPageAction) => { - switch (action.type) { - case 'update': - return { - ...state, - ...action.payload, - }; - case 'refresh': - return { ...state }; - default: - throw new Error(`Action "${(action as MonitorManagementPageAction)?.type}" not recognizable`); - } -}; diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/validation.test.ts b/x-pack/plugins/synthetics/public/components/monitor_management/validation.test.ts deleted file mode 100644 index 6fa57eb5cd964..0000000000000 --- a/x-pack/plugins/synthetics/public/components/monitor_management/validation.test.ts +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - ConfigKey, - DataStream, - HTTPFields, - BrowserFields, - MonitorFields, - ScheduleUnit, - ServiceLocations, -} from '../../../common/runtime_types'; -import { validate, validateCommon } from './validation'; - -describe('[Monitor Management] validation', () => { - const commonPropsValid: Partial = { - [ConfigKey.SCHEDULE]: { number: '5', unit: ScheduleUnit.MINUTES }, - [ConfigKey.TIMEOUT]: '3m', - [ConfigKey.LOCATIONS]: [ - { - id: 'test-service-location', - isServiceManaged: true, - url: 'https:test-url.com', - geo: { lat: 33.33432323, lon: 73.23424221 }, - label: 'EU West', - }, - ] as ServiceLocations, - [ConfigKey.NAME]: 'test-name', - [ConfigKey.NAMESPACE]: 'namespace', - }; - - describe('Common monitor fields', () => { - it('should return false for all valid props', () => { - const result = Object.values(validateCommon).map((validator) => { - return validator ? validator(commonPropsValid) : true; - }); - - expect(result.reduce((previous, current) => previous || current)).toBeFalsy(); - }); - - it('should invalidate on invalid namespace', () => { - const validatorFn = validateCommon[ConfigKey.NAMESPACE]; - const result = [undefined, null, '', '*/&<>:', 'A', 'a'.repeat(101)].map((testValue) => - validatorFn?.({ [ConfigKey.NAMESPACE]: testValue } as Partial) - ); - - expect(result.reduce((previous, current) => previous && current)).toBeTruthy(); - }); - }); - - describe('HTTP', () => { - const httpPropsValid: Partial = { - ...commonPropsValid, - [ConfigKey.RESPONSE_STATUS_CHECK]: ['200', '204'], - [ConfigKey.RESPONSE_HEADERS_CHECK]: { 'Content-Type': 'application/json' }, - [ConfigKey.REQUEST_HEADERS_CHECK]: { 'Accept-Language': 'en-GB,en-US;q=0.9,en;q=0.8' }, - [ConfigKey.MAX_REDIRECTS]: '3', - [ConfigKey.URLS]: 'https:// example-url.com', - }; - - it('should return false for all valid props', () => { - const validators = validate[DataStream.HTTP]; - const keysToValidate = [ - ConfigKey.SCHEDULE, - ConfigKey.TIMEOUT, - ConfigKey.LOCATIONS, - ConfigKey.RESPONSE_STATUS_CHECK, - ConfigKey.RESPONSE_HEADERS_CHECK, - ConfigKey.REQUEST_HEADERS_CHECK, - ConfigKey.MAX_REDIRECTS, - ConfigKey.URLS, - ]; - const validatorFns = keysToValidate.map((key) => validators[key]); - const result = validatorFns.map((fn) => fn?.(httpPropsValid) ?? true); - - expect(result).not.toEqual(expect.arrayContaining([true])); - }); - - it('should invalidate when locations is empty', () => { - const validators = validate[DataStream.HTTP]; - const validatorFn = validators[ConfigKey.LOCATIONS]; - const result = [undefined, null, []].map( - (testValue) => - validatorFn?.({ [ConfigKey.LOCATIONS]: testValue } as Partial) ?? false - ); - - expect(result).toEqual([true, true, true]); - }); - }); - - describe.each([ - [ConfigKey.SOURCE_INLINE, 'step(() => {});'], - [ConfigKey.SOURCE_ZIP_URL, 'https://test.zip'], - ])('Browser', (configKey, value) => { - const browserProps: Partial = { - ...commonPropsValid, - [ConfigKey.MONITOR_TYPE]: DataStream.BROWSER, - [ConfigKey.TIMEOUT]: undefined, - [configKey]: value, - }; - - it('should return false for all valid props', () => { - const validators = validate[DataStream.BROWSER]; - const keysToValidate = [ConfigKey.SCHEDULE, ConfigKey.TIMEOUT, configKey]; - const validatorFns = keysToValidate.map((key) => validators[key]); - const result = validatorFns.map((fn) => fn?.(browserProps) ?? true); - - expect(result).not.toEqual(expect.arrayContaining([true])); - }); - - it('should invalidate when locations is empty', () => { - const validators = validate[DataStream.BROWSER]; - const validatorFn = validators[ConfigKey.LOCATIONS]; - const result = [undefined, null, []].map( - (testValue) => - validatorFn?.({ [ConfigKey.LOCATIONS]: testValue } as Partial) ?? false - ); - - expect(result).toEqual([true, true, true]); - }); - }); - - // TODO: Add test for other monitor types if needed -}); diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/alert_query_bar/query_bar.tsx b/x-pack/plugins/synthetics/public/components/overview/alerts/alert_query_bar/query_bar.tsx deleted file mode 100644 index 0e9244cdc15ad..0000000000000 --- a/x-pack/plugins/synthetics/public/components/overview/alerts/alert_query_bar/query_bar.tsx +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useEffect, useState } from 'react'; -import { EuiFlexItem } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { QueryStringInput } from '@kbn/unified-search-plugin/public'; -import { isValidKuery } from '../../query_bar/query_bar'; -import * as labels from '../translations'; -import { useIndexPattern } from '../../../../hooks'; - -interface Props { - query: string; - onChange: (query: string) => void; -} - -export const AlertQueryBar = ({ query = '', onChange }: Props) => { - const indexPattern = useIndexPattern(); - - const [inputVal, setInputVal] = useState(query); - - useEffect(() => { - onChange(query); - setInputVal(query); - }, [onChange, query]); - - return ( - - { - setInputVal(queryN?.query as string); - if (isValidKuery(queryN?.query as string)) { - // we want to submit when user clears or paste a complete kuery - onChange(queryN.query as string); - } - }} - onSubmit={(queryN) => { - if (queryN) onChange(queryN.query as string); - }} - query={{ query: inputVal, language: 'kuery' }} - aria-label={labels.ALERT_KUERY_BAR_ARIA} - dataTestSubj="xpack.uptime.alerts.monitorStatus.filterBar" - autoSubmit={true} - disableLanguageSwitcher={true} - isInvalid={!!(inputVal && !query)} - placeholder={i18n.translate('xpack.uptime.alerts.searchPlaceholder.kql', { - defaultMessage: 'Filter using kql syntax', - })} - /> - - ); -}; diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/alerts_containers/alert_monitor_status.tsx b/x-pack/plugins/synthetics/public/components/overview/alerts/alerts_containers/alert_monitor_status.tsx deleted file mode 100644 index 09b116c5bbc45..0000000000000 --- a/x-pack/plugins/synthetics/public/components/overview/alerts/alerts_containers/alert_monitor_status.tsx +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useEffect } from 'react'; -import { useSelector, useDispatch } from 'react-redux'; -import { isRight } from 'fp-ts/lib/Either'; -import { selectedFiltersSelector } from '../../../../state/selectors'; -import { AlertMonitorStatusComponent } from '../monitor_status_alert/alert_monitor_status'; -import { setSearchTextAction } from '../../../../state/actions'; -import { - AtomicStatusCheckParamsType, - GetMonitorAvailabilityParamsType, -} from '../../../../../common/runtime_types'; - -import { useSnapShotCount } from './use_snap_shot'; -import { FILTER_FIELDS } from '../../../../../common/constants'; - -const { TYPE, TAGS, LOCATION, PORT } = FILTER_FIELDS; - -interface Props { - ruleParams: { [key: string]: any }; - enabled: boolean; - numTimes: number; - setRuleParams: (key: string, value: any) => void; - timerange: { - from: string; - to: string; - }; -} - -export const AlertMonitorStatus: React.FC = ({ - enabled, - numTimes, - setRuleParams, - timerange, - ruleParams, -}) => { - const dispatch = useDispatch(); - - useEffect(() => { - if (ruleParams.search) { - dispatch(setSearchTextAction(ruleParams.search)); - } - }, [ruleParams, dispatch]); - - const { count, loading } = useSnapShotCount({ - query: ruleParams.search, - filters: ruleParams.filters, - }); - - const isOldAlert = React.useMemo( - () => - Object.entries(ruleParams).length > 0 && - !isRight(AtomicStatusCheckParamsType.decode(ruleParams)) && - !isRight(GetMonitorAvailabilityParamsType.decode(ruleParams)), - [ruleParams] - ); - - const selectedFilters = useSelector(selectedFiltersSelector); - useEffect(() => { - if (!ruleParams.filters && selectedFilters !== null) { - setRuleParams('filters', { - [PORT]: selectedFilters?.ports ?? [], - [LOCATION]: selectedFilters?.locations ?? [], - [TYPE]: selectedFilters?.schemes ?? [], - [TAGS]: selectedFilters?.tags ?? [], - }); - } - }, [ruleParams, setRuleParams, selectedFilters]); - - return ( - - ); -}; - -// eslint-disable-next-line import/no-default-export -export { AlertMonitorStatus as default }; diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/anomaly_alert/translations.ts b/x-pack/plugins/synthetics/public/components/overview/alerts/anomaly_alert/translations.ts deleted file mode 100644 index 1249c66f92cbb..0000000000000 --- a/x-pack/plugins/synthetics/public/components/overview/alerts/anomaly_alert/translations.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const AnomalyTranslations = { - criteriaAriaLabel: i18n.translate('xpack.uptime.alerts.anomaly.criteriaExpression.ariaLabel', { - defaultMessage: 'An expression displaying the criteria for a selected monitor.', - }), - whenMonitor: i18n.translate('xpack.uptime.alerts.anomaly.criteriaExpression.description', { - defaultMessage: 'When monitor', - }), - scoreAriaLabel: i18n.translate('xpack.uptime.alerts.anomaly.scoreExpression.ariaLabel', { - defaultMessage: 'An expression displaying the criteria for an anomaly alert threshold.', - }), - hasAnomalyWithSeverity: i18n.translate( - 'xpack.uptime.alerts.anomaly.scoreExpression.description', - { - defaultMessage: 'has anomaly with severity', - description: 'An expression displaying the criteria for an anomaly alert threshold.', - } - ), -}; diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/translations.ts b/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/translations.ts deleted file mode 100644 index ca00aabc8b9b3..0000000000000 --- a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/translations.ts +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const alertFilterLabels = { - USING: i18n.translate('xpack.uptime.alerts.monitorStatus.filters.using', { - defaultMessage: 'Using', - }), - - USING_PORT: i18n.translate('xpack.uptime.alerts.monitorStatus.filters.usingPort', { - defaultMessage: 'Using port', - }), - - ANY_PORT: i18n.translate('xpack.uptime.alerts.monitorStatus.filters.anyPort', { - defaultMessage: 'any port', - }), - - WITH: i18n.translate('xpack.uptime.alerts.monitorStatus.filters.with', { - defaultMessage: 'Using', - }), - - WITH_TAG: i18n.translate('xpack.uptime.alerts.monitorStatus.filters.withTag', { - defaultMessage: 'With tag', - }), - - ANY_TAG: i18n.translate('xpack.uptime.alerts.monitorStatus.filters.anyTag', { - defaultMessage: 'any tag', - }), - - OF: i18n.translate('xpack.uptime.alerts.monitorStatus.filters.of', { - defaultMessage: 'Of', - }), - - OF_TYPE: i18n.translate('xpack.uptime.alerts.monitorStatus.filters.ofType', { - defaultMessage: 'Of type', - }), - - ANY_TYPE: i18n.translate('xpack.uptime.alerts.monitorStatus.filters.anyType', { - defaultMessage: 'any type', - }), - - FROM: i18n.translate('xpack.uptime.alerts.monitorStatus.filters.from', { - defaultMessage: 'From', - }), - - FROM_LOCATION: i18n.translate('xpack.uptime.alerts.monitorStatus.filters.fromLocation', { - defaultMessage: 'From location', - }), - - ANY_LOCATION: i18n.translate('xpack.uptime.alerts.monitorStatus.filters.anyLocation', { - defaultMessage: 'any location', - }), - - REMOVE_FILTER_LABEL: (title: string) => - i18n.translate('xpack.uptime.alerts.monitorExpression.label', { - defaultMessage: 'Remove filter {title}', - values: { title }, - }), -}; - -export const statusExpLabels = { - ENABLED_CHECKBOX: i18n.translate('xpack.uptime.alerts.monitorStatus.statusEnabledCheck.label', { - defaultMessage: 'Status check', - }), -}; - -export const timeExpLabels = { - OPEN_TIME_POPOVER: i18n.translate( - 'xpack.uptime.alerts.monitorStatus.timerangeUnitExpression.ariaLabel', - { - defaultMessage: 'Open the popover for time range unit select field', - } - ), - SELECT_TIME_RANGE_ARIA: i18n.translate( - 'xpack.uptime.alerts.monitorStatus.timerangeUnitSelectable', - { - defaultMessage: 'Selectable field for the time range units alerts should use', - } - ), - SELECT_TIME_RANGE_HEADLINE: i18n.translate( - 'xpack.uptime.alerts.monitorStatus.timerangeSelectionHeader', - { - defaultMessage: 'Select time range unit', - } - ), -}; - -export const filterAriaLabels = { - PORT: i18n.translate('xpack.uptime.alerts.monitorStatus.filters.port.label', { - defaultMessage: `Select port filters to apply to the alert's query.`, - }), - TAG: i18n.translate('xpack.uptime.alerts.monitorStatus.filters.tag.label', { - defaultMessage: `Select tag filters to apply to the alert's query.`, - }), - SCHEME: i18n.translate('xpack.uptime.alerts.monitorStatus.filters.scheme.label', { - defaultMessage: `Select protocol scheme filters to apply to the alert's query.`, - }), - LOCATION: i18n.translate('xpack.uptime.alerts.monitorStatus.filters.location.label', { - defaultMessage: `Select location filters to apply to the alert's query.`, - }), -}; diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_status_alert/alert_monitor_status.tsx b/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_status_alert/alert_monitor_status.tsx deleted file mode 100644 index 577df06802e40..0000000000000 --- a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_status_alert/alert_monitor_status.tsx +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useCallback, useEffect, useState } from 'react'; -import { EuiCallOut, EuiSpacer, EuiHorizontalRule, EuiLoadingSpinner } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { FiltersExpressionsSelect, StatusExpressionSelect } from '../monitor_expressions'; -import { AddFilterButton } from './add_filter_btn'; -import { OldAlertCallOut } from './old_alert_call_out'; -import { AvailabilityExpressionSelect } from '../monitor_expressions/availability_expression_select'; -import { AlertQueryBar } from '../alert_query_bar/query_bar'; -import { useGetUrlParams } from '../../../../hooks'; -import { FILTER_FIELDS } from '../../../../../common/constants'; - -export interface AlertMonitorStatusProps { - ruleParams: { [key: string]: any }; - enabled: boolean; - isOldAlert: boolean; - snapshotCount: number; - snapshotLoading?: boolean; - numTimes: number; - setRuleParams: (key: string, value: any) => void; - timerange: { - from: string; - to: string; - }; -} - -export const hasFilters = (filters?: { [key: string]: string[] }) => { - if (!filters || Object.keys(filters).length === 0) { - return false; - } - - return Object.values(FILTER_FIELDS).some((f) => filters[f].length); -}; - -export const AlertMonitorStatusComponent: React.FC = (props) => { - const { ruleParams, isOldAlert, setRuleParams, snapshotCount, snapshotLoading } = props; - - const alertFilters = ruleParams?.filters ?? {}; - const [newFilters, setNewFilters] = useState( - Object.keys(alertFilters).filter((f) => alertFilters[f].length) - ); - - const { search = '' } = useGetUrlParams(); - - useEffect(() => { - if (search) { - setRuleParams('search', search); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - const onSearchChange = useCallback( - (value: string) => { - setRuleParams('search', value); - }, - [setRuleParams] - ); - - return ( - <> - - - - {' '} - {snapshotLoading && } - - } - iconType="iInCircle" - /> - - - - - - - - { - setNewFilters([...newFilters, newFilter]); - }} - /> - - { - if (newFilters.includes(removeFilter)) { - setNewFilters(newFilters.filter((item) => item !== removeFilter)); - } - }} - setRuleParams={setRuleParams} - shouldUpdateUrl={false} - /> - - - - - - - - - - - - ); -}; diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/translations.ts b/x-pack/plugins/synthetics/public/components/overview/alerts/translations.ts deleted file mode 100644 index 76d8ebaea3719..0000000000000 --- a/x-pack/plugins/synthetics/public/components/overview/alerts/translations.ts +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const SECONDS_TIME_RANGE = i18n.translate( - 'xpack.uptime.alerts.timerangeUnitSelectable.secondsOption.ariaLabel', - { - defaultMessage: '"Seconds" time range select item', - } -); - -export const SECONDS = i18n.translate('xpack.uptime.alerts.monitorStatus.timerangeOption.seconds', { - defaultMessage: 'seconds', -}); - -export const MINUTES_TIME_RANGE = i18n.translate( - 'xpack.uptime.alerts.timerangeUnitSelectable.minutesOption.ariaLabel', - { - defaultMessage: '"Minutes" time range select item', - } -); - -export const MINUTES = i18n.translate('xpack.uptime.alerts.monitorStatus.timerangeOption.minutes', { - defaultMessage: 'minutes', -}); - -export const HOURS_TIME_RANGE = i18n.translate( - 'xpack.uptime.alerts.timerangeUnitSelectable.hoursOption.ariaLabel', - { - defaultMessage: '"Hours" time range select item', - } -); - -export const HOURS = i18n.translate('xpack.uptime.alerts.monitorStatus.timerangeOption.hours', { - defaultMessage: 'hours', -}); - -export const DAYS_TIME_RANGE = i18n.translate( - 'xpack.uptime.alerts.timerangeUnitSelectable.daysOption.ariaLabel', - { - defaultMessage: '"Days" time range select item', - } -); - -export const DAYS = i18n.translate('xpack.uptime.alerts.monitorStatus.timerangeOption.days', { - defaultMessage: 'days', -}); - -export const WEEKS_TIME_RANGE = i18n.translate( - 'xpack.uptime.alerts.timerangeUnitSelectable.weeksOption.ariaLabel', - { - defaultMessage: '"Weeks" time range select item', - } -); - -export const WEEKS = i18n.translate('xpack.uptime.alerts.monitorStatus.timerangeOption.weeks', { - defaultMessage: 'weeks', -}); - -export const MONTHS_TIME_RANGE = i18n.translate( - 'xpack.uptime.alerts.timerangeUnitSelectable.monthsOption.ariaLabel', - { - defaultMessage: '"Months" time range select item', - } -); - -export const MONTHS = i18n.translate('xpack.uptime.alerts.monitorStatus.timerangeOption.months', { - defaultMessage: 'months', -}); - -export const YEARS_TIME_RANGE = i18n.translate( - 'xpack.uptime.alerts.timerangeUnitSelectable.yearsOption.ariaLabel', - { - defaultMessage: '"Years" time range select item', - } -); - -export const YEARS = i18n.translate('xpack.uptime.alerts.monitorStatus.timerangeOption.years', { - defaultMessage: 'years', -}); - -export const ALERT_KUERY_BAR_ARIA = i18n.translate( - 'xpack.uptime.alerts.monitorStatus.filterBar.ariaLabel', - { - defaultMessage: 'Input that allows filtering criteria for the monitor status alert', - } -); - -export const OPEN_THE_POPOVER_DOWN_COUNT = i18n.translate( - 'xpack.uptime.alerts.monitorStatus.numTimesExpression.ariaLabel', - { - defaultMessage: 'Open the popover for down count input', - } -); - -export const ENTER_NUMBER_OF_DOWN_COUNTS = i18n.translate( - 'xpack.uptime.alerts.monitorStatus.numTimesField.ariaLabel', - { - defaultMessage: 'Enter number of down counts required to trigger the alert', - } -); - -export const MATCHING_MONITORS_DOWN = i18n.translate( - 'xpack.uptime.alerts.monitorStatus.numTimesExpression.matchingMonitors.description', - { - defaultMessage: 'matching monitors are down >', - } -); - -export const ANY_MONITOR_DOWN = i18n.translate( - 'xpack.uptime.alerts.monitorStatus.numTimesExpression.anyMonitors.description', - { - defaultMessage: 'any monitor is down >', - } -); - -export const OPEN_THE_POPOVER_TIME_RANGE_VALUE = i18n.translate( - 'xpack.uptime.alerts.monitorStatus.timerangeValueExpression.ariaLabel', - { - defaultMessage: 'Open the popover for time range value field', - } -); - -export const ENTER_NUMBER_OF_TIME_UNITS = i18n.translate( - 'xpack.uptime.alerts.monitorStatus.timerangeValueField.ariaLabel', - { - defaultMessage: `Enter the number of time units for the alert's range`, - } -); - -export const ENTER_NUMBER_OF_TIME_UNITS_DESCRIPTION = i18n.translate( - 'xpack.uptime.alerts.monitorStatus.timerangeValueField.expression', - { - defaultMessage: 'within', - } -); - -export const ENTER_NUMBER_OF_TIME_UNITS_VALUE = (value: number) => - i18n.translate('xpack.uptime.alerts.monitorStatus.timerangeValueField.value', { - defaultMessage: 'last {value}', - values: { value }, - }); - -export const ENTER_AVAILABILITY_RANGE_ENABLED = i18n.translate( - 'xpack.uptime.alerts.monitorStatus.availability.isEnabledCheckbox.label', - { - defaultMessage: 'Availability', - } -); - -export const ENTER_AVAILABILITY_RANGE_POPOVER_ARIA_LABEL = i18n.translate( - 'xpack.uptime.alerts.monitorStatus.availability.timerangeValueField.popover.ariaLabel', - { - defaultMessage: 'Specify availability tracking time range', - } -); - -export const ENTER_AVAILABILITY_RANGE_UNITS_ARIA_LABEL = i18n.translate( - 'xpack.uptime.alerts.monitorStatus.availability.timerangeValueField.ariaLabel', - { - defaultMessage: `Enter the number of units for the alert's availability check.`, - } -); - -export const ENTER_AVAILABILITY_RANGE_UNITS_DESCRIPTION = i18n.translate( - 'xpack.uptime.alerts.monitorStatus.availability.timerangeValueField.expression', - { - defaultMessage: 'within the last', - } -); - -export const ENTER_AVAILABILITY_THRESHOLD_ARIA_LABEL = i18n.translate( - 'xpack.uptime.alerts.monitorStatus.availability.threshold.ariaLabel', - { - defaultMessage: 'Specify availability thresholds for this alert', - } -); - -export const ENTER_AVAILABILITY_THRESHOLD_INPUT_ARIA_LABEL = i18n.translate( - 'xpack.uptime.alerts.monitorStatus.availability.threshold.input.ariaLabel', - { - defaultMessage: 'Input an availability threshold to check for this alert', - } -); - -export const ENTER_AVAILABILITY_THRESHOLD_DESCRIPTION = i18n.translate( - 'xpack.uptime.alerts.monitorStatus.availability.threshold.description', - { - defaultMessage: 'matching monitors are up in', - description: - 'This fragment explains that an alert will fire for monitors matching user-specified criteria', - } -); - -export const ENTER_ANY_AVAILABILITY_THRESHOLD_DESCRIPTION = i18n.translate( - 'xpack.uptime.alerts.monitorStatus.availability.threshold.anyMonitorDescription', - { - defaultMessage: 'any monitor is up in', - description: - 'This fragment explains that an alert will fire for monitors matching user-specified criteria', - } -); - -export const ENTER_AVAILABILITY_THRESHOLD_VALUE = (value: string) => - i18n.translate('xpack.uptime.alerts.monitorStatus.availability.threshold.value', { - defaultMessage: '< {value}% of checks', - description: - 'This fragment specifies criteria that will cause an alert to fire for uptime monitors', - values: { value }, - }); - -export const ENTER_AVAILABILITY_RANGE_SELECT_ARIA = i18n.translate( - 'xpack.uptime.alerts.monitorStatus.availability.unit.selectable', - { - defaultMessage: 'Use this select to set the availability range units for this alert', - } -); - -export const ENTER_AVAILABILITY_RANGE_SELECT_HEADLINE = i18n.translate( - 'xpack.uptime.alerts.monitorStatus.availability.unit.headline', - { - defaultMessage: 'Select time range unit', - } -); - -export const ADD_FILTER = i18n.translate('xpack.uptime.alerts.monitorStatus.addFilter', { - defaultMessage: `Add filter`, -}); - -export const LOCATION = i18n.translate('xpack.uptime.alerts.monitorStatus.addFilter.location', { - defaultMessage: `Location`, -}); - -export const TAG = i18n.translate('xpack.uptime.alerts.monitorStatus.addFilter.tag', { - defaultMessage: `Tag`, -}); - -export const PORT = i18n.translate('xpack.uptime.alerts.monitorStatus.addFilter.port', { - defaultMessage: `Port`, -}); - -export const TYPE = i18n.translate('xpack.uptime.alerts.monitorStatus.addFilter.type', { - defaultMessage: `Type`, -}); - -export const TlsTranslations = { - criteriaAriaLabel: i18n.translate('xpack.uptime.alerts.tls.criteriaExpression.ariaLabel', { - defaultMessage: - 'An expression displaying the criteria for monitor that are watched by this alert', - }), - criteriaDescription: i18n.translate('xpack.uptime.alerts.tls.criteriaExpression.description', { - defaultMessage: 'when', - description: - 'The context of this `when` is in the conditional sense, like "when there are three cookies, eat them all".', - }), - criteriaValue: i18n.translate('xpack.uptime.alerts.tls.criteriaExpression.value', { - defaultMessage: 'any monitor', - }), - expirationAriaLabel: i18n.translate('xpack.uptime.alerts.tls.expirationExpression.ariaLabel', { - defaultMessage: - 'An expression displaying the threshold that will trigger the TLS alert for certificate expiration', - }), - expirationDescription: i18n.translate( - 'xpack.uptime.alerts.tls.expirationExpression.description', - { - defaultMessage: 'has a certificate expiring within', - } - ), - expirationValue: (value?: number) => - i18n.translate('xpack.uptime.alerts.tls.expirationExpression.value', { - defaultMessage: '{value} days', - values: { value }, - }), - ageAriaLabel: i18n.translate('xpack.uptime.alerts.tls.ageExpression.ariaLabel', { - defaultMessage: - 'An expressing displaying the threshold that will trigger the TLS alert for old certificates', - }), - ageDescription: i18n.translate('xpack.uptime.alerts.tls.ageExpression.description', { - defaultMessage: 'or older than', - }), - ageValue: (value?: number) => - i18n.translate('xpack.uptime.alerts.tls.ageExpression.value', { - defaultMessage: '{value} days', - values: { value }, - }), -}; - -export const ToggleFlyoutTranslations = { - toggleButtonAriaLabel: i18n.translate('xpack.uptime.alertsPopover.toggleButton.ariaLabel', { - defaultMessage: 'Open alerts and rules context menu', - }), - openAlertContextPanelAriaLabel: i18n.translate('xpack.uptime.openAlertContextPanel.ariaLabel', { - defaultMessage: 'Open the rule context panel so you can choose a rule type', - }), - openAlertContextPanelLabel: i18n.translate('xpack.uptime.openAlertContextPanel.label', { - defaultMessage: 'Create rule', - }), - toggleTlsAriaLabel: i18n.translate('xpack.uptime.toggleTlsAlertButton.ariaLabel', { - defaultMessage: 'Open TLS rule flyout', - }), - toggleTlsContent: i18n.translate('xpack.uptime.toggleTlsAlertButton.content', { - defaultMessage: 'TLS rule', - }), - toggleMonitorStatusAriaLabel: i18n.translate('xpack.uptime.toggleAlertFlyout.ariaLabel', { - defaultMessage: 'Open add rule flyout', - }), - toggleMonitorStatusContent: i18n.translate('xpack.uptime.toggleAlertButton.content', { - defaultMessage: 'Monitor status rule', - }), - navigateToAlertingUIAriaLabel: i18n.translate('xpack.uptime.navigateToAlertingUi', { - defaultMessage: 'Leave Uptime and go to Alerting Management page', - }), - navigateToAlertingButtonContent: i18n.translate('xpack.uptime.navigateToAlertingButton.content', { - defaultMessage: 'Manage rules', - }), - toggleAlertFlyoutButtonLabel: i18n.translate('xpack.uptime.alerts.createRulesPanel.title', { - defaultMessage: 'Create rules', - }), -}; diff --git a/x-pack/plugins/synthetics/public/components/overview/filter_group/translations.tsx b/x-pack/plugins/synthetics/public/components/overview/filter_group/translations.tsx deleted file mode 100644 index 5882631dd8f3f..0000000000000 --- a/x-pack/plugins/synthetics/public/components/overview/filter_group/translations.tsx +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const filterLabels = { - LOCATION: i18n.translate('xpack.uptime.filterBar.options.location.name', { - defaultMessage: 'Location', - }), - - PORT: i18n.translate('xpack.uptime.filterBar.options.portLabel', { defaultMessage: 'Port' }), - - SCHEME: i18n.translate('xpack.uptime.filterBar.options.schemeLabel', { - defaultMessage: 'Scheme', - }), - - TAG: i18n.translate('xpack.uptime.filterBar.options.tagsLabel', { - defaultMessage: 'Tag', - }), -}; diff --git a/x-pack/plugins/synthetics/public/components/overview/monitor_list/columns/status_badge.tsx b/x-pack/plugins/synthetics/public/components/overview/monitor_list/columns/status_badge.tsx deleted file mode 100644 index fe2c7730275db..0000000000000 --- a/x-pack/plugins/synthetics/public/components/overview/monitor_list/columns/status_badge.tsx +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiBadge, EuiToolTip } from '@elastic/eui'; -import React, { useContext, useState } from 'react'; -import { STATUS } from '../../../../../common/constants'; -import { getHealthMessage } from './monitor_status_column'; -import { UptimeThemeContext } from '../../../../contexts'; -import { PingError } from '../../../../../common/runtime_types'; -import { getInlineErrorLabel } from '../../../monitor_management/monitor_list/inline_error'; -import { StdErrorPopover } from '../../../monitor_management/monitor_list/stderr_logs_popover'; - -export const StatusBadge = ({ - status, - checkGroup, - summaryError, - monitorType, -}: { - status: string; - monitorType: string; - checkGroup?: string; - summaryError?: PingError; -}) => { - const { - colors: { dangerBehindText }, - } = useContext(UptimeThemeContext); - const [isOpen, setIsOpen] = useState(false); - - if (status === STATUS.UP) { - return ( - - {getHealthMessage(status)} - - ); - } - - const errorMessage = - monitorType !== 'browser' ? summaryError?.message : getInlineErrorLabel(summaryError?.message); - - const button = ( - - setIsOpen(true)} - onClickAriaLabel={errorMessage} - > - {getHealthMessage(status)} - - - ); - - if (monitorType !== 'browser') { - return button; - } - - return ( - - ); -}; diff --git a/x-pack/plugins/synthetics/public/components/overview/monitor_list/columns/translations.ts b/x-pack/plugins/synthetics/public/components/overview/monitor_list/columns/translations.ts deleted file mode 100644 index 279307975d588..0000000000000 --- a/x-pack/plugins/synthetics/public/components/overview/monitor_list/columns/translations.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const ENABLE_STATUS_ALERT = i18n.translate('xpack.uptime.monitorList.enableDownAlert', { - defaultMessage: 'Enable status alerts', -}); - -export const DISABLE_STATUS_ALERT = i18n.translate('xpack.uptime.monitorList.disableDownAlert', { - defaultMessage: 'Disable status alerts', -}); - -export const EXPAND_TAGS_LABEL = i18n.translate('xpack.uptime.monitorList.tags.expand', { - defaultMessage: 'Click to view remaining tags', -}); - -export const EXPAND_LOCATIONS_LABEL = i18n.translate('xpack.uptime.monitorList.locations.expand', { - defaultMessage: 'Click to view remaining locations', -}); diff --git a/x-pack/plugins/synthetics/public/components/overview/monitor_list/monitor_list.test.tsx b/x-pack/plugins/synthetics/public/components/overview/monitor_list/monitor_list.test.tsx deleted file mode 100644 index b82cf6f552bf9..0000000000000 --- a/x-pack/plugins/synthetics/public/components/overview/monitor_list/monitor_list.test.tsx +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { waitFor } from '@testing-library/react'; -import { - MonitorSummariesResult, - CursorDirection, - SortOrder, - makePing, - Ping, - MonitorSummary, -} from '../../../../common/runtime_types'; -import { MonitorListComponent } from './monitor_list'; -import moment from 'moment'; -import { IHttpFetchError, ResponseErrorBody } from '@kbn/core/public'; -import { mockMoment } from '../../../lib/helper/test_helpers'; -import { render } from '../../../lib/helper/rtl_helpers'; -import { NO_DATA_MESSAGE } from './translations'; - -const testFooPings: Ping[] = [ - makePing({ - docId: 'foo1', - id: 'foo', - type: 'icmp', - status: 'up', - duration: 123, - timestamp: '124', - ip: '127.0.0.1', - }), - makePing({ - docId: 'foo2', - id: 'foo', - type: 'icmp', - status: 'up', - duration: 123, - timestamp: '125', - ip: '127.0.0.2', - }), - makePing({ - docId: 'foo3', - id: 'foo', - type: 'icmp', - status: 'down', - duration: 123, - timestamp: '126', - ip: '127.0.0.3', - }), -]; - -const testFooSummary: MonitorSummary = { - monitor_id: 'foo', - state: { - monitor: { type: 'http', duration: { us: 1000 } }, - summaryPings: testFooPings, - summary: { - up: 1, - down: 2, - }, - timestamp: '123', - url: {}, - }, -}; - -const testBarPings: Ping[] = [ - makePing({ - docId: 'bar1', - id: 'bar', - type: 'icmp', - status: 'down', - duration: 123, - timestamp: '125', - ip: '127.0.0.1', - }), - makePing({ - docId: 'bar2', - id: 'bar', - type: 'icmp', - status: 'down', - duration: 123, - timestamp: '126', - ip: '127.0.0.1', - }), -]; - -const testBarSummary: MonitorSummary = { - monitor_id: 'bar', - state: { - monitor: { type: 'http', duration: { us: 1000 } }, - summaryPings: testBarPings, - summary: { - up: 2, - down: 0, - }, - timestamp: '125', - url: {}, - }, -}; - -describe('MonitorList component', () => { - let localStorageMock: any; - - beforeAll(() => { - mockMoment(); - global.innerWidth = 1200; - - // Trigger the window resize event. - global.dispatchEvent(new Event('resize')); - }); - - const getMonitorList = (timestamp?: string): MonitorSummariesResult => { - if (timestamp) { - testBarSummary.state.timestamp = timestamp; - testFooSummary.state.timestamp = timestamp; - } else { - testBarSummary.state.timestamp = '125'; - testFooSummary.state.timestamp = '123'; - } - return { - nextPagePagination: null, - prevPagePagination: null, - summaries: [testFooSummary, testBarSummary], - }; - }; - - beforeEach(() => { - localStorageMock = { - getItem: jest.fn().mockImplementation(() => '25'), - setItem: jest.fn(), - }; - - global.localStorage = localStorageMock; - }); - - it('renders a no items message when no data is provided', async () => { - const { findByText } = render( - - ); - expect(await findByText(NO_DATA_MESSAGE)).toBeInTheDocument(); - }); - - it('renders the monitor list', async () => { - const { findByLabelText } = render( - - ); - - expect( - await findByLabelText( - 'Monitor Status table with columns for Status, Name, URL, IP, Downtime History and Integrations. The table is currently displaying 2 items.' - ) - ).toBeInTheDocument(); - }); - - it('renders error list', async () => { - const { findByText } = render( - , - loading: false, - }} - pageSize={10} - setPageSize={jest.fn()} - refreshedMonitorIds={[]} - /> - ); - - expect(await findByText('foo message')).toBeInTheDocument(); - }); - - describe('MonitorListPagination component', () => { - let paginationResult: MonitorSummariesResult; - - beforeEach(() => { - paginationResult = { - prevPagePagination: JSON.stringify({ - cursorKey: { monitor_id: 123 }, - cursorDirection: CursorDirection.BEFORE, - sortOrder: SortOrder.ASC, - }), - nextPagePagination: JSON.stringify({ - cursorKey: { monitor_id: 456 }, - cursorDirection: CursorDirection.AFTER, - sortOrder: SortOrder.ASC, - }), - summaries: [testFooSummary, testBarSummary], - }; - }); - - it('renders the pagination', async () => { - const { findByText, findByLabelText } = render( - - ); - - expect(await findByText('Rows per page: 10')).toBeInTheDocument(); - expect(await findByLabelText('Prev page of results')).toBeInTheDocument(); - expect(await findByLabelText('Next page of results')).toBeInTheDocument(); - }); - }); - - describe('responsive behavior', () => { - describe('xl screens', () => { - beforeAll(() => { - global.innerWidth = 1200; - - // Trigger the window resize event. - global.dispatchEvent(new Event('resize')); - }); - - it('shows ping histogram and expand button on xl and xxl screens', async () => { - const list = getMonitorList(moment().subtract(5, 'minute').toISOString()); - const { getByTestId, getByText } = render( - - ); - - await waitFor(() => { - expect( - getByTestId( - `xpack.uptime.monitorList.${list.summaries[0].monitor_id}.expandMonitorDetail` - ) - ).toBeInTheDocument(); - expect(getByText('Downtime history')).toBeInTheDocument(); - }); - }); - }); - - describe('large and medium screens', () => { - it('hides ping histogram and expand button on extra large screens', async () => { - global.innerWidth = 1199; - - // Trigger the window resize event. - global.dispatchEvent(new Event('resize')); - - const { queryByTestId, queryByText } = render( - - ); - - await waitFor(() => { - expect( - queryByTestId('xpack.uptime.monitorList.always-down.expandMonitorDetail') - ).not.toBeInTheDocument(); - expect(queryByText('Downtime history')).not.toBeInTheDocument(); - }); - }); - }); - }); -}); diff --git a/x-pack/plugins/synthetics/public/components/overview/monitor_list/monitor_list.tsx b/x-pack/plugins/synthetics/public/components/overview/monitor_list/monitor_list.tsx deleted file mode 100644 index f18f912e5231f..0000000000000 --- a/x-pack/plugins/synthetics/public/components/overview/monitor_list/monitor_list.tsx +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import React, { useState } from 'react'; -import useWindowSize from 'react-use/lib/useWindowSize'; -import useDebounce from 'react-use/lib/useDebounce'; -import { - EuiButtonIcon, - EuiBasicTable, - EuiFlexGroup, - EuiFlexItem, - EuiLink, - EuiPanel, - EuiSpacer, - getBreakpoint, -} from '@elastic/eui'; -import { euiStyled } from '@kbn/kibana-react-plugin/common'; -import { X509Expiry } from '../../../../common/runtime_types'; -import { MonitorSummary } from '../../../../common/runtime_types'; -import { MonitorListStatusColumn } from './columns/monitor_status_column'; -import { ExpandedRowMap } from './types'; -import { MonitorBarSeries } from '../../common/charts'; -import { OverviewPageLink } from './overview_page_link'; -import * as labels from './translations'; -import { MonitorListPageSizeSelect } from './monitor_list_page_size_select'; -import { MonitorListDrawer } from './monitor_list_drawer/list_drawer_container'; -import { MonitorListProps } from './monitor_list_container'; -import { MonitorList } from '../../../state/reducers/monitor_list'; -import { CertStatusColumn } from './columns/cert_status_column'; -import { MonitorListHeader } from './monitor_list_header'; -import { TAGS_LABEL, URL_LABEL } from '../../common/translations'; -import { EnableMonitorAlert } from './columns/enable_alert'; -import { STATUS_ALERT_COLUMN, TEST_NOW_COLUMN } from './translations'; -import { MonitorNameColumn } from './columns/monitor_name_col'; -import { MonitorTags } from '../../common/monitor_tags'; -import { useMonitorHistogram } from './use_monitor_histogram'; -import { TestNowColumn } from './columns/test_now_col'; -import { NoItemsMessage } from './no_items_message'; - -interface Props extends MonitorListProps { - pageSize: number; - setPageSize: (val: number) => void; - monitorList: MonitorList; - refreshedMonitorIds: string[]; -} - -export const MonitorListComponent: ({ - filters, - monitorList: { list, error, loading }, - pageSize, - refreshedMonitorIds, - setPageSize, -}: Props) => any = ({ - filters, - refreshedMonitorIds = [], - monitorList: { list, error, loading }, - pageSize, - setPageSize, -}) => { - const [expandedDrawerIds, updateExpandedDrawerIds] = useState([]); - const { width } = useWindowSize(); - const [hideExtraColumns, setHideExtraColumns] = useState(false); - - useDebounce( - () => { - setHideExtraColumns(['m', 'l'].includes(getBreakpoint(width) ?? '')); - }, - 50, - [width] - ); - - const items = list.summaries ?? []; - - const { histogramsById, minInterval } = useMonitorHistogram({ items }); - - const nextPagePagination = list.nextPagePagination ?? ''; - const prevPagePagination = list.prevPagePagination ?? ''; - - const toggleDrawer = (id: string) => { - if (expandedDrawerIds.includes(id)) { - updateExpandedDrawerIds(expandedDrawerIds.filter((p) => p !== id)); - } else { - updateExpandedDrawerIds([...expandedDrawerIds, id]); - } - }; - - const getExpandedRowMap = () => { - return expandedDrawerIds.reduce((map: ExpandedRowMap, id: string) => { - return { - ...map, - [id]: ( - monitorId === id)!} - /> - ), - }; - }, {}); - }; - - const columns = [ - ...[ - { - align: 'left' as const, - field: 'state.summary.status', - name: labels.STATUS_COLUMN_LABEL, - mobileOptions: { - fullWidth: true, - }, - render: ( - status: string, - { - monitor_id: monitorId, - state: { - timestamp, - summaryPings, - monitor: { type, duration, checkGroup }, - error: summaryError, - }, - configId, - }: MonitorSummary - ) => { - return ( - - ); - }, - }, - { - align: 'left' as const, - field: 'state.monitor.name', - name: labels.NAME_COLUMN_LABEL, - mobileOptions: { - fullWidth: true, - }, - render: (_name: string, summary: MonitorSummary) => , - sortable: true, - }, - { - align: 'left' as const, - field: 'state.url.full', - name: URL_LABEL, - width: '30%', - render: (url: string) => ( - - {url} - - ), - }, - { - align: 'left' as const, - field: 'state.monitor.name', - name: TAGS_LABEL, - width: '12%', - render: (_name: string, summary: MonitorSummary) => , - }, - { - align: 'left' as const, - field: 'state.tls.server.x509', - name: labels.TLS_COLUMN_LABEL, - render: (x509: X509Expiry) => , - }, - ], - ...(!hideExtraColumns - ? [ - { - align: 'left' as const, - field: 'monitor_id', - name: labels.HISTORY_COLUMN_LABEL, - mobileOptions: { - show: false, - }, - render: (monitorId: string) => ( - - ), - }, - ] - : []), - { - align: 'center' as const, - field: '', - name: STATUS_ALERT_COLUMN, - width: '100px', - render: (item: MonitorSummary) => ( - - ), - }, - { - align: 'center' as const, - field: '', - name: TEST_NOW_COLUMN, - width: '100px', - render: (item: MonitorSummary) => ( - - ), - }, - ...(!hideExtraColumns - ? [ - { - align: 'right' as const, - field: 'monitor_id', - name: '', - sortable: true, - isExpander: true, - width: '40px', - render: (id: string) => { - return ( - toggleDrawer(id)} - /> - ); - }, - }, - ] - : []), - ]; - - return ( - - - - } - columns={columns} - tableLayout={'auto'} - rowProps={ - hideExtraColumns - ? ({ monitor_id: monitorId }) => ({ - onClick: () => toggleDrawer(monitorId), - 'aria-label': labels.getExpandDrawerLabel(monitorId), - }) - : ({ monitor_id: monitorId }) => ({ - className: refreshedMonitorIds.includes(monitorId) ? 'refresh-row' : undefined, - }) - } - /> - - - - - - - - - - - - - - - - - - ); -}; - -const WrapperPanel = euiStyled(EuiPanel)` - &&& { - .refresh-row{ - background-color: #f0f4fb; - -webkit-transition: background-color 3000ms linear; - -ms-transition: background-color 3000ms linear; - transition: background-color 3000ms linear; - } - } -`; diff --git a/x-pack/plugins/synthetics/public/components/overview/monitor_list/status_filter.tsx b/x-pack/plugins/synthetics/public/components/overview/monitor_list/status_filter.tsx deleted file mode 100644 index b83a112ffd93e..0000000000000 --- a/x-pack/plugins/synthetics/public/components/overview/monitor_list/status_filter.tsx +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { i18n } from '@kbn/i18n'; -import { EuiFilterGroup } from '@elastic/eui'; -import { FilterStatusButton } from './filter_status_button'; -import { useGetUrlParams } from '../../../hooks'; -import { STATUS_DOWN_LABEL, STATUS_UP_LABEL } from '../../common/translations'; - -export const StatusFilter: React.FC = () => { - const { statusFilter } = useGetUrlParams(); - - // Empty string for all filter button value, since we dont store it in url, so keeping it in sync - const ALL = ''; - - return ( - - - - - - ); -}; diff --git a/x-pack/plugins/synthetics/public/components/overview/monitor_list/translations.ts b/x-pack/plugins/synthetics/public/components/overview/monitor_list/translations.ts deleted file mode 100644 index ba006884a42cb..0000000000000 --- a/x-pack/plugins/synthetics/public/components/overview/monitor_list/translations.ts +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const STATUS_COLUMN_LABEL = i18n.translate('xpack.uptime.monitorList.statusColumnLabel', { - defaultMessage: 'Status', -}); - -export const NAME_COLUMN_LABEL = i18n.translate('xpack.uptime.monitorList.nameColumnLabel', { - defaultMessage: 'Name', -}); - -export const HISTORY_COLUMN_LABEL = i18n.translate( - 'xpack.uptime.monitorList.monitorHistoryColumnLabel', - { - defaultMessage: 'Downtime history', - } -); - -export const TLS_COLUMN_LABEL = i18n.translate('xpack.uptime.monitorList.tlsColumnLabel', { - defaultMessage: 'TLS Certificate', -}); - -export const getExpandDrawerLabel = (id: string) => { - return i18n.translate('xpack.uptime.monitorList.expandDrawerButton.ariaLabel', { - defaultMessage: 'Expand row for monitor with ID {id}', - description: 'The user can click a button on this table and expand further details.', - values: { - id, - }, - }); -}; - -export const getDescriptionLabel = (itemsLength: number) => { - return i18n.translate('xpack.uptime.monitorList.table.description', { - defaultMessage: - 'Monitor Status table with columns for Status, Name, URL, IP, Downtime History and Integrations. The table is currently displaying {length} items.', - values: { length: itemsLength }, - }); -}; - -export const NO_MONITOR_ITEM_SELECTED = i18n.translate( - 'xpack.uptime.monitorList.noItemForSelectedFiltersMessage', - { - defaultMessage: 'No monitors found for selected filter criteria', - description: - 'This message is show if there are no monitors in the table and some filter or search criteria exists', - } -); - -export const LOADING = i18n.translate('xpack.uptime.monitorList.loading', { - defaultMessage: 'Loading...', - description: 'Shown when the monitor list is waiting for a server response', -}); - -export const NO_DATA_MESSAGE = i18n.translate('xpack.uptime.monitorList.noItemMessage', { - defaultMessage: 'No uptime monitors found', - description: 'This message is shown if the monitors table is rendered but has no items.', -}); - -export const RESPONSE_ANOMALY_SCORE = i18n.translate( - 'xpack.uptime.monitorList.anomalyColumn.label', - { - defaultMessage: 'Response Anomaly Score', - } -); - -export const STATUS_ALERT_COLUMN = i18n.translate('xpack.uptime.monitorList.statusAlert.label', { - defaultMessage: 'Status alert', -}); - -export const TEST_NOW_COLUMN = i18n.translate('xpack.uptime.monitorList.testNow.label', { - defaultMessage: 'Test now', -}); diff --git a/x-pack/plugins/synthetics/public/components/overview/query_bar/query_bar.tsx b/x-pack/plugins/synthetics/public/components/overview/query_bar/query_bar.tsx deleted file mode 100644 index d6d864ed312af..0000000000000 --- a/x-pack/plugins/synthetics/public/components/overview/query_bar/query_bar.tsx +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useState } from 'react'; -import { i18n } from '@kbn/i18n'; -import { EuiFlexItem } from '@elastic/eui'; -import { QueryStringInput } from '@kbn/unified-search-plugin/public'; -import { SyntaxType, useQueryBar } from './use_query_bar'; -import { KQL_PLACE_HOLDER, SIMPLE_SEARCH_PLACEHOLDER } from './translations'; -import { useGetUrlParams, useIndexPattern } from '../../../hooks'; - -const SYNTAX_STORAGE = 'uptime:queryBarSyntax'; - -export const isValidKuery = (query: string) => { - if (query === '') { - return true; - } - const listOfOperators = [':', '>=', '=>', '>', '<']; - for (let i = 0; i < listOfOperators.length; i++) { - const operator = listOfOperators[i]; - const qParts = query.trim().split(operator); - if (query.includes(operator) && qParts.length > 1 && qParts[1]) { - return true; - } - } - return false; -}; - -export const QueryBar = () => { - const { search: urlValue } = useGetUrlParams(); - - const { query, setQuery, submitImmediately } = useQueryBar(); - - const indexPattern = useIndexPattern(); - - const [inputVal, setInputVal] = useState(query.query as string); - - const isInValid = () => { - if (query.language === SyntaxType.text) { - return false; - } - return inputVal?.trim() !== urlValue?.trim(); - }; - - return ( - - { - if (queryN?.language === SyntaxType.text) { - setQuery({ query: queryN.query as string, language: queryN.language }); - } - if (queryN?.language === SyntaxType.kuery && isValidKuery(queryN?.query as string)) { - // we want to submit when user clears or paste a complete kuery - setQuery({ query: queryN.query as string, language: queryN.language }); - } - setInputVal(queryN?.query as string); - }} - onSubmit={(queryN) => { - if (queryN) setQuery({ query: queryN.query as string, language: queryN.language }); - submitImmediately(); - }} - query={{ ...query, query: inputVal }} - aria-label={i18n.translate('xpack.uptime.filterBar.ariaLabel', { - defaultMessage: 'Input filter criteria for the overview page', - })} - data-test-subj="uptimeSearchBarInput" - autoSubmit={true} - storageKey={SYNTAX_STORAGE} - placeholder={ - query.language === SyntaxType.kuery ? KQL_PLACE_HOLDER : SIMPLE_SEARCH_PLACEHOLDER - } - isInvalid={isInValid()} - /> - - ); -}; diff --git a/x-pack/plugins/synthetics/public/components/overview/query_bar/translations.ts b/x-pack/plugins/synthetics/public/components/overview/query_bar/translations.ts deleted file mode 100644 index 6bb4ebbf098a9..0000000000000 --- a/x-pack/plugins/synthetics/public/components/overview/query_bar/translations.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const KQL_PLACE_HOLDER = i18n.translate('xpack.uptime.kueryBar.searchPlaceholder.kql', { - defaultMessage: - 'Search using kql syntax for monitor IDs, names and type etc (E.g monitor.type: "http" AND tags: "dev")', -}); - -export const SIMPLE_SEARCH_PLACEHOLDER = i18n.translate( - 'xpack.uptime.kueryBar.searchPlaceholder.simple', - { - defaultMessage: 'Search by monitor ID, name, or url (E.g. http:// )', - } -); diff --git a/x-pack/plugins/synthetics/public/components/settings/translations.ts b/x-pack/plugins/synthetics/public/components/settings/translations.ts deleted file mode 100644 index 1a0692f1f45bf..0000000000000 --- a/x-pack/plugins/synthetics/public/components/settings/translations.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const certificateFormTranslations = { - ageInputAriaLabel: i18n.translate( - 'xpack.uptime.sourceConfiguration.ageLimitThresholdInput.ariaLabel', - { - defaultMessage: - 'An input that controls the maximum number of days for which a TLS certificate may be valid before Kibana will show a warning.', - } - ), - expirationInputAriaLabel: i18n.translate( - 'xpack.uptime.sourceConfiguration.certificateExpirationThresholdInput.ariaLabel', - { - defaultMessage: - 'An input that controls the minimum number of days remaining for TLS certificate expiration before Kibana will show a warning.', - } - ), -}; - -export const alertFormI18n = { - inputPlaceHolder: i18n.translate( - 'xpack.uptime.sourceConfiguration.alertDefaultForm.selectConnector', - { - defaultMessage: 'Please select one or more connectors', - } - ), - emailPlaceHolder: i18n.translate( - 'xpack.uptime.sourceConfiguration.alertDefaultForm.emailConnectorPlaceHolder', - { - defaultMessage: 'To: Email for email connector', - } - ), -}; diff --git a/x-pack/plugins/synthetics/public/components/synthetics/status_badge.tsx b/x-pack/plugins/synthetics/public/components/synthetics/status_badge.tsx deleted file mode 100644 index f97c0eab32b55..0000000000000 --- a/x-pack/plugins/synthetics/public/components/synthetics/status_badge.tsx +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import React, { useContext, FC } from 'react'; -import { UptimeAppColors } from '../../apps/uptime_app'; -import { UptimeThemeContext } from '../../contexts'; - -interface StatusBadgeProps { - isMobile?: boolean; - status?: string; - stepNo: number; -} - -export function colorFromStatus(color: UptimeAppColors, status?: string) { - switch (status) { - case 'succeeded': - return color.success; - case 'failed': - return color.dangerBehindText; - default: - return 'default'; - } -} - -export function textFromStatus(status?: string) { - switch (status) { - case 'succeeded': - return i18n.translate('xpack.uptime.synthetics.statusBadge.succeededMessage', { - defaultMessage: 'Succeeded', - }); - case 'failed': - return i18n.translate('xpack.uptime.synthetics.statusBadge.failedMessage', { - defaultMessage: 'Failed', - }); - case 'skipped': - return i18n.translate('xpack.uptime.synthetics.statusBadge.skippedMessage', { - defaultMessage: 'Skipped', - }); - default: - return null; - } -} - -export const StatusBadge: FC = ({ status, stepNo, isMobile }) => { - const theme = useContext(UptimeThemeContext); - return ( - - {!isMobile && ( - - - {stepNo}. - - - )} - - {textFromStatus(status)} - - - ); -}; diff --git a/x-pack/plugins/synthetics/public/components/synthetics/translations.ts b/x-pack/plugins/synthetics/public/components/synthetics/translations.ts deleted file mode 100644 index 743118574b325..0000000000000 --- a/x-pack/plugins/synthetics/public/components/synthetics/translations.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const STEP_NAME_LABEL = i18n.translate('xpack.uptime.stepList.stepName', { - defaultMessage: 'Step name', -}); - -export const COLLAPSE_LABEL = i18n.translate('xpack.uptime.stepList.collapseRow', { - defaultMessage: 'Collapse', -}); - -export const EXPAND_LABEL = i18n.translate('xpack.uptime.stepList.expandRow', { - defaultMessage: 'Expand', -}); diff --git a/x-pack/plugins/synthetics/public/contexts/uptime_index_pattern_context.tsx b/x-pack/plugins/synthetics/public/contexts/uptime_index_pattern_context.tsx deleted file mode 100644 index 765d9f8527c88..0000000000000 --- a/x-pack/plugins/synthetics/public/contexts/uptime_index_pattern_context.tsx +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { createContext, useContext } from 'react'; -import { useFetcher } from '@kbn/observability-plugin/public'; -import { DataPublicPluginStart, IndexPattern } from '@kbn/data-plugin/public'; -import { useHasData } from '../components/overview/empty_state/use_has_data'; - -export const UptimeIndexPatternContext = createContext({} as IndexPattern); - -export const UptimeIndexPatternContextProvider: React.FC<{ data: DataPublicPluginStart }> = ({ - children, - data: { indexPatterns }, -}) => { - const { settings, data: indexStatus } = useHasData(); - - const heartbeatIndices = settings?.heartbeatIndices || ''; - - const { data } = useFetcher>(async () => { - if (heartbeatIndices && indexStatus?.indexExists) { - // this only creates an index pattern in memory, not as saved object - return indexPatterns.create({ title: heartbeatIndices }); - } - }, [heartbeatIndices, indexStatus?.indexExists]); - - return ; -}; - -export const useIndexPattern = () => useContext(UptimeIndexPatternContext); diff --git a/x-pack/plugins/synthetics/public/hooks/index.ts b/x-pack/plugins/synthetics/public/hooks/index.ts deleted file mode 100644 index e96d746a05514..0000000000000 --- a/x-pack/plugins/synthetics/public/hooks/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export * from './use_composite_image'; -export * from './update_kuery_string'; -export * from './use_monitor'; -export * from './use_search_text'; -export * from './use_cert_status'; -export * from './use_telemetry'; -export * from './use_url_params'; -export * from './use_breakpoints'; -export { useIndexPattern } from '../contexts/uptime_index_pattern_context'; diff --git a/x-pack/plugins/synthetics/public/icons/heartbeat_white.svg b/x-pack/plugins/synthetics/public/icons/heartbeat_white.svg deleted file mode 100644 index 866206f32f5a1..0000000000000 --- a/x-pack/plugins/synthetics/public/icons/heartbeat_white.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - \ No newline at end of file diff --git a/x-pack/plugins/synthetics/public/index.ts b/x-pack/plugins/synthetics/public/index.ts index 86170e9bc863a..cc0ad290e6f0a 100644 --- a/x-pack/plugins/synthetics/public/index.ts +++ b/x-pack/plugins/synthetics/public/index.ts @@ -6,7 +6,7 @@ */ import { PluginInitializerContext } from '@kbn/core/public'; -import { UptimePlugin } from './apps/plugin'; +import { UptimePlugin } from './plugin'; export const plugin = (initializerContext: PluginInitializerContext) => new UptimePlugin(initializerContext); diff --git a/x-pack/plugins/synthetics/public/apps/__snapshots__/uptime_page_template.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/app/__snapshots__/uptime_page_template.test.tsx.snap similarity index 100% rename from x-pack/plugins/synthetics/public/apps/__snapshots__/uptime_page_template.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/app/__snapshots__/uptime_page_template.test.tsx.snap diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/app/render_app.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/app/render_app.tsx new file mode 100644 index 0000000000000..efb35813201ae --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/app/render_app.tsx @@ -0,0 +1,82 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import ReactDOM from 'react-dom'; +import { i18n as i18nFormatter } from '@kbn/i18n'; +import { AppMountParameters, CoreStart } from '@kbn/core/public'; +import { getIntegratedAppAvailability } from '../lib/adapters/framework/capabilities_adapter'; +import { + DEFAULT_DARK_MODE, + DEFAULT_TIMEPICKER_QUICK_RANGES, + INTEGRATED_SOLUTIONS, +} from '../../../common/constants'; +import { UptimeApp, UptimeAppProps } from './uptime_app'; +import { ClientPluginsSetup, ClientPluginsStart } from '../../plugin'; + +export function renderApp( + core: CoreStart, + plugins: ClientPluginsSetup, + startPlugins: ClientPluginsStart, + appMountParameters: AppMountParameters, + isDev: boolean +) { + const { + application: { capabilities }, + chrome: { setBadge, setHelpExtension }, + docLinks, + http: { basePath }, + i18n, + } = core; + + const { apm, infrastructure, logs } = getIntegratedAppAvailability( + capabilities, + INTEGRATED_SOLUTIONS + ); + + const canSave = (capabilities.uptime.save ?? false) as boolean; + + const props: UptimeAppProps = { + isDev, + plugins, + canSave, + core, + i18n, + startPlugins, + basePath: basePath.get(), + darkMode: core.uiSettings.get(DEFAULT_DARK_MODE), + commonlyUsedRanges: core.uiSettings.get(DEFAULT_TIMEPICKER_QUICK_RANGES), + isApmAvailable: apm, + isInfraAvailable: infrastructure, + isLogsAvailable: logs, + renderGlobalHelpControls: () => + setHelpExtension({ + appName: i18nFormatter.translate('xpack.synthetics.header.appName', { + defaultMessage: 'Uptime', + }), + links: [ + { + linkType: 'documentation', + href: `${docLinks.links.observability.monitorUptime}`, + }, + { + linkType: 'discuss', + href: 'https://discuss.elastic.co/c/uptime', + }, + ], + }), + setBadge, + appMountParameters, + setBreadcrumbs: core.chrome.setBreadcrumbs, + }; + + ReactDOM.render(, appMountParameters.element); + + return () => { + ReactDOM.unmountComponentAtNode(appMountParameters.element); + }; +} diff --git a/x-pack/plugins/synthetics/public/apps/uptime_app.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/app/uptime_app.tsx similarity index 91% rename from x-pack/plugins/synthetics/public/apps/uptime_app.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/app/uptime_app.tsx index b106123de1b29..8d694bfe81aed 100644 --- a/x-pack/plugins/synthetics/public/apps/uptime_app.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/app/uptime_app.tsx @@ -18,7 +18,7 @@ import { } from '@kbn/kibana-react-plugin/public'; import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; import { InspectorContextProvider } from '@kbn/observability-plugin/public'; -import { ClientPluginsSetup, ClientPluginsStart } from './plugin'; +import { ClientPluginsSetup, ClientPluginsStart } from '../../plugin'; import { UMUpdateBadge } from '../lib/lib'; import { UptimeRefreshContextProvider, @@ -33,7 +33,7 @@ import { UptimeAlertsFlyoutWrapper } from '../components/overview'; import { store, storage } from '../state'; import { kibanaService } from '../state/kibana_service'; import { ActionMenu } from '../components/common/header/action_menu'; -import { UptimeIndexPatternContextProvider } from '../contexts/uptime_index_pattern_context'; +import { UptimeDataViewContextProvider } from '../contexts/uptime_data_view_context'; export interface UptimeAppColors { danger: string; @@ -84,10 +84,10 @@ const Application = (props: UptimeAppProps) => { setBadge( !canSave ? { - text: i18n.translate('xpack.uptime.badge.readOnly.text', { + text: i18n.translate('xpack.synthetics.badge.readOnly.text', { defaultMessage: 'Read only', }), - tooltip: i18n.translate('xpack.uptime.badge.readOnly.tooltip', { + tooltip: i18n.translate('xpack.synthetics.badge.readOnly.tooltip', { defaultMessage: 'Unable to save', }), iconType: 'glasses', @@ -124,7 +124,7 @@ const Application = (props: UptimeAppProps) => { - +
{
-
+
diff --git a/x-pack/plugins/synthetics/public/apps/uptime_overview_fetcher.ts b/x-pack/plugins/synthetics/public/legacy_uptime/app/uptime_overview_fetcher.ts similarity index 100% rename from x-pack/plugins/synthetics/public/apps/uptime_overview_fetcher.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/app/uptime_overview_fetcher.ts diff --git a/x-pack/plugins/synthetics/public/apps/uptime_page_template.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/app/uptime_page_template.test.tsx similarity index 96% rename from x-pack/plugins/synthetics/public/apps/uptime_page_template.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/app/uptime_page_template.test.tsx index 26a40074c7530..38105052f352e 100644 --- a/x-pack/plugins/synthetics/public/apps/uptime_page_template.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/app/uptime_page_template.test.tsx @@ -10,7 +10,7 @@ import React from 'react'; import 'jest-styled-components'; import { render } from '../lib/helper/rtl_helpers'; import { UptimePageTemplateComponent } from './uptime_page_template'; -import { OVERVIEW_ROUTE } from '../../common/constants'; +import { OVERVIEW_ROUTE } from '../../../common/constants'; import { useBreakpoints } from '../hooks/use_breakpoints'; jest.mock('../hooks/use_breakpoints', () => { diff --git a/x-pack/plugins/synthetics/public/apps/uptime_page_template.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/app/uptime_page_template.tsx similarity index 95% rename from x-pack/plugins/synthetics/public/apps/uptime_page_template.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/app/uptime_page_template.tsx index e359916de1d22..08ebd5f06a69b 100644 --- a/x-pack/plugins/synthetics/public/apps/uptime_page_template.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/app/uptime_page_template.tsx @@ -10,8 +10,8 @@ import styled from 'styled-components'; import { EuiPageHeaderProps, EuiPageTemplateProps } from '@elastic/eui'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { useInspectorContext } from '@kbn/observability-plugin/public'; -import { CERTIFICATES_ROUTE, OVERVIEW_ROUTE } from '../../common/constants'; -import { ClientPluginsStart } from './plugin'; +import { CERTIFICATES_ROUTE, OVERVIEW_ROUTE } from '../../../common/constants'; +import { ClientPluginsStart } from '../../plugin'; import { useNoDataConfig } from './use_no_data_config'; import { EmptyStateLoading } from '../components/overview/empty_state/empty_state_loading'; import { EmptyStateError } from '../components/overview/empty_state/empty_state_error'; diff --git a/x-pack/plugins/synthetics/public/apps/use_no_data_config.ts b/x-pack/plugins/synthetics/public/legacy_uptime/app/use_no_data_config.ts similarity index 82% rename from x-pack/plugins/synthetics/public/apps/use_no_data_config.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/app/use_no_data_config.ts index 1424d4047b6f0..c485c498e6fa7 100644 --- a/x-pack/plugins/synthetics/public/apps/use_no_data_config.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/app/use_no_data_config.ts @@ -10,7 +10,7 @@ import { useContext } from 'react'; import { useSelector } from 'react-redux'; import { KibanaPageTemplateProps, useKibana } from '@kbn/kibana-react-plugin/public'; import { UptimeSettingsContext } from '../contexts'; -import { ClientPluginsStart } from './plugin'; +import { ClientPluginsStart } from '../../plugin'; import { indexStatusSelector } from '../state/selectors'; export function useNoDataConfig(): KibanaPageTemplateProps['noDataConfig'] { @@ -25,15 +25,15 @@ export function useNoDataConfig(): KibanaPageTemplateProps['noDataConfig'] { // Returns no data config when there is no historical data if (data && !data.indexExists) { return { - solution: i18n.translate('xpack.uptime.noDataConfig.solutionName', { + solution: i18n.translate('xpack.synthetics.noDataConfig.solutionName', { defaultMessage: 'Observability', }), actions: { beats: { - title: i18n.translate('xpack.uptime.noDataConfig.beatsCard.title', { + title: i18n.translate('xpack.synthetics.noDataConfig.beatsCard.title', { defaultMessage: 'Add monitors with Heartbeat', }), - description: i18n.translate('xpack.uptime.noDataConfig.beatsCard.description', { + description: i18n.translate('xpack.synthetics.noDataConfig.beatsCard.description', { defaultMessage: 'Proactively monitor the availability of your sites and services. Receive alerts and resolve issues faster to optimize your users experience.', }), diff --git a/x-pack/plugins/synthetics/public/components/certificates/__snapshots__/cert_monitors.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/__snapshots__/cert_monitors.test.tsx.snap similarity index 100% rename from x-pack/plugins/synthetics/public/components/certificates/__snapshots__/cert_monitors.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/__snapshots__/cert_monitors.test.tsx.snap diff --git a/x-pack/plugins/synthetics/public/components/certificates/__snapshots__/cert_search.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/__snapshots__/cert_search.test.tsx.snap similarity index 100% rename from x-pack/plugins/synthetics/public/components/certificates/__snapshots__/cert_search.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/__snapshots__/cert_search.test.tsx.snap diff --git a/x-pack/plugins/synthetics/public/components/certificates/__snapshots__/cert_status.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/__snapshots__/cert_status.test.tsx.snap similarity index 100% rename from x-pack/plugins/synthetics/public/components/certificates/__snapshots__/cert_status.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/__snapshots__/cert_status.test.tsx.snap diff --git a/x-pack/plugins/synthetics/public/components/certificates/cert_monitors.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/cert_monitors.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/certificates/cert_monitors.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/cert_monitors.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/certificates/cert_monitors.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/cert_monitors.tsx similarity index 93% rename from x-pack/plugins/synthetics/public/components/certificates/cert_monitors.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/cert_monitors.tsx index 30b8b572c783f..0688aae060fba 100644 --- a/x-pack/plugins/synthetics/public/components/certificates/cert_monitors.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/cert_monitors.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { EuiToolTip } from '@elastic/eui'; -import { CertMonitor } from '../../../common/runtime_types'; +import { CertMonitor } from '../../../../common/runtime_types'; import { MonitorPageLink } from '../common/monitor_page_link'; interface Props { diff --git a/x-pack/plugins/synthetics/public/components/certificates/cert_refresh_btn.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/cert_refresh_btn.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/certificates/cert_refresh_btn.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/cert_refresh_btn.tsx diff --git a/x-pack/plugins/synthetics/public/components/certificates/cert_search.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/cert_search.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/certificates/cert_search.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/cert_search.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/certificates/cert_search.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/cert_search.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/certificates/cert_search.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/cert_search.tsx diff --git a/x-pack/plugins/synthetics/public/components/certificates/cert_status.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/cert_status.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/certificates/cert_status.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/cert_status.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/certificates/cert_status.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/cert_status.tsx similarity index 93% rename from x-pack/plugins/synthetics/public/components/certificates/cert_status.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/cert_status.tsx index 30bbb241205e5..ec11fc240d6a1 100644 --- a/x-pack/plugins/synthetics/public/components/certificates/cert_status.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/cert_status.tsx @@ -11,10 +11,10 @@ import styled from 'styled-components'; import { EuiHealth, EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { useSelector } from 'react-redux'; -import { Cert } from '../../../common/runtime_types'; +import { Cert } from '../../../../common/runtime_types'; import { useCertStatus } from '../../hooks'; import * as labels from './translations'; -import { CERT_STATUS } from '../../../common/constants'; +import { CERT_STATUS } from '../../../../common/constants'; import { selectDynamicSettings } from '../../state/selectors'; interface Props { @@ -86,7 +86,7 @@ export const CertStatus: React.FC = ({ cert }) => { {' '} { return ( {total ?? 0}, diff --git a/x-pack/plugins/synthetics/public/components/certificates/certificates_list.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/certificates_list.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/certificates/certificates_list.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/certificates_list.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/certificates/certificates_list.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/certificates_list.tsx similarity index 97% rename from x-pack/plugins/synthetics/public/components/certificates/certificates_list.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/certificates_list.tsx index 44d314b52356f..381ee9cd5b792 100644 --- a/x-pack/plugins/synthetics/public/components/certificates/certificates_list.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/certificates_list.tsx @@ -11,7 +11,7 @@ import { Direction, EuiBasicTable } from '@elastic/eui'; import { CertStatus } from './cert_status'; import { CertMonitors } from './cert_monitors'; import * as labels from './translations'; -import { Cert, CertMonitor, CertResult } from '../../../common/runtime_types'; +import { Cert, CertMonitor, CertResult } from '../../../../common/runtime_types'; import { FingerprintCol } from './fingerprint_col'; import { LOADING_CERTIFICATES, NO_CERTS_AVAILABLE } from './translations'; diff --git a/x-pack/plugins/synthetics/public/components/certificates/fingerprint_col.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/fingerprint_col.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/certificates/fingerprint_col.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/fingerprint_col.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/certificates/fingerprint_col.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/fingerprint_col.tsx similarity index 96% rename from x-pack/plugins/synthetics/public/components/certificates/fingerprint_col.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/fingerprint_col.tsx index fa29c0b7d1e43..dac9f239eb104 100644 --- a/x-pack/plugins/synthetics/public/components/certificates/fingerprint_col.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/fingerprint_col.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { EuiButtonEmpty, EuiButtonIcon, EuiCopy, EuiToolTip } from '@elastic/eui'; import styled from 'styled-components'; -import { Cert } from '../../../common/runtime_types'; +import { Cert } from '../../../../common/runtime_types'; import { COPY_FINGERPRINT } from './translations'; const EmptyButton = styled(EuiButtonEmpty)` diff --git a/x-pack/plugins/synthetics/public/components/certificates/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/index.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/certificates/index.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/index.ts diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/translations.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/translations.ts new file mode 100644 index 0000000000000..7b7c3205cfc08 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/translations.ts @@ -0,0 +1,76 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const OK = i18n.translate('xpack.synthetics.certs.ok', { + defaultMessage: 'OK', +}); + +export const EXPIRED = i18n.translate('xpack.synthetics.certs.expired', { + defaultMessage: 'Expired', +}); + +export const EXPIRES_SOON = i18n.translate('xpack.synthetics.certs.expireSoon', { + defaultMessage: 'Expires soon', +}); + +export const EXPIRES = i18n.translate('xpack.synthetics.certs.expires', { + defaultMessage: 'Expires', +}); + +export const SEARCH_CERTS = i18n.translate('xpack.synthetics.certs.searchCerts', { + defaultMessage: 'Search certificates', +}); + +export const STATUS_COL = i18n.translate('xpack.synthetics.certs.list.status', { + defaultMessage: 'Status', +}); + +export const TOO_OLD = i18n.translate('xpack.synthetics.certs.list.status.old', { + defaultMessage: 'Too old', +}); + +export const COMMON_NAME_COL = i18n.translate('xpack.synthetics.certs.list.commonName', { + defaultMessage: 'Common name', +}); + +export const MONITORS_COL = i18n.translate('xpack.synthetics.certs.list.monitors', { + defaultMessage: 'Monitors', +}); + +export const ISSUED_BY_COL = i18n.translate('xpack.synthetics.certs.list.issuedBy', { + defaultMessage: 'Issued by', +}); + +export const VALID_UNTIL_COL = i18n.translate('xpack.synthetics.certs.list.validUntil', { + defaultMessage: 'Valid until', +}); + +export const AGE_COL = i18n.translate('xpack.synthetics.certs.list.ageCol', { + defaultMessage: 'Age', +}); + +export const DAYS = i18n.translate('xpack.synthetics.certs.list.days', { + defaultMessage: 'days', +}); + +export const FINGERPRINTS_COL = i18n.translate('xpack.synthetics.certs.list.expirationDate', { + defaultMessage: 'Fingerprints', +}); + +export const COPY_FINGERPRINT = i18n.translate('xpack.synthetics.certs.list.copyFingerprint', { + defaultMessage: 'Click to copy fingerprint value', +}); + +export const NO_CERTS_AVAILABLE = i18n.translate('xpack.synthetics.certs.list.empty', { + defaultMessage: 'No Certificates found. Note: Certificates are only visible for Heartbeat 7.8+', +}); + +export const LOADING_CERTIFICATES = i18n.translate('xpack.synthetics.certificates.loading', { + defaultMessage: 'Loading certificates ...', +}); diff --git a/x-pack/plugins/synthetics/public/components/certificates/use_cert_search.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/use_cert_search.ts similarity index 91% rename from x-pack/plugins/synthetics/public/components/certificates/use_cert_search.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/use_cert_search.ts index 47facebe4401f..4a13a7fc68d15 100644 --- a/x-pack/plugins/synthetics/public/components/certificates/use_cert_search.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/certificates/use_cert_search.ts @@ -9,7 +9,7 @@ import { useSelector } from 'react-redux'; import { useContext } from 'react'; import { createEsParams, useEsSearch } from '@kbn/observability-plugin/public'; -import { CertResult, GetCertsParams, Ping } from '../../../common/runtime_types'; +import { CertResult, GetCertsParams, Ping } from '../../../../common/runtime_types'; import { selectDynamicSettings } from '../../state/selectors'; import { @@ -20,7 +20,7 @@ import { DEFAULT_TO, getCertsRequestBody, processCertsResult, -} from '../../../common/requests/get_certs_request_body'; +} from '../../../../common/requests/get_certs_request_body'; import { UptimeRefreshContext } from '../../contexts'; export const useCertSearch = ({ diff --git a/x-pack/plugins/synthetics/public/components/common/__snapshots__/location_link.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/__snapshots__/location_link.test.tsx.snap similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/__snapshots__/location_link.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/__snapshots__/location_link.test.tsx.snap diff --git a/x-pack/plugins/synthetics/public/components/common/__snapshots__/monitor_page_link.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/__snapshots__/monitor_page_link.test.tsx.snap similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/__snapshots__/monitor_page_link.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/__snapshots__/monitor_page_link.test.tsx.snap diff --git a/x-pack/plugins/synthetics/public/components/common/__snapshots__/monitor_tags.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/__snapshots__/monitor_tags.test.tsx.snap similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/__snapshots__/monitor_tags.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/__snapshots__/monitor_tags.test.tsx.snap diff --git a/x-pack/plugins/synthetics/public/components/common/alerts/uptime_edit_alert_flyout.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/alerts/uptime_edit_alert_flyout.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/alerts/uptime_edit_alert_flyout.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/alerts/uptime_edit_alert_flyout.tsx diff --git a/x-pack/plugins/synthetics/public/components/common/charts/__snapshots__/chart_empty_state.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/__snapshots__/chart_empty_state.test.tsx.snap similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/charts/__snapshots__/chart_empty_state.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/__snapshots__/chart_empty_state.test.tsx.snap diff --git a/x-pack/plugins/synthetics/public/components/common/charts/__snapshots__/chart_wrapper.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/__snapshots__/chart_wrapper.test.tsx.snap similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/charts/__snapshots__/chart_wrapper.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/__snapshots__/chart_wrapper.test.tsx.snap diff --git a/x-pack/plugins/synthetics/public/components/common/charts/__snapshots__/donut_chart.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/__snapshots__/donut_chart.test.tsx.snap similarity index 98% rename from x-pack/plugins/synthetics/public/components/common/charts/__snapshots__/donut_chart.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/__snapshots__/donut_chart.test.tsx.snap index 320a64617807a..19d20244e2ccf 100644 --- a/x-pack/plugins/synthetics/public/components/common/charts/__snapshots__/donut_chart.test.tsx.snap +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/__snapshots__/donut_chart.test.tsx.snap @@ -812,13 +812,13 @@ exports[`DonutChart component renders a donut chart 1`] = ` Down 32 @@ -854,13 +854,13 @@ exports[`DonutChart component renders a donut chart 1`] = ` Up 95 @@ -967,13 +967,13 @@ exports[`DonutChart component renders a green check when all monitors are up 1`] Down 0 @@ -1009,13 +1009,13 @@ exports[`DonutChart component renders a green check when all monitors are up 1`] Up 95 diff --git a/x-pack/plugins/synthetics/public/components/common/charts/__snapshots__/donut_chart_legend_row.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/__snapshots__/donut_chart_legend_row.test.tsx.snap similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/charts/__snapshots__/donut_chart_legend_row.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/__snapshots__/donut_chart_legend_row.test.tsx.snap diff --git a/x-pack/plugins/synthetics/public/components/common/charts/__snapshots__/monitor_bar_series.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/__snapshots__/monitor_bar_series.test.tsx.snap similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/charts/__snapshots__/monitor_bar_series.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/__snapshots__/monitor_bar_series.test.tsx.snap diff --git a/x-pack/plugins/synthetics/public/components/common/charts/annotation_tooltip.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/annotation_tooltip.tsx similarity index 92% rename from x-pack/plugins/synthetics/public/components/common/charts/annotation_tooltip.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/annotation_tooltip.tsx index 50a8760c10af0..68269c016ab0b 100644 --- a/x-pack/plugins/synthetics/public/components/common/charts/annotation_tooltip.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/annotation_tooltip.tsx @@ -39,14 +39,14 @@ export const AnnotationTooltip = ({ details }: { details: string }) => { {moment(data.time).format('lll')}
diff --git a/x-pack/plugins/synthetics/public/components/common/charts/chart_empty_state.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/chart_empty_state.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/charts/chart_empty_state.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/chart_empty_state.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/common/charts/chart_empty_state.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/chart_empty_state.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/charts/chart_empty_state.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/chart_empty_state.tsx diff --git a/x-pack/plugins/synthetics/public/components/common/charts/chart_wrapper.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/chart_wrapper.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/charts/chart_wrapper.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/chart_wrapper.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/common/charts/chart_wrapper/chart_wrapper.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/chart_wrapper/chart_wrapper.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/charts/chart_wrapper/chart_wrapper.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/chart_wrapper/chart_wrapper.tsx diff --git a/x-pack/plugins/synthetics/public/components/common/charts/chart_wrapper/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/chart_wrapper/index.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/charts/chart_wrapper/index.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/chart_wrapper/index.ts diff --git a/x-pack/plugins/synthetics/public/components/common/charts/donut_chart.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/donut_chart.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/charts/donut_chart.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/donut_chart.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/common/charts/donut_chart.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/donut_chart.tsx similarity index 96% rename from x-pack/plugins/synthetics/public/components/common/charts/donut_chart.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/donut_chart.tsx index 3638b52e39783..457819c5448c3 100644 --- a/x-pack/plugins/synthetics/public/components/common/charts/donut_chart.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/donut_chart.tsx @@ -52,7 +52,7 @@ export const DonutChart = ({ height, down, up }: DonutChartProps) => { { + it('applies valid props as expected', () => { + const up = 45; + const down = 23; + const component = renderWithIntl(); + + expect( + component.find('[data-test-subj="xpack.synthetics.snapshot.donutChart.up.label"]').text() + ).toBe(STATUS_UP_LABEL); + expect( + component.find('[data-test-subj="xpack.synthetics.snapshot.donutChart.up"]').text() + ).toBe(`${up}`); + expect( + component.find('[data-test-subj="xpack.synthetics.snapshot.donutChart.down.label"]').text() + ).toBe(STATUS_DOWN_LABEL); + expect( + component.find('[data-test-subj="xpack.synthetics.snapshot.donutChart.down"]').text() + ).toBe(`${down}`); + }); +}); diff --git a/x-pack/plugins/synthetics/public/components/common/charts/donut_chart_legend.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/donut_chart_legend.tsx similarity index 90% rename from x-pack/plugins/synthetics/public/components/common/charts/donut_chart_legend.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/donut_chart_legend.tsx index b7bb1ccab14ec..f8b785730961f 100644 --- a/x-pack/plugins/synthetics/public/components/common/charts/donut_chart_legend.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/donut_chart_legend.tsx @@ -36,14 +36,14 @@ export const DonutChartLegend = ({ down, up }: Props) => { color={danger} content={down} message={STATUS_DOWN_LABEL} - data-test-subj={'xpack.uptime.snapshot.donutChart.down'} + data-test-subj={'xpack.synthetics.snapshot.donutChart.down'} /> ); diff --git a/x-pack/plugins/synthetics/public/components/common/charts/donut_chart_legend_row.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/donut_chart_legend_row.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/charts/donut_chart_legend_row.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/donut_chart_legend_row.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/common/charts/donut_chart_legend_row.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/donut_chart_legend_row.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/charts/donut_chart_legend_row.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/donut_chart_legend_row.tsx diff --git a/x-pack/plugins/synthetics/public/components/common/charts/duration_chart.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/duration_chart.tsx similarity index 92% rename from x-pack/plugins/synthetics/public/components/common/charts/duration_chart.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/duration_chart.tsx index 1a09a38835578..eb591fd538d98 100644 --- a/x-pack/plugins/synthetics/public/components/common/charts/duration_chart.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/duration_chart.tsx @@ -20,7 +20,7 @@ import { } from '@elastic/charts'; import { useSelector } from 'react-redux'; import { getChartDateLabel } from '../../../lib/helper'; -import { LocationDurationLine } from '../../../../common/types'; +import { LocationDurationLine } from '../../../../../common/types'; import { DurationLineSeriesList } from './duration_line_series_list'; import { ChartWrapper } from './chart_wrapper'; import { useUrlParams } from '../../../hooks'; @@ -95,7 +95,7 @@ export const DurationChartComponent = ({ return ( getTickFormat(d)} - title={i18n.translate('xpack.uptime.monitorCharts.durationChart.leftAxis.title', { + title={i18n.translate('xpack.synthetics.monitorCharts.durationChart.leftAxis.title', { defaultMessage: 'Duration in {unit}', values: { unit: monitor.monitor.type === 'browser' ? SECONDS_LABEL : MS_LABEL }, })} @@ -141,12 +141,12 @@ export const DurationChartComponent = ({ up }} /> } - title={i18n.translate('xpack.uptime.durationChart.emptyPrompt.title', { + title={i18n.translate('xpack.synthetics.durationChart.emptyPrompt.title', { defaultMessage: 'No duration data available', })} /> diff --git a/x-pack/plugins/synthetics/public/components/common/charts/duration_charts.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/duration_charts.test.tsx similarity index 97% rename from x-pack/plugins/synthetics/public/components/common/charts/duration_charts.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/duration_charts.test.tsx index fee4143df11f9..fc24e723528c9 100644 --- a/x-pack/plugins/synthetics/public/components/common/charts/duration_charts.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/duration_charts.test.tsx @@ -8,7 +8,7 @@ import React from 'react'; import DateMath from '@kbn/datemath'; import { DurationChartComponent } from './duration_chart'; -import { MonitorDurationResult } from '../../../../common/types'; +import { MonitorDurationResult } from '../../../../../common/types'; import { render } from '../../../lib/helper/rtl_helpers'; describe('MonitorCharts component', () => { diff --git a/x-pack/plugins/synthetics/public/components/common/charts/duration_line_bar_list.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/duration_line_bar_list.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/charts/duration_line_bar_list.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/duration_line_bar_list.tsx diff --git a/x-pack/plugins/synthetics/public/components/common/charts/duration_line_series_list.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/duration_line_series_list.tsx similarity index 95% rename from x-pack/plugins/synthetics/public/components/common/charts/duration_line_series_list.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/duration_line_series_list.tsx index bc744be163223..3f8c2abb9fc2c 100644 --- a/x-pack/plugins/synthetics/public/components/common/charts/duration_line_series_list.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/duration_line_series_list.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { LineSeries, CurveType, Fit, ScaleType } from '@elastic/charts'; -import { LocationDurationLine } from '../../../../common/types'; +import { LocationDurationLine } from '../../../../../common/types'; import { microToMilli, microToSec } from '../../../lib/formatting'; import { MS_LABEL, SEC_LABEL } from '../translations'; diff --git a/x-pack/plugins/synthetics/public/components/common/charts/get_tick_format.test.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/get_tick_format.test.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/charts/get_tick_format.test.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/get_tick_format.test.ts diff --git a/x-pack/plugins/synthetics/public/components/common/charts/get_tick_format.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/get_tick_format.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/charts/get_tick_format.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/get_tick_format.ts diff --git a/x-pack/plugins/synthetics/public/components/common/charts/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/index.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/charts/index.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/index.ts diff --git a/x-pack/plugins/synthetics/public/components/common/charts/monitor_bar_series.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/monitor_bar_series.test.tsx similarity index 98% rename from x-pack/plugins/synthetics/public/components/common/charts/monitor_bar_series.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/monitor_bar_series.test.tsx index 792b357b3baba..e8a2afbd8af23 100644 --- a/x-pack/plugins/synthetics/public/components/common/charts/monitor_bar_series.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/monitor_bar_series.test.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { MonitorBarSeries, MonitorBarSeriesProps } from './monitor_bar_series'; import { renderWithRouter, shallowWithRouter, MountWithReduxProvider } from '../../../lib'; -import { HistogramPoint } from '../../../../common/runtime_types'; +import { HistogramPoint } from '../../../../../common/runtime_types'; describe('MonitorBarSeries component', () => { let props: MonitorBarSeriesProps; diff --git a/x-pack/plugins/synthetics/public/components/common/charts/monitor_bar_series.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/monitor_bar_series.tsx similarity index 94% rename from x-pack/plugins/synthetics/public/components/common/charts/monitor_bar_series.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/monitor_bar_series.tsx index 34cf55c0af48c..35b2b830d91bd 100644 --- a/x-pack/plugins/synthetics/public/components/common/charts/monitor_bar_series.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/monitor_bar_series.tsx @@ -22,7 +22,7 @@ import React, { useContext } from 'react'; import moment from 'moment'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiText, EuiToolTip } from '@elastic/eui'; -import { HistogramPoint } from '../../../../common/runtime_types'; +import { HistogramPoint } from '../../../../../common/runtime_types'; import { getChartDateLabel, seriesHasDownValues } from '../../../lib/helper'; import { useUrlParams } from '../../../hooks'; import { UptimeThemeContext } from '../../../contexts'; @@ -92,7 +92,7 @@ export const MonitorBarSeries = ({ histogramSeries, minInterval }: MonitorBarSer id={id} color={danger} data={(histogramSeries || []).map(({ timestamp, down }) => [timestamp, down])} - name={i18n.translate('xpack.uptime.monitorList.downLineSeries.downLabel', { + name={i18n.translate('xpack.synthetics.monitorList.downLineSeries.downLabel', { defaultMessage: 'Down checks', })} timeZone="local" @@ -108,7 +108,7 @@ export const MonitorBarSeries = ({ histogramSeries, minInterval }: MonitorBarSer position="top" content={ down }} /> diff --git a/x-pack/plugins/synthetics/public/components/common/charts/ping_histogram.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/ping_histogram.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/charts/ping_histogram.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/ping_histogram.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/common/charts/ping_histogram.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/ping_histogram.tsx similarity index 88% rename from x-pack/plugins/synthetics/public/components/common/charts/ping_histogram.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/ping_histogram.tsx index c302f47e29bdd..c3f9f5086ec9b 100644 --- a/x-pack/plugins/synthetics/public/components/common/charts/ping_histogram.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/ping_histogram.tsx @@ -28,7 +28,7 @@ import { createExploratoryViewUrl } from '@kbn/observability-plugin/public'; import { getChartDateLabel } from '../../../lib/helper'; import { ChartWrapper } from './chart_wrapper'; import { UptimeThemeContext } from '../../../contexts'; -import { HistogramResult } from '../../../../common/runtime_types'; +import { HistogramResult } from '../../../../../common/runtime_types'; import { useMonitorId, useUrlParams } from '../../../hooks'; import { ChartEmptyState } from './chart_empty_state'; import { getDateRangeFromChartElement } from './utils'; @@ -88,10 +88,10 @@ export const PingHistogramComponent: React.FC = ({ if (!data?.histogram?.length) { content = ( @@ -129,7 +129,7 @@ export const PingHistogramComponent: React.FC = ({ = ({ {...chartTheme} /> = ({ tickFormat={timeFormatter(getChartDateLabel(absoluteStartDate, absoluteEndDate))} /> numeral(d).format('0')} labelFormat={(d) => numeral(d).format('0a')} - title={i18n.translate('xpack.uptime.snapshotHistogram.yAxis.title', { + title={i18n.translate('xpack.synthetics.snapshotHistogram.yAxis.title', { defaultMessage: 'Pings', description: 'The label on the y-axis of a chart that displays the number of times Heartbeat has pinged a set of services/websites.', @@ -176,7 +176,7 @@ export const PingHistogramComponent: React.FC = ({ color={[danger, gray]} data={barData} id={STATUS_DOWN_LABEL} - name={i18n.translate('xpack.uptime.snapshotHistogram.series.pings', { + name={i18n.translate('xpack.synthetics.snapshotHistogram.series.pings', { defaultMessage: 'Monitor Pings', })} stackAccessors={['x']} @@ -222,7 +222,7 @@ export const PingHistogramComponent: React.FC = ({

@@ -231,7 +231,10 @@ export const PingHistogramComponent: React.FC = ({ {showAnalyzeButton && ( - + )} diff --git a/x-pack/plugins/synthetics/public/components/common/charts/utils.test.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/utils.test.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/charts/utils.test.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/utils.test.ts diff --git a/x-pack/plugins/synthetics/public/components/common/charts/utils.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/utils.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/charts/utils.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/charts/utils.ts diff --git a/x-pack/plugins/synthetics/public/components/common/header/action_menu.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/header/action_menu.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/header/action_menu.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/header/action_menu.tsx diff --git a/x-pack/plugins/synthetics/public/components/common/header/action_menu_content.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/header/action_menu_content.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/header/action_menu_content.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/header/action_menu_content.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/common/header/action_menu_content.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/header/action_menu_content.tsx similarity index 84% rename from x-pack/plugins/synthetics/public/components/common/header/action_menu_content.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/header/action_menu_content.tsx index 3e7a6db48ff36..1fb150bd9e70e 100644 --- a/x-pack/plugins/synthetics/public/components/common/header/action_menu_content.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/header/action_menu_content.tsx @@ -16,21 +16,21 @@ import { useKibana } from '@kbn/kibana-react-plugin/public'; import { useUptimeSettingsContext } from '../../../contexts/uptime_settings_context'; import { useGetUrlParams } from '../../../hooks'; import { ToggleAlertFlyoutButton } from '../../overview/alerts/alerts_containers'; -import { MONITOR_ROUTE, SETTINGS_ROUTE } from '../../../../common/constants'; +import { MONITOR_ROUTE, SETTINGS_ROUTE } from '../../../../../common/constants'; import { stringifyUrlParams } from '../../../lib/helper/stringify_url_params'; import { InspectorHeaderLink } from './inspector_header_link'; import { monitorStatusSelector } from '../../../state/selectors'; import { ManageMonitorsBtn } from './manage_monitors_btn'; -const ADD_DATA_LABEL = i18n.translate('xpack.uptime.addDataButtonLabel', { +const ADD_DATA_LABEL = i18n.translate('xpack.synthetics.addDataButtonLabel', { defaultMessage: 'Add data', }); -const ANALYZE_DATA = i18n.translate('xpack.uptime.analyzeDataButtonLabel', { +const ANALYZE_DATA = i18n.translate('xpack.synthetics.analyzeDataButtonLabel', { defaultMessage: 'Explore data', }); -const ANALYZE_MESSAGE = i18n.translate('xpack.uptime.analyzeDataButtonLabel.message', { +const ANALYZE_MESSAGE = i18n.translate('xpack.synthetics.analyzeDataButtonLabel.message', { defaultMessage: 'Explore Data allows you to select and filter result data in any dimension and look for the cause or impact of performance problems.', }); @@ -76,7 +76,7 @@ export function ActionMenuContent(): React.ReactElement { - + {ANALYZE_MESSAGE}

}> - {i18n.translate('xpack.uptime.inspectButtonText', { + {i18n.translate('xpack.synthetics.inspectButtonText', { defaultMessage: 'Inspect', })} diff --git a/x-pack/plugins/synthetics/public/components/common/header/manage_monitors_btn.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/header/manage_monitors_btn.tsx similarity index 77% rename from x-pack/plugins/synthetics/public/components/common/header/manage_monitors_btn.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/header/manage_monitors_btn.tsx index 5cc489fe4d7a4..2d0ac2654b71f 100644 --- a/x-pack/plugins/synthetics/public/components/common/header/manage_monitors_btn.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/header/manage_monitors_btn.tsx @@ -13,13 +13,13 @@ import { useHistory } from 'react-router-dom'; import useLocalStorage from 'react-use/lib/useLocalStorage'; import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { MONITOR_MANAGEMENT_ROUTE } from '../../../../common/constants'; +import { MONITOR_MANAGEMENT_ROUTE } from '../../../../../common/constants'; import { PUBLIC_BETA_DESCRIPTION } from '../../../pages/monitor_management/service_allowed_wrapper'; -import { ClientPluginsSetup } from '../../../apps/plugin'; +import { ClientPluginsSetup } from '../../../../plugin'; import { useUptimeSettingsContext } from '../../../contexts/uptime_settings_context'; export const ManageMonitorsBtn = () => { - const [isOpen, setIsOpen] = useLocalStorage('xpack.uptime.monitorManagement.openTour', true); + const [isOpen, setIsOpen] = useLocalStorage('xpack.synthetics.monitorManagement.openTour', true); const history = useHistory(); @@ -70,7 +70,7 @@ export const ManageMonitorsBtn = () => { onClick={handleOnClick} > @@ -79,23 +79,23 @@ export const ManageMonitorsBtn = () => { }; const GETTING_STARTED_LABEL = i18n.translate( - 'xpack.uptime.monitorManagement.gettingStarted.label', + 'xpack.synthetics.monitorManagement.gettingStarted.label', { defaultMessage: 'Get started with Synthetic Monitoring', } ); -const MONITOR_MANAGEMENT_LABEL = i18n.translate('xpack.uptime.monitorManagement.try.label', { +const MONITOR_MANAGEMENT_LABEL = i18n.translate('xpack.synthetics.monitorManagement.try.label', { defaultMessage: 'Try Monitor Management', }); -const DISMISS_LABEL = i18n.translate('xpack.uptime.monitorManagement.try.dismiss', { +const DISMISS_LABEL = i18n.translate('xpack.synthetics.monitorManagement.try.dismiss', { defaultMessage: 'Dismiss', }); -const NAVIGATE_LABEL = i18n.translate('xpack.uptime.page_header.manageLink.label', { +const NAVIGATE_LABEL = i18n.translate('xpack.synthetics.page_header.manageLink.label', { defaultMessage: 'Navigate to the Uptime Monitor Management page', }); -const NEW_LABEL = i18n.translate('xpack.uptime.monitorManagement.new.label', { +const NEW_LABEL = i18n.translate('xpack.synthetics.monitorManagement.new.label', { defaultMessage: 'New', }); diff --git a/x-pack/plugins/synthetics/public/components/common/header/page_tabs.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/header/page_tabs.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/header/page_tabs.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/header/page_tabs.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/common/header/page_tabs.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/header/page_tabs.tsx similarity index 96% rename from x-pack/plugins/synthetics/public/components/common/header/page_tabs.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/header/page_tabs.tsx index 74b037971c126..9711a9d7acb9e 100644 --- a/x-pack/plugins/synthetics/public/components/common/header/page_tabs.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/header/page_tabs.tsx @@ -10,14 +10,14 @@ import React, { useEffect, useState } from 'react'; import { EuiTabs, EuiTab } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { useHistory, useRouteMatch } from 'react-router-dom'; -import { CERTIFICATES_ROUTE, OVERVIEW_ROUTE } from '../../../../common/constants'; +import { CERTIFICATES_ROUTE, OVERVIEW_ROUTE } from '../../../../../common/constants'; import { useGetUrlParams } from '../../../hooks'; import { stringifyUrlParams } from '../../../lib/helper/stringify_url_params'; const tabs = [ { id: OVERVIEW_ROUTE, - name: i18n.translate('xpack.uptime.overviewPage.headerText', { + name: i18n.translate('xpack.synthetics.overviewPage.headerText', { defaultMessage: 'Overview', description: `The text that will be displayed in the app's heading when the Overview page loads.`, }), diff --git a/x-pack/plugins/synthetics/public/components/common/higher_order/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/higher_order/index.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/higher_order/index.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/higher_order/index.ts diff --git a/x-pack/plugins/synthetics/public/components/common/higher_order/responsive_wrapper.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/higher_order/responsive_wrapper.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/higher_order/responsive_wrapper.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/higher_order/responsive_wrapper.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/common/higher_order/responsive_wrapper.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/higher_order/responsive_wrapper.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/higher_order/responsive_wrapper.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/higher_order/responsive_wrapper.tsx diff --git a/x-pack/plugins/synthetics/public/components/common/location_link.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/location_link.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/location_link.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/location_link.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/common/location_link.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/location_link.tsx similarity index 93% rename from x-pack/plugins/synthetics/public/components/common/location_link.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/location_link.tsx index 7e2ee54008e96..9bf66ab243604 100644 --- a/x-pack/plugins/synthetics/public/components/common/location_link.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/location_link.tsx @@ -28,7 +28,7 @@ export const LocationLink = ({ location, textSize }: LocationLinkProps) => { ) : ( - {i18n.translate('xpack.uptime.monitorList.geoName.helpLinkAnnotation', { + {i18n.translate('xpack.synthetics.monitorList.geoName.helpLinkAnnotation', { defaultMessage: 'Add location', description: 'Text that instructs the user to navigate to our docs to add a geographic location to their data', diff --git a/x-pack/plugins/synthetics/public/components/common/monitor_page_link.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/monitor_page_link.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/monitor_page_link.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/monitor_page_link.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/common/monitor_page_link.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/monitor_page_link.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/monitor_page_link.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/monitor_page_link.tsx diff --git a/x-pack/plugins/synthetics/public/components/common/monitor_tags.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/monitor_tags.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/monitor_tags.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/monitor_tags.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/common/monitor_tags.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/monitor_tags.tsx similarity index 93% rename from x-pack/plugins/synthetics/public/components/common/monitor_tags.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/monitor_tags.tsx index 35684e8326f6c..14e185e3e9318 100644 --- a/x-pack/plugins/synthetics/public/components/common/monitor_tags.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/monitor_tags.tsx @@ -10,13 +10,13 @@ import { EuiBadge, EuiBadgeGroup, EuiLink } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { useHistory } from 'react-router-dom'; import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { Ping } from '../../../common/runtime_types/ping'; -import { MonitorSummary } from '../../../common/runtime_types/monitor'; +import { Ping } from '../../../../common/runtime_types/ping'; +import { MonitorSummary } from '../../../../common/runtime_types/monitor'; import { useFilterUpdate } from '../../hooks/use_filter_update'; import { useGetUrlParams } from '../../hooks'; import { parseCurrentFilters } from '../overview/monitor_list/columns/monitor_name_col'; import { EXPAND_TAGS_LABEL } from '../overview/monitor_list/columns/translations'; -import { OVERVIEW_ROUTE } from '../../../common/constants'; +import { OVERVIEW_ROUTE } from '../../../../common/constants'; interface Props { ping?: Ping | null; @@ -37,7 +37,7 @@ const getTagsFromPing = (ping: Ping) => { }; const getFilterLabel = (tag: string) => { - return i18n.translate('xpack.uptime.monitorList.tags.filter', { + return i18n.translate('xpack.synthetics.monitorList.tags.filter', { defaultMessage: 'Filter all monitors with tag {tag}', values: { tag, diff --git a/x-pack/plugins/synthetics/public/components/common/react_router_helpers/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/react_router_helpers/index.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/react_router_helpers/index.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/react_router_helpers/index.ts diff --git a/x-pack/plugins/synthetics/public/components/common/react_router_helpers/link_events.test.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/react_router_helpers/link_events.test.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/react_router_helpers/link_events.test.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/react_router_helpers/link_events.test.ts diff --git a/x-pack/plugins/synthetics/public/components/common/react_router_helpers/link_events.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/react_router_helpers/link_events.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/react_router_helpers/link_events.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/react_router_helpers/link_events.ts diff --git a/x-pack/plugins/synthetics/public/components/common/react_router_helpers/link_for_eui.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/react_router_helpers/link_for_eui.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/react_router_helpers/link_for_eui.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/react_router_helpers/link_for_eui.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/common/react_router_helpers/link_for_eui.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/react_router_helpers/link_for_eui.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/react_router_helpers/link_for_eui.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/react_router_helpers/link_for_eui.tsx diff --git a/x-pack/plugins/synthetics/public/components/common/step_detail_link.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/step_detail_link.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/step_detail_link.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/step_detail_link.tsx diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/common/translations.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/translations.ts new file mode 100644 index 0000000000000..8587ddd6f863e --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/translations.ts @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const URL_LABEL = i18n.translate('xpack.synthetics.monitorList.table.url.name', { + defaultMessage: 'Url', +}); + +export const TAGS_LABEL = i18n.translate('xpack.synthetics.monitorList.table.tags.name', { + defaultMessage: 'Tags', +}); + +export const STATUS_UP_LABEL = i18n.translate('xpack.synthetics.monitorList.statusColumn.upLabel', { + defaultMessage: 'Up', +}); + +export const STATUS_DOWN_LABEL = i18n.translate( + 'xpack.synthetics.monitorList.statusColumn.downLabel', + { + defaultMessage: 'Down', + } +); + +export const STATUS_COMPLETE_LABEL = i18n.translate( + 'xpack.synthetics.monitorList.statusColumn.completeLabel', + { + defaultMessage: 'Complete', + } +); + +export const STATUS_FAILED_LABEL = i18n.translate( + 'xpack.synthetics.monitorList.statusColumn.failedLabel', + { + defaultMessage: 'Failed', + } +); + +export const SECONDS_LABEL = i18n.translate('xpack.synthetics.seconds.label', { + defaultMessage: 'seconds', +}); + +export const SEC_LABEL = i18n.translate('xpack.synthetics.seconds.shortForm.label', { + defaultMessage: 'sec', +}); + +export const MS_LABEL = i18n.translate('xpack.synthetics.millisecond.abbreviation.label', { + defaultMessage: 'ms', +}); diff --git a/x-pack/plugins/synthetics/public/components/common/uptime_date_picker.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/uptime_date_picker.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/common/uptime_date_picker.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/uptime_date_picker.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/common/uptime_date_picker.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/uptime_date_picker.tsx similarity index 98% rename from x-pack/plugins/synthetics/public/components/common/uptime_date_picker.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/common/uptime_date_picker.tsx index f509f9b53114b..ff01b9cb352ee 100644 --- a/x-pack/plugins/synthetics/public/components/common/uptime_date_picker.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/common/uptime_date_picker.tsx @@ -8,7 +8,7 @@ import React, { useContext, useEffect } from 'react'; import { EuiSuperDatePicker } from '@elastic/eui'; import { useUrlParams } from '../../hooks'; -import { CLIENT_DEFAULTS } from '../../../common/constants'; +import { CLIENT_DEFAULTS } from '../../../../common/constants'; import { UptimeRefreshContext, UptimeSettingsContext, diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/browser/advanced_fields.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/advanced_fields.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/browser/advanced_fields.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/advanced_fields.test.tsx diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/advanced_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/advanced_fields.tsx new file mode 100644 index 0000000000000..64409608f7a4d --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/advanced_fields.tsx @@ -0,0 +1,242 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo, useCallback } from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { + EuiAccordion, + EuiSelect, + EuiFieldText, + EuiCheckbox, + EuiFormRow, + EuiSpacer, +} from '@elastic/eui'; +import { ComboBox } from '../combo_box'; +import { DescribedFormGroupWithWrap } from '../common/described_form_group_with_wrap'; + +import { useBrowserAdvancedFieldsContext, useBrowserSimpleFieldsContext } from '../contexts'; + +import { ConfigKey, Validation, ScreenshotOption } from '../types'; + +import { OptionalLabel } from '../optional_label'; +import { ThrottlingFields } from './throttling_fields'; + +interface Props { + validate: Validation; + children?: React.ReactNode; + minColumnWidth?: string; + onFieldBlur?: (field: ConfigKey) => void; +} + +export const BrowserAdvancedFields = memo( + ({ validate, children, minColumnWidth, onFieldBlur }) => { + const { fields, setFields } = useBrowserAdvancedFieldsContext(); + const { fields: simpleFields } = useBrowserSimpleFieldsContext(); + + const handleInputChange = useCallback( + ({ value, configKey }: { value: unknown; configKey: ConfigKey }) => { + setFields((prevFields) => ({ ...prevFields, [configKey]: value })); + }, + [setFields] + ); + + return ( + + + {simpleFields[ConfigKey.SOURCE_ZIP_URL] && ( + + + + } + description={ + + } + > + + + } + labelAppend={} + helpText={ + + } + > + + handleInputChange({ + value: event.target.value, + configKey: ConfigKey.JOURNEY_FILTERS_MATCH, + }) + } + onBlur={() => onFieldBlur?.(ConfigKey.JOURNEY_FILTERS_MATCH)} + data-test-subj="syntheticsBrowserJourneyFiltersMatch" + /> + + + } + labelAppend={} + helpText={ + + } + > + + handleInputChange({ value, configKey: ConfigKey.JOURNEY_FILTERS_TAGS }) + } + onBlur={() => onFieldBlur?.(ConfigKey.JOURNEY_FILTERS_TAGS)} + data-test-subj="syntheticsBrowserJourneyFiltersTags" + /> + + + )} + + + + } + description={ + + } + > + + + + + } + data-test-subj="syntheticsBrowserIgnoreHttpsErrors" + > + + } + onChange={(event) => + handleInputChange({ + value: event.target.checked, + configKey: ConfigKey.IGNORE_HTTPS_ERRORS, + }) + } + onBlur={() => onFieldBlur?.(ConfigKey.IGNORE_HTTPS_ERRORS)} + /> + + + + } + labelAppend={} + helpText={ + + } + > + + handleInputChange({ + value: event.target.value, + configKey: ConfigKey.SCREENSHOTS, + }) + } + onBlur={() => onFieldBlur?.(ConfigKey.SCREENSHOTS)} + data-test-subj="syntheticsBrowserScreenshots" + /> + + + } + labelAppend={} + helpText={ + + } + > + + handleInputChange({ value, configKey: ConfigKey.SYNTHETICS_ARGS }) + } + onBlur={() => onFieldBlur?.(ConfigKey.SYNTHETICS_ARGS)} + data-test-subj="syntheticsBrowserSyntheticsArgs" + /> + + + + + {children} + + ); + } +); + +const requestMethodOptions = Object.values(ScreenshotOption).map((option) => ({ + value: option, + text: option.replace(/-/g, ' '), +})); diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/browser/formatters.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/formatters.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/browser/formatters.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/formatters.ts diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/browser/normalizers.test.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/normalizers.test.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/browser/normalizers.test.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/normalizers.test.ts diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/browser/normalizers.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/normalizers.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/browser/normalizers.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/normalizers.ts diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/browser/script_recorder_fields.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/script_recorder_fields.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/browser/script_recorder_fields.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/script_recorder_fields.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/browser/script_recorder_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/script_recorder_fields.tsx similarity index 85% rename from x-pack/plugins/synthetics/public/components/fleet_package/browser/script_recorder_fields.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/script_recorder_fields.tsx index e85bebe7f6b83..704fbd6edcdfb 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/browser/script_recorder_fields.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/script_recorder_fields.tsx @@ -46,7 +46,7 @@ export function ScriptRecorderFields({ onChange, script, fileName }: Props) { @@ -71,7 +71,7 @@ export function ScriptRecorderFields({ onChange, script, fileName }: Props) { iconSide="right" > @@ -85,7 +85,7 @@ export function ScriptRecorderFields({ onChange, script, fileName }: Props) { color="danger" > @@ -120,14 +120,14 @@ export function ScriptRecorderFields({ onChange, script, fileName }: Props) { } const PLACEHOLDER_FILE_NAME = i18n.translate( - 'xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.scriptRecorder.mockFileName', + 'xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.scriptRecorder.mockFileName', { defaultMessage: 'test_script.js', } ); const CLOSE_BUTTON_LABEL = i18n.translate( - 'xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.scriptRecorder.closeButtonLabel', + 'xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.scriptRecorder.closeButtonLabel', { defaultMessage: 'Close script flyout', } diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/simple_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/simple_fields.tsx new file mode 100644 index 0000000000000..e25f135c5efa8 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/simple_fields.tsx @@ -0,0 +1,129 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo, useMemo, useCallback } from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { EuiFormRow } from '@elastic/eui'; +import { Validation } from '../types'; +import { ConfigKey } from '../types'; +import { useBrowserSimpleFieldsContext } from '../contexts'; +import { ScheduleField } from '../schedule_field'; +import { SourceField } from './source_field'; +import { SimpleFieldsWrapper } from '../common/simple_fields_wrapper'; + +interface Props { + validate: Validation; + onFieldBlur: (field: ConfigKey) => void; // To propagate blurred state up to parents +} + +export const BrowserSimpleFields = memo(({ validate, onFieldBlur }) => { + const { fields, setFields, defaultValues } = useBrowserSimpleFieldsContext(); + const handleInputChange = useCallback( + ({ value, configKey }: { value: unknown; configKey: ConfigKey }) => { + setFields((prevFields) => ({ ...prevFields, [configKey]: value })); + }, + [setFields] + ); + const onChangeSourceField = useCallback( + ({ + zipUrl, + folder, + username, + password, + inlineScript, + params, + proxyUrl, + isGeneratedScript, + fileName, + }) => { + setFields((prevFields) => ({ + ...prevFields, + [ConfigKey.SOURCE_ZIP_URL]: zipUrl, + [ConfigKey.SOURCE_ZIP_PROXY_URL]: proxyUrl, + [ConfigKey.SOURCE_ZIP_FOLDER]: folder, + [ConfigKey.SOURCE_ZIP_USERNAME]: username, + [ConfigKey.SOURCE_ZIP_PASSWORD]: password, + [ConfigKey.SOURCE_INLINE]: inlineScript, + [ConfigKey.PARAMS]: params, + [ConfigKey.METADATA]: { + ...prevFields[ConfigKey.METADATA], + script_source: { + is_generated_script: isGeneratedScript, + file_name: fileName, + }, + }, + })); + }, + [setFields] + ); + + return ( + + + } + isInvalid={!!validate[ConfigKey.SCHEDULE]?.(fields)} + error={ + + } + > + + handleInputChange({ + value: schedule, + configKey: ConfigKey.SCHEDULE, + }) + } + onBlur={() => onFieldBlur(ConfigKey.SCHEDULE)} + number={fields[ConfigKey.SCHEDULE].number} + unit={fields[ConfigKey.SCHEDULE].unit} + /> + + + } + > + ({ + zipUrl: defaultValues[ConfigKey.SOURCE_ZIP_URL], + proxyUrl: defaultValues[ConfigKey.SOURCE_ZIP_PROXY_URL], + folder: defaultValues[ConfigKey.SOURCE_ZIP_FOLDER], + username: defaultValues[ConfigKey.SOURCE_ZIP_USERNAME], + password: defaultValues[ConfigKey.SOURCE_ZIP_PASSWORD], + inlineScript: defaultValues[ConfigKey.SOURCE_INLINE], + params: defaultValues[ConfigKey.PARAMS], + isGeneratedScript: + defaultValues[ConfigKey.METADATA].script_source?.is_generated_script, + fileName: defaultValues[ConfigKey.METADATA].script_source?.file_name, + }), + [defaultValues] + )} + /> + + + ); +}); diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/browser/source_field.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/source_field.test.tsx similarity index 98% rename from x-pack/plugins/synthetics/public/components/fleet_package/browser/source_field.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/source_field.test.tsx index ae5db0662dd85..97001df29a69e 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/browser/source_field.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/source_field.test.tsx @@ -8,7 +8,7 @@ import 'jest-canvas-mock'; import React from 'react'; import { fireEvent, screen, waitFor } from '@testing-library/react'; -import { ConfigKey } from '../../../../common/runtime_types'; +import { ConfigKey } from '../../../../../common/runtime_types'; import { render } from '../../../lib/helper/rtl_helpers'; import { IPolicyConfigContextProvider } from '../contexts/policy_config_context'; import { SourceField, defaultValues } from './source_field'; diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/browser/source_field.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/source_field.tsx similarity index 80% rename from x-pack/plugins/synthetics/public/components/fleet_package/browser/source_field.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/source_field.tsx index 89f3461800923..1da198c17eb52 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/browser/source_field.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/source_field.tsx @@ -85,7 +85,7 @@ export const SourceField = ({ onChange, onFieldBlur, defaultConfig = defaultValu const zipUrlLabel = ( ); @@ -104,13 +104,13 @@ export const SourceField = ({ onChange, onFieldBlur, defaultConfig = defaultValu isInvalid={!config.zipUrl} error={ } helpText={ } @@ -128,14 +128,14 @@ export const SourceField = ({ onChange, onFieldBlur, defaultConfig = defaultValu } labelAppend={} helpText={ } @@ -152,14 +152,14 @@ export const SourceField = ({ onChange, onFieldBlur, defaultConfig = defaultValu } labelAppend={} helpText={ } @@ -176,21 +176,21 @@ export const SourceField = ({ onChange, onFieldBlur, defaultConfig = defaultValu } labelAppend={} helpText={ } > } labelAppend={} helpText={ } @@ -232,14 +232,14 @@ export const SourceField = ({ onChange, onFieldBlur, defaultConfig = defaultValu } labelAppend={} helpText={ } @@ -260,7 +260,7 @@ export const SourceField = ({ onChange, onFieldBlur, defaultConfig = defaultValu id: 'syntheticsBrowserInlineConfig', name: ( ), @@ -270,20 +270,20 @@ export const SourceField = ({ onChange, onFieldBlur, defaultConfig = defaultValu isInvalid={!config.inlineScript} error={ } helpText={ } > { } @@ -46,7 +46,7 @@ export const ThrottlingDisabledCallout = () => { iconType="alert" > @@ -58,7 +58,7 @@ export const ThrottlingExceededCallout = () => { } @@ -66,7 +66,7 @@ export const ThrottlingExceededCallout = () => { iconType="alert" > @@ -82,7 +82,7 @@ export const ThrottlingExceededMessage = ({ }) => { return ( @@ -115,7 +115,7 @@ export const ThrottlingFields = memo(({ validate, minColumnWidth, onField } @@ -126,7 +126,7 @@ export const ThrottlingFields = memo(({ validate, minColumnWidth, onField ) : ( ) @@ -154,7 +154,7 @@ export const ThrottlingFields = memo(({ validate, minColumnWidth, onField } @@ -165,7 +165,7 @@ export const ThrottlingFields = memo(({ validate, minColumnWidth, onField ) : ( ) @@ -193,7 +193,7 @@ export const ThrottlingFields = memo(({ validate, minColumnWidth, onField } @@ -201,7 +201,7 @@ export const ThrottlingFields = memo(({ validate, minColumnWidth, onField isInvalid={!!validate[ConfigKey.LATENCY]?.(fields)} error={ } @@ -238,14 +238,14 @@ export const ThrottlingFields = memo(({ validate, minColumnWidth, onField title={

} description={ } @@ -257,7 +257,7 @@ export const ThrottlingFields = memo(({ validate, minColumnWidth, onField checked={fields[ConfigKey.IS_THROTTLING_ENABLED]} label={ } diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/browser/uploader.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/uploader.tsx similarity index 84% rename from x-pack/plugins/synthetics/public/components/fleet_package/browser/uploader.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/uploader.tsx index 76c2287ca645d..ce65818d23fc3 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/browser/uploader.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/uploader.tsx @@ -63,21 +63,21 @@ export function Uploader({ onUpload }: Props) { } const TESTING_SCRIPT_LABEL = i18n.translate( - 'xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.fieldLabel', + 'xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.fieldLabel', { defaultMessage: 'Testing script', } ); const PROMPT_TEXT = i18n.translate( - 'xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.label', + 'xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.label', { defaultMessage: 'Select recorder-generated .js file', } ); const INVALID_FILE_ERROR = i18n.translate( - 'xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.invalidFileError', + 'xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.invalidFileError', { defaultMessage: 'Invalid file type. Please upload a .js file generated by the Elastic Synthetics Recorder.', @@ -85,7 +85,7 @@ const INVALID_FILE_ERROR = i18n.translate( ); const PARSING_ERROR = i18n.translate( - 'xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.parsingError', + 'xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.parsingError', { defaultMessage: 'Error uploading file. Please upload a .js file generated by the Elastic Synthetics Recorder in inline script format.', diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/browser/zip_url_tls_fields.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/zip_url_tls_fields.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/browser/zip_url_tls_fields.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/zip_url_tls_fields.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/browser/zip_url_tls_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/zip_url_tls_fields.tsx similarity index 96% rename from x-pack/plugins/synthetics/public/components/fleet_package/browser/zip_url_tls_fields.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/zip_url_tls_fields.tsx index 590c5d4f3abc5..21f2a548413c1 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/browser/zip_url_tls_fields.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/zip_url_tls_fields.tsx @@ -62,7 +62,7 @@ export const ZipUrlTLSFields = () => { checked={!!isZipUrlTLSEnabled} label={ } diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/code_editor.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/code_editor.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/code_editor.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/code_editor.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/combo_box.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/combo_box.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/combo_box.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/combo_box.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/combo_box.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/combo_box.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/combo_box.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/combo_box.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/common/common_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/common_fields.tsx similarity index 80% rename from x-pack/plugins/synthetics/public/components/fleet_package/common/common_fields.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/common_fields.tsx index 78569e8ba65a4..acdc6655cf24b 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/common/common_fields.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/common_fields.tsx @@ -45,14 +45,14 @@ export function CommonFields({ fields, onChange, onFieldBlur, validate }: Props) } labelAppend={} helpText={ } @@ -73,7 +73,7 @@ export function CommonFields({ fields, onChange, onFieldBlur, validate }: Props) } @@ -81,19 +81,19 @@ export function CommonFields({ fields, onChange, onFieldBlur, validate }: Props) error={ parseInt(fields[ConfigKey.TIMEOUT] || '', 10) < 0 ? ( ) : ( ) } helpText={ } @@ -115,14 +115,14 @@ export function CommonFields({ fields, onChange, onFieldBlur, validate }: Props) } labelAppend={} helpText={ } diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/common/described_form_group_with_wrap.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/described_form_group_with_wrap.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/common/described_form_group_with_wrap.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/described_form_group_with_wrap.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/common/enabled.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/enabled.tsx similarity index 84% rename from x-pack/plugins/synthetics/public/components/fleet_package/common/enabled.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/enabled.tsx index 29f947984b340..1d76fe8a72e86 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/common/enabled.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/enabled.tsx @@ -22,7 +22,7 @@ export function Enabled({ fields, onChange, onBlur }: Props) { } @@ -30,7 +30,7 @@ export function Enabled({ fields, onChange, onBlur }: Props) { } diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/common/formatters.test.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/formatters.test.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/common/formatters.test.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/formatters.test.ts diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/common/formatters.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/formatters.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/common/formatters.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/formatters.ts diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/common/normalizers.test.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.test.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/common/normalizers.test.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.test.ts diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/common/normalizers.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts similarity index 88% rename from x-pack/plugins/synthetics/public/components/fleet_package/common/normalizers.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts index 8f1b7ad230d9c..0119b415faed8 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/common/normalizers.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts @@ -7,9 +7,11 @@ import { NewPackagePolicyInput } from '@kbn/fleet-plugin/common'; import { CommonFields, ConfigKey, DataStream } from '../types'; -import { defaultValues as commonDefaultValues } from './default_values'; -import { DEFAULT_NAMESPACE_STRING } from '../../../../common/constants'; -import { defaultConfig } from '../contexts'; +import { + DEFAULT_COMMON_FIELDS, + DEFAULT_NAMESPACE_STRING, + DEFAULT_FIELDS, +} from '../../../../../common/constants/monitor_defaults'; // TO DO: create a standard input format that all fields resolve to export type Normalizer = (fields: NewPackagePolicyInput['vars']) => unknown; @@ -46,15 +48,15 @@ export function getCronNormalizer(key: string, defaultValues: Fields): N } export const getCommonNormalizer = (key: ConfigKey) => { - return getNormalizer(key, commonDefaultValues); + return getNormalizer(key, DEFAULT_COMMON_FIELDS); }; export const getCommonjsonToJavascriptNormalizer = (key: ConfigKey) => { - return getJsonToJavascriptNormalizer(key, commonDefaultValues); + return getJsonToJavascriptNormalizer(key, DEFAULT_COMMON_FIELDS); }; export const getCommonCronToSecondsNormalizer = (key: ConfigKey) => { - return getCronNormalizer(key, commonDefaultValues); + return getCronNormalizer(key, DEFAULT_COMMON_FIELDS); }; export const commonNormalizers: CommonNormalizerMap = { @@ -76,7 +78,7 @@ export const commonNormalizers: CommonNormalizerMap = { number, }; } else { - return defaultConfig[type][ConfigKey.SCHEDULE]; + return DEFAULT_FIELDS[type][ConfigKey.SCHEDULE]; } }, [ConfigKey.APM_SERVICE_NAME]: getCommonNormalizer(ConfigKey.APM_SERVICE_NAME), diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/common/simple_fields_wrapper.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/simple_fields_wrapper.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/common/simple_fields_wrapper.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/simple_fields_wrapper.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/common/tls_options.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/tls_options.tsx similarity index 82% rename from x-pack/plugins/synthetics/public/components/fleet_package/common/tls_options.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/tls_options.tsx index 76b49c04ad2cb..3103a6b90912e 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/common/tls_options.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/tls_options.tsx @@ -97,7 +97,7 @@ export const TLSOptions: React.FunctionComponent = memo( @@ -108,7 +108,7 @@ export const TLSOptions: React.FunctionComponent = memo( } @@ -135,7 +135,7 @@ export const TLSOptions: React.FunctionComponent = memo( } @@ -144,7 +144,7 @@ export const TLSOptions: React.FunctionComponent = memo( >

@@ -156,7 +156,7 @@ export const TLSOptions: React.FunctionComponent = memo( } @@ -165,7 +165,7 @@ export const TLSOptions: React.FunctionComponent = memo( > = memo( } helpText={ } @@ -219,14 +219,14 @@ export const TLSOptions: React.FunctionComponent = memo( <> {tlsRoleLabels[tlsRole]}{' '} } helpText={ } @@ -256,14 +256,14 @@ export const TLSOptions: React.FunctionComponent = memo( <> {tlsRoleLabels[tlsRole]}{' '} } helpText={ } @@ -293,14 +293,14 @@ export const TLSOptions: React.FunctionComponent = memo( <> {tlsRoleLabels[tlsRole]}{' '} } helpText={ } @@ -326,13 +326,13 @@ export const TLSOptions: React.FunctionComponent = memo( const tlsRoleLabels = { client: ( ), server: ( ), @@ -340,28 +340,28 @@ const tlsRoleLabels = { const verificationModeHelpText = { [VerificationMode.CERTIFICATE]: i18n.translate( - 'xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.certificate.description', + 'xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.certificate.description', { defaultMessage: 'Verifies that the provided certificate is signed by a trusted authority (CA), but does not perform any hostname verification.', } ), [VerificationMode.FULL]: i18n.translate( - 'xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.full.description', + 'xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.full.description', { defaultMessage: 'Verifies that the provided certificate is signed by a trusted authority (CA) and also verifies that the server’s hostname (or IP address) matches the names identified within the certificate.', } ), [VerificationMode.NONE]: i18n.translate( - 'xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.none.description', + 'xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.none.description', { defaultMessage: 'Performs no verification of the server’s certificate. It is primarily intended as a temporary diagnostic mechanism when attempting to resolve TLS errors; its use in production environments is strongly discouraged.', } ), [VerificationMode.STRICT]: i18n.translate( - 'xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.strict.description', + 'xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.strict.description', { defaultMessage: 'Verifies that the provided certificate is signed by a trusted authority (CA) and also verifies that the server’s hostname (or IP address) matches the names identified within the certificate. If the Subject Alternative Name is empty, it returns an error.', @@ -371,25 +371,25 @@ const verificationModeHelpText = { const verificationModeLabels = { [VerificationMode.CERTIFICATE]: i18n.translate( - 'xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.certificate.label', + 'xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.certificate.label', { defaultMessage: 'Certificate', } ), [VerificationMode.FULL]: i18n.translate( - 'xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.full.label', + 'xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.full.label', { defaultMessage: 'Full', } ), [VerificationMode.NONE]: i18n.translate( - 'xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.none.label', + 'xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.none.label', { defaultMessage: 'None', } ), [VerificationMode.STRICT]: i18n.translate( - 'xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.strict.label', + 'xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.strict.label', { defaultMessage: 'Strict', } diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/browser_context.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/browser_context.tsx new file mode 100644 index 0000000000000..e89e4dcd1d5bd --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/browser_context.tsx @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { createContext, useContext, useMemo, useState } from 'react'; +import { BrowserSimpleFields } from '../types'; +import { DEFAULT_BROWSER_SIMPLE_FIELDS } from '../../../../../common/constants/monitor_defaults'; + +interface BrowserSimpleFieldsContext { + setFields: React.Dispatch>; + fields: BrowserSimpleFields; + defaultValues: BrowserSimpleFields; +} + +interface BrowserSimpleFieldsContextProvider { + children: React.ReactNode; + defaultValues?: BrowserSimpleFields; +} + +export const initialValues: BrowserSimpleFields = DEFAULT_BROWSER_SIMPLE_FIELDS; + +const defaultContext: BrowserSimpleFieldsContext = { + setFields: (_fields: React.SetStateAction) => { + throw new Error( + 'setFields was not initialized for Browser Simple Fields, set it when you invoke the context' + ); + }, + fields: initialValues, // mutable + defaultValues: initialValues, // immutable +}; + +export const BrowserSimpleFieldsContext = createContext(defaultContext); + +export const BrowserSimpleFieldsContextProvider = ({ + children, + defaultValues = initialValues, +}: BrowserSimpleFieldsContextProvider) => { + const [fields, setFields] = useState(defaultValues); + + const value = useMemo(() => { + return { fields, setFields, defaultValues }; + }, [fields, defaultValues]); + + return ; +}; + +export const useBrowserSimpleFieldsContext = () => useContext(BrowserSimpleFieldsContext); diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/browser_context_advanced.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/browser_context_advanced.tsx similarity index 75% rename from x-pack/plugins/synthetics/public/components/fleet_package/contexts/browser_context_advanced.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/browser_context_advanced.tsx index 3ddd7953a6310..d81e1dc631ee2 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/browser_context_advanced.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/browser_context_advanced.tsx @@ -6,7 +6,8 @@ */ import React, { createContext, useContext, useMemo, useState } from 'react'; -import { BrowserAdvancedFields, ConfigKey, ScreenshotOption } from '../types'; +import { BrowserAdvancedFields } from '../types'; +import { DEFAULT_BROWSER_ADVANCED_FIELDS } from '../../../../../common/constants/monitor_defaults'; interface BrowserAdvancedFieldsContext { setFields: React.Dispatch>; @@ -19,18 +20,7 @@ interface BrowserAdvancedFieldsContextProvider { defaultValues?: BrowserAdvancedFields; } -export const initialValues: BrowserAdvancedFields = { - [ConfigKey.SCREENSHOTS]: ScreenshotOption.ON, - [ConfigKey.SYNTHETICS_ARGS]: [], - [ConfigKey.JOURNEY_FILTERS_MATCH]: '', - [ConfigKey.JOURNEY_FILTERS_TAGS]: [], - [ConfigKey.IGNORE_HTTPS_ERRORS]: false, - [ConfigKey.IS_THROTTLING_ENABLED]: true, - [ConfigKey.DOWNLOAD_SPEED]: '5', - [ConfigKey.UPLOAD_SPEED]: '3', - [ConfigKey.LATENCY]: '20', - [ConfigKey.THROTTLING_CONFIG]: '5d/3u/20l', -}; +export const initialValues: BrowserAdvancedFields = DEFAULT_BROWSER_ADVANCED_FIELDS; const defaultContext: BrowserAdvancedFieldsContext = { setFields: (_fields: React.SetStateAction) => { diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/browser_provider.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/browser_provider.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/contexts/browser_provider.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/browser_provider.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/http_context.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/http_context.tsx similarity index 79% rename from x-pack/plugins/synthetics/public/components/fleet_package/contexts/http_context.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/http_context.tsx index a4a0c7bb16aa8..d45dfc01f0de6 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/http_context.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/http_context.tsx @@ -6,8 +6,8 @@ */ import React, { createContext, useContext, useMemo, useState } from 'react'; -import { HTTPSimpleFields, ConfigKey, DataStream } from '../types'; -import { defaultValues as commonDefaultValues } from '../common/default_values'; +import { HTTPSimpleFields } from '../types'; +import { DEFAULT_HTTP_SIMPLE_FIELDS } from '../../../../../common/constants/monitor_defaults'; interface HTTPSimpleFieldsContext { setFields: React.Dispatch>; @@ -20,15 +20,7 @@ interface HTTPSimpleFieldsContextProvider { defaultValues?: HTTPSimpleFields; } -export const initialValues: HTTPSimpleFields = { - ...commonDefaultValues, - [ConfigKey.METADATA]: { - is_tls_enabled: false, - }, - [ConfigKey.URLS]: '', - [ConfigKey.MAX_REDIRECTS]: '0', - [ConfigKey.MONITOR_TYPE]: DataStream.HTTP, -}; +export const initialValues: HTTPSimpleFields = DEFAULT_HTTP_SIMPLE_FIELDS; const defaultContext: HTTPSimpleFieldsContext = { setFields: (_fields: React.SetStateAction) => { diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/http_context_advanced.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/http_context_advanced.tsx new file mode 100644 index 0000000000000..549f314bc3d3a --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/http_context_advanced.tsx @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { createContext, useContext, useMemo, useState } from 'react'; +import { HTTPAdvancedFields } from '../types'; +import { DEFAULT_HTTP_ADVANCED_FIELDS } from '../../../../../common/constants/monitor_defaults'; + +interface HTTPAdvancedFieldsContext { + setFields: React.Dispatch>; + fields: HTTPAdvancedFields; + defaultValues: HTTPAdvancedFields; +} + +interface HTTPAdvancedFieldsContextProvider { + children: React.ReactNode; + defaultValues?: HTTPAdvancedFields; +} + +export const initialValues: HTTPAdvancedFields = DEFAULT_HTTP_ADVANCED_FIELDS; + +export const defaultContext: HTTPAdvancedFieldsContext = { + setFields: (_fields: React.SetStateAction) => { + throw new Error('setFields was not initialized, set it when you invoke the context'); + }, + fields: initialValues, + defaultValues: initialValues, +}; + +export const HTTPAdvancedFieldsContext = createContext(defaultContext); + +export const HTTPAdvancedFieldsContextProvider = ({ + children, + defaultValues = initialValues, +}: HTTPAdvancedFieldsContextProvider) => { + const [fields, setFields] = useState(defaultValues); + + const value = useMemo(() => { + return { fields, setFields, defaultValues }; + }, [fields, defaultValues]); + + return ; +}; + +export const useHTTPAdvancedFieldsContext = () => useContext(HTTPAdvancedFieldsContext); diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/http_provider.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/http_provider.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/contexts/http_provider.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/http_provider.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/icmp_context.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/icmp_context.tsx similarity index 82% rename from x-pack/plugins/synthetics/public/components/fleet_package/contexts/icmp_context.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/icmp_context.tsx index f0547e621afc4..4e7667650ff10 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/icmp_context.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/icmp_context.tsx @@ -6,8 +6,8 @@ */ import React, { createContext, useContext, useMemo, useState } from 'react'; -import { ICMPSimpleFields, ConfigKey, DataStream } from '../types'; -import { defaultValues as commonDefaultValues } from '../common/default_values'; +import { ICMPSimpleFields } from '../types'; +import { DEFAULT_ICMP_SIMPLE_FIELDS } from '../../../../../common/constants/monitor_defaults'; interface ICMPSimpleFieldsContext { setFields: React.Dispatch>; @@ -20,12 +20,7 @@ interface ICMPSimpleFieldsContextProvider { defaultValues?: ICMPSimpleFields; } -export const initialValues: ICMPSimpleFields = { - ...commonDefaultValues, - [ConfigKey.HOSTS]: '', - [ConfigKey.MONITOR_TYPE]: DataStream.ICMP, - [ConfigKey.WAIT]: '1', -}; +export const initialValues: ICMPSimpleFields = DEFAULT_ICMP_SIMPLE_FIELDS; const defaultContext: ICMPSimpleFieldsContext = { setFields: (_fields: React.SetStateAction) => { diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/index.ts new file mode 100644 index 0000000000000..a80e295e8bc40 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/index.ts @@ -0,0 +1,66 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +export type { IPolicyConfigContextProvider } from './policy_config_context'; +export { + PolicyConfigContext, + PolicyConfigContextProvider, + initialValue as defaultPolicyConfig, + defaultContext as defaultPolicyConfigValues, + usePolicyConfigContext, +} from './policy_config_context'; +export { + HTTPSimpleFieldsContext, + HTTPSimpleFieldsContextProvider, + initialValues as defaultHTTPSimpleFields, + useHTTPSimpleFieldsContext, +} from './http_context'; +export { + HTTPAdvancedFieldsContext, + HTTPAdvancedFieldsContextProvider, + initialValues as defaultHTTPAdvancedFields, + useHTTPAdvancedFieldsContext, +} from './http_context_advanced'; +export { + TCPSimpleFieldsContext, + TCPSimpleFieldsContextProvider, + initialValues as defaultTCPSimpleFields, + useTCPSimpleFieldsContext, +} from './tcp_context'; +export { + ICMPSimpleFieldsContext, + ICMPSimpleFieldsContextProvider, + initialValues as defaultICMPSimpleFields, + useICMPSimpleFieldsContext, +} from './icmp_context'; +export { + TCPAdvancedFieldsContext, + TCPAdvancedFieldsContextProvider, + initialValues as defaultTCPAdvancedFields, + useTCPAdvancedFieldsContext, +} from './tcp_context_advanced'; +export { + BrowserSimpleFieldsContext, + BrowserSimpleFieldsContextProvider, + initialValues as defaultBrowserSimpleFields, + useBrowserSimpleFieldsContext, +} from './browser_context'; +export { + BrowserAdvancedFieldsContext, + BrowserAdvancedFieldsContextProvider, + initialValues as defaultBrowserAdvancedFields, + useBrowserAdvancedFieldsContext, +} from './browser_context_advanced'; +export { + TLSFieldsContext, + TLSFieldsContextProvider, + initialValues as defaultTLSFields, + useTLSFieldsContext, +} from './tls_fields_context'; +export { HTTPContextProvider } from './http_provider'; +export { TCPContextProvider } from './tcp_provider'; +export { BrowserContextProvider } from './browser_provider'; +export { SyntheticsProviders } from './synthetics_context_providers'; diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/policy_config_context.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/policy_config_context.tsx similarity index 97% rename from x-pack/plugins/synthetics/public/components/fleet_package/contexts/policy_config_context.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/policy_config_context.tsx index 5d47b4e9d0984..49f83d9577661 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/policy_config_context.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/policy_config_context.tsx @@ -6,13 +6,13 @@ */ import React, { createContext, useContext, useMemo, useState } from 'react'; -import { DEFAULT_NAMESPACE_STRING } from '../../../../common/constants'; +import { DEFAULT_NAMESPACE_STRING } from '../../../../../common/constants/monitor_defaults'; import { ScheduleUnit, MonitorServiceLocations, ThrottlingOptions, DEFAULT_THROTTLING, -} from '../../../../common/runtime_types'; +} from '../../../../../common/runtime_types'; import { DataStream } from '../types'; interface IPolicyConfigContext { diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/synthetics_context_providers.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/synthetics_context_providers.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/contexts/synthetics_context_providers.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/synthetics_context_providers.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/tcp_context.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/tcp_context.tsx similarity index 80% rename from x-pack/plugins/synthetics/public/components/fleet_package/contexts/tcp_context.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/tcp_context.tsx index 38a15c3e39453..9b3e1052100e9 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/tcp_context.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/tcp_context.tsx @@ -6,8 +6,8 @@ */ import React, { createContext, useContext, useMemo, useState } from 'react'; -import { TCPSimpleFields, ConfigKey, DataStream } from '../types'; -import { defaultValues as commonDefaultValues } from '../common/default_values'; +import { TCPSimpleFields } from '../types'; +import { DEFAULT_TCP_SIMPLE_FIELDS } from '../../../../../common/constants/monitor_defaults'; interface TCPSimpleFieldsContext { setFields: React.Dispatch>; @@ -20,14 +20,7 @@ interface TCPSimpleFieldsContextProvider { defaultValues?: TCPSimpleFields; } -export const initialValues: TCPSimpleFields = { - ...commonDefaultValues, - [ConfigKey.METADATA]: { - is_tls_enabled: false, - }, - [ConfigKey.HOSTS]: '', - [ConfigKey.MONITOR_TYPE]: DataStream.TCP, -}; +export const initialValues: TCPSimpleFields = DEFAULT_TCP_SIMPLE_FIELDS; const defaultContext: TCPSimpleFieldsContext = { setFields: (_fields: React.SetStateAction) => { diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/tcp_context_advanced.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/tcp_context_advanced.tsx similarity index 84% rename from x-pack/plugins/synthetics/public/components/fleet_package/contexts/tcp_context_advanced.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/tcp_context_advanced.tsx index 7fe29f7648841..8d1174ed96bc6 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/tcp_context_advanced.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/tcp_context_advanced.tsx @@ -6,7 +6,8 @@ */ import React, { createContext, useContext, useMemo, useState } from 'react'; -import { TCPAdvancedFields, ConfigKey } from '../types'; +import { TCPAdvancedFields } from '../types'; +import { DEFAULT_TCP_ADVANCED_FIELDS } from '../../../../../common/constants/monitor_defaults'; interface TCPAdvancedFieldsContext { setFields: React.Dispatch>; @@ -19,12 +20,7 @@ interface TCPAdvancedFieldsContextProvider { defaultValues?: TCPAdvancedFields; } -export const initialValues: TCPAdvancedFields = { - [ConfigKey.PROXY_URL]: '', - [ConfigKey.PROXY_USE_LOCAL_RESOLVER]: false, - [ConfigKey.RESPONSE_RECEIVE_CHECK]: '', - [ConfigKey.REQUEST_SEND_CHECK]: '', -}; +export const initialValues: TCPAdvancedFields = DEFAULT_TCP_ADVANCED_FIELDS; const defaultContext: TCPAdvancedFieldsContext = { setFields: (_fields: React.SetStateAction) => { diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/tcp_provider.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/tcp_provider.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/contexts/tcp_provider.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/tcp_provider.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/tls_fields_context.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/tls_fields_context.tsx similarity index 90% rename from x-pack/plugins/synthetics/public/components/fleet_package/contexts/tls_fields_context.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/tls_fields_context.tsx index a76655a235c4f..14ec64bf640b7 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/contexts/tls_fields_context.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/tls_fields_context.tsx @@ -7,7 +7,7 @@ import React, { createContext, useContext, useMemo, useState } from 'react'; import { TLSFields } from '../types'; -import { defaultValues as tlsDefaultValues } from '../tls/default_values'; +import { DEFAULT_TLS_FIELDS } from '../../../../../common/constants/monitor_defaults'; interface TLSFieldsContext { setFields: React.Dispatch>; @@ -20,7 +20,7 @@ interface TLSFieldsContextProvider { defaultValues?: TLSFields; } -export const initialValues: TLSFields = tlsDefaultValues; +export const initialValues: TLSFields = DEFAULT_TLS_FIELDS; const defaultContext: TLSFieldsContext = { setFields: (_fields: React.SetStateAction) => { diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/custom_fields.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/custom_fields.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/custom_fields.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/custom_fields.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/custom_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/custom_fields.tsx similarity index 87% rename from x-pack/plugins/synthetics/public/components/fleet_package/custom_fields.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/custom_fields.tsx index f1e4210f206d4..928c11249f698 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/custom_fields.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/custom_fields.tsx @@ -47,7 +47,7 @@ const dataStreamToString = [ { value: DataStream.BROWSER, text: i18n.translate( - 'xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browserLabel', + 'xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browserLabel', { defaultMessage: 'Browser (Beta)', } @@ -104,14 +104,14 @@ export const CustomFields = memo( title={

} description={ } @@ -124,7 +124,7 @@ export const CustomFields = memo( } @@ -135,7 +135,7 @@ export const CustomFields = memo( } error={ } @@ -154,7 +154,7 @@ export const CustomFields = memo( ( external >
@@ -187,14 +187,14 @@ export const CustomFields = memo( title={

} description={ } @@ -206,7 +206,7 @@ export const CustomFields = memo( checked={!!isTLSEnabled} label={ } diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/header_field.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/header_field.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/header_field.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/header_field.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/header_field.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/header_field.tsx similarity index 95% rename from x-pack/plugins/synthetics/public/components/fleet_package/header_field.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/header_field.tsx index c80ed6cd300f7..112a0879d404d 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/header_field.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/header_field.tsx @@ -57,7 +57,7 @@ export const HeaderField = ({ } diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/helpers/context_helpers.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/helpers/context_helpers.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/helpers/context_helpers.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/helpers/context_helpers.ts diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/helpers/formatters.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/helpers/formatters.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/helpers/formatters.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/helpers/formatters.ts diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/helpers/normalizers.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/helpers/normalizers.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/helpers/normalizers.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/helpers/normalizers.ts diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/hooks/use_policy.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/hooks/use_policy.ts similarity index 84% rename from x-pack/plugins/synthetics/public/components/fleet_package/hooks/use_policy.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/hooks/use_policy.ts index 2fc33de1bab39..9f43cbb238a79 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/hooks/use_policy.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/hooks/use_policy.ts @@ -25,34 +25,10 @@ import { useTLSFieldsContext, useBrowserSimpleFieldsContext, useBrowserAdvancedFieldsContext, - defaultHTTPAdvancedFields, - defaultHTTPSimpleFields, - defaultICMPSimpleFields, - defaultTCPSimpleFields, - defaultTCPAdvancedFields, - defaultBrowserSimpleFields, - defaultBrowserAdvancedFields, - defaultTLSFields, } from '../contexts'; +import { DEFAULT_FIELDS } from '../../../../../common/constants/monitor_defaults'; -export const defaultConfig: PolicyConfig = { - [DataStream.HTTP]: { - ...defaultHTTPSimpleFields, - ...defaultHTTPAdvancedFields, - ...defaultTLSFields, - }, - [DataStream.TCP]: { - ...defaultTCPSimpleFields, - ...defaultTCPAdvancedFields, - ...defaultTLSFields, - }, - [DataStream.ICMP]: defaultICMPSimpleFields, - [DataStream.BROWSER]: { - ...defaultBrowserSimpleFields, - ...defaultBrowserAdvancedFields, - ...defaultTLSFields, - }, -}; +export const defaultConfig: PolicyConfig = DEFAULT_FIELDS; export const usePolicy = (fleetPolicyName: string = '') => { const { diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/hooks/use_update_policy.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/hooks/use_update_policy.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/hooks/use_update_policy.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/hooks/use_update_policy.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/hooks/use_update_policy.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/hooks/use_update_policy.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/hooks/use_update_policy.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/hooks/use_update_policy.ts diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/http/advanced_fields.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/http/advanced_fields.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/http/advanced_fields.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/http/advanced_fields.test.tsx diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/http/advanced_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/http/advanced_fields.tsx new file mode 100644 index 0000000000000..e2afb91e3f684 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/http/advanced_fields.tsx @@ -0,0 +1,492 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, memo } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { + EuiAccordion, + EuiCode, + EuiFieldText, + EuiFormRow, + EuiSelect, + EuiCheckbox, + EuiSpacer, + EuiFieldPassword, +} from '@elastic/eui'; +import { DescribedFormGroupWithWrap } from '../common/described_form_group_with_wrap'; + +import { useHTTPAdvancedFieldsContext } from '../contexts'; + +import { ConfigKey, HTTPMethod, Validation } from '../types'; + +import { OptionalLabel } from '../optional_label'; +import { HeaderField } from '../header_field'; +import { RequestBodyField } from '../request_body_field'; +import { ResponseBodyIndexField } from '../index_response_body_field'; +import { ComboBox } from '../combo_box'; + +interface Props { + validate: Validation; + children?: React.ReactNode; + minColumnWidth?: string; + onFieldBlur?: (field: ConfigKey) => void; +} + +export const HTTPAdvancedFields = memo( + ({ validate, children, minColumnWidth, onFieldBlur }) => { + const { fields, setFields } = useHTTPAdvancedFieldsContext(); + const handleInputChange = useCallback( + ({ value, configKey }: { value: unknown; configKey: ConfigKey }) => { + setFields((prevFields) => ({ ...prevFields, [configKey]: value })); + }, + [setFields] + ); + + return ( + + } + data-test-subj="syntheticsHTTPAdvancedFieldsAccordion" + > + + + + + } + description={ + + } + data-test-subj="httpAdvancedFieldsSection" + > + + + } + labelAppend={} + helpText={ + + } + > + + handleInputChange({ + value: event.target.value, + configKey: ConfigKey.USERNAME, + }) + } + onBlur={() => onFieldBlur?.(ConfigKey.USERNAME)} + data-test-subj="syntheticsUsername" + /> + + + } + labelAppend={} + helpText={ + + } + > + + handleInputChange({ + value: event.target.value, + configKey: ConfigKey.PASSWORD, + }) + } + onBlur={() => onFieldBlur?.(ConfigKey.PASSWORD)} + data-test-subj="syntheticsPassword" + /> + + + } + labelAppend={} + helpText={ + + } + > + + handleInputChange({ + value: event.target.value, + configKey: ConfigKey.PROXY_URL, + }) + } + onBlur={() => onFieldBlur?.(ConfigKey.PROXY_URL)} + data-test-subj="syntheticsProxyUrl" + /> + + + } + helpText={ + + } + > + + handleInputChange({ + value: event.target.value, + configKey: ConfigKey.REQUEST_METHOD_CHECK, + }) + } + onBlur={() => onFieldBlur?.(ConfigKey.REQUEST_METHOD_CHECK)} + data-test-subj="syntheticsRequestMethod" + /> + + + } + labelAppend={} + isInvalid={!!validate[ConfigKey.REQUEST_HEADERS_CHECK]?.(fields)} + error={ + + } + helpText={ + + } + > + + handleInputChange({ + value, + configKey: ConfigKey.REQUEST_HEADERS_CHECK, + }), + [handleInputChange] + )} + onBlur={() => onFieldBlur?.(ConfigKey.REQUEST_HEADERS_CHECK)} + data-test-subj="syntheticsRequestHeaders" + /> + + + } + labelAppend={} + helpText={ + + } + fullWidth + > + + handleInputChange({ + value, + configKey: ConfigKey.REQUEST_BODY_CHECK, + }), + [handleInputChange] + )} + onBlur={() => onFieldBlur?.(ConfigKey.REQUEST_BODY_CHECK)} + /> + + + + + + + } + description={ + + } + > + + + + http.response.body.headers + + } + data-test-subj="syntheticsIndexResponseHeaders" + > + + } + onChange={(event) => + handleInputChange({ + value: event.target.checked, + configKey: ConfigKey.RESPONSE_HEADERS_INDEX, + }) + } + onBlur={() => onFieldBlur?.(ConfigKey.RESPONSE_HEADERS_INDEX)} + /> + + + + http.response.body.contents + + } + > + + handleInputChange({ value: policy, configKey: ConfigKey.RESPONSE_BODY_INDEX }), + [handleInputChange] + )} + onBlur={() => onFieldBlur?.(ConfigKey.RESPONSE_BODY_INDEX)} + /> + + + + + + } + description={ + + } + > + + } + labelAppend={} + isInvalid={!!validate[ConfigKey.RESPONSE_STATUS_CHECK]?.(fields)} + error={ + + } + helpText={i18n.translate( + 'xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.responseStatusCheck.helpText', + { + defaultMessage: + 'A list of expected status codes. Press enter to add a new code. 4xx and 5xx codes are considered down by default. Other codes are considered up.', + } + )} + > + + handleInputChange({ + value, + configKey: ConfigKey.RESPONSE_STATUS_CHECK, + }) + } + onBlur={() => onFieldBlur?.(ConfigKey.RESPONSE_STATUS_CHECK)} + data-test-subj="syntheticsResponseStatusCheck" + /> + + + } + labelAppend={} + isInvalid={!!validate[ConfigKey.RESPONSE_HEADERS_CHECK]?.(fields)} + error={[ + , + ]} + helpText={ + + } + > + + handleInputChange({ + value, + configKey: ConfigKey.RESPONSE_HEADERS_CHECK, + }), + [handleInputChange] + )} + onBlur={() => onFieldBlur?.(ConfigKey.RESPONSE_HEADERS_CHECK)} + data-test-subj="syntheticsResponseHeaders" + /> + + + } + labelAppend={} + helpText={i18n.translate( + 'xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseBodyCheckPositive.helpText', + { + defaultMessage: + 'A list of regular expressions to match the body output. Press enter to add a new expression. Only a single expression needs to match.', + } + )} + > + + handleInputChange({ + value, + configKey: ConfigKey.RESPONSE_BODY_CHECK_POSITIVE, + }), + [handleInputChange] + )} + onBlur={() => onFieldBlur?.(ConfigKey.RESPONSE_BODY_CHECK_POSITIVE)} + data-test-subj="syntheticsResponseBodyCheckPositive" + /> + + + } + labelAppend={} + helpText={i18n.translate( + 'xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseBodyCheckNegative.helpText', + { + defaultMessage: + 'A list of regular expressions to match the the body output negatively. Press enter to add a new expression. Return match failed if single expression matches.', + } + )} + > + + handleInputChange({ + value, + configKey: ConfigKey.RESPONSE_BODY_CHECK_NEGATIVE, + }), + [handleInputChange] + )} + onBlur={() => onFieldBlur?.(ConfigKey.RESPONSE_BODY_CHECK_NEGATIVE)} + data-test-subj="syntheticsResponseBodyCheckNegative" + /> + + + {children} + + ); + } +); + +const requestMethodOptions = Object.values(HTTPMethod).map((method) => ({ + value: method, + text: method, +})); diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/http/formatters.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/http/formatters.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/http/formatters.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/http/formatters.ts diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/http/normalizers.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/http/normalizers.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/http/normalizers.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/http/normalizers.ts diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/http/simple_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/http/simple_fields.tsx new file mode 100644 index 0000000000000..9e7f2f4bab6af --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/http/simple_fields.tsx @@ -0,0 +1,126 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiFieldNumber, EuiFieldText, EuiFormRow } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import React, { memo, useCallback } from 'react'; +import { SimpleFieldsWrapper } from '../common/simple_fields_wrapper'; +import { useHTTPSimpleFieldsContext } from '../contexts'; +import { OptionalLabel } from '../optional_label'; +import { ScheduleField } from '../schedule_field'; +import { ConfigKey, Validation } from '../types'; + +interface Props { + validate: Validation; + onFieldBlur: (field: ConfigKey) => void; // To propagate blurred state up to parents +} + +export const HTTPSimpleFields = memo(({ validate, onFieldBlur }) => { + const { fields, setFields } = useHTTPSimpleFieldsContext(); + const handleInputChange = useCallback( + ({ value, configKey }: { value: unknown; configKey: ConfigKey }) => { + setFields((prevFields) => ({ ...prevFields, [configKey]: value })); + }, + [setFields] + ); + + return ( + + + } + isInvalid={!!validate[ConfigKey.URLS]?.(fields)} + error={ + + } + > + + handleInputChange({ value: event.target.value, configKey: ConfigKey.URLS }) + } + onBlur={() => onFieldBlur(ConfigKey.URLS)} + data-test-subj="syntheticsUrlField" + /> + + + } + isInvalid={!!validate[ConfigKey.SCHEDULE]?.(fields)} + error={ + + } + > + + handleInputChange({ + value: schedule, + configKey: ConfigKey.SCHEDULE, + }) + } + onBlur={() => onFieldBlur(ConfigKey.SCHEDULE)} + number={fields[ConfigKey.SCHEDULE].number} + unit={fields[ConfigKey.SCHEDULE].unit} + /> + + + } + isInvalid={!!validate[ConfigKey.MAX_REDIRECTS]?.(fields)} + error={ + + } + labelAppend={} + helpText={ + + } + > + + handleInputChange({ + value: event.target.value, + configKey: ConfigKey.MAX_REDIRECTS, + }) + } + onBlur={() => onFieldBlur(ConfigKey.MAX_REDIRECTS)} + /> + + + ); +}); diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/icmp/advanced_fields.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/icmp/advanced_fields.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/icmp/advanced_fields.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/icmp/advanced_fields.test.tsx diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/icmp/advanced_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/icmp/advanced_fields.tsx new file mode 100644 index 0000000000000..7aac2de3cf14e --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/icmp/advanced_fields.tsx @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiAccordion, EuiSpacer } from '@elastic/eui'; +import React from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; + +export const ICMPAdvancedFields = ({ children }: { children?: React.ReactNode }) => { + if (!!children) { + return ( + + } + data-test-subj="syntheticsICMPAdvancedFieldsAccordion" + > + + {children} + + ); + } + + return <>; +}; diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/icmp/formatters.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/icmp/formatters.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/icmp/formatters.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/icmp/formatters.ts diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/icmp/normalizers.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/icmp/normalizers.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/icmp/normalizers.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/icmp/normalizers.ts diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/icmp/simple_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/icmp/simple_fields.tsx new file mode 100644 index 0000000000000..c420fce0176b7 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/icmp/simple_fields.tsx @@ -0,0 +1,130 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo, useCallback } from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { EuiFormRow, EuiFieldText, EuiFieldNumber } from '@elastic/eui'; +import { ConfigKey, Validation } from '../types'; +import { useICMPSimpleFieldsContext } from '../contexts'; +import { OptionalLabel } from '../optional_label'; +import { ScheduleField } from '../schedule_field'; +import { SimpleFieldsWrapper } from '../common/simple_fields_wrapper'; + +interface Props { + validate: Validation; + onFieldBlur: (field: ConfigKey) => void; // To propagate blurred state up to parents +} + +export const ICMPSimpleFields = memo(({ validate, onFieldBlur }) => { + const { fields, setFields } = useICMPSimpleFieldsContext(); + const handleInputChange = useCallback( + ({ value, configKey }: { value: unknown; configKey: ConfigKey }) => { + setFields((prevFields) => ({ ...prevFields, [configKey]: value })); + }, + [setFields] + ); + + return ( + + + } + isInvalid={!!validate[ConfigKey.HOSTS]?.(fields)} + error={ + + } + > + + handleInputChange({ + value: event.target.value, + configKey: ConfigKey.HOSTS, + }) + } + onBlur={() => onFieldBlur(ConfigKey.HOSTS)} + data-test-subj="syntheticsICMPHostField" + /> + + + } + isInvalid={!!validate[ConfigKey.SCHEDULE]?.(fields)} + error={ + + } + > + + handleInputChange({ + value: schedule, + configKey: ConfigKey.SCHEDULE, + }) + } + onBlur={() => onFieldBlur(ConfigKey.SCHEDULE)} + number={fields[ConfigKey.SCHEDULE].number} + unit={fields[ConfigKey.SCHEDULE].unit} + /> + + + } + isInvalid={!!validate[ConfigKey.WAIT]?.(fields)} + error={ + + } + labelAppend={} + helpText={ + + } + > + + handleInputChange({ + value: event.target.value, + configKey: ConfigKey.WAIT, + }) + } + onBlur={() => onFieldBlur(ConfigKey.WAIT)} + step={'any'} + /> + + + ); +}); diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/index.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/index.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/index.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/index.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/index_response_body_field.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/index_response_body_field.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/index_response_body_field.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/index_response_body_field.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/index_response_body_field.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/index_response_body_field.tsx similarity index 86% rename from x-pack/plugins/synthetics/public/components/fleet_package/index_response_body_field.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/index_response_body_field.tsx index b8b350b84d104..aff500151e685 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/index_response_body_field.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/index_response_body_field.tsx @@ -45,7 +45,7 @@ export const ResponseBodyIndexField = ({ defaultValue, onChange, onBlur }: Props checked={checked} label={ } @@ -60,7 +60,7 @@ export const ResponseBodyIndexField = ({ defaultValue, onChange, onBlur }: Props { } @@ -128,7 +128,7 @@ export const KeyValuePairsField = ({ { } @@ -151,7 +151,7 @@ export const KeyValuePairsField = ({ handleOnChange(event, index, true)} @@ -174,9 +177,12 @@ export const KeyValuePairsField = ({ } endControl={ handleOnChange(event, index, false)} diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/lazy_synthetics_custom_assets_extension.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/lazy_synthetics_custom_assets_extension.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/lazy_synthetics_custom_assets_extension.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/lazy_synthetics_custom_assets_extension.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/lazy_synthetics_policy_create_extension.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/lazy_synthetics_policy_create_extension.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/lazy_synthetics_policy_create_extension.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/lazy_synthetics_policy_create_extension.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/lazy_synthetics_policy_edit_extension.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/lazy_synthetics_policy_edit_extension.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/lazy_synthetics_policy_edit_extension.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/lazy_synthetics_policy_edit_extension.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/optional_label.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/optional_label.tsx similarity index 85% rename from x-pack/plugins/synthetics/public/components/fleet_package/optional_label.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/optional_label.tsx index 8d81b77b01faf..a9db178a84bb3 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/optional_label.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/optional_label.tsx @@ -12,7 +12,7 @@ export const OptionalLabel = () => { return ( diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/request_body_field.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/request_body_field.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/request_body_field.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/request_body_field.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/request_body_field.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/request_body_field.tsx similarity index 86% rename from x-pack/plugins/synthetics/public/components/fleet_package/request_body_field.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/request_body_field.tsx index a81a4b076ad70..19cb8cda978f8 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/request_body_field.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/request_body_field.tsx @@ -87,7 +87,7 @@ export const RequestBodyField = ({ onChange, onBlur, type, value }: Props) => { content: ( { content: ( { content: ( { } @@ -180,24 +180,27 @@ export const RequestBodyField = ({ onChange, onBlur, type, value }: Props) => { const modeLabels = { [Mode.FORM]: i18n.translate( - 'xpack.uptime.createPackagePolicy.stepConfigure.requestBodyType.form', + 'xpack.synthetics.createPackagePolicy.stepConfigure.requestBodyType.form', { defaultMessage: 'Form', } ), [Mode.PLAINTEXT]: i18n.translate( - 'xpack.uptime.createPackagePolicy.stepConfigure.requestBodyType.text', + 'xpack.synthetics.createPackagePolicy.stepConfigure.requestBodyType.text', { defaultMessage: 'Text', } ), [Mode.JSON]: i18n.translate( - 'xpack.uptime.createPackagePolicy.stepConfigure.requestBodyType.JSON', + 'xpack.synthetics.createPackagePolicy.stepConfigure.requestBodyType.JSON', { defaultMessage: 'JSON', } ), - [Mode.XML]: i18n.translate('xpack.uptime.createPackagePolicy.stepConfigure.requestBodyType.XML', { - defaultMessage: 'XML', - }), + [Mode.XML]: i18n.translate( + 'xpack.synthetics.createPackagePolicy.stepConfigure.requestBodyType.XML', + { + defaultMessage: 'XML', + } + ), }; diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/schedule_field.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/schedule_field.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/schedule_field.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/schedule_field.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/schedule_field.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/schedule_field.tsx similarity index 84% rename from x-pack/plugins/synthetics/public/components/fleet_package/schedule_field.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/schedule_field.tsx index d24095a7824c8..e5d5d05a3cd77 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/schedule_field.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/schedule_field.tsx @@ -32,7 +32,7 @@ export const ScheduleField = ({ number, onChange, onBlur, unit }: Props) => { { { const allOptions = [ { - text: i18n.translate('xpack.uptime.createPackagePolicy.stepConfigure.scheduleField.seconds', { - defaultMessage: 'Seconds', - }), + text: i18n.translate( + 'xpack.synthetics.createPackagePolicy.stepConfigure.scheduleField.seconds', + { + defaultMessage: 'Seconds', + } + ), value: ScheduleUnit.SECONDS, }, { - text: i18n.translate('xpack.uptime.createPackagePolicy.stepConfigure.scheduleField.minutes', { - defaultMessage: 'Minutes', - }), + text: i18n.translate( + 'xpack.synthetics.createPackagePolicy.stepConfigure.scheduleField.minutes', + { + defaultMessage: 'Minutes', + } + ), value: ScheduleUnit.MINUTES, }, ]; diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/synthetics_custom_assets_extension.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_custom_assets_extension.tsx similarity index 76% rename from x-pack/plugins/synthetics/public/components/fleet_package/synthetics_custom_assets_extension.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_custom_assets_extension.tsx index 65ebdf27dd374..64d1be74e71fd 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/synthetics_custom_assets_extension.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_custom_assets_extension.tsx @@ -14,18 +14,18 @@ import { CustomAssetsAccordion, } from '@kbn/fleet-plugin/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { ClientPluginsStart } from '../../apps/plugin'; -import { PLUGIN } from '../../../common/constants/plugin'; +import { ClientPluginsStart } from '../../../plugin'; +import { PLUGIN } from '../../../../common/constants/plugin'; export const SyntheticsCustomAssetsExtension: PackageAssetsComponent = () => { const { http } = useKibana().services; const views: CustomAssetsAccordionProps['views'] = [ { - name: i18n.translate('xpack.uptime.fleetIntegration.assets.name', { + name: i18n.translate('xpack.synthetics.fleetIntegration.assets.name', { defaultMessage: 'Monitors', }), url: http?.basePath.prepend(`/app/${PLUGIN.ID}`) ?? '', - description: i18n.translate('xpack.uptime.fleetIntegration.assets.description', { + description: i18n.translate('xpack.synthetics.fleetIntegration.assets.description', { defaultMessage: 'View monitors in Uptime', }), }, diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/synthetics_policy_create_extension.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_create_extension.tsx similarity index 76% rename from x-pack/plugins/synthetics/public/components/fleet_package/synthetics_policy_create_extension.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_create_extension.tsx index e93cc20e4d2ad..6247619f6a3b6 100644 --- a/x-pack/plugins/synthetics/public/components/fleet_package/synthetics_policy_create_extension.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_create_extension.tsx @@ -10,40 +10,14 @@ import { PackagePolicyCreateExtensionComponentProps } from '@kbn/fleet-plugin/pu import { useTrackPageview } from '@kbn/observability-plugin/public'; import { DataStream } from './types'; import { PolicyConfig } from './types'; -import { - usePolicyConfigContext, - defaultHTTPSimpleFields, - defaultHTTPAdvancedFields, - defaultTCPSimpleFields, - defaultTCPAdvancedFields, - defaultICMPSimpleFields, - defaultBrowserSimpleFields, - defaultBrowserAdvancedFields, - defaultTLSFields, -} from './contexts'; +import { usePolicyConfigContext } from './contexts'; +import { DEFAULT_FIELDS } from '../../../../common/constants/monitor_defaults'; import { CustomFields } from './custom_fields'; import { useUpdatePolicy } from './hooks/use_update_policy'; import { usePolicy } from './hooks/use_policy'; import { validate } from './validation'; -export const defaultConfig: PolicyConfig = { - [DataStream.HTTP]: { - ...defaultHTTPSimpleFields, - ...defaultHTTPAdvancedFields, - ...defaultTLSFields, - }, - [DataStream.TCP]: { - ...defaultTCPSimpleFields, - ...defaultTCPAdvancedFields, - ...defaultTLSFields, - }, - [DataStream.ICMP]: defaultICMPSimpleFields, - [DataStream.BROWSER]: { - ...defaultBrowserSimpleFields, - ...defaultBrowserAdvancedFields, - ...defaultTLSFields, - }, -}; +export const defaultConfig: PolicyConfig = DEFAULT_FIELDS; /** * Exports Synthetics-specific package policy instructions diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/synthetics_policy_create_extension_wrapper.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_create_extension_wrapper.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/synthetics_policy_create_extension_wrapper.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_create_extension_wrapper.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/synthetics_policy_create_extension_wrapper.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_create_extension_wrapper.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/synthetics_policy_create_extension_wrapper.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_create_extension_wrapper.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/synthetics_policy_edit_extension.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_edit_extension.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/synthetics_policy_edit_extension.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_edit_extension.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/synthetics_policy_edit_extension_wrapper.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_edit_extension_wrapper.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/synthetics_policy_edit_extension_wrapper.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_edit_extension_wrapper.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/synthetics_policy_edit_extension_wrapper.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_edit_extension_wrapper.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/synthetics_policy_edit_extension_wrapper.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_edit_extension_wrapper.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/tcp/advanced_fields.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tcp/advanced_fields.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/tcp/advanced_fields.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tcp/advanced_fields.test.tsx diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tcp/advanced_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tcp/advanced_fields.tsx new file mode 100644 index 0000000000000..adc23ecffe3fd --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tcp/advanced_fields.tsx @@ -0,0 +1,187 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo, useCallback } from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { EuiAccordion, EuiCheckbox, EuiFormRow, EuiFieldText, EuiSpacer } from '@elastic/eui'; +import { DescribedFormGroupWithWrap } from '../common/described_form_group_with_wrap'; + +import { useTCPAdvancedFieldsContext } from '../contexts'; + +import { ConfigKey } from '../types'; + +import { OptionalLabel } from '../optional_label'; + +interface Props { + children?: React.ReactNode; + minColumnWidth?: string; + onFieldBlur?: (field: ConfigKey) => void; +} + +export const TCPAdvancedFields = memo(({ children, minColumnWidth, onFieldBlur }) => { + const { fields, setFields } = useTCPAdvancedFieldsContext(); + + const handleInputChange = useCallback( + ({ value, configKey }: { value: unknown; configKey: ConfigKey }) => { + setFields((prevFields) => ({ ...prevFields, [configKey]: value })); + }, + [setFields] + ); + + return ( + + + + + + } + description={ + + } + > + + + } + labelAppend={} + helpText={ + + } + > + + handleInputChange({ + value: event.target.value, + configKey: ConfigKey.PROXY_URL, + }) + } + onBlur={() => onFieldBlur?.(ConfigKey.PROXY_URL)} + data-test-subj="syntheticsProxyUrl" + /> + + {!!fields[ConfigKey.PROXY_URL] && ( + + + } + onChange={(event) => + handleInputChange({ + value: event.target.checked, + configKey: ConfigKey.PROXY_USE_LOCAL_RESOLVER, + }) + } + /> + + )} + + } + labelAppend={} + helpText={ + + } + > + + handleInputChange({ + value: event.target.value, + configKey: ConfigKey.REQUEST_SEND_CHECK, + }), + [handleInputChange] + )} + onBlur={() => onFieldBlur?.(ConfigKey.REQUEST_SEND_CHECK)} + data-test-subj="syntheticsTCPRequestSendCheck" + /> + + + + + + } + description={ + + } + > + + } + labelAppend={} + helpText={ + + } + > + + handleInputChange({ + value: event.target.value, + configKey: ConfigKey.RESPONSE_RECEIVE_CHECK, + }), + [handleInputChange] + )} + onBlur={() => onFieldBlur?.(ConfigKey.RESPONSE_RECEIVE_CHECK)} + data-test-subj="syntheticsTCPResponseReceiveCheck" + /> + + + {children} + + ); +}); diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/tcp/formatters.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tcp/formatters.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/tcp/formatters.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tcp/formatters.ts diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/tcp/normalizers.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tcp/normalizers.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/tcp/normalizers.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tcp/normalizers.ts diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tcp/simple_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tcp/simple_fields.tsx new file mode 100644 index 0000000000000..b9f5c7a990b49 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tcp/simple_fields.tsx @@ -0,0 +1,95 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo, useCallback } from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { EuiFormRow, EuiFieldText } from '@elastic/eui'; +import { ConfigKey, Validation } from '../types'; +import { useTCPSimpleFieldsContext } from '../contexts'; +import { ScheduleField } from '../schedule_field'; +import { SimpleFieldsWrapper } from '../common/simple_fields_wrapper'; + +interface Props { + validate: Validation; + onFieldBlur: (field: ConfigKey) => void; // To propagate blurred state up to parents +} + +export const TCPSimpleFields = memo(({ validate, onFieldBlur }) => { + const { fields, setFields } = useTCPSimpleFieldsContext(); + const handleInputChange = useCallback( + ({ value, configKey }: { value: unknown; configKey: ConfigKey }) => { + setFields((prevFields) => ({ ...prevFields, [configKey]: value })); + }, + [setFields] + ); + + return ( + + + } + isInvalid={!!validate[ConfigKey.HOSTS]?.(fields)} + error={ + + } + > + + handleInputChange({ + value: event.target.value, + configKey: ConfigKey.HOSTS, + }) + } + onBlur={() => onFieldBlur(ConfigKey.HOSTS)} + data-test-subj="syntheticsTCPHostField" + /> + + + + } + isInvalid={!!validate[ConfigKey.SCHEDULE]?.(fields)} + error={ + + } + > + + handleInputChange({ + value: schedule, + configKey: ConfigKey.SCHEDULE, + }) + } + onBlur={() => onFieldBlur(ConfigKey.SCHEDULE)} + number={fields[ConfigKey.SCHEDULE].number} + unit={fields[ConfigKey.SCHEDULE].unit} + /> + + + ); +}); diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/tls/formatters.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tls/formatters.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/tls/formatters.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tls/formatters.ts diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/tls/normalizers.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tls/normalizers.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/tls/normalizers.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tls/normalizers.ts diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/tls_fields.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tls_fields.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/tls_fields.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tls_fields.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/tls_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tls_fields.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/tls_fields.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tls_fields.tsx diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/types.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/types.tsx new file mode 100644 index 0000000000000..0a5de311c5cb3 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/types.tsx @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { + HTTPFields, + TCPFields, + ICMPFields, + BrowserFields, + ConfigKey, + ContentType, + DataStream, + Mode, + ThrottlingConfigKey, + ThrottlingSuffix, + ThrottlingSuffixType, +} from '../../../../common/runtime_types'; +export * from '../../../../common/runtime_types/monitor_management'; +export * from '../../../../common/types/monitor_validation'; + +export interface PolicyConfig { + [DataStream.HTTP]: HTTPFields; + [DataStream.TCP]: TCPFields; + [DataStream.ICMP]: ICMPFields; + [DataStream.BROWSER]: BrowserFields; +} + +export const contentTypesToMode = { + [ContentType.FORM]: Mode.FORM, + [ContentType.JSON]: Mode.JSON, + [ContentType.TEXT]: Mode.PLAINTEXT, + [ContentType.XML]: Mode.XML, +}; + +export const configKeyToThrottlingSuffix: Record = { + [ConfigKey.DOWNLOAD_SPEED]: ThrottlingSuffix.DOWNLOAD, + [ConfigKey.UPLOAD_SPEED]: ThrottlingSuffix.UPLOAD, + [ConfigKey.LATENCY]: ThrottlingSuffix.LATENCY, +}; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/validation.test.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/validation.test.ts new file mode 100644 index 0000000000000..b2cca04b44d1b --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/validation.test.ts @@ -0,0 +1,74 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + ConfigKey, + DataStream, + HTTPFields, + BrowserFields, + MonitorFields, + ScheduleUnit, +} from '../../../../common/runtime_types'; +import { validate } from './validation'; + +describe('[Monitor Management] validation', () => { + const commonPropsValid: Partial = { + [ConfigKey.SCHEDULE]: { number: '5', unit: ScheduleUnit.MINUTES }, + [ConfigKey.TIMEOUT]: '3m', + }; + + describe('HTTP', () => { + const httpPropsValid: Partial = { + ...commonPropsValid, + [ConfigKey.RESPONSE_STATUS_CHECK]: ['200', '204'], + [ConfigKey.RESPONSE_HEADERS_CHECK]: { 'Content-Type': 'application/json' }, + [ConfigKey.REQUEST_HEADERS_CHECK]: { 'Accept-Language': 'en-GB,en-US;q=0.9,en;q=0.8' }, + [ConfigKey.MAX_REDIRECTS]: '3', + [ConfigKey.URLS]: 'https:// example-url.com', + }; + + it('should return false for all valid props', () => { + const validators = validate[DataStream.HTTP]; + const keysToValidate = [ + ConfigKey.SCHEDULE, + ConfigKey.TIMEOUT, + ConfigKey.RESPONSE_STATUS_CHECK, + ConfigKey.RESPONSE_HEADERS_CHECK, + ConfigKey.REQUEST_HEADERS_CHECK, + ConfigKey.MAX_REDIRECTS, + ConfigKey.URLS, + ]; + const validatorFns = keysToValidate.map((key) => validators[key]); + const result = validatorFns.map((fn) => fn?.(httpPropsValid) ?? true); + + expect(result).not.toEqual(expect.arrayContaining([true])); + }); + }); + + describe.each([ + [ConfigKey.SOURCE_INLINE, 'step(() => {});'], + [ConfigKey.SOURCE_ZIP_URL, 'https://test.zip'], + ])('Browser', (configKey, value) => { + const browserProps: Partial = { + ...commonPropsValid, + [ConfigKey.MONITOR_TYPE]: DataStream.BROWSER, + [ConfigKey.TIMEOUT]: null, + [configKey]: value, + }; + + it('should return false for all valid props', () => { + const validators = validate[DataStream.BROWSER]; + const keysToValidate = [ConfigKey.SCHEDULE, ConfigKey.TIMEOUT, configKey]; + const validatorFns = keysToValidate.map((key) => validators[key]); + const result = validatorFns.map((fn) => fn?.(browserProps) ?? true); + + expect(result).not.toEqual(expect.arrayContaining([true])); + }); + }); + + // TODO: Add test for other monitor types if needed +}); diff --git a/x-pack/plugins/synthetics/public/components/fleet_package/validation.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/validation.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/fleet_package/validation.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/validation.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/__snapshots__/monitor_charts.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/__snapshots__/monitor_charts.test.tsx.snap similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/__snapshots__/monitor_charts.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/__snapshots__/monitor_charts.test.tsx.snap diff --git a/x-pack/plugins/synthetics/public/components/monitor/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/index.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/index.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/index.ts diff --git a/x-pack/plugins/synthetics/public/components/monitor/ml/__snapshots__/confirm_delete.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/__snapshots__/confirm_delete.test.tsx.snap similarity index 87% rename from x-pack/plugins/synthetics/public/components/monitor/ml/__snapshots__/confirm_delete.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/__snapshots__/confirm_delete.test.tsx.snap index 9d670158bc53a..aeab5ef85266d 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ml/__snapshots__/confirm_delete.test.tsx.snap +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/__snapshots__/confirm_delete.test.tsx.snap @@ -14,14 +14,14 @@ exports[`ML Confirm Job Delete shallow renders without errors 1`] = `

@@ -42,7 +42,7 @@ exports[`ML Confirm Job Delete shallow renders without errors while loading 1`]

) diff --git a/x-pack/plugins/synthetics/public/components/monitor/ml/__snapshots__/ml_integerations.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/__snapshots__/ml_integerations.test.tsx.snap similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ml/__snapshots__/ml_integerations.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/__snapshots__/ml_integerations.test.tsx.snap diff --git a/x-pack/plugins/synthetics/public/components/monitor/ml/confirm_alert_delete.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/confirm_alert_delete.tsx similarity index 93% rename from x-pack/plugins/synthetics/public/components/monitor/ml/confirm_alert_delete.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/confirm_alert_delete.tsx index 0d8700ff41169..0ba5f139d8f28 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ml/confirm_alert_delete.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/confirm_alert_delete.tsx @@ -29,7 +29,7 @@ export const ConfirmAlertDeletion: React.FC = ({ onConfirm, onCancel }) = >

diff --git a/x-pack/plugins/synthetics/public/components/monitor/ml/confirm_delete.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/confirm_delete.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ml/confirm_delete.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/confirm_delete.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/ml/confirm_delete.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/confirm_delete.tsx similarity index 88% rename from x-pack/plugins/synthetics/public/components/monitor/ml/confirm_delete.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/confirm_delete.tsx index a0d1d7b5c1732..ccbfbd917488a 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ml/confirm_delete.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/confirm_delete.tsx @@ -31,14 +31,14 @@ export const ConfirmJobDeletion: React.FC = ({ loading, onConfirm, onCanc {!loading ? (

) : (

) @@ -47,7 +47,7 @@ export const ConfirmJobDeletion: React.FC = ({ loading, onConfirm, onCanc {!loading ? (

diff --git a/x-pack/plugins/synthetics/public/components/monitor/ml/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/index.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ml/index.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/index.ts diff --git a/x-pack/plugins/synthetics/public/components/monitor/ml/license_info.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/license_info.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ml/license_info.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/license_info.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/ml/license_info.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/license_info.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ml/license_info.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/license_info.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/ml/manage_ml_job.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/manage_ml_job.tsx similarity index 98% rename from x-pack/plugins/synthetics/public/components/monitor/ml/manage_ml_job.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/manage_ml_job.tsx index 435eb7e4f9001..f6b8198a24699 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ml/manage_ml_job.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/manage_ml_job.tsx @@ -10,7 +10,7 @@ import React, { useCallback, useContext, useState } from 'react'; import { EuiButton, EuiContextMenu, EuiIcon, EuiPopover } from '@elastic/eui'; import { useSelector, useDispatch } from 'react-redux'; import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { CLIENT_ALERT_TYPES } from '../../../../common/constants/alerts'; +import { CLIENT_ALERT_TYPES } from '../../../../../common/constants/alerts'; import { canDeleteMLJobSelector, hasMLJobSelector, diff --git a/x-pack/plugins/synthetics/public/components/monitor/ml/ml_flyout.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/ml_flyout.test.tsx similarity index 98% rename from x-pack/plugins/synthetics/public/components/monitor/ml/ml_flyout.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/ml_flyout.test.tsx index 8669bc180f42f..6a0bda2c5fb04 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ml/ml_flyout.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/ml_flyout.test.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { MLFlyoutView } from './ml_flyout'; import { UptimeSettingsContext } from '../../../contexts'; -import { CLIENT_DEFAULTS } from '../../../../common/constants'; +import { CLIENT_DEFAULTS } from '../../../../../common/constants'; import * as redux from 'react-redux'; import { render, forNearestButton } from '../../../lib/helper/rtl_helpers'; import * as labels from './translations'; diff --git a/x-pack/plugins/synthetics/public/components/monitor/ml/ml_flyout.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/ml_flyout.tsx similarity index 94% rename from x-pack/plugins/synthetics/public/components/monitor/ml/ml_flyout.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/ml_flyout.tsx index c367b60a65016..d72b8893eeca0 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ml/ml_flyout.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/ml_flyout.tsx @@ -56,7 +56,7 @@ export function MLFlyoutView({ isCreatingJob, onClickCreate, onClose, canCreateM

{labels.CREAT_ML_JOB_DESC}

diff --git a/x-pack/plugins/synthetics/public/components/monitor/ml/ml_flyout_container.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/ml_flyout_container.tsx similarity index 98% rename from x-pack/plugins/synthetics/public/components/monitor/ml/ml_flyout_container.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/ml_flyout_container.tsx index 482e3f70b3180..49eaef7b176ac 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ml/ml_flyout_container.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/ml_flyout_container.tsx @@ -31,7 +31,7 @@ import { useGetUrlParams } from '../../../hooks'; import { getDynamicSettings } from '../../../state/actions/dynamic_settings'; import { useMonitorId } from '../../../hooks'; import { kibanaService } from '../../../state/kibana_service'; -import { CLIENT_ALERT_TYPES } from '../../../../common/constants/alerts'; +import { CLIENT_ALERT_TYPES } from '../../../../../common/constants/alerts'; interface Props { onClose: () => void; diff --git a/x-pack/plugins/synthetics/public/components/monitor/ml/ml_integeration.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/ml_integeration.tsx similarity index 98% rename from x-pack/plugins/synthetics/public/components/monitor/ml/ml_integeration.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/ml_integeration.tsx index 6396f99e4d62c..675554906694b 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ml/ml_integeration.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/ml_integeration.tsx @@ -22,7 +22,7 @@ import { UptimeRefreshContext } from '../../../contexts'; import * as labels from './translations'; import { ManageMLJobComponent } from './manage_ml_job'; import { useMonitorId } from '../../../hooks'; -import { getMLJobId } from '../../../../common/lib'; +import { getMLJobId } from '../../../../../common/lib'; export const MLIntegrationComponent = () => { const [isMlFlyoutOpen, setIsMlFlyoutOpen] = useState(false); diff --git a/x-pack/plugins/synthetics/public/components/monitor/ml/ml_integerations.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/ml_integerations.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ml/ml_integerations.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/ml_integerations.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/ml/ml_job_link.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/ml_job_link.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ml/ml_job_link.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/ml_job_link.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/ml/ml_job_link.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/ml_job_link.tsx similarity index 96% rename from x-pack/plugins/synthetics/public/components/monitor/ml/ml_job_link.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/ml_job_link.tsx index e14f37f617aac..2e9d771e11150 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ml/ml_job_link.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/ml_job_link.tsx @@ -9,7 +9,7 @@ import React from 'react'; import url from 'url'; import { EuiButtonEmpty } from '@elastic/eui'; import rison, { RisonValue } from 'rison-node'; -import { getMLJobId } from '../../../../common/lib'; +import { getMLJobId } from '../../../../../common/lib'; interface Props { monitorId: string; diff --git a/x-pack/plugins/synthetics/public/components/monitor/ml/ml_manage_job.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/ml_manage_job.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ml/ml_manage_job.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/ml_manage_job.test.tsx diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/translations.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/translations.tsx new file mode 100644 index 0000000000000..9236d809177af --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/translations.tsx @@ -0,0 +1,198 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const JOB_CREATED_SUCCESS_TITLE = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreatedNotificationTitle', + { + defaultMessage: 'Job successfully created', + } +); + +export const JOB_CREATED_SUCCESS_MESSAGE = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreatedNotificationText', + { + defaultMessage: + 'The analysis is now running for response duration chart. It might take a while before results are added to the response times graph.', + } +); + +export const JOB_CREATED_LAZY_SUCCESS_MESSAGE = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreatedLazyNotificationText', + { + defaultMessage: + 'The analysis is waiting for an ML node to become available. It might take a while before results are added to the response times graph.', + } +); + +export const JOB_CREATION_FAILED = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreationFailedNotificationTitle', + { + defaultMessage: 'Job creation failed', + } +); + +export const JOB_CREATION_FAILED_MESSAGE = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreationFailedNotificationText', + { + defaultMessage: + 'Your current license may not allow for creating machine learning jobs, or this job may already exist.', + } +); + +export const JOB_DELETION = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.jobDeletionNotificationTitle', + { + defaultMessage: 'Job deleted', + } +); + +export const JOB_DELETION_SUCCESS = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.jobDeletionSuccessNotificationText', + { + defaultMessage: 'Job is successfully deleted', + } +); + +export const JOB_DELETION_CONFIRMATION = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.jobDeletionConfirmLabel', + { + defaultMessage: 'Delete anomaly detection job?', + } +); + +export const VIEW_JOB = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreatedNotificationText.viewJobLinkText', + { + defaultMessage: 'View job', + } +); + +export const EXPLORE_IN_ML_APP = i18n.translate( + 'xpack.synthetics.ml.durationChart.exploreInMlApp', + { + defaultMessage: 'Explore in ML App', + } +); + +export const ENABLE_ANOMALY_DETECTION = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.enableAnomalyDetectionTitle', + { + defaultMessage: 'Enable anomaly detection', + } +); + +export const ANOMALY_DETECTION = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.anomalyDetectionTitle', + { + defaultMessage: 'Anomaly detection', + } +); + +export const DISABLE_ANOMALY_DETECTION = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.disableAnomalyDetectionTitle', + { + defaultMessage: 'Disable anomaly detection', + } +); + +export const ENABLE_ANOMALY_ALERT = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.enableAnomalyAlert', + { + defaultMessage: 'Enable anomaly alert', + } +); + +export const ENABLE_ANOMALY_NO_PERMISSIONS_TOOLTIP = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.noPermissionsTooltip', + { + defaultMessage: 'You need read-write access to Uptime to create anomaly alerts.', + } +); + +export const DISABLE_ANOMALY_ALERT = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.disableAnomalyAlert', + { + defaultMessage: 'Disable anomaly alert', + } +); + +export const MANAGE_ANOMALY_DETECTION = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.manageAnomalyDetectionTitle', + { + defaultMessage: 'Manage anomaly detection', + } +); + +export const ML_MANAGEMENT_PAGE = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.manageMLJobDescription.mlJobsPageLinkText', + { + defaultMessage: 'Machine Learning jobs management page', + } +); + +export const TAKE_SOME_TIME_TEXT = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.manageMLJobDescription.noteText', + { + defaultMessage: 'Note: It might take a few minutes for the job to begin calculating results.', + } +); + +export const CREATE_NEW_JOB = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.createNewJobButtonLabel', + { + defaultMessage: 'Create new job', + } +); + +export const CANCEL_LABEL = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.cancelLabel', + { + defaultMessage: 'Cancel', + } +); + +export const CREAT_ML_JOB_DESC = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.createMLJobDescription', + { + defaultMessage: `Here you can create a machine learning job to calculate anomaly scores on + response durations for Uptime Monitor. Once enabled, the monitor duration chart on the details page + will show the expected bounds and annotate the graph with anomalies. You can also potentially + identify periods of increased latency across geographical regions.`, + } +); + +export const START_TRAIL = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.startTrial', + { + defaultMessage: 'Start free 14-day trial', + } +); + +export const START_TRAIL_DESC = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.startTrialDesc', + { + defaultMessage: + 'In order to access duration anomaly detection, you have to be subscribed to an Elastic Platinum license.', + } +); + +export const ENABLE_MANAGE_JOB = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.enable_or_manage_job', + { + defaultMessage: + 'You can enable anomaly detection job or if job is already there you can manage the job or alert.', + } +); + +export const ADD_JOB_PERMISSIONS_NEEDED = i18n.translate( + 'xpack.synthetics.ml.enableAnomalyDetectionPanel.add_job_permissions_needed', + { + defaultMessage: 'Permissions needed', + } +); diff --git a/x-pack/plugins/synthetics/public/components/monitor/ml/use_anomaly_alert.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/use_anomaly_alert.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ml/use_anomaly_alert.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ml/use_anomaly_alert.ts diff --git a/x-pack/plugins/synthetics/public/components/monitor/monitor_charts.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/monitor_charts.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/monitor_charts.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/monitor_charts.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/monitor_charts.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/monitor_charts.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/monitor_charts.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/monitor_charts.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/monitor_duration/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/monitor_duration/index.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/monitor_duration/index.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/monitor_duration/index.ts diff --git a/x-pack/plugins/synthetics/public/components/monitor/monitor_duration/monitor_duration.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/monitor_duration/monitor_duration.tsx similarity index 86% rename from x-pack/plugins/synthetics/public/components/monitor/monitor_duration/monitor_duration.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/monitor_duration/monitor_duration.tsx index dbd8846707d1b..822a476f5225a 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/monitor_duration/monitor_duration.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/monitor_duration/monitor_duration.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiTitle, EuiSpacer } from '@elastic/eui'; -import { LocationDurationLine } from '../../../../common/types'; +import { LocationDurationLine } from '../../../../../common/types'; import { MLIntegrationComponent } from '../ml/ml_integeration'; import { AnomalyRecords } from '../../../state/actions'; import { DurationChartComponent } from '../../common/charts'; @@ -41,13 +41,13 @@ export const MonitorDurationComponent = ({

{hasMLJob ? ( ) : ( )} @@ -59,7 +59,7 @@ export const MonitorDurationComponent = ({ {/* */} {/* */} - {/* */} + {/* */} {/* */} {/* */} diff --git a/x-pack/plugins/synthetics/public/components/monitor/monitor_duration/monitor_duration_container.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/monitor_duration/monitor_duration_container.tsx similarity index 96% rename from x-pack/plugins/synthetics/public/components/monitor/monitor_duration/monitor_duration_container.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/monitor_duration/monitor_duration_container.tsx index 8b88c8d59a47c..63f95fd966544 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/monitor_duration/monitor_duration_container.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/monitor_duration/monitor_duration_container.tsx @@ -23,8 +23,8 @@ import { } from '../../../state/selectors'; import { UptimeRefreshContext } from '../../../contexts'; import { MonitorDurationComponent } from './monitor_duration'; -import { MonitorIdParam } from '../../../../common/types'; -import { getMLJobId } from '../../../../common/lib'; +import { MonitorIdParam } from '../../../../../common/types'; +import { getMLJobId } from '../../../../../common/lib'; import { useUptimeSettingsContext } from '../../../contexts/uptime_settings_context'; export const MonitorDuration: React.FC = ({ monitorId }) => { diff --git a/x-pack/plugins/synthetics/public/components/monitor/monitor_title.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/monitor_title.test.tsx similarity index 98% rename from x-pack/plugins/synthetics/public/components/monitor/monitor_title.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/monitor_title.test.tsx index 726ad235f7f49..f9e3572ead511 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/monitor_title.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/monitor_title.test.tsx @@ -10,7 +10,7 @@ import moment from 'moment'; import { screen } from '@testing-library/react'; import { render } from '../../lib/helper/rtl_helpers'; import * as reactRouterDom from 'react-router-dom'; -import { Ping } from '../../../common/runtime_types'; +import { Ping } from '../../../../common/runtime_types'; import { MonitorPageTitle, MonitorPageTitleContent } from './monitor_title'; jest.mock('react-router-dom', () => { diff --git a/x-pack/plugins/synthetics/public/components/monitor/monitor_title.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/monitor_title.tsx similarity index 88% rename from x-pack/plugins/synthetics/public/components/monitor/monitor_title.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/monitor_title.tsx index 8cbc9eed0a210..ce343ac1f6bd7 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/monitor_title.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/monitor_title.tsx @@ -12,7 +12,7 @@ import { useSelector } from 'react-redux'; import { useMonitorId } from '../../hooks'; import { monitorStatusSelector } from '../../state/selectors'; import { EnableMonitorAlert } from '../overview/monitor_list/columns/enable_alert'; -import { Ping } from '../../../common/runtime_types/ping'; +import { Ping } from '../../../../common/runtime_types/ping'; import { useBreadcrumbs } from '../../hooks/use_breadcrumbs'; const isAutogeneratedId = (id: string) => { @@ -42,28 +42,28 @@ export const MonitorPageTitleContent: React.FC = () => { case 'http': return ( ); case 'tcp': return ( ); case 'icmp': return ( ); case 'browser': return ( ); @@ -85,7 +85,7 @@ export const MonitorPageTitleContent: React.FC = () => { {renderMonitorType(type)}{' '} @@ -96,7 +96,7 @@ export const MonitorPageTitleContent: React.FC = () => { diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_histogram/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_histogram/index.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ping_histogram/index.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_histogram/index.ts diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_histogram/ping_histogram_container.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_histogram/ping_histogram_container.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ping_histogram/ping_histogram_container.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_histogram/ping_histogram_container.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/__snapshots__/expanded_row.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/__snapshots__/expanded_row.test.tsx.snap similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/__snapshots__/expanded_row.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/__snapshots__/expanded_row.test.tsx.snap diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/__snapshots__/ping_headers.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/__snapshots__/ping_headers.test.tsx.snap similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/__snapshots__/ping_headers.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/__snapshots__/ping_headers.test.tsx.snap diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/expand_row.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/expand_row.test.tsx similarity index 94% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/expand_row.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/expand_row.test.tsx index e3ac1f2e17125..06b43744a2ac2 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/expand_row.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/expand_row.test.tsx @@ -8,12 +8,12 @@ import React from 'react'; import { screen } from '@testing-library/react'; -import { makePing } from '../../../../../common/runtime_types'; +import { makePing } from '../../../../../../common/runtime_types'; import { render } from '../../../../lib/helper/rtl_helpers'; import { ExpandRowColumn } from './expand_row'; -import { Ping } from '../../../../../common/runtime_types/ping'; +import { Ping } from '../../../../../../common/runtime_types/ping'; describe('ExpandRowColumn', () => { const defaultPing = makePing({ diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/expand_row.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/expand_row.tsx similarity index 88% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/expand_row.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/expand_row.tsx index b0453dd8f2680..3e5104357463f 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/expand_row.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/expand_row.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiButtonIcon } from '@elastic/eui'; -import { Ping } from '../../../../../common/runtime_types/ping'; +import { Ping } from '../../../../../../common/runtime_types/ping'; import { PingListExpandedRowComponent } from '../expanded_row'; export const toggleDetails = ( @@ -50,10 +50,10 @@ export const ExpandRowColumn = ({ item, expandedRows, setExpandedRows }: Props) isDisabled={!rowShouldExpand(item)} aria-label={ expandedRows[item.docId] - ? i18n.translate('xpack.uptime.pingList.collapseRow', { + ? i18n.translate('xpack.synthetics.pingList.collapseRow', { defaultMessage: 'Collapse', }) - : i18n.translate('xpack.uptime.pingList.expandRow', { defaultMessage: 'Expand' }) + : i18n.translate('xpack.synthetics.pingList.expandRow', { defaultMessage: 'Expand' }) } iconType={expandedRows[item.docId] ? 'arrowUp' : 'arrowDown'} /> diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/failed_step.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/failed_step.tsx similarity index 88% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/failed_step.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/failed_step.tsx index 38f51a2bafebb..da3b93bd0e09d 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/failed_step.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/failed_step.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import { FailedStepsApiResponse } from '../../../../../common/runtime_types/ping/synthetics'; +import { FailedStepsApiResponse } from '../../../../../../common/runtime_types/ping/synthetics'; interface Props { checkGroup?: string; diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_error.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_error.tsx similarity index 91% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_error.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_error.tsx index db7dc46fc9043..beb29b4201438 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_error.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_error.tsx @@ -7,7 +7,7 @@ import React from 'react'; import styled from 'styled-components'; -import { Ping } from '../../../../../common/runtime_types/ping'; +import { Ping } from '../../../../../../common/runtime_types/ping'; const StyledSpan = styled.span` display: -webkit-box; diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_status.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_status.tsx similarity index 86% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_status.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_status.tsx index dcf3fdb9163db..6d46803da22fd 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_status.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_status.tsx @@ -9,8 +9,8 @@ import React, { useContext } from 'react'; import { i18n } from '@kbn/i18n'; import moment from 'moment'; import { EuiBadge, EuiSpacer, EuiText } from '@elastic/eui'; -import { Ping } from '../../../../../common/runtime_types/ping'; -import { MONITOR_TYPES, STATUS } from '../../../../../common/constants'; +import { Ping } from '../../../../../../common/runtime_types/ping'; +import { MONITOR_TYPES, STATUS } from '../../../../../../common/constants'; import { UptimeThemeContext } from '../../../../contexts'; import { STATUS_COMPLETE_LABEL, @@ -47,7 +47,7 @@ export const PingStatusColumn = ({ pingStatus, item }: Props) => { } return ( -
+
{ - {i18n.translate('xpack.uptime.pingList.recencyMessage', { + {i18n.translate('xpack.synthetics.pingList.recencyMessage', { values: { fromNow: checkedTime }, defaultMessage: 'Checked {fromNow}', description: diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/index.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/index.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/index.ts diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/no_image_available.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/no_image_available.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/no_image_available.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/no_image_available.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/no_image_available.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/no_image_available.tsx similarity index 92% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/no_image_available.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/no_image_available.tsx index 4790b8c1dd376..62c1392a2ed52 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/no_image_available.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/no_image_available.tsx @@ -21,7 +21,7 @@ export const NoImageAvailable = () => { diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/no_image_display.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/no_image_display.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/no_image_display.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/no_image_display.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/no_image_display.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/no_image_display.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/no_image_display.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/no_image_display.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/ping_timestamp.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/ping_timestamp.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/ping_timestamp.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/ping_timestamp.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/ping_timestamp.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/ping_timestamp.tsx similarity index 98% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/ping_timestamp.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/ping_timestamp.tsx index 4083df8c98a1a..3bc443426d523 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/ping_timestamp.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/ping_timestamp.tsx @@ -16,7 +16,7 @@ import { isScreenshotRef, ScreenshotImageBlob, ScreenshotRefImageData, -} from '../../../../../../common/runtime_types'; +} from '../../../../../../../common/runtime_types'; import { getJourneyScreenshot } from '../../../../../state/api/journey'; import { UptimeSettingsContext } from '../../../../../contexts'; diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/step_image_caption.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/step_image_caption.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/step_image_caption.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/step_image_caption.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/step_image_caption.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/step_image_caption.tsx similarity index 97% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/step_image_caption.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/step_image_caption.tsx index eb0d8c30ae53d..1003b51319136 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/step_image_caption.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/step_image_caption.tsx @@ -9,7 +9,7 @@ import React, { MouseEvent, useEffect } from 'react'; import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiText, useEuiTheme } from '@elastic/eui'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; -import { ScreenshotRefImageData } from '../../../../../../common/runtime_types'; +import { ScreenshotRefImageData } from '../../../../../../../common/runtime_types'; import { useBreakpoints } from '../../../../../hooks'; import { nextAriaLabel, prevAriaLabel } from './translations'; diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/step_image_popover.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/step_image_popover.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/step_image_popover.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/step_image_popover.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/step_image_popover.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/step_image_popover.tsx similarity index 97% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/step_image_popover.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/step_image_popover.tsx index 73c43da98bfc4..1d97e3e4e248a 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/ping_timestamp/step_image_popover.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/step_image_popover.tsx @@ -8,7 +8,7 @@ import { EuiImage, EuiLoadingSpinner, EuiPopover } from '@elastic/eui'; import React from 'react'; import styled from 'styled-components'; -import { ScreenshotRefImageData } from '../../../../../../common/runtime_types/ping/synthetics'; +import { ScreenshotRefImageData } from '../../../../../../../common/runtime_types/ping/synthetics'; import { fullSizeImageAlt } from './translations'; import { useCompositeImage } from '../../../../../hooks/use_composite_image'; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/translations.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/translations.ts new file mode 100644 index 0000000000000..065af8f7ff5d2 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/ping_timestamp/translations.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const prevAriaLabel = i18n.translate( + 'xpack.synthetics.synthetics.prevStepButton.airaLabel', + { + defaultMessage: 'Previous step', + } +); + +export const nextAriaLabel = i18n.translate( + 'xpack.synthetics.synthetics.nextStepButton.ariaLabel', + { + defaultMessage: 'Next step', + } +); + +export const imageLoadingSpinnerAriaLabel = i18n.translate( + 'xpack.synthetics.synthetics.imageLoadingSpinner.ariaLabel', + { + defaultMessage: 'An animated spinner indicating the image is loading', + } +); + +export const fullSizeImageAlt = i18n.translate( + 'xpack.synthetics.synthetics.thumbnail.fullSize.alt', + { + defaultMessage: `A larger version of the screenshot for this journey step's thumbnail.`, + } +); + +export const formatCaptionContent = (stepNumber: number, totalSteps?: number) => + i18n.translate('xpack.synthetics.synthetics.pingTimestamp.captionContent', { + defaultMessage: 'Step: {stepNumber} of {totalSteps}', + values: { + stepNumber, + totalSteps, + }, + }); diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/response_code.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/response_code.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/columns/response_code.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/columns/response_code.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/doc_link_body.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/doc_link_body.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/doc_link_body.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/doc_link_body.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/doc_link_body.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/doc_link_body.tsx similarity index 87% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/doc_link_body.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/doc_link_body.tsx index f56df517455de..d917cd1aeb5a1 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ping_list/doc_link_body.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/doc_link_body.tsx @@ -16,7 +16,7 @@ const bodyDocsLink = export const DocLinkForBody = () => { const docsLink = ( - {i18n.translate('xpack.uptime.pingList.drawer.body.docsLink', { + {i18n.translate('xpack.synthetics.pingList.drawer.body.docsLink', { defaultMessage: 'docs', description: 'Docs link to set response body', })} @@ -26,7 +26,7 @@ export const DocLinkForBody = () => { return ( diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/expanded_row.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/expanded_row.test.tsx similarity index 98% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/expanded_row.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/expanded_row.test.tsx index f87501a79e964..d65536bf75c4a 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ping_list/expanded_row.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/expanded_row.test.tsx @@ -8,7 +8,7 @@ import { mountWithIntl, renderWithIntl, shallowWithIntl } from '@kbn/test-jest-helpers'; import React from 'react'; import { PingListExpandedRowComponent } from './expanded_row'; -import { Ping } from '../../../../common/runtime_types'; +import { Ping } from '../../../../../common/runtime_types'; import { DocLinkForBody } from './doc_link_body'; describe('PingListExpandedRow', () => { diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/expanded_row.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/expanded_row.tsx similarity index 86% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/expanded_row.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/expanded_row.tsx index df0d273d3bc3a..0d27d7cbb92b9 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ping_list/expanded_row.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/expanded_row.tsx @@ -18,7 +18,7 @@ import { } from '@elastic/eui'; import React from 'react'; import { i18n } from '@kbn/i18n'; -import { Ping, HttpResponseBody } from '../../../../common/runtime_types'; +import { Ping, HttpResponseBody } from '../../../../../common/runtime_types'; import { DocLinkForBody } from './doc_link_body'; import { PingRedirects } from './ping_redirects'; import { PingHeaders } from './headers'; @@ -33,14 +33,14 @@ const BodyDescription = ({ body }: { body: HttpResponseBody }) => { const truncatedText = contentBytes > 0 && contentBytes < bodyBytes - ? i18n.translate('xpack.uptime.pingList.expandedRow.truncated', { + ? i18n.translate('xpack.synthetics.pingList.expandedRow.truncated', { defaultMessage: 'Showing first {contentBytes} bytes.', values: { contentBytes }, }) : null; const bodySizeText = bodyBytes > 0 - ? i18n.translate('xpack.uptime.pingList.expandedRow.bodySize', { + ? i18n.translate('xpack.synthetics.pingList.expandedRow.bodySize', { defaultMessage: 'Body size is {bodyBytes}.', values: { bodyBytes: formatNumber(bodyBytes, '0b') }, }) @@ -59,7 +59,9 @@ export const PingListExpandedRowComponent = ({ ping }: Props) => { // Show the error block if (ping.error) { listItems.push({ - title: i18n.translate('xpack.uptime.pingList.expandedRow.error', { defaultMessage: 'Error' }), + title: i18n.translate('xpack.synthetics.pingList.expandedRow.error', { + defaultMessage: 'Error', + }), description: {ping.error.message}, }); } @@ -69,7 +71,7 @@ export const PingListExpandedRowComponent = ({ ping }: Props) => { const body = ping.http.response.body; listItems.push({ - title: i18n.translate('xpack.uptime.pingList.expandedRow.response_body', { + title: i18n.translate('xpack.synthetics.pingList.expandedRow.response_body', { defaultMessage: 'Response Body', }), description: ( diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/headers.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/headers.tsx similarity index 88% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/headers.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/headers.tsx index 7740116d9f36e..bff0e91f2cd05 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ping_list/headers.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/headers.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { EuiAccordion, EuiDescriptionList, EuiSpacer, EuiText } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { PingHeaders as HeadersProp } from '../../../../common/runtime_types'; +import { PingHeaders as HeadersProp } from '../../../../../common/runtime_types'; interface Props { headers: HeadersProp; @@ -30,7 +30,7 @@ export const PingHeaders = ({ headers }: Props) => { buttonContent={

- {i18n.translate('xpack.uptime.pingList.headers.title', { + {i18n.translate('xpack.synthetics.pingList.headers.title', { defaultMessage: 'Response headers', })}

diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/index.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/index.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/index.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/index.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/location_name.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/location_name.tsx similarity index 92% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/location_name.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/location_name.tsx index dd1f65789fdd9..81c59a85d4169 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ping_list/location_name.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/location_name.tsx @@ -20,7 +20,7 @@ export const LocationName = ({ location }: LocationNameProps) => href="https://www.elastic.co/guide/en/beats/heartbeat/current/configuration-observer-options.html" target="_blank" > - {i18n.translate('xpack.uptime.locationName.helpLinkAnnotation', { + {i18n.translate('xpack.synthetics.locationName.helpLinkAnnotation', { defaultMessage: 'Add location', description: 'Text that instructs the user to navigate to our docs to add a geographic location to their data', diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/ping_headers.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/ping_headers.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/ping_headers.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/ping_headers.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/ping_list.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/ping_list.test.tsx similarity index 98% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/ping_list.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/ping_list.test.tsx index bfcf359ac0525..ddb33e4dd5fea 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ping_list/ping_list.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/ping_list.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { formatDuration, PingList } from './ping_list'; -import { Ping, PingsResponse } from '../../../../common/runtime_types'; +import { Ping, PingsResponse } from '../../../../../common/runtime_types'; import { ExpandedRowMap } from '../../overview/monitor_list/types'; import { rowShouldExpand, toggleDetails } from './columns/expand_row'; import * as pingListHook from './use_pings'; diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/ping_list.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/ping_list.tsx similarity index 90% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/ping_list.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/ping_list.tsx index 27141aa436d67..948172e1ea681 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ping_list/ping_list.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/ping_list.tsx @@ -29,7 +29,7 @@ const MILLIS_LIMIT = ONE_SECOND_AS_MICROS * 1; export const formatDuration = (durationMicros: number) => { if (durationMicros < MILLIS_LIMIT) { - return i18n.translate('xpack.uptime.pingList.durationMsColumnFormatting', { + return i18n.translate('xpack.synthetics.pingList.durationMsColumnFormatting', { values: { millis: microsToMillis(durationMicros) }, defaultMessage: '{millis} ms', }); @@ -39,12 +39,12 @@ export const formatDuration = (durationMicros: number) => { // we format seconds with correct pluralization here and not for `ms` because it is much more likely users // will encounter times of exactly '1' second. if (seconds === '1') { - return i18n.translate('xpack.uptime.pingist.durationSecondsColumnFormatting.singular', { + return i18n.translate('xpack.synthetics.pingist.durationSecondsColumnFormatting.singular', { values: { seconds }, defaultMessage: '{seconds} second', }); } - return i18n.translate('xpack.uptime.pingist.durationSecondsColumnFormatting', { + return i18n.translate('xpack.synthetics.pingist.durationSecondsColumnFormatting', { values: { seconds }, defaultMessage: '{seconds} seconds', }); diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/ping_list_header.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/ping_list_header.tsx similarity index 94% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/ping_list_header.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/ping_list_header.tsx index b94663630aee6..51e86627a1b0d 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ping_list/ping_list_header.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/ping_list_header.tsx @@ -18,7 +18,7 @@ export const PingListHeader = () => {

diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/ping_list_table.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/ping_list_table.tsx similarity index 92% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/ping_list_table.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/ping_list_table.tsx index 5e2737684b333..1dbda32925161 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ping_list/ping_list_table.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/ping_list_table.tsx @@ -12,11 +12,11 @@ import moment from 'moment'; import { useHistory } from 'react-router-dom'; import { useDispatch } from 'react-redux'; import * as I18LABELS from './translations'; -import { FailedStepsApiResponse, Ping } from '../../../../common/runtime_types'; +import { FailedStepsApiResponse, Ping } from '../../../../../common/runtime_types'; import { PingStatusColumn } from './columns/ping_status'; import { ERROR_LABEL, LOCATION_LABEL, RES_CODE_LABEL, TIMESTAMP_LABEL } from './translations'; import { LocationName } from './location_name'; -import { MONITOR_TYPES } from '../../../../common/constants'; +import { MONITOR_TYPES } from '../../../../../common/constants'; import { PingTimestamp } from './columns/ping_timestamp'; import { getShortTimeStamp } from '../../overview/monitor_list/columns/monitor_status_column'; import { PingErrorCol } from './columns/ping_error'; @@ -128,7 +128,7 @@ export function PingListTable({ loading, error, pings, pagination, onChange, fai align: 'right', dataType: 'number', field: 'monitor.ip', - name: i18n.translate('xpack.uptime.pingList.ipAddressColumnLabel', { + name: i18n.translate('xpack.synthetics.pingList.ipAddressColumnLabel', { defaultMessage: 'IP', }), }, @@ -137,7 +137,7 @@ export function PingListTable({ loading, error, pings, pagination, onChange, fai { align: 'center', field: 'monitor.duration.us', - name: i18n.translate('xpack.uptime.pingList.durationMsColumnLabel', { + name: i18n.translate('xpack.synthetics.pingList.durationMsColumnLabel', { defaultMessage: 'Duration', }), render: (duration: number | null) => @@ -164,7 +164,7 @@ export function PingListTable({ loading, error, pings, pagination, onChange, fai { field: 'monitor.status', align: 'left', - name: i18n.translate('xpack.uptime.pingList.columns.failedStep', { + name: i18n.translate('xpack.synthetics.pingList.columns.failedStep', { defaultMessage: 'Failed step', }), render: (_timestamp: string, item: Ping) => ( @@ -234,10 +234,10 @@ export function PingListTable({ loading, error, pings, pagination, onChange, fai pagination={pagination} noItemsMessage={ loading - ? i18n.translate('xpack.uptime.pingList.pingsLoadingMesssage', { + ? i18n.translate('xpack.synthetics.pingList.pingsLoadingMesssage', { defaultMessage: 'Loading history...', }) - : i18n.translate('xpack.uptime.pingList.pingsUnavailableMessage', { + : i18n.translate('xpack.synthetics.pingList.pingsUnavailableMessage', { defaultMessage: 'No history found', }) } diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/ping_redirects.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/ping_redirects.tsx similarity index 84% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/ping_redirects.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/ping_redirects.tsx index 01e0cb5be2b0f..365a52e8f54fe 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ping_list/ping_redirects.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/ping_redirects.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import styled from 'styled-components'; import { EuiListGroup, EuiListGroupItemProps, EuiPanel, EuiSpacer, EuiText } from '@elastic/eui'; -import { Ping } from '../../../../common/runtime_types/ping'; +import { Ping } from '../../../../../common/runtime_types/ping'; const ListGroup = styled(EuiListGroup)` &&& { @@ -41,7 +41,7 @@ export const PingRedirects: React.FC = ({ monitorStatus, showTitle }) => iconType: 'popout', iconSize: 's', alwaysShow: true, - 'aria-label': i18n.translate('xpack.uptime.monitorList.redirects.openWindow', { + 'aria-label': i18n.translate('xpack.synthetics.monitorList.redirects.openWindow', { defaultMessage: 'Link will open in new window.', }), }, @@ -59,7 +59,7 @@ export const PingRedirects: React.FC = ({ monitorStatus, showTitle }) => color: 'text', iconType: 'popout', iconSize: 's', - 'aria-label': i18n.translate('xpack.uptime.monitorList.redirects.openWindow', { + 'aria-label': i18n.translate('xpack.synthetics.monitorList.redirects.openWindow', { defaultMessage: 'Link will open in new window.', }), alwaysShow: true, @@ -74,7 +74,7 @@ export const PingRedirects: React.FC = ({ monitorStatus, showTitle }) => {showTitle && (

- {i18n.translate('xpack.uptime.monitorList.redirects.title', { + {i18n.translate('xpack.synthetics.monitorList.redirects.title', { defaultMessage: 'Redirects', })}

@@ -83,7 +83,7 @@ export const PingRedirects: React.FC = ({ monitorStatus, showTitle }) => { - {i18n.translate('xpack.uptime.monitorList.redirects.description', { + {i18n.translate('xpack.synthetics.monitorList.redirects.description', { defaultMessage: 'Heartbeat followed {number} redirects while executing ping.', values: { number: list?.length ?? 0, diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/response_code.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/response_code.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/response_code.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/response_code.test.tsx diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/translations.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/translations.ts new file mode 100644 index 0000000000000..81e4451f9103f --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/translations.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const STATUS_LABEL = i18n.translate('xpack.synthetics.pingList.statusColumnLabel', { + defaultMessage: 'Status', +}); + +export const RES_CODE_LABEL = i18n.translate('xpack.synthetics.pingList.responseCodeColumnLabel', { + defaultMessage: 'Response code', +}); +export const ERROR_TYPE_LABEL = i18n.translate('xpack.synthetics.pingList.errorTypeColumnLabel', { + defaultMessage: 'Error type', +}); +export const ERROR_LABEL = i18n.translate('xpack.synthetics.pingList.errorColumnLabel', { + defaultMessage: 'Error', +}); + +export const LOCATION_LABEL = i18n.translate('xpack.synthetics.pingList.locationNameColumnLabel', { + defaultMessage: 'Location', +}); + +export const TIMESTAMP_LABEL = i18n.translate('xpack.synthetics.pingList.timestampColumnLabel', { + defaultMessage: 'Timestamp', +}); diff --git a/x-pack/plugins/synthetics/public/components/monitor/ping_list/use_pings.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/use_pings.ts similarity index 94% rename from x-pack/plugins/synthetics/public/components/monitor/ping_list/use_pings.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/use_pings.ts index 94669b4aeb8e8..6306e8357018c 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/ping_list/use_pings.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/use_pings.ts @@ -9,13 +9,13 @@ import { useDispatch, useSelector } from 'react-redux'; import { useCallback, useContext, useEffect } from 'react'; import { useFetcher } from '@kbn/observability-plugin/public'; import { selectPingList } from '../../../state/selectors'; -import { GetPingsParams, Ping } from '../../../../common/runtime_types/ping'; +import { GetPingsParams, Ping } from '../../../../../common/runtime_types/ping'; import { getPings as getPingsAction } from '../../../state/actions'; import { useGetUrlParams, useMonitorId } from '../../../hooks'; import { UptimeRefreshContext, UptimeSettingsContext } from '../../../contexts'; import { fetchJourneysFailedSteps } from '../../../state/api/journey'; import { useSelectedFilters } from '../../../hooks/use_selected_filters'; -import { MONITOR_TYPES } from '../../../../common/constants'; +import { MONITOR_TYPES } from '../../../../../common/constants'; interface Props { pageSize: number; diff --git a/x-pack/plugins/synthetics/public/components/monitor/status_details/__snapshots__/monitor_status.bar.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/__snapshots__/monitor_status.bar.test.tsx.snap similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/status_details/__snapshots__/monitor_status.bar.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/__snapshots__/monitor_status.bar.test.tsx.snap diff --git a/x-pack/plugins/synthetics/public/components/monitor/status_details/__snapshots__/ssl_certificate.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/__snapshots__/ssl_certificate.test.tsx.snap similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/status_details/__snapshots__/ssl_certificate.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/__snapshots__/ssl_certificate.test.tsx.snap diff --git a/x-pack/plugins/synthetics/public/components/monitor/status_details/__snapshots__/status_by_location.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/__snapshots__/status_by_location.test.tsx.snap similarity index 94% rename from x-pack/plugins/synthetics/public/components/monitor/status_details/__snapshots__/status_by_location.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/__snapshots__/status_by_location.test.tsx.snap index 449038f1023d8..7bb4c36d3d0d0 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/status_details/__snapshots__/status_by_location.test.tsx.snap +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/__snapshots__/status_by_location.test.tsx.snap @@ -15,7 +15,7 @@ exports[`StatusByLocation component renders properly against props 1`] = `

= ({ allLocations }) => { return ( { diff --git a/x-pack/plugins/synthetics/public/components/monitor/status_details/location_availability/location_availability.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/location_availability/location_availability.tsx similarity index 94% rename from x-pack/plugins/synthetics/public/components/monitor/status_details/location_availability/location_availability.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/location_availability/location_availability.tsx index c851369d63e9e..f7634c77eb017 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/status_details/location_availability/location_availability.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/location_availability/location_availability.tsx @@ -9,7 +9,7 @@ import React from 'react'; import styled from 'styled-components'; import { EuiFlexGroup, EuiFlexItem, EuiErrorBoundary, EuiTitle } from '@elastic/eui'; import { LocationStatusTags } from '../availability_reporting'; -import { MonitorLocations } from '../../../../../common/runtime_types'; +import { MonitorLocations } from '../../../../../../common/runtime_types'; import { MonitoringFrom } from '../translations'; const EuiFlexItemTags = styled(EuiFlexItem)` diff --git a/x-pack/plugins/synthetics/public/components/monitor/status_details/monitor_status.bar.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/monitor_status.bar.test.tsx similarity index 96% rename from x-pack/plugins/synthetics/public/components/monitor/status_details/monitor_status.bar.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/monitor_status.bar.test.tsx index af3c47b9caf30..640d207fbb138 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/status_details/monitor_status.bar.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/monitor_status.bar.test.tsx @@ -8,7 +8,7 @@ import moment from 'moment'; import React from 'react'; import { MonitorStatusBar } from './status_bar'; -import { Ping } from '../../../../common/runtime_types'; +import { Ping } from '../../../../../common/runtime_types'; import * as redux from 'react-redux'; import { renderWithRouter } from '../../../lib'; import { createMemoryHistory } from 'history'; diff --git a/x-pack/plugins/synthetics/public/components/monitor/status_details/ssl_certificate.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/ssl_certificate.test.tsx similarity index 95% rename from x-pack/plugins/synthetics/public/components/monitor/status_details/ssl_certificate.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/ssl_certificate.test.tsx index 03ce292e63621..3951ced34c0f9 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/status_details/ssl_certificate.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/ssl_certificate.test.tsx @@ -8,11 +8,11 @@ import React from 'react'; import moment from 'moment'; import { EuiIcon } from '@elastic/eui'; -import { Tls } from '../../../../common/runtime_types'; +import { Tls } from '../../../../../common/runtime_types'; import { MonitorSSLCertificate } from './status_bar'; import * as redux from 'react-redux'; import { mountWithRouter, renderWithRouter, shallowWithRouter } from '../../../lib'; -import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../common/constants'; +import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../../common/constants'; describe('SSL Certificate component', () => { let monitorTls: Tls; diff --git a/x-pack/plugins/synthetics/public/components/monitor/status_details/status_bar/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/status_bar/index.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/status_details/status_bar/index.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/status_bar/index.ts diff --git a/x-pack/plugins/synthetics/public/components/monitor/status_details/status_bar/monitor_redirects.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/status_bar/monitor_redirects.tsx similarity index 91% rename from x-pack/plugins/synthetics/public/components/monitor/status_details/status_bar/monitor_redirects.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/status_bar/monitor_redirects.tsx index 8a3a8118d5a6e..2f1dba51bb933 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/status_details/status_bar/monitor_redirects.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/status_bar/monitor_redirects.tsx @@ -9,7 +9,7 @@ import React, { useState } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiPopover } from '@elastic/eui'; import styled from 'styled-components'; -import { Ping } from '../../../../../common/runtime_types'; +import { Ping } from '../../../../../../common/runtime_types'; import { PingRedirects } from '../../ping_list/ping_redirects'; import { MonListDescription, MonListTitle } from './status_bar'; @@ -33,7 +33,7 @@ export const MonitorRedirects: React.FC = ({ monitorStatus }) => { onClick={() => setIsPopoverOpen(!isPopoverOpen)} data-test-subj="uptimeMonitorRedirectInfo" > - {i18n.translate('xpack.uptime.monitorList.redirects.title.number', { + {i18n.translate('xpack.synthetics.monitorList.redirects.title.number', { defaultMessage: '{number}', values: { number: list?.length ?? 0, diff --git a/x-pack/plugins/synthetics/public/components/monitor/status_details/status_bar/ssl_certificate.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/status_bar/ssl_certificate.tsx similarity index 87% rename from x-pack/plugins/synthetics/public/components/monitor/status_details/status_bar/ssl_certificate.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/status_bar/ssl_certificate.tsx index ca47db608451c..5d421cbd4a448 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/status_details/status_bar/ssl_certificate.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/status_bar/ssl_certificate.tsx @@ -9,8 +9,8 @@ import React from 'react'; import { Link } from 'react-router-dom'; import { EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { Tls, X509Expiry } from '../../../../../common/runtime_types'; -import { CERTIFICATES_ROUTE } from '../../../../../common/constants'; +import { Tls, X509Expiry } from '../../../../../../common/runtime_types'; +import { CERTIFICATES_ROUTE } from '../../../../../../common/constants'; import { MonListDescription, MonListTitle } from './status_bar'; import { CertStatusColumn } from '../../../overview/monitor_list/columns/cert_status_column'; @@ -40,7 +40,7 @@ export const MonitorSSLCertificate = ({ tls }: Props) => { <> diff --git a/x-pack/plugins/synthetics/public/components/monitor/status_details/status_bar/status_bar.test.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/status_bar/status_bar.test.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/status_details/status_bar/status_bar.test.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/status_bar/status_bar.test.ts diff --git a/x-pack/plugins/synthetics/public/components/monitor/status_details/status_bar/status_bar.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/status_bar/status_bar.tsx similarity index 88% rename from x-pack/plugins/synthetics/public/components/monitor/status_details/status_bar/status_bar.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/status_bar/status_bar.tsx index c9da27d01848c..7ca855bc0a697 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/status_details/status_bar/status_bar.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/status_bar/status_bar.tsx @@ -22,7 +22,7 @@ import { StatusByLocations } from './status_by_location'; import { useStatusBar } from './use_status_bar'; import { MonitorIDLabel, OverallAvailability } from '../translations'; import { TAGS_LABEL, URL_LABEL } from '../../../common/translations'; -import { MonitorLocations } from '../../../../../common/runtime_types/monitor'; +import { MonitorLocations } from '../../../../../../common/runtime_types/monitor'; import { formatAvailabilityValue } from '../availability_reporting/availability_reporting'; import { MonitorRedirects } from './monitor_redirects'; import { MonitorTags } from '../../../common/monitor_tags'; @@ -44,19 +44,19 @@ export const MonListDescription = styled(EuiDescriptionListDescription)` export const renderMonitorType = (type: string | undefined) => { switch (type) { case 'http': - return i18n.translate('xpack.uptime.monitorDetails.statusBar.pingType.http', { + return i18n.translate('xpack.synthetics.monitorDetails.statusBar.pingType.http', { defaultMessage: 'HTTP', }); case 'tcp': - return i18n.translate('xpack.uptime.monitorDetails.statusBar.pingType.tcp', { + return i18n.translate('xpack.synthetics.monitorDetails.statusBar.pingType.tcp', { defaultMessage: 'TCP', }); case 'icmp': - return i18n.translate('xpack.uptime.monitorDetails.statusBar.pingType.icmp', { + return i18n.translate('xpack.synthetics.monitorDetails.statusBar.pingType.icmp', { defaultMessage: 'ICMP', }); case 'browser': - return i18n.translate('xpack.uptime.monitorDetails.statusBar.pingType.browser', { + return i18n.translate('xpack.synthetics.monitorDetails.statusBar.pingType.browser', { defaultMessage: 'Browser', }); default: @@ -83,7 +83,7 @@ export const MonitorStatusBar: React.FC = () => { {OverallAvailability} {

{locations.length <= 1 ? ( { /> ) : ( { diff --git a/x-pack/plugins/synthetics/public/components/monitor/status_details/status_details.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/status_details.tsx similarity index 96% rename from x-pack/plugins/synthetics/public/components/monitor/status_details/status_details.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/status_details.tsx index 5b20e83f0ec85..0c9c347fc8c80 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/status_details/status_details.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/status_details.tsx @@ -10,7 +10,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; import styled from 'styled-components'; import { LocationAvailability } from './location_availability/location_availability'; import { UptimeRefreshContext } from '../../../contexts'; -import { MonitorLocations } from '../../../../common/runtime_types'; +import { MonitorLocations } from '../../../../../common/runtime_types'; import { MonitorStatusBar } from './status_bar'; interface MonitorStatusDetailsProps { diff --git a/x-pack/plugins/synthetics/public/components/monitor/status_details/status_details_container.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/status_details_container.tsx similarity index 95% rename from x-pack/plugins/synthetics/public/components/monitor/status_details/status_details_container.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/status_details_container.tsx index 1fb138da9e84b..7affbde63ba02 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/status_details/status_details_container.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/status_details_container.tsx @@ -13,7 +13,7 @@ import { getMonitorLocationsAction } from '../../../state/actions/monitor'; import { MonitorStatusDetailsComponent } from '.'; import { UptimeRefreshContext } from '../../../contexts'; import { AppState } from '../../../state'; -import { MonitorIdParam } from '../../../../common/types'; +import { MonitorIdParam } from '../../../../../common/types'; export const MonitorStatusDetails: React.FC = ({ monitorId }) => { const { lastRefresh } = useContext(UptimeRefreshContext); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/translations.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/translations.ts new file mode 100644 index 0000000000000..f17ac2f580303 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/translations.ts @@ -0,0 +1,101 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const healthStatusMessageAriaLabel = i18n.translate( + 'xpack.synthetics.monitorStatusBar.healthStatusMessageAriaLabel', + { + defaultMessage: 'Monitor status', + } +); + +export const typeLabel = i18n.translate('xpack.synthetics.monitorStatusBar.type.label', { + defaultMessage: 'Type', +}); + +export const typeAriaLabel = i18n.translate('xpack.synthetics.monitorStatusBar.type.ariaLabel', { + defaultMessage: 'Monitor type', +}); + +export const monitorUrlLinkAriaLabel = i18n.translate( + 'xpack.synthetics.monitorStatusBar.monitorUrlLinkAriaLabel', + { + defaultMessage: 'Monitor URL link', + } +); + +export const durationTextAriaLabel = i18n.translate( + 'xpack.synthetics.monitorStatusBar.durationTextAriaLabel', + { + defaultMessage: 'Monitor duration in milliseconds', + } +); + +export const timestampFromNowTextAriaLabel = i18n.translate( + 'xpack.synthetics.monitorStatusBar.timestampFromNowTextAriaLabel', + { + defaultMessage: 'Time since last check', + } +); + +export const loadingMessage = i18n.translate('xpack.synthetics.monitorStatusBar.loadingMessage', { + defaultMessage: 'Loading…', +}); + +export const MonitorIDLabel = i18n.translate('xpack.synthetics.monitorStatusBar.monitor.id', { + defaultMessage: 'Monitor ID', +}); + +export const OverallAvailability = i18n.translate( + 'xpack.synthetics.monitorStatusBar.monitor.availability', + { + defaultMessage: 'Overall availability', + } +); + +export const MonitoringFrom = i18n.translate( + 'xpack.synthetics.monitorStatusBar.monitor.monitoringFrom', + { + defaultMessage: 'Monitoring from', + } +); + +export const ChangeToMapView = i18n.translate( + 'xpack.synthetics.monitorStatusBar.monitor.monitoringFrom.listToMap', + { + defaultMessage: 'Change to map view to check availability by location.', + } +); + +export const ChangeToListView = i18n.translate( + 'xpack.synthetics.monitorStatusBar.monitor.monitoringFrom.MapToList', + { + defaultMessage: 'Change to list view to check availability by location.', + } +); + +export const LocationLabel = i18n.translate( + 'xpack.synthetics.monitorStatusBar.monitor.availabilityReport.location', + { + defaultMessage: 'Location', + } +); + +export const AvailabilityLabel = i18n.translate( + 'xpack.synthetics.monitorStatusBar.monitor.availabilityReport.availability', + { + defaultMessage: 'Availability', + } +); + +export const LastCheckLabel = i18n.translate( + 'xpack.synthetics.monitorStatusBar.monitor.availabilityReport.lastCheck', + { + defaultMessage: 'Last check', + } +); diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/step_detail_container.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/step_detail_container.tsx similarity index 94% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/step_detail_container.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/step_detail_container.tsx index 1e493ad21b4d3..117da7f0a73ce 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/step_detail_container.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/step_detail_container.tsx @@ -12,7 +12,7 @@ import { useMonitorBreadcrumb } from './use_monitor_breadcrumb'; import { WaterfallChartContainer } from './waterfall/waterfall_chart_container'; import { useStepDetailPage } from '../../../../pages/synthetics/step_detail_page'; -export const NO_STEP_DATA = i18n.translate('xpack.uptime.synthetics.stepDetail.noData', { +export const NO_STEP_DATA = i18n.translate('xpack.synthetics.synthetics.stepDetail.noData', { defaultMessage: 'No data could be found for this step', }); diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/step_page_nav.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/step_page_nav.tsx similarity index 93% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/step_page_nav.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/step_page_nav.tsx index 81c72b74c18e8..bddad0132def2 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/step_page_nav.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/step_page_nav.tsx @@ -11,14 +11,14 @@ import moment from 'moment'; import { i18n } from '@kbn/i18n'; export const PREVIOUS_CHECK_BUTTON_TEXT = i18n.translate( - 'xpack.uptime.synthetics.stepDetail.previousCheckButtonText', + 'xpack.synthetics.synthetics.stepDetail.previousCheckButtonText', { defaultMessage: 'Previous check', } ); export const NEXT_CHECK_BUTTON_TEXT = i18n.translate( - 'xpack.uptime.synthetics.stepDetail.nextCheckButtonText', + 'xpack.synthetics.synthetics.stepDetail.nextCheckButtonText', { defaultMessage: 'Next check', } diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/step_page_title.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/step_page_title.tsx similarity index 96% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/step_page_title.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/step_page_title.tsx index 44a318401a789..2e90fc3299ba1 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/step_page_title.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/step_page_title.tsx @@ -41,7 +41,7 @@ export const StepPageTitleContent = ({ { // NOTE: This happens client side as the "payload" property is mapped diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/types.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/types.ts new file mode 100644 index 0000000000000..c396bec47e0e6 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/types.ts @@ -0,0 +1,262 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { NetworkEvent } from '../../../../../../../common/runtime_types'; + +export enum Timings { + Blocked = 'blocked', + Dns = 'dns', + Connect = 'connect', + Ssl = 'ssl', + Send = 'send', + Wait = 'wait', + Receive = 'receive', +} + +export enum Metadata { + Status = 'status', + ResourceSize = 'resourceSize', + TransferSize = 'transferSize', + CertificateIssuer = 'certificateIssuer', + CertificateIssueDate = 'certificateIssueDate', + CertificateExpiryDate = 'certificateExpiryDate', + CertificateSubject = 'certificateSubject', + IP = 'ip', + MimeType = 'mimeType', + RequestStart = 'requestStart', +} + +export const FriendlyTimingLabels = { + [Timings.Blocked]: i18n.translate( + 'xpack.synthetics.synthetics.waterfallChart.labels.timings.blocked', + { + defaultMessage: 'Queued / Blocked', + } + ), + [Timings.Dns]: i18n.translate('xpack.synthetics.synthetics.waterfallChart.labels.timings.dns', { + defaultMessage: 'DNS', + }), + [Timings.Connect]: i18n.translate( + 'xpack.synthetics.synthetics.waterfallChart.labels.timings.connect', + { + defaultMessage: 'Connecting', + } + ), + [Timings.Ssl]: i18n.translate('xpack.synthetics.synthetics.waterfallChart.labels.timings.ssl', { + defaultMessage: 'TLS', + }), + [Timings.Send]: i18n.translate('xpack.synthetics.synthetics.waterfallChart.labels.timings.send', { + defaultMessage: 'Sending request', + }), + [Timings.Wait]: i18n.translate('xpack.synthetics.synthetics.waterfallChart.labels.timings.wait', { + defaultMessage: 'Waiting (TTFB)', + }), + [Timings.Receive]: i18n.translate( + 'xpack.synthetics.synthetics.waterfallChart.labels.timings.receive', + { + defaultMessage: 'Content downloading', + } + ), +}; + +export const FriendlyFlyoutLabels = { + [Metadata.Status]: i18n.translate( + 'xpack.synthetics.synthetics.waterfallChart.labels.metadata.status', + { + defaultMessage: 'Status', + } + ), + [Metadata.MimeType]: i18n.translate( + 'xpack.synthetics.synthetics.waterfallChart.labels.metadata.contentType', + { + defaultMessage: 'Content type', + } + ), + [Metadata.RequestStart]: i18n.translate( + 'xpack.synthetics.synthetics.waterfallChart.labels.metadata.requestStart', + { + defaultMessage: 'Request start', + } + ), + [Metadata.ResourceSize]: i18n.translate( + 'xpack.synthetics.synthetics.waterfallChart.labels.metadata.resourceSize', + { + defaultMessage: 'Resource size', + } + ), + [Metadata.TransferSize]: i18n.translate( + 'xpack.synthetics.synthetics.waterfallChart.labels.metadata.transferSize', + { + defaultMessage: 'Transfer size', + } + ), + [Metadata.CertificateIssuer]: i18n.translate( + 'xpack.synthetics.synthetics.waterfallChart.labels.metadata.certificateIssuer', + { + defaultMessage: 'Issuer', + } + ), + [Metadata.CertificateIssueDate]: i18n.translate( + 'xpack.synthetics.synthetics.waterfallChart.labels.metadata.certificateIssueDate', + { + defaultMessage: 'Valid from', + } + ), + [Metadata.CertificateExpiryDate]: i18n.translate( + 'xpack.synthetics.synthetics.waterfallChart.labels.metadata.certificateExpiryDate', + { + defaultMessage: 'Valid until', + } + ), + [Metadata.CertificateSubject]: i18n.translate( + 'xpack.synthetics.synthetics.waterfallChart.labels.metadata.certificateSubject', + { + defaultMessage: 'Common name', + } + ), + [Metadata.IP]: i18n.translate('xpack.synthetics.synthetics.waterfallChart.labels.metadata.ip', { + defaultMessage: 'IP', + }), +}; + +export const TIMING_ORDER = [ + Timings.Blocked, + Timings.Dns, + Timings.Connect, + Timings.Ssl, + Timings.Send, + Timings.Wait, + Timings.Receive, +] as const; + +export const META_DATA_ORDER_FLYOUT = [ + Metadata.MimeType, + Timings.Dns, + Timings.Connect, + Timings.Ssl, + Timings.Wait, + Timings.Receive, +] as const; + +export type CalculatedTimings = { + [K in Timings]?: number; +}; + +export enum MimeType { + Html = 'html', + Script = 'script', + Stylesheet = 'stylesheet', + Media = 'media', + Font = 'font', + XHR = 'xhr', + Other = 'other', +} + +export const FriendlyMimetypeLabels = { + [MimeType.Html]: i18n.translate( + 'xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.html', + { + defaultMessage: 'HTML', + } + ), + [MimeType.Script]: i18n.translate( + 'xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.script', + { + defaultMessage: 'JS', + } + ), + [MimeType.Stylesheet]: i18n.translate( + 'xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.stylesheet', + { + defaultMessage: 'CSS', + } + ), + [MimeType.Media]: i18n.translate( + 'xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.media', + { + defaultMessage: 'Media', + } + ), + [MimeType.Font]: i18n.translate( + 'xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.font', + { + defaultMessage: 'Font', + } + ), + [MimeType.XHR]: i18n.translate( + 'xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.xhr', + { + defaultMessage: 'XHR', + } + ), + [MimeType.Other]: i18n.translate( + 'xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.other', + { + defaultMessage: 'Other', + } + ), +}; + +// NOTE: This list tries to cover the standard spec compliant mime types, +// and a few popular non-standard ones, but it isn't exhaustive. +export const MimeTypesMap: Record = { + 'text/html': MimeType.Html, + 'application/javascript': MimeType.Script, + 'text/javascript': MimeType.Script, + 'text/css': MimeType.Stylesheet, + // Images + 'image/apng': MimeType.Media, + 'image/bmp': MimeType.Media, + 'image/gif': MimeType.Media, + 'image/x-icon': MimeType.Media, + 'image/jpeg': MimeType.Media, + 'image/png': MimeType.Media, + 'image/svg+xml': MimeType.Media, + 'image/tiff': MimeType.Media, + 'image/webp': MimeType.Media, + // Common audio / video formats + 'audio/wave': MimeType.Media, + 'audio/wav': MimeType.Media, + 'audio/x-wav': MimeType.Media, + 'audio/x-pn-wav': MimeType.Media, + 'audio/webm': MimeType.Media, + 'video/webm': MimeType.Media, + 'video/mp4': MimeType.Media, + 'audio/ogg': MimeType.Media, + 'video/ogg': MimeType.Media, + 'application/ogg': MimeType.Media, + // Fonts + 'font/otf': MimeType.Font, + 'font/ttf': MimeType.Font, + 'font/woff': MimeType.Font, + 'font/woff2': MimeType.Font, + 'application/x-font-opentype': MimeType.Font, + 'application/font-woff': MimeType.Font, + 'application/font-woff2': MimeType.Font, + 'application/vnd.ms-fontobject': MimeType.Font, + 'application/font-sfnt': MimeType.Font, + + // XHR + 'application/json': MimeType.XHR, +}; + +export type NetworkItem = NetworkEvent; +export type NetworkItems = NetworkItem[]; + +export type SidebarItem = Pick & { + isHighlighted: boolean; + index: number; + offsetIndex: number; +}; +export type SidebarItems = SidebarItem[]; + +export interface LegendItem { + name: string; + colour: string; +} +export type LegendItems = LegendItem[]; diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_container.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_container.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_container.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_container.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_container.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_container.tsx similarity index 82% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_container.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_container.tsx index ffa9cb5f2925f..95c42d505fbf2 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_container.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_container.tsx @@ -15,11 +15,14 @@ import { networkEventsSelector } from '../../../../../state/selectors'; import { WaterfallChartWrapper } from './waterfall_chart_wrapper'; import { extractItems } from './data_formatting'; import { useStepWaterfallMetrics } from '../use_step_waterfall_metrics'; -import { JourneyStep } from '../../../../../../common/runtime_types'; +import { JourneyStep } from '../../../../../../../common/runtime_types'; -export const NO_DATA_TEXT = i18n.translate('xpack.uptime.synthetics.stepDetail.waterfallNoData', { - defaultMessage: 'No waterfall data could be found for this step', -}); +export const NO_DATA_TEXT = i18n.translate( + 'xpack.synthetics.synthetics.stepDetail.waterfallNoData', + { + defaultMessage: 'No waterfall data could be found for this step', + } +); interface Props { checkGroup: string; @@ -60,9 +63,12 @@ export const WaterfallChartContainer: React.FC = ({ checkGroup, stepIndex @@ -88,7 +94,7 @@ export const WaterfallChartContainer: React.FC = ({ checkGroup, stepIndex } @@ -96,7 +102,7 @@ export const WaterfallChartContainer: React.FC = ({ checkGroup, stepIndex iconType="help" > diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.tsx similarity index 98% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.tsx index 4b50f86e6ee3b..0849832107aeb 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.tsx @@ -15,7 +15,7 @@ import { WaterfallFilter } from './waterfall_filter'; import { WaterfallFlyout } from './waterfall_flyout'; import { WaterfallSidebarItem } from './waterfall_sidebar_item'; import { MarkerItems } from '../../waterfall/context/waterfall_chart'; -import { JourneyStep } from '../../../../../../common/runtime_types'; +import { JourneyStep } from '../../../../../../../common/runtime_types'; export const renderLegendItem: RenderItem = (item) => { return ( diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_filter.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_filter.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_filter.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_filter.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_filter.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_filter.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_filter.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_filter.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_flyout.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_flyout.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_flyout.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_flyout.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_flyout.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_flyout.tsx similarity index 92% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_flyout.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_flyout.tsx index bdcea95c0c0c3..4c78010e9c4e6 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_flyout.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_flyout.tsx @@ -24,26 +24,26 @@ import { MiddleTruncatedText } from '../../waterfall'; import { WaterfallMetadataEntry } from '../../waterfall/types'; import { OnFlyoutClose } from '../../waterfall/components/use_flyout'; -export const DETAILS = i18n.translate('xpack.uptime.synthetics.waterfall.flyout.details', { +export const DETAILS = i18n.translate('xpack.synthetics.synthetics.waterfall.flyout.details', { defaultMessage: 'Details', }); export const CERTIFICATES = i18n.translate( - 'xpack.uptime.synthetics.waterfall.flyout.certificates', + 'xpack.synthetics.synthetics.waterfall.flyout.certificates', { defaultMessage: 'Certificate headers', } ); export const REQUEST_HEADERS = i18n.translate( - 'xpack.uptime.synthetics.waterfall.flyout.requestHeaders', + 'xpack.synthetics.synthetics.waterfall.flyout.requestHeaders', { defaultMessage: 'Request headers', } ); export const RESPONSE_HEADERS = i18n.translate( - 'xpack.uptime.synthetics.waterfall.flyout.responseHeaders', + 'xpack.synthetics.synthetics.waterfall.flyout.responseHeaders', { defaultMessage: 'Response headers', } diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_sidebar_item.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_sidebar_item.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_sidebar_item.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_sidebar_item.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_sidebar_item.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_sidebar_item.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/step_detail/waterfall/waterfall_sidebar_item.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_sidebar_item.tsx diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/translations.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/translations.ts new file mode 100644 index 0000000000000..cf7ab30c8867d --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/translations.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const VIEW_PERFORMANCE = i18n.translate( + 'xpack.synthetics.pingList.synthetics.performanceBreakDown', + { + defaultMessage: 'View performance breakdown', + } +); diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/README.md b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/README.md similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/README.md rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/README.md diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/constants.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/constants.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/constants.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/constants.ts diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/legend.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/legend.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/legend.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/legend.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/middle_truncated_text.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/middle_truncated_text.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/middle_truncated_text.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/middle_truncated_text.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/middle_truncated_text.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/middle_truncated_text.tsx similarity index 94% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/middle_truncated_text.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/middle_truncated_text.tsx index f649a5f2d373f..7da52b2ce9bc2 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/middle_truncated_text.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/middle_truncated_text.tsx @@ -146,9 +146,12 @@ export const MiddleTruncatedText = ({ type="lock" size="s" color="success" - aria-label={i18n.translate('xpack.uptime.waterfallChart.sidebar.url.https', { - defaultMessage: 'https', - })} + aria-label={i18n.translate( + 'xpack.synthetics.waterfallChart.sidebar.url.https', + { + defaultMessage: 'https', + } + )} /> )} {chunks.first} @@ -170,7 +173,7 @@ export const MiddleTruncatedText = ({ diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/network_requests_total.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/network_requests_total.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/network_requests_total.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/network_requests_total.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/network_requests_total.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/network_requests_total.tsx similarity index 79% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/network_requests_total.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/network_requests_total.tsx index fe45c45b13d25..4fac0b3cd00d2 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/network_requests_total.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/network_requests_total.tsx @@ -28,13 +28,13 @@ export const NetworkRequestsTotal = ({ fetchedNetworkRequests ? ( @@ -45,7 +45,7 @@ export const NetworkRequestsTotal = ({ />{' '} {showHighlightedNetworkRequests && highlightedNetworkRequests >= 0 && ( fetchedNetworkRequests && ( )} diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/sidebar.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/sidebar.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/sidebar.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/sidebar.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/styles.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/styles.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/styles.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/styles.ts diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/translations.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/translations.ts new file mode 100644 index 0000000000000..6bb0c03f7b99e --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/translations.ts @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const FILTER_REQUESTS_LABEL = i18n.translate( + 'xpack.synthetics.synthetics.waterfall.searchBox.placeholder', + { + defaultMessage: 'Filter network requests', + } +); + +export const FILTER_SCREENREADER_LABEL = i18n.translate( + 'xpack.synthetics.synthetics.waterfall.filterGroup.filterScreenreaderLabel', + { + defaultMessage: 'Filter by', + } +); + +export const FILTER_REMOVE_SCREENREADER_LABEL = i18n.translate( + 'xpack.synthetics.synthetics.waterfall.filterGroup.removeFilterScreenReaderLabel', + { + defaultMessage: 'Remove filter by', + } +); + +export const FILTER_POPOVER_OPEN_LABEL = i18n.translate( + 'xpack.synthetics.pingList.synthetics.waterfall.filters.popover', + { + defaultMessage: 'Click to open waterfall filters', + } +); + +export const FILTER_COLLAPSE_REQUESTS_LABEL = i18n.translate( + 'xpack.synthetics.pingList.synthetics.waterfall.filters.collapseRequestsLabel', + { + defaultMessage: 'Collapse to only show matching requests', + } +); + +export const SIDEBAR_FILTER_MATCHES_SCREENREADER_LABEL = i18n.translate( + 'xpack.synthetics.synthetics.waterfall.sidebar.filterMatchesScreenReaderLabel', + { + defaultMessage: 'Resource matches filter', + } +); diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/use_bar_charts.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/use_bar_charts.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/use_bar_charts.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/use_bar_charts.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/use_bar_charts.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/use_bar_charts.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/use_bar_charts.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/use_bar_charts.ts diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/use_flyout.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/use_flyout.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/use_flyout.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/use_flyout.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/use_flyout.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/use_flyout.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/use_flyout.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/use_flyout.ts diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall_bar_chart.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall_bar_chart.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall_bar_chart.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall_bar_chart.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall_chart.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall_chart.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall_chart.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall_chart.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall_chart_fixed_axis.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall_chart_fixed_axis.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall_chart_fixed_axis.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall_chart_fixed_axis.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall_flyout_table.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall_flyout_table.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall_flyout_table.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall_flyout_table.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall_marker_icon.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall_marker_icon.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall_marker_icon.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall_marker_icon.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall_marker_icon.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall_marker_icon.tsx similarity index 78% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall_marker_icon.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall_marker_icon.tsx index 4bef5fb041520..675224bfa8f79 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall_marker_icon.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall_marker_icon.tsx @@ -16,7 +16,7 @@ export function WaterfallMarkerIcon({ field, label }: { field: string; label: st if (!field) { return ( ', () => { diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall_marker_trend.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall_marker_trend.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall_marker_trend.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall_marker_trend.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall_markers.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall_markers.tsx similarity index 89% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall_markers.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall_markers.tsx index 883a7a8ea9268..1a8e5dd1d51b4 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall_markers.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall_markers.tsx @@ -78,7 +78,7 @@ export function WaterfallChartMarkers() { { dataValue: offset, details: label, - header: i18n.translate('xpack.uptime.synthetics.waterfall.offsetUnit', { + header: i18n.translate('xpack.synthetics.synthetics.waterfall.offsetUnit', { defaultMessage: '{offset} ms', values: { offset }, }), @@ -149,27 +149,30 @@ const Wrapper = euiStyled.span` } `; -export const FCP_LABEL = i18n.translate('xpack.uptime.synthetics.waterfall.fcpLabel', { +export const FCP_LABEL = i18n.translate('xpack.synthetics.synthetics.waterfall.fcpLabel', { defaultMessage: 'First contentful paint', }); -export const LCP_LABEL = i18n.translate('xpack.uptime.synthetics.waterfall.lcpLabel', { +export const LCP_LABEL = i18n.translate('xpack.synthetics.synthetics.waterfall.lcpLabel', { defaultMessage: 'Largest contentful paint', }); export const LAYOUT_SHIFT_LABEL = i18n.translate( - 'xpack.uptime.synthetics.waterfall.layoutShiftLabel', + 'xpack.synthetics.synthetics.waterfall.layoutShiftLabel', { defaultMessage: 'Layout shift', } ); -export const LOAD_EVENT_LABEL = i18n.translate('xpack.uptime.synthetics.waterfall.loadEventLabel', { - defaultMessage: 'Load event', -}); +export const LOAD_EVENT_LABEL = i18n.translate( + 'xpack.synthetics.synthetics.waterfall.loadEventLabel', + { + defaultMessage: 'Load event', + } +); export const DOCUMENT_CONTENT_LOADED_LABEL = i18n.translate( - 'xpack.uptime.synthetics.waterfall.domContentLabel', + 'xpack.synthetics.synthetics.waterfall.domContentLabel', { defaultMessage: 'DOM Content Loaded', } diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall_tooltip_content.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall_tooltip_content.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall_tooltip_content.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall_tooltip_content.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall_tooltip_content.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall_tooltip_content.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/components/waterfall_tooltip_content.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/components/waterfall_tooltip_content.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/context/waterfall_chart.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/context/waterfall_chart.tsx similarity index 97% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/context/waterfall_chart.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/context/waterfall_chart.tsx index d495b7432bce7..fd38fbbfb6bb6 100644 --- a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/context/waterfall_chart.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/context/waterfall_chart.tsx @@ -9,7 +9,7 @@ import React, { createContext, useContext, Context } from 'react'; import { WaterfallData, WaterfallDataEntry, WaterfallMetadata } from '../types'; import { OnSidebarClick, OnElementClick, OnProjectionClick } from '../components/use_flyout'; import { SidebarItems } from '../../step_detail/waterfall/types'; -import { JourneyStep } from '../../../../../../common/runtime_types'; +import { JourneyStep } from '../../../../../../../common/runtime_types'; export type MarkerItems = Array<{ id: diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/index.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/index.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/index.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/index.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/types.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/types.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor/synthetics/waterfall/types.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/waterfall/types.ts diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/action_bar/action_bar.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/action_bar/action_bar.test.tsx similarity index 98% rename from x-pack/plugins/synthetics/public/components/monitor_management/action_bar/action_bar.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/action_bar/action_bar.test.tsx index 64b7984b00b40..e903f4d23424b 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/action_bar/action_bar.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/action_bar/action_bar.test.tsx @@ -15,7 +15,7 @@ import { HTTPFields, ScheduleUnit, SyntheticsMonitor, -} from '../../../../common/runtime_types'; +} from '../../../../../common/runtime_types'; import { ActionBar } from './action_bar'; describe('', () => { diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/action_bar/action_bar.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/action_bar/action_bar.tsx similarity index 84% rename from x-pack/plugins/synthetics/public/components/monitor_management/action_bar/action_bar.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/action_bar/action_bar.tsx index 4c6f296e468f9..80e614eb4d77f 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/action_bar/action_bar.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/action_bar/action_bar.tsx @@ -21,11 +21,11 @@ import { useSelector } from 'react-redux'; import { FETCH_STATUS, useFetcher } from '@kbn/observability-plugin/public'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; -import { MONITOR_MANAGEMENT_ROUTE } from '../../../../common/constants'; +import { MONITOR_MANAGEMENT_ROUTE } from '../../../../../common/constants'; import { UptimeSettingsContext } from '../../../contexts'; import { setMonitor } from '../../../state/api'; -import { SyntheticsMonitor } from '../../../../common/runtime_types'; +import { SyntheticsMonitor } from '../../../../../common/runtime_types'; import { TestRun } from '../test_now_mode/test_now_mode'; import { monitorManagementListSelector } from '../../../state/selectors'; @@ -65,7 +65,7 @@ export const ActionBar = ({ } return setMonitor({ monitor, - id: monitorId ? Buffer.from(monitorId, 'base64').toString('utf8') : undefined, + id: monitorId, }); }, [monitor, monitorId, isValid, isSaving]); @@ -186,51 +186,57 @@ const WarningText = euiStyled(EuiText)` padding-left: 8px; `; -const DISCARD_LABEL = i18n.translate('xpack.uptime.monitorManagement.discardLabel', { +const DISCARD_LABEL = i18n.translate('xpack.synthetics.monitorManagement.discardLabel', { defaultMessage: 'Discard', }); -const SAVE_MONITOR_LABEL = i18n.translate('xpack.uptime.monitorManagement.saveMonitorLabel', { +const SAVE_MONITOR_LABEL = i18n.translate('xpack.synthetics.monitorManagement.saveMonitorLabel', { defaultMessage: 'Save monitor', }); -const UPDATE_MONITOR_LABEL = i18n.translate('xpack.uptime.monitorManagement.updateMonitorLabel', { - defaultMessage: 'Update monitor', -}); +const UPDATE_MONITOR_LABEL = i18n.translate( + 'xpack.synthetics.monitorManagement.updateMonitorLabel', + { + defaultMessage: 'Update monitor', + } +); -const RUN_TEST_LABEL = i18n.translate('xpack.uptime.monitorManagement.runTest', { +const RUN_TEST_LABEL = i18n.translate('xpack.synthetics.monitorManagement.runTest', { defaultMessage: 'Run test', }); -const RE_RUN_TEST_LABEL = i18n.translate('xpack.uptime.monitorManagement.reRunTest', { +const RE_RUN_TEST_LABEL = i18n.translate('xpack.synthetics.monitorManagement.reRunTest', { defaultMessage: 'Re-run test', }); -const VALIDATION_ERROR_LABEL = i18n.translate('xpack.uptime.monitorManagement.validationError', { - defaultMessage: 'Your monitor has errors. Please fix them before saving.', -}); +const VALIDATION_ERROR_LABEL = i18n.translate( + 'xpack.synthetics.monitorManagement.validationError', + { + defaultMessage: 'Your monitor has errors. Please fix them before saving.', + } +); const MONITOR_SUCCESS_LABEL = i18n.translate( - 'xpack.uptime.monitorManagement.monitorAddedSuccessMessage', + 'xpack.synthetics.monitorManagement.monitorAddedSuccessMessage', { defaultMessage: 'Monitor added successfully.', } ); const MONITOR_UPDATED_SUCCESS_LABEL = i18n.translate( - 'xpack.uptime.monitorManagement.monitorEditedSuccessMessage', + 'xpack.synthetics.monitorManagement.monitorEditedSuccessMessage', { defaultMessage: 'Monitor updated successfully.', } ); const MONITOR_FAILURE_LABEL = i18n.translate( - 'xpack.uptime.monitorManagement.monitorFailureMessage', + 'xpack.synthetics.monitorManagement.monitorFailureMessage', { defaultMessage: 'Monitor was unable to be saved. Please try again later.', } ); -const TEST_NOW_DESCRIPTION = i18n.translate('xpack.uptime.testRun.description', { +const TEST_NOW_DESCRIPTION = i18n.translate('xpack.synthetics.testRun.description', { defaultMessage: 'Test your monitor and verify the results before saving', }); diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/action_bar/action_bar_errors.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/action_bar/action_bar_errors.test.tsx similarity index 98% rename from x-pack/plugins/synthetics/public/components/monitor_management/action_bar/action_bar_errors.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/action_bar/action_bar_errors.test.tsx index b92357f3ecc14..bb40077dab78d 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/action_bar/action_bar_errors.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/action_bar/action_bar_errors.test.tsx @@ -15,7 +15,7 @@ import { HTTPFields, ScheduleUnit, SyntheticsMonitor, -} from '../../../../common/runtime_types'; +} from '../../../../../common/runtime_types'; import { spyOnUseFetcher } from '../../../lib/helper/spy_use_fetcher'; import * as kibana from '../../../state/kibana_service'; import { ActionBar } from './action_bar'; diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/action_bar/action_bar_portal.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/action_bar/action_bar_portal.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor_management/action_bar/action_bar_portal.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/action_bar/action_bar_portal.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/add_monitor_btn.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/add_monitor_btn.tsx similarity index 88% rename from x-pack/plugins/synthetics/public/components/monitor_management/add_monitor_btn.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/add_monitor_btn.tsx index 7596c11dbddad..90bec2d28f988 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/add_monitor_btn.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/add_monitor_btn.tsx @@ -11,7 +11,7 @@ import { EuiButton, EuiFlexItem, EuiFlexGroup, EuiToolTip, EuiSwitch } from '@el import { useHistory } from 'react-router-dom'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { kibanaService } from '../../state/kibana_service'; -import { MONITOR_ADD_ROUTE } from '../../../common/constants'; +import { MONITOR_ADD_ROUTE } from '../../../../common/constants'; import { useEnablement } from './hooks/use_enablement'; import { useSyntheticsServiceAllowed } from './hooks/use_service_allowed'; @@ -135,47 +135,47 @@ export const AddMonitorBtn = () => { ); }; -const ADD_MONITOR_LABEL = i18n.translate('xpack.uptime.monitorManagement.addMonitorLabel', { +const ADD_MONITOR_LABEL = i18n.translate('xpack.synthetics.monitorManagement.addMonitorLabel', { defaultMessage: 'Add monitor', }); const SYNTHETICS_ENABLE_LABEL = i18n.translate( - 'xpack.uptime.monitorManagement.syntheticsEnableLabel', + 'xpack.synthetics.monitorManagement.syntheticsEnableLabel', { defaultMessage: 'Enable', } ); const SYNTHETICS_ENABLE_FAILURE = i18n.translate( - 'xpack.uptime.monitorManagement.syntheticsEnabledFailure', + 'xpack.synthetics.monitorManagement.syntheticsEnabledFailure', { defaultMessage: 'Monitor Management was not able to be enabled. Please contact support.', } ); const SYNTHETICS_DISABLE_FAILURE = i18n.translate( - 'xpack.uptime.monitorManagement.syntheticsDisabledFailure', + 'xpack.synthetics.monitorManagement.syntheticsDisabledFailure', { defaultMessage: 'Monitor Management was not able to be disabled. Please contact support.', } ); const SYNTHETICS_ENABLE_SUCCESS = i18n.translate( - 'xpack.uptime.monitorManagement.syntheticsEnableSuccess', + 'xpack.synthetics.monitorManagement.syntheticsEnableSuccess', { defaultMessage: 'Monitor Management enabled successfully.', } ); const SYNTHETICS_DISABLE_SUCCESS = i18n.translate( - 'xpack.uptime.monitorManagement.syntheticsDisabledSuccess', + 'xpack.synthetics.monitorManagement.syntheticsDisabledSuccess', { defaultMessage: 'Monitor Management disabled successfully.', } ); const SYNTHETICS_DISABLED_MESSAGE = i18n.translate( - 'xpack.uptime.monitorManagement.syntheticsDisabled', + 'xpack.synthetics.monitorManagement.syntheticsDisabled', { defaultMessage: 'Monitor Management is currently disabled. Please contact an administrator to enable Monitor Management.', @@ -183,7 +183,7 @@ const SYNTHETICS_DISABLED_MESSAGE = i18n.translate( ); const SYNTHETICS_ENABLE_TOOL_TIP_MESSAGE = i18n.translate( - 'xpack.uptime.monitorManagement.syntheticsEnableToolTip', + 'xpack.synthetics.monitorManagement.syntheticsEnableToolTip', { defaultMessage: 'Enable Monitor Management to create lightweight and real-browser monitors from locations around the world.', @@ -191,7 +191,7 @@ const SYNTHETICS_ENABLE_TOOL_TIP_MESSAGE = i18n.translate( ); const SYNTHETICS_DISABLE_TOOL_TIP_MESSAGE = i18n.translate( - 'xpack.uptime.monitorManagement.syntheticsDisableToolTip', + 'xpack.synthetics.monitorManagement.syntheticsDisableToolTip', { defaultMessage: 'Disabling Monitor Management will immediately stop the execution of monitors in all test locations and prevent the creation of new monitors.', @@ -199,7 +199,7 @@ const SYNTHETICS_DISABLE_TOOL_TIP_MESSAGE = i18n.translate( ); const API_KEYS_DISABLED_TOOL_TIP_MESSAGE = i18n.translate( - 'xpack.uptime.monitorManagement.apiKeysDisabledToolTip', + 'xpack.synthetics.monitorManagement.apiKeysDisabledToolTip', { defaultMessage: 'API Keys are disabled for this cluster. Monitor Management requires the use of API keys to write back to your Elasticsearch cluster. To enable API keys, please contact an administrator.', diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/content/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/content/index.ts new file mode 100644 index 0000000000000..8c88fb8944a23 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/content/index.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const SYNTHETICS_ENABLE_FAILURE = i18n.translate( + 'xpack.synthetics.monitorManagement.syntheticsEnabledFailure', + { + defaultMessage: 'Monitor Management was not able to be enabled. Please contact support.', + } +); + +export const SYNTHETICS_DISABLE_FAILURE = i18n.translate( + 'xpack.synthetics.monitorManagement.syntheticsDisabledFailure', + { + defaultMessage: 'Monitor Management was not able to be disabled. Please contact support.', + } +); + +export const SYNTHETICS_ENABLE_SUCCESS = i18n.translate( + 'xpack.synthetics.monitorManagement.syntheticsEnableSuccess', + { + defaultMessage: 'Monitor Management enabled successfully.', + } +); + +export const SYNTHETICS_DISABLE_SUCCESS = i18n.translate( + 'xpack.synthetics.monitorManagement.syntheticsDisabledSuccess', + { + defaultMessage: 'Monitor Management disabled successfully.', + } +); diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/edit_monitor_config.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/edit_monitor_config.tsx similarity index 96% rename from x-pack/plugins/synthetics/public/components/monitor_management/edit_monitor_config.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/edit_monitor_config.tsx index 28e0bb105e29a..245f058c48d94 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/edit_monitor_config.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/edit_monitor_config.tsx @@ -14,11 +14,11 @@ import { DataStream, ScheduleUnit, ThrottlingOptions, -} from '../../../common/runtime_types'; +} from '../../../../common/runtime_types'; import { SyntheticsProviders } from '../fleet_package/contexts'; import { PolicyConfig } from '../fleet_package/types'; import { MonitorConfig } from './monitor_config/monitor_config'; -import { DEFAULT_NAMESPACE_STRING } from '../../../common/constants'; +import { DEFAULT_NAMESPACE_STRING } from '../../../../common/constants/monitor_defaults'; interface Props { monitor: MonitorFields; diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_enablement.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_enablement.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_enablement.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_enablement.ts diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_format_monitor.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_format_monitor.ts similarity index 94% rename from x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_format_monitor.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_format_monitor.ts index 49d467d7b8799..5d600a10daf39 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_format_monitor.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_format_monitor.ts @@ -6,8 +6,8 @@ */ import { useEffect, useRef, useState } from 'react'; -import { ConfigKey, DataStream, MonitorFields } from '../../../../common/runtime_types'; -import { Validation } from '../../../../common/types'; +import { ConfigKey, DataStream, MonitorFields } from '../../../../../common/runtime_types'; +import { Validation } from '../../../../../common/types'; interface Props { monitorType: DataStream; diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_inline_errors.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_inline_errors.test.tsx similarity index 97% rename from x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_inline_errors.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_inline_errors.test.tsx index fe20dc3ea6c9d..ebc9b55556d40 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_inline_errors.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_inline_errors.test.tsx @@ -8,7 +8,7 @@ import { renderHook } from '@testing-library/react-hooks'; import { MockRedux } from '../../../lib/helper/rtl_helpers'; import { useInlineErrors } from './use_inline_errors'; -import { DEFAULT_THROTTLING } from '../../../../common/runtime_types'; +import { DEFAULT_THROTTLING } from '../../../../../common/runtime_types'; import * as obsvPlugin from '@kbn/observability-plugin/public/hooks/use_es_search'; function mockNow(date: string | number | Date) { diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_inline_errors.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_inline_errors.ts similarity index 92% rename from x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_inline_errors.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_inline_errors.ts index adc07853a93cd..9970622ca416b 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_inline_errors.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_inline_errors.ts @@ -10,11 +10,11 @@ import moment from 'moment'; import { useMemo } from 'react'; import { useEsSearch } from '@kbn/observability-plugin/public'; import { monitorManagementListSelector } from '../../../state/selectors'; -import { Ping } from '../../../../common/runtime_types'; -import { EXCLUDE_RUN_ONCE_FILTER } from '../../../../common/constants/client_defaults'; +import { Ping } from '../../../../../common/runtime_types'; +import { EXCLUDE_RUN_ONCE_FILTER } from '../../../../../common/constants/client_defaults'; import { useUptimeRefreshContext } from '../../../contexts/uptime_refresh_context'; import { useInlineErrorsCount } from './use_inline_errors_count'; -import { SYNTHETICS_INDEX_PATTERN } from '../../../../common/constants'; +import { SYNTHETICS_INDEX_PATTERN } from '../../../../../common/constants'; const sortFieldMap: Record = { ['name.keyword']: 'monitor.name', diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_inline_errors_count.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_inline_errors_count.test.tsx similarity index 97% rename from x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_inline_errors_count.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_inline_errors_count.test.tsx index 7ad0d58488e99..b1dbb41880e65 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_inline_errors_count.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_inline_errors_count.test.tsx @@ -9,7 +9,7 @@ import { renderHook } from '@testing-library/react-hooks'; import { MockRedux } from '../../../lib/helper/rtl_helpers'; import { useInlineErrorsCount } from './use_inline_errors_count'; import * as obsvPlugin from '@kbn/observability-plugin/public/hooks/use_es_search'; -import { DEFAULT_THROTTLING } from '../../../../common/runtime_types'; +import { DEFAULT_THROTTLING } from '../../../../../common/runtime_types'; function mockNow(date: string | number | Date) { const fakeNow = new Date(date).getTime(); diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_inline_errors_count.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_inline_errors_count.ts similarity index 94% rename from x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_inline_errors_count.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_inline_errors_count.ts index 64b37d371cac5..dc69346e6c9a5 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_inline_errors_count.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_inline_errors_count.ts @@ -11,7 +11,7 @@ import { useEsSearch } from '@kbn/observability-plugin/public'; import { monitorManagementListSelector } from '../../../state/selectors'; import { useUptimeRefreshContext } from '../../../contexts/uptime_refresh_context'; import { getInlineErrorFilters } from './use_inline_errors'; -import { SYNTHETICS_INDEX_PATTERN } from '../../../../common/constants'; +import { SYNTHETICS_INDEX_PATTERN } from '../../../../../common/constants'; export function useInlineErrorsCount() { const monitorList = useSelector(monitorManagementListSelector); diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_invalid_monitors.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_invalid_monitors.tsx similarity index 90% rename from x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_invalid_monitors.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_invalid_monitors.tsx index cf63e7c4cd9e6..38e45e9a839d3 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_invalid_monitors.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_invalid_monitors.tsx @@ -8,8 +8,8 @@ import moment from 'moment'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { useFetcher } from '@kbn/observability-plugin/public'; -import { Ping, SyntheticsMonitor } from '../../../../common/runtime_types'; -import { syntheticsMonitorType } from '../../../../common/types/saved_objects'; +import { Ping, SyntheticsMonitor } from '../../../../../common/runtime_types'; +import { syntheticsMonitorType } from '../../../../../common/types/saved_objects'; export const useInvalidMonitors = (errorSummaries?: Ping[]) => { const { savedObjects } = useKibana().services; diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_locations.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_locations.test.tsx similarity index 96% rename from x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_locations.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_locations.test.tsx index 46b8981b74a0f..020dea1209dff 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_locations.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_locations.test.tsx @@ -14,7 +14,7 @@ import { useLocations } from './use_locations'; import * as reactRedux from 'react-redux'; import { getServiceLocations } from '../../../state/actions'; -import { DEFAULT_THROTTLING } from '../../../../common/runtime_types'; +import { DEFAULT_THROTTLING } from '../../../../../common/runtime_types'; describe('useExpViewTimeRange', function () { const dispatch = jest.fn(); diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_locations.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_locations.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_locations.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_locations.ts diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_monitor_list.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_monitor_list.ts new file mode 100644 index 0000000000000..e0899571f38b8 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_monitor_list.ts @@ -0,0 +1,67 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useEffect, useReducer, Reducer } from 'react'; +import { useDispatch } from 'react-redux'; +import { useParams } from 'react-router-dom'; +import { getMonitors } from '../../../state/actions'; +import { ConfigKey } from '../../../../../common/constants/monitor_management'; +import { MonitorManagementListPageState } from '../monitor_list/monitor_list'; + +export function useMonitorList() { + const dispatch = useDispatch(); + + const [pageState, dispatchPageAction] = useReducer( + monitorManagementPageReducer, + { + pageIndex: 1, // saved objects page index is base 1 + pageSize: 10, + sortOrder: 'asc', + sortField: `${ConfigKey.NAME}.keyword`, + } + ); + + const { pageIndex, pageSize, sortField, sortOrder } = pageState as MonitorManagementListPageState; + + const { type: viewType } = useParams<{ type: 'all' | 'invalid' }>(); + + useEffect(() => { + if (viewType === 'all') { + dispatch(getMonitors({ page: pageIndex, perPage: pageSize, sortOrder, sortField })); + } + }, [dispatch, pageIndex, pageSize, sortField, sortOrder, viewType, pageState]); + + return { + pageState, + dispatchPageAction, + viewType, + }; +} + +export type MonitorManagementPageAction = + | { + type: 'update'; + payload: MonitorManagementListPageState; + } + | { type: 'refresh' }; + +const monitorManagementPageReducer: Reducer< + MonitorManagementListPageState, + MonitorManagementPageAction +> = (state: MonitorManagementListPageState, action: MonitorManagementPageAction) => { + switch (action.type) { + case 'update': + return { + ...state, + ...action.payload, + }; + case 'refresh': + return { ...state }; + default: + throw new Error(`Action "${(action as MonitorManagementPageAction)?.type}" not recognizable`); + } +}; diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_run_once_errors.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_run_once_errors.ts similarity index 87% rename from x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_run_once_errors.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_run_once_errors.ts index 52218986744c0..916ca8c00b972 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_run_once_errors.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_run_once_errors.ts @@ -7,7 +7,7 @@ import { useEffect, useMemo, useState } from 'react'; import { i18n } from '@kbn/i18n'; -import { Locations, ServiceLocationErrors } from '../../../../common/runtime_types'; +import { Locations, ServiceLocationErrors } from '../../../../../common/runtime_types'; export function useRunOnceErrors({ testRunId, @@ -80,20 +80,20 @@ export function useRunOnceErrors({ }; } -const PushErrorLabel = i18n.translate('xpack.uptime.testRun.pushErrorLabel', { +const PushErrorLabel = i18n.translate('xpack.synthetics.testRun.pushErrorLabel', { defaultMessage: 'Push error', }); -const RunErrorLabel = i18n.translate('xpack.uptime.testRun.runErrorLabel', { +const RunErrorLabel = i18n.translate('xpack.synthetics.testRun.runErrorLabel', { defaultMessage: 'Error running test', }); const getLocationTestErrorLabel = (locationName: string) => - i18n.translate('xpack.uptime.testRun.runErrorLocation', { + i18n.translate('xpack.synthetics.testRun.runErrorLocation', { defaultMessage: 'Failed to run monitor on location {locationName}.', values: { locationName }, }); -const PushErrorService = i18n.translate('xpack.uptime.testRun.pushError', { +const PushErrorService = i18n.translate('xpack.synthetics.testRun.pushError', { defaultMessage: 'Failed to push the monitor to service.', }); diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_service_allowed.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_service_allowed.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor_management/hooks/use_service_allowed.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_service_allowed.ts diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/loader/loader.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/loader/loader.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor_management/loader/loader.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/loader/loader.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/loader/loader.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/loader/loader.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor_management/loader/loader.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/loader/loader.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/mocks/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/mocks/index.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor_management/mocks/index.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/mocks/index.ts diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/mocks/locations.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/mocks/locations.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor_management/mocks/locations.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/mocks/locations.ts diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/locations.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/locations.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/locations.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/locations.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/locations.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/locations.tsx similarity index 92% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/locations.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/locations.tsx index 3d20e54aa3a3a..029503196b6a3 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/locations.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/locations.tsx @@ -10,7 +10,7 @@ import { useSelector } from 'react-redux'; import { i18n } from '@kbn/i18n'; import { EuiCheckboxGroup, EuiFormRow } from '@elastic/eui'; import { monitorManagementListSelector } from '../../../state/selectors'; -import { MonitorServiceLocations } from '../../../../common/runtime_types'; +import { MonitorServiceLocations } from '../../../../../common/runtime_types'; interface Props { selectedLocations: MonitorServiceLocations; @@ -70,14 +70,14 @@ export const ServiceLocations = ({ selectedLocations, setLocations, isInvalid, o }; const VALIDATION_ERROR = i18n.translate( - 'xpack.uptime.monitorManagement.serviceLocationsValidationError', + 'xpack.synthetics.monitorManagement.serviceLocationsValidationError', { defaultMessage: 'At least one service location must be specified', } ); export const LOCATIONS_LABEL = i18n.translate( - 'xpack.uptime.monitorManagement.monitorLocationsLabel', + 'xpack.synthetics.monitorManagement.monitorLocationsLabel', { defaultMessage: 'Monitor locations', } diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/monitor_advanced_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_advanced_fields.tsx similarity index 81% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/monitor_advanced_fields.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_advanced_fields.tsx index 5fdae73a43e11..c4b57f66c227d 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/monitor_advanced_fields.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_advanced_fields.tsx @@ -8,8 +8,8 @@ import { EuiFieldText, EuiFormRow, EuiLink, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import React, { memo } from 'react'; import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { ConfigKey } from '../../../../common/runtime_types'; -import type { Validation } from '../../../../common/types'; +import { ConfigKey } from '../../../../../common/runtime_types'; +import type { Validation } from '../../../../../common/types'; import { DescribedFormGroupWithWrap } from '../../fleet_package/common/described_form_group_with_wrap'; import { usePolicyConfigContext } from '../../fleet_package/contexts'; @@ -35,14 +35,14 @@ export const MonitorManagementAdvancedFields = memo( title={

} description={ } @@ -54,13 +54,13 @@ export const MonitorManagementAdvancedFields = memo( error={namespaceErrorMsg} label={ } helpText={ ( external > diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/monitor_config.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_config.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/monitor_config.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_config.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/monitor_config.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_config.tsx similarity index 89% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/monitor_config.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_config.tsx index c2e828fe33211..3e85c932bf700 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/monitor_config.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_config.tsx @@ -17,7 +17,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { v4 as uuidv4 } from 'uuid'; -import { defaultConfig, usePolicyConfigContext } from '../../fleet_package/contexts'; +import { usePolicyConfigContext } from '../../fleet_package/contexts'; import { usePolicy } from '../../fleet_package/hooks/use_policy'; import { validate } from '../validation'; @@ -25,7 +25,8 @@ import { ActionBarPortal } from '../action_bar/action_bar_portal'; import { useFormatMonitor } from '../hooks/use_format_monitor'; import { MonitorFields } from './monitor_fields'; import { TestNowMode, TestRun } from '../test_now_mode/test_now_mode'; -import { MonitorFields as MonitorFieldsType } from '../../../../common/runtime_types'; +import { MonitorFields as MonitorFieldsType } from '../../../../../common/runtime_types'; +import { DEFAULT_FIELDS } from '../../../../../common/constants/monitor_defaults'; export const MonitorConfig = ({ isEdit = false }: { isEdit: boolean }) => { const { monitorType } = usePolicyConfigContext(); @@ -41,7 +42,7 @@ export const MonitorConfig = ({ isEdit = false }: { isEdit: boolean }) => { monitorType, validate, config: policyConfig[monitorType], - defaultConfig: defaultConfig[monitorType], + defaultConfig: DEFAULT_FIELDS[monitorType], }); const [hasBeenSubmitted, setHasBeenSubmitted] = useState(false); @@ -111,10 +112,10 @@ export const MonitorConfig = ({ isEdit = false }: { isEdit: boolean }) => { ); }; -const TEST_RESULT = i18n.translate('xpack.uptime.monitorManagement.testResult', { +const TEST_RESULT = i18n.translate('xpack.synthetics.monitorManagement.testResult', { defaultMessage: 'Test result', }); -const CLOSE_LABEL = i18n.translate('xpack.uptime.monitorManagement.closeButtonLabel', { +const CLOSE_LABEL = i18n.translate('xpack.synthetics.monitorManagement.closeButtonLabel', { defaultMessage: 'Close', }); diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/monitor_fields.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx similarity index 97% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/monitor_fields.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx index 7320410ae52eb..b4e97ba724393 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/monitor_fields.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.test.tsx @@ -9,7 +9,7 @@ import { fireEvent } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { ConfigKey, DataStream, HTTPFields } from '../../../../common/runtime_types'; +import { ConfigKey, DataStream, HTTPFields } from '../../../../../common/runtime_types'; import { render } from '../../../lib/helper/rtl_helpers'; import { BrowserContextProvider, diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/monitor_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.tsx similarity index 96% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/monitor_fields.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.tsx index 655bb5cecac85..eb109dd5d1063 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/monitor_fields.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_fields.tsx @@ -7,7 +7,7 @@ import React, { useMemo, useState } from 'react'; import { EuiForm } from '@elastic/eui'; -import { ConfigKey, DataStream } from '../../../../common/runtime_types'; +import { ConfigKey, DataStream } from '../../../../../common/runtime_types'; import { usePolicyConfigContext } from '../../fleet_package/contexts'; import { CustomFields } from '../../fleet_package/custom_fields'; diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/monitor_name_location.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_name_location.tsx similarity index 84% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/monitor_name_location.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_name_location.tsx index 8e8df803c7d75..0f7206f65992f 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/monitor_name_location.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/monitor_name_location.tsx @@ -9,8 +9,8 @@ import React, { useEffect, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiFormRow, EuiFieldText } from '@elastic/eui'; -import { ConfigKey } from '../../../../common/runtime_types'; -import { Validation } from '../../../../common/types'; +import { ConfigKey } from '../../../../../common/runtime_types'; +import { Validation } from '../../../../../common/types'; import { usePolicyConfigContext } from '../../fleet_package/contexts'; import { ServiceLocations } from './locations'; import { useMonitorName } from './use_monitor_name'; @@ -40,7 +40,7 @@ export const MonitorNameAndLocation = ({ validate, onFieldBlur }: Props) => { } @@ -51,7 +51,7 @@ export const MonitorNameAndLocation = ({ validate, onFieldBlur }: Props) => { NAME_ALREADY_EXISTS ) : ( ) @@ -79,6 +79,9 @@ export const MonitorNameAndLocation = ({ validate, onFieldBlur }: Props) => { ); }; -const NAME_ALREADY_EXISTS = i18n.translate('xpack.uptime.monitorManagement.duplicateNameError', { - defaultMessage: 'Monitor name already exists.', -}); +const NAME_ALREADY_EXISTS = i18n.translate( + 'xpack.synthetics.monitorManagement.duplicateNameError', + { + defaultMessage: 'Monitor name already exists.', + } +); diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/use_monitor_name.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/use_monitor_name.test.tsx similarity index 87% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/use_monitor_name.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/use_monitor_name.test.tsx index ccfc1312cbf25..04879cd0da65b 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/use_monitor_name.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/use_monitor_name.test.tsx @@ -9,7 +9,16 @@ import { defaultCore, WrappedHelper } from '../../../lib/helper/rtl_helpers'; import { renderHook } from '@testing-library/react-hooks'; import { useMonitorName } from './use_monitor_name'; -import * as hooks from '../../../hooks/use_monitor'; +import * as reactRouter from 'react-router-dom'; + +const mockRouter = { + ...reactRouter, +}; + +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useParams: jest.fn().mockReturnValue({}), +})); describe('useMonitorName', () => { it('returns expected results', () => { @@ -56,7 +65,7 @@ describe('useMonitorName', () => { }, }); - jest.spyOn(hooks, 'useMonitorId').mockReturnValue('test-id'); + jest.spyOn(mockRouter, 'useParams').mockReturnValue({ monitorId: 'test-id' }); const { result, waitForNextUpdate } = renderHook(() => useMonitorName({ search: 'Test' }), { wrapper: WrappedHelper, diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/use_monitor_name.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/use_monitor_name.ts similarity index 90% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/use_monitor_name.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/use_monitor_name.ts index 200a9599b405e..e8d3848856a2b 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_config/use_monitor_name.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_config/use_monitor_name.ts @@ -8,8 +8,8 @@ import { useEffect, useState } from 'react'; import { useFetcher } from '@kbn/observability-plugin/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { syntheticsMonitorType } from '../../../../common/types/saved_objects'; -import { useMonitorId } from '../../../hooks'; +import { useParams } from 'react-router-dom'; +import { syntheticsMonitorType } from '../../../../../common/types/saved_objects'; interface AggsResponse { monitorNames: { @@ -22,7 +22,7 @@ interface AggsResponse { export const useMonitorName = ({ search = '' }: { search?: string }) => { const [values, setValues] = useState([]); - const monitorId = useMonitorId(); + const { monitorId } = useParams<{ monitorId: string }>(); const { savedObjects } = useKibana().services; diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/actions.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/actions.test.tsx similarity index 94% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/actions.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/actions.test.tsx index f60d54e9cb4f6..af2e54503d0b1 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/actions.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/actions.test.tsx @@ -19,7 +19,7 @@ describe('', () => { expect(screen.getByLabelText('Edit monitor')).toHaveAttribute( 'href', - '/app/uptime/edit-monitor/dGVzdC1pZA==' + '/app/uptime/edit-monitor/test-id' ); }); }); diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/actions.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/actions.tsx similarity index 87% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/actions.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/actions.tsx index 47a0b8547ea8c..ddd0d0cc0a63e 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/actions.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/actions.tsx @@ -12,7 +12,7 @@ import moment from 'moment'; import { UptimeSettingsContext } from '../../../contexts'; import { DeleteMonitor } from './delete_monitor'; import { InlineError } from './inline_error'; -import { MonitorManagementListResult, Ping } from '../../../../common/runtime_types'; +import { MonitorManagementListResult, Ping } from '../../../../../common/runtime_types'; interface Props { id: string; @@ -45,7 +45,7 @@ export const Actions = ({ id, name, onUpdate, isDisabled, errorSummaries, monito @@ -62,6 +62,6 @@ export const Actions = ({ id, name, onUpdate, isDisabled, errorSummaries, monito ); }; -const EDIT_MONITOR_LABEL = i18n.translate('xpack.uptime.monitorManagement.editMonitorLabel', { +const EDIT_MONITOR_LABEL = i18n.translate('xpack.synthetics.monitorManagement.editMonitorLabel', { defaultMessage: 'Edit monitor', }); diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/all_monitors.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/all_monitors.tsx similarity index 95% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/all_monitors.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/all_monitors.tsx index 550d3b487a4ae..ac6fab66bbb1e 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/all_monitors.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/all_monitors.tsx @@ -10,7 +10,7 @@ import { useSelector } from 'react-redux'; import { MonitorManagementList, MonitorManagementListPageState } from './monitor_list'; import { monitorManagementListSelector } from '../../../state/selectors'; import { MonitorManagementList as MonitorManagementListState } from '../../../state/reducers/monitor_management'; -import { Ping } from '../../../../common/runtime_types'; +import { Ping } from '../../../../../common/runtime_types'; interface Props { pageState: MonitorManagementListPageState; diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/delete_monitor.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/delete_monitor.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/delete_monitor.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/delete_monitor.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/delete_monitor.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/delete_monitor.tsx similarity index 86% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/delete_monitor.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/delete_monitor.tsx index 0a90e4eb39a06..0feac678e6518 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/delete_monitor.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/delete_monitor.tsx @@ -103,27 +103,30 @@ export const DeleteMonitor = ({ }; const DELETE_DESCRIPTION_LABEL = i18n.translate( - 'xpack.uptime.monitorManagement.confirmDescriptionLabel', + 'xpack.synthetics.monitorManagement.confirmDescriptionLabel', { defaultMessage: 'This action will delete the monitor but keep any data collected. This action cannot be undone.', } ); -const YES_LABEL = i18n.translate('xpack.uptime.monitorManagement.yesLabel', { +const YES_LABEL = i18n.translate('xpack.synthetics.monitorManagement.yesLabel', { defaultMessage: 'Delete', }); -const NO_LABEL = i18n.translate('xpack.uptime.monitorManagement.noLabel', { +const NO_LABEL = i18n.translate('xpack.synthetics.monitorManagement.noLabel', { defaultMessage: 'Cancel', }); -const DELETE_MONITOR_LABEL = i18n.translate('xpack.uptime.monitorManagement.deleteMonitorLabel', { - defaultMessage: 'Delete monitor', -}); +const DELETE_MONITOR_LABEL = i18n.translate( + 'xpack.synthetics.monitorManagement.deleteMonitorLabel', + { + defaultMessage: 'Delete monitor', + } +); const MONITOR_DELETE_SUCCESS_LABEL = i18n.translate( - 'xpack.uptime.monitorManagement.monitorDeleteSuccessMessage', + 'xpack.synthetics.monitorManagement.monitorDeleteSuccessMessage', { defaultMessage: 'Monitor deleted successfully.', } @@ -131,14 +134,14 @@ const MONITOR_DELETE_SUCCESS_LABEL = i18n.translate( // TODO: Discuss error states with product const MONITOR_DELETE_FAILURE_LABEL = i18n.translate( - 'xpack.uptime.monitorManagement.monitorDeleteFailureMessage', + 'xpack.synthetics.monitorManagement.monitorDeleteFailureMessage', { defaultMessage: 'Monitor was unable to be deleted. Please try again later.', } ); const MONITOR_DELETE_LOADING_LABEL = i18n.translate( - 'xpack.uptime.monitorManagement.monitorDeleteLoadingMessage', + 'xpack.synthetics.monitorManagement.monitorDeleteLoadingMessage', { defaultMessage: 'Deleting monitor...', } diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/enablement_empty_state.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/enablement_empty_state.tsx similarity index 87% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/enablement_empty_state.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/enablement_empty_state.tsx index 0e7916f44a3aa..745ec636af6b0 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/enablement_empty_state.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/enablement_empty_state.tsx @@ -88,21 +88,21 @@ export const EnablementEmptyState = ({ focusButton }: { focusButton: boolean }) }; const MONITOR_MANAGEMENT_ENABLEMENT_LABEL = i18n.translate( - 'xpack.uptime.monitorManagement.emptyState.enablement.enabled.title', + 'xpack.synthetics.monitorManagement.emptyState.enablement.enabled.title', { defaultMessage: 'Enable Monitor Management', } ); const MONITOR_MANAGEMENT_DISABLED_LABEL = i18n.translate( - 'xpack.uptime.monitorManagement.emptyState.enablement.disabled.title', + 'xpack.synthetics.monitorManagement.emptyState.enablement.disabled.title', { defaultMessage: 'Monitor Management is disabled', } ); const MONITOR_MANAGEMENT_ENABLEMENT_MESSAGE = i18n.translate( - 'xpack.uptime.monitorManagement.emptyState.enablement', + 'xpack.synthetics.monitorManagement.emptyState.enablement', { defaultMessage: 'Enable Monitor Management to run lightweight and real-browser monitors from hosted testing locations around the world. Enabling Monitor Management will generate an API key to allow the Synthetics Service to write back to your Elasticsearch cluster.', @@ -110,7 +110,7 @@ const MONITOR_MANAGEMENT_ENABLEMENT_MESSAGE = i18n.translate( ); const MONITOR_MANAGEMENT_DISABLED_MESSAGE = i18n.translate( - 'xpack.uptime.monitorManagement.emptyState.enablement.disabledDescription', + 'xpack.synthetics.monitorManagement.emptyState.enablement.disabledDescription', { defaultMessage: 'Monitor Management is currently disabled. Monitor Management allows you to run lightweight and real-browser monitors from hosted testing locations around the world. To enable Monitor Management, please contact an administrator.', @@ -118,18 +118,18 @@ const MONITOR_MANAGEMENT_DISABLED_MESSAGE = i18n.translate( ); const MONITOR_MANAGEMENT_ENABLEMENT_BTN_LABEL = i18n.translate( - 'xpack.uptime.monitorManagement.emptyState.enablement.title', + 'xpack.synthetics.monitorManagement.emptyState.enablement.title', { defaultMessage: 'Enable', } ); -const DOCS_LABEL = i18n.translate('xpack.uptime.monitorManagement.emptyState.enablement.doc', { +const DOCS_LABEL = i18n.translate('xpack.synthetics.monitorManagement.emptyState.enablement.doc', { defaultMessage: 'Read the docs', }); const LEARN_MORE_LABEL = i18n.translate( - 'xpack.uptime.monitorManagement.emptyState.enablement.learnMore', + 'xpack.synthetics.monitorManagement.emptyState.enablement.learnMore', { defaultMessage: 'Want to learn more?', } diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/inline_error.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/inline_error.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/inline_error.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/inline_error.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/inline_error.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/inline_error.tsx similarity index 82% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/inline_error.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/inline_error.tsx index 187c81ff8c6e9..7ba74def660c9 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/inline_error.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/inline_error.tsx @@ -8,7 +8,7 @@ import React, { useState } from 'react'; import { EuiButtonIcon, EuiToolTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { Ping } from '../../../../common/runtime_types'; +import { Ping } from '../../../../../common/runtime_types'; import { StdErrorPopover } from './stderr_logs_popover'; export const InlineError = ({ errorSummary }: { errorSummary: Ping }) => { @@ -40,12 +40,15 @@ export const InlineError = ({ errorSummary }: { errorSummary: Ping }) => { }; export const getInlineErrorLabel = (message?: string) => { - return i18n.translate('xpack.uptime.monitorList.statusColumn.error.message', { + return i18n.translate('xpack.synthetics.monitorList.statusColumn.error.message', { defaultMessage: '{message}. Click for more details.', values: { message }, }); }; -export const ERROR_LOGS_LABEL = i18n.translate('xpack.uptime.monitorList.statusColumn.error.logs', { - defaultMessage: 'Error logs', -}); +export const ERROR_LOGS_LABEL = i18n.translate( + 'xpack.synthetics.monitorList.statusColumn.error.logs', + { + defaultMessage: 'Error logs', + } +); diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/invalid_monitors.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/invalid_monitors.tsx similarity index 97% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/invalid_monitors.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/invalid_monitors.tsx index 342b9c6547b1b..5dea7b7ee06fd 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/invalid_monitors.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/invalid_monitors.tsx @@ -13,7 +13,7 @@ import { MonitorManagementListResult, Ping, DEFAULT_THROTTLING, -} from '../../../../common/runtime_types'; +} from '../../../../../common/runtime_types'; interface Props { loading: boolean; diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/list_tabs.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/list_tabs.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/list_tabs.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/list_tabs.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/list_tabs.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/list_tabs.tsx similarity index 88% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/list_tabs.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/list_tabs.tsx index 17b7ca839dcd0..e2da72effa560 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/list_tabs.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/list_tabs.tsx @@ -18,7 +18,7 @@ import React, { useState, Fragment, useEffect } from 'react'; import { useHistory, useParams } from 'react-router-dom'; import { useUptimeRefreshContext } from '../../../contexts/uptime_refresh_context'; import { MonitorManagementListPageState } from './monitor_list'; -import { ConfigKey } from '../../../../common/runtime_types'; +import { ConfigKey } from '../../../../../common/runtime_types'; export const MonitorListTabs = ({ invalidTotal, @@ -114,14 +114,17 @@ export const MonitorListTabs = ({ ); }; -export const REFRESH_LABEL = i18n.translate('xpack.uptime.monitorList.refresh', { +export const REFRESH_LABEL = i18n.translate('xpack.synthetics.monitorList.refresh', { defaultMessage: 'Refresh', }); -export const INVALID_MONITORS_LABEL = i18n.translate('xpack.uptime.monitorList.invalidMonitors', { - defaultMessage: 'Invalid monitors', -}); +export const INVALID_MONITORS_LABEL = i18n.translate( + 'xpack.synthetics.monitorList.invalidMonitors', + { + defaultMessage: 'Invalid monitors', + } +); -export const ALL_MONITORS_LABEL = i18n.translate('xpack.uptime.monitorList.allMonitors', { +export const ALL_MONITORS_LABEL = i18n.translate('xpack.synthetics.monitorList.allMonitors', { defaultMessage: 'All monitors', }); diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_async_error.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_async_error.test.tsx similarity index 97% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_async_error.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_async_error.test.tsx index da89876cc9b0b..2592aabf9eb09 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_async_error.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_async_error.test.tsx @@ -7,7 +7,7 @@ import { screen } from '@testing-library/react'; import React from 'react'; -import { DEFAULT_THROTTLING } from '../../../../common/runtime_types'; +import { DEFAULT_THROTTLING } from '../../../../../common/runtime_types'; import { render } from '../../../lib/helper/rtl_helpers'; import { MonitorManagementList as MonitorManagementListState } from '../../../state/reducers/monitor_management'; import { MonitorAsyncError } from './monitor_async_error'; diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_async_error.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_async_error.tsx similarity index 83% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_async_error.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_async_error.tsx index 48aeaf3648a0b..77659c8357e24 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_async_error.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_async_error.tsx @@ -22,7 +22,7 @@ export const MonitorAsyncError = () => { } @@ -31,7 +31,7 @@ export const MonitorAsyncError = () => { >

@@ -58,28 +58,28 @@ export const MonitorAsyncError = () => { }; const REASON_LABEL = i18n.translate( - 'xpack.uptime.monitorManagement.monitorSync.failure.reasonLabel', + 'xpack.synthetics.monitorManagement.monitorSync.failure.reasonLabel', { defaultMessage: 'Reason', } ); const STATUS_LABEL = i18n.translate( - 'xpack.uptime.monitorManagement.monitorSync.failure.statusLabel', + 'xpack.synthetics.monitorManagement.monitorSync.failure.statusLabel', { defaultMessage: 'Status', } ); const NOT_AVAILABLE_LABEL = i18n.translate( - 'xpack.uptime.monitorManagement.monitorSync.failure.notAvailable', + 'xpack.synthetics.monitorManagement.monitorSync.failure.notAvailable', { defaultMessage: 'Not available', } ); const DISMISS_LABEL = i18n.translate( - 'xpack.uptime.monitorManagement.monitorSync.failure.dismissLabel', + 'xpack.synthetics.monitorManagement.monitorSync.failure.dismissLabel', { defaultMessage: 'Dismiss', } diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_enabled.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_enabled.test.tsx similarity index 98% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_enabled.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_enabled.test.tsx index d7e04f0e6140f..9d30d985f09d9 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_enabled.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_enabled.test.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { ConfigKey, DataStream, SyntheticsMonitor } from '../../../../common/runtime_types'; +import { ConfigKey, DataStream, SyntheticsMonitor } from '../../../../../common/runtime_types'; import { render } from '../../../lib/helper/rtl_helpers'; import { FETCH_STATUS } from '@kbn/observability-plugin/public'; import { spyOnUseFetcher } from '../../../lib/helper/spy_use_fetcher'; diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_enabled.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_enabled.tsx similarity index 84% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_enabled.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_enabled.tsx index e441e44da221d..4b00f96077548 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_enabled.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_enabled.tsx @@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n'; import React, { useEffect, useState } from 'react'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { FETCH_STATUS, useFetcher } from '@kbn/observability-plugin/public'; -import { ConfigKey, EncryptedSyntheticsMonitor } from '../../../../common/runtime_types'; +import { ConfigKey, EncryptedSyntheticsMonitor } from '../../../../../common/runtime_types'; import { setMonitor } from '../../../state/api'; interface Props { @@ -87,28 +87,34 @@ export const MonitorEnabled = ({ id, monitor, onUpdate, isDisabled }: Props) => ); }; -const ENABLE_MONITOR_LABEL = i18n.translate('xpack.uptime.monitorManagement.enableMonitorLabel', { - defaultMessage: 'Enable monitor', -}); +const ENABLE_MONITOR_LABEL = i18n.translate( + 'xpack.synthetics.monitorManagement.enableMonitorLabel', + { + defaultMessage: 'Enable monitor', + } +); -const DISABLE_MONITOR_LABEL = i18n.translate('xpack.uptime.monitorManagement.disableMonitorLabel', { - defaultMessage: 'Disable monitor', -}); +const DISABLE_MONITOR_LABEL = i18n.translate( + 'xpack.synthetics.monitorManagement.disableMonitorLabel', + { + defaultMessage: 'Disable monitor', + } +); const getMonitorEnabledSuccessLabel = (name: string) => - i18n.translate('xpack.uptime.monitorManagement.monitorEnabledSuccessMessage', { + i18n.translate('xpack.synthetics.monitorManagement.monitorEnabledSuccessMessage', { defaultMessage: 'Monitor {name} enabled successfully.', values: { name }, }); const getMonitorDisabledSuccessLabel = (name: string) => - i18n.translate('xpack.uptime.monitorManagement.monitorDisabledSuccessMessage', { + i18n.translate('xpack.synthetics.monitorManagement.monitorDisabledSuccessMessage', { defaultMessage: 'Monitor {name} disabled successfully.', values: { name }, }); const getMonitorEnabledUpdateFailureMessage = (name: string) => - i18n.translate('xpack.uptime.monitorManagement.monitorEnabledUpdateFailureMessage', { + i18n.translate('xpack.synthetics.monitorManagement.monitorEnabledUpdateFailureMessage', { defaultMessage: 'Unable to update monitor {name}.', values: { name }, }); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_list.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_list.test.tsx new file mode 100644 index 0000000000000..5c13b34366d59 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_list.test.tsx @@ -0,0 +1,131 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; +import { + ConfigKey, + DataStream, + HTTPFields, + ScheduleUnit, + DEFAULT_THROTTLING, +} from '../../../../../common/runtime_types'; +import { render } from '../../../lib/helper/rtl_helpers'; +import { MonitorManagementList as MonitorManagementListState } from '../../../state/reducers/monitor_management'; +import { MonitorManagementList, MonitorManagementListPageState } from './monitor_list'; + +describe('', () => { + const onUpdate = jest.fn(); + const onPageStateChange = jest.fn(); + const monitors = []; + for (let i = 0; i < 12; i++) { + monitors.push({ + id: `test-monitor-id-${i}`, + updated_at: '123', + attributes: { + name: `test-monitor-${i}`, + enabled: true, + schedule: { + unit: ScheduleUnit.MINUTES, + number: `${i * 10}`, + }, + urls: `https://test-${i}.co`, + type: DataStream.HTTP, + tags: [`tag-${i}`], + } as HTTPFields, + }); + } + const state = { + monitorManagementList: { + throttling: DEFAULT_THROTTLING, + list: { + perPage: 5, + page: 1, + total: 6, + monitors, + syncErrors: null, + }, + locations: [], + enablement: null, + error: { + serviceLocations: null, + monitorList: null, + enablement: null, + }, + loading: { + monitorList: true, + serviceLocations: false, + enablement: false, + }, + syntheticsService: { + loading: false, + signupUrl: null, + }, + } as MonitorManagementListState, + }; + + const pageState: MonitorManagementListPageState = { + pageIndex: 1, + pageSize: 10, + sortField: `${ConfigKey.NAME}.keyword`, + sortOrder: 'asc', + }; + + it.each(monitors)('navigates to edit monitor flow on edit pencil', (monitor) => { + render( + , + { state } + ); + + expect(screen.getByText(monitor.attributes.name)).toBeInTheDocument(); + expect(screen.getByText(monitor.attributes.urls)).toBeInTheDocument(); + monitor.attributes.tags.forEach((tag) => { + expect(screen.getByText(tag)).toBeInTheDocument(); + }); + expect(screen.getByText(monitor.attributes.schedule.number)).toBeInTheDocument(); + }); + + it('handles changing per page', () => { + render( + , + { state } + ); + + userEvent.click(screen.getByTestId('tablePaginationPopoverButton')); + + userEvent.click(screen.getByText('10 rows')); + + expect(onPageStateChange).toBeCalledWith(expect.objectContaining({ pageSize: 10 })); + }); + + it('handles refreshing and changing page when navigating to the next page', async () => { + const { getByTestId } = render( + , + { state } + ); + + userEvent.click(getByTestId('pagination-button-next')); + + expect(onPageStateChange).toBeCalledWith(expect.objectContaining({ pageIndex: 2 })); + }); +}); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_list.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_list.tsx new file mode 100644 index 0000000000000..fbd21fe09c1ec --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_list.tsx @@ -0,0 +1,225 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { + Criteria, + EuiBasicTable, + EuiBasicTableColumn, + EuiLink, + EuiPanel, + EuiSpacer, +} from '@elastic/eui'; +import { EuiTableSortingType } from '@elastic/eui/src/components/basic_table/table_types'; +import { i18n } from '@kbn/i18n'; +import React, { useCallback, useContext, useMemo } from 'react'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { + CommonFields, + ConfigKey, + FetchMonitorManagementListQueryArgs, + ICMPSimpleFields, + Ping, + ServiceLocations, + EncryptedSyntheticsMonitorWithId, + TCPSimpleFields, +} from '../../../../../common/runtime_types'; +import { UptimeSettingsContext } from '../../../contexts'; +import { useBreakpoints } from '../../../hooks'; +import { MonitorManagementList as MonitorManagementListState } from '../../../state/reducers/monitor_management'; +import * as labels from '../../overview/monitor_list/translations'; +import { Actions } from './actions'; +import { MonitorEnabled } from './monitor_enabled'; +import { MonitorLocations } from './monitor_locations'; +import { MonitorTags } from './tags'; + +export interface MonitorManagementListPageState { + pageIndex: number; + pageSize: number; + sortField: + | `${ConfigKey.URLS}.keyword` + | `${ConfigKey.NAME}.keyword` + | `${ConfigKey.MONITOR_TYPE}.keyword`; + sortOrder: NonNullable; +} + +interface Props { + pageState: MonitorManagementListPageState; + monitorList: MonitorManagementListState; + onPageStateChange: (state: MonitorManagementListPageState) => void; + onUpdate: () => void; + errorSummaries?: Ping[]; +} + +export const MonitorManagementList = ({ + pageState: { pageIndex, pageSize, sortField, sortOrder }, + monitorList: { + list, + error: { monitorList: error }, + loading: { monitorList: loading }, + }, + onPageStateChange, + onUpdate, + errorSummaries, +}: Props) => { + const { basePath } = useContext(UptimeSettingsContext); + const isXl = useBreakpoints().up('xl'); + + const { total } = list as MonitorManagementListState['list']; + const monitors: EncryptedSyntheticsMonitorWithId[] = useMemo( + () => + list.monitors.map((monitor) => ({ + ...monitor.attributes, + id: monitor.id, + })), + [list.monitors] + ); + + const handleOnChange = useCallback( + ({ + page = { index: 0, size: 10 }, + sort = { field: ConfigKey.NAME, direction: 'asc' }, + }: Criteria) => { + const { index, size } = page; + const { field, direction } = sort; + + onPageStateChange({ + pageIndex: index + 1, // page index for Saved Objects is base 1 + pageSize: size, + sortField: `${field}.keyword` as MonitorManagementListPageState['sortField'], + sortOrder: direction, + }); + }, + [onPageStateChange] + ); + + const pagination = { + pageIndex: pageIndex - 1, // page index for EuiBasicTable is base 0 + pageSize, + totalItemCount: total || 0, + pageSizeOptions: [5, 10, 25, 50, 100], + }; + + const sorting: EuiTableSortingType = { + sort: { + field: sortField.replace('.keyword', '') as keyof EncryptedSyntheticsMonitorWithId, + direction: sortOrder, + }, + }; + + const canEdit: boolean = !!useKibana().services?.application?.capabilities.uptime.save; + + const columns = [ + { + align: 'left' as const, + field: ConfigKey.NAME as string, + name: i18n.translate('xpack.synthetics.monitorManagement.monitorList.monitorName', { + defaultMessage: 'Monitor name', + }), + sortable: true, + render: (name: string, { id }: EncryptedSyntheticsMonitorWithId) => ( + {name} + ), + }, + { + align: 'left' as const, + field: ConfigKey.MONITOR_TYPE, + name: i18n.translate('xpack.synthetics.monitorManagement.monitorList.monitorType', { + defaultMessage: 'Monitor type', + }), + sortable: true, + }, + { + align: 'left' as const, + field: ConfigKey.TAGS, + name: i18n.translate('xpack.synthetics.monitorManagement.monitorList.tags', { + defaultMessage: 'Tags', + }), + render: (tags: string[]) => (tags ? : null), + }, + { + align: 'left' as const, + field: ConfigKey.LOCATIONS, + name: i18n.translate('xpack.synthetics.monitorManagement.monitorList.locations', { + defaultMessage: 'Locations', + }), + render: (locations: ServiceLocations) => + locations ? : null, + }, + { + align: 'left' as const, + field: ConfigKey.SCHEDULE, + name: i18n.translate('xpack.synthetics.monitorManagement.monitorList.schedule', { + defaultMessage: 'Frequency (min)', + }), + render: (schedule: CommonFields[ConfigKey.SCHEDULE]) => schedule?.number, + }, + { + align: 'left' as const, + field: ConfigKey.URLS, + name: i18n.translate('xpack.synthetics.monitorManagement.monitorList.URL', { + defaultMessage: 'URL', + }), + sortable: true, + render: (urls: string, { hosts }: TCPSimpleFields | ICMPSimpleFields) => urls || hosts, + truncateText: true, + textOnly: true, + }, + { + align: 'left' as const, + field: ConfigKey.ENABLED as string, + name: i18n.translate('xpack.synthetics.monitorManagement.monitorList.enabled', { + defaultMessage: 'Enabled', + }), + render: (_enabled: boolean, monitor: EncryptedSyntheticsMonitorWithId) => ( + + ), + }, + { + align: 'left' as const, + name: i18n.translate('xpack.synthetics.monitorManagement.monitorList.actions', { + defaultMessage: 'Actions', + }), + render: (fields: EncryptedSyntheticsMonitorWithId) => ( + + ), + }, + ] as Array>; + + return ( + + + + + ); +}; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_list_container.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_list_container.tsx new file mode 100644 index 0000000000000..727f4f6dee72b --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_list_container.tsx @@ -0,0 +1,89 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, Dispatch } from 'react'; +import { useSelector } from 'react-redux'; +import { useParams } from 'react-router-dom'; +import { useTrackPageview } from '@kbn/observability-plugin/public'; +import { monitorManagementListSelector } from '../../../state/selectors'; +import { MonitorAsyncError } from './monitor_async_error'; +import { useInlineErrors } from '../hooks/use_inline_errors'; +import { MonitorListTabs } from './list_tabs'; +import { AllMonitors } from './all_monitors'; +import { InvalidMonitors } from './invalid_monitors'; +import { useInvalidMonitors } from '../hooks/use_invalid_monitors'; +import { MonitorManagementListPageState } from './monitor_list'; +import { MonitorManagementPageAction } from '../hooks/use_monitor_list'; + +export const MonitorListContainer = ({ + isEnabled, + pageState, + dispatchPageAction, +}: { + isEnabled?: boolean; + pageState: MonitorManagementListPageState; + dispatchPageAction: Dispatch; +}) => { + const onPageStateChange = useCallback( + (state) => { + dispatchPageAction({ type: 'update', payload: state }); + }, + [dispatchPageAction] + ); + + const onUpdate = useCallback(() => { + dispatchPageAction({ type: 'refresh' }); + }, [dispatchPageAction]); + + useTrackPageview({ app: 'uptime', path: 'manage-monitors' }); + useTrackPageview({ app: 'uptime', path: 'manage-monitors', delay: 15000 }); + + const monitorList = useSelector(monitorManagementListSelector); + + const { type: viewType } = useParams<{ type: 'all' | 'invalid' }>(); + const { errorSummaries, loading, count } = useInlineErrors({ + onlyInvalidMonitors: viewType === 'invalid', + sortField: pageState.sortField, + sortOrder: pageState.sortOrder, + }); + + const { data: monitorSavedObjects, loading: objectsLoading } = useInvalidMonitors(errorSummaries); + + if (!isEnabled && monitorList.list.total === 0) { + return null; + } + + return ( + <> + + + {viewType === 'all' ? ( + + ) : ( + + )} + + ); +}; diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_locations.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_locations.tsx similarity index 94% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_locations.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_locations.tsx index 940e6260d864c..5f9ad96bca464 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/monitor_locations.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/monitor_locations.tsx @@ -7,7 +7,7 @@ import React, { useState } from 'react'; import { EuiBadge, EuiBadgeGroup } from '@elastic/eui'; -import { ServiceLocations, ServiceLocation } from '../../../../common/runtime_types'; +import { ServiceLocations, ServiceLocation } from '../../../../../common/runtime_types'; import { EXPAND_LOCATIONS_LABEL } from '../../overview/monitor_list/columns/translations'; import { useLocations } from '../hooks/use_locations'; diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/stderr_logs_popover.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/stderr_logs_popover.tsx similarity index 83% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/stderr_logs_popover.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/stderr_logs_popover.tsx index c50cd33b13b1f..bdafa20adfcac 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/stderr_logs_popover.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/stderr_logs_popover.tsx @@ -44,12 +44,15 @@ const Container = styled.div` `; export const getInlineErrorLabel = (message?: string) => { - return i18n.translate('xpack.uptime.monitorList.statusColumn.error.messageLabel', { + return i18n.translate('xpack.synthetics.monitorList.statusColumn.error.messageLabel', { defaultMessage: '{message}. Click for more details.', values: { message }, }); }; -export const ERROR_LOGS_LABEL = i18n.translate('xpack.uptime.monitorList.statusColumn.error.logs', { - defaultMessage: 'Error logs', -}); +export const ERROR_LOGS_LABEL = i18n.translate( + 'xpack.synthetics.monitorList.statusColumn.error.logs', + { + defaultMessage: 'Error logs', + } +); diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/tags.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/tags.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor_management/monitor_list/tags.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/monitor_list/tags.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/show_sync_errors.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/show_sync_errors.tsx similarity index 82% rename from x-pack/plugins/synthetics/public/components/monitor_management/show_sync_errors.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/show_sync_errors.tsx index 2a6512b7b7dfc..0fde06c764c08 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/show_sync_errors.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/show_sync_errors.tsx @@ -9,19 +9,19 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { toMountPoint } from '@kbn/kibana-react-plugin/public'; import { kibanaService } from '../../state/kibana_service'; -import { ServiceLocationErrors, ServiceLocations } from '../../../common/runtime_types'; +import { ServiceLocationErrors, ServiceLocations } from '../../../../common/runtime_types'; export const showSyncErrors = (errors: ServiceLocationErrors, locations: ServiceLocations) => { Object.values(errors).forEach((location) => { const { status: responseStatus, reason } = location.error || {}; kibanaService.toasts.addWarning({ - title: i18n.translate('xpack.uptime.monitorManagement.service.error.title', { + title: i18n.translate('xpack.synthetics.monitorManagement.service.error.title', { defaultMessage: `Unable to sync monitor config`, }), text: toMountPoint( <>

- {i18n.translate('xpack.uptime.monitorManagement.service.error.message', { + {i18n.translate('xpack.synthetics.monitorManagement.service.error.message', { defaultMessage: `Your monitor was saved, but there was a problem syncing the configuration for {location}. We will automatically try again later. If this problem continues, your monitors will stop running in {location}. Please contact Support for assistance.`, values: { location: locations?.find((loc) => loc?.id === location.locationId)?.label, @@ -31,13 +31,13 @@ export const showSyncErrors = (errors: ServiceLocationErrors, locations: Service {responseStatus || reason ? (

{responseStatus - ? i18n.translate('xpack.uptime.monitorManagement.service.error.status', { + ? i18n.translate('xpack.synthetics.monitorManagement.service.error.status', { defaultMessage: 'Status: {status}. ', values: { status: responseStatus }, }) : null} {reason - ? i18n.translate('xpack.uptime.monitorManagement.service.error.reason', { + ? i18n.translate('xpack.synthetics.monitorManagement.service.error.reason', { defaultMessage: 'Reason: {reason}.', values: { reason }, }) diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/browser/browser_test_results.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/browser/browser_test_results.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/browser/browser_test_results.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/browser/browser_test_results.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/browser/browser_test_results.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/browser/browser_test_results.tsx similarity index 94% rename from x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/browser/browser_test_results.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/browser/browser_test_results.tsx index e5ca115b09b97..87eecddac3e65 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/browser/browser_test_results.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/browser/browser_test_results.tsx @@ -115,7 +115,7 @@ function getButtonContent({

- {i18n.translate('xpack.uptime.monitorManagement.stepCompleted', { + {i18n.translate('xpack.synthetics.monitorManagement.stepCompleted', { defaultMessage: '{stepCount, number} {stepCount, plural, one {step} other {steps}} completed', values: { @@ -129,10 +129,10 @@ function getButtonContent({ ); } -const FAILED_TO_RUN = i18n.translate('xpack.uptime.monitorManagement.failedRun', { +const FAILED_TO_RUN = i18n.translate('xpack.synthetics.monitorManagement.failedRun', { defaultMessage: 'Failed to run steps', }); -const LOADING_STEPS = i18n.translate('xpack.uptime.monitorManagement.loadingSteps', { +const LOADING_STEPS = i18n.translate('xpack.synthetics.monitorManagement.loadingSteps', { defaultMessage: 'Loading steps...', }); diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/browser/use_browser_run_once_monitors.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/browser/use_browser_run_once_monitors.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/browser/use_browser_run_once_monitors.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/browser/use_browser_run_once_monitors.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/browser/use_browser_run_once_monitors.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/browser/use_browser_run_once_monitors.ts similarity index 98% rename from x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/browser/use_browser_run_once_monitors.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/browser/use_browser_run_once_monitors.ts index 68f96b5d7b487..034fad5b9a8d0 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/browser/use_browser_run_once_monitors.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/browser/use_browser_run_once_monitors.ts @@ -6,11 +6,11 @@ */ import { useEffect, useState, useRef } from 'react'; import { createEsParams, useEsSearch, useFetcher } from '@kbn/observability-plugin/public'; -import { JourneyStep } from '../../../../../common/runtime_types'; +import { JourneyStep } from '../../../../../../common/runtime_types'; import { useTickTick } from '../use_tick_tick'; import { fetchJourneySteps } from '../../../../state/api/journey'; import { isStepEnd } from '../../../synthetics/check_steps/steps_list'; -import { SYNTHETICS_INDEX_PATTERN } from '../../../../../common/constants'; +import { SYNTHETICS_INDEX_PATTERN } from '../../../../../../common/constants'; export interface CheckGroupResult { checkGroupId: string; diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/simple/simple_test_results.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/simple/simple_test_results.test.tsx similarity index 99% rename from x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/simple/simple_test_results.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/simple/simple_test_results.test.tsx index 6ef4daf9fbdf3..c0bab63b1c11d 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/simple/simple_test_results.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/simple/simple_test_results.test.tsx @@ -11,7 +11,7 @@ import { render } from '../../../../lib/helper/rtl_helpers'; import { SimpleTestResults } from './simple_test_results'; import { kibanaService } from '../../../../state/kibana_service'; import * as runOnceHooks from './use_simple_run_once_monitors'; -import { Ping } from '../../../../../common/runtime_types'; +import { Ping } from '../../../../../../common/runtime_types'; describe('SimpleTestResults', function () { const onDone = jest.fn(); diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/simple/simple_test_results.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/simple/simple_test_results.tsx similarity index 96% rename from x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/simple/simple_test_results.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/simple/simple_test_results.tsx index b1ac899a8951e..580c936272b59 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/simple/simple_test_results.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/simple/simple_test_results.tsx @@ -6,7 +6,7 @@ */ import React, { useEffect, useState } from 'react'; import { useSimpleRunOnceMonitors } from './use_simple_run_once_monitors'; -import { Ping } from '../../../../../common/runtime_types'; +import { Ping } from '../../../../../../common/runtime_types'; import { PingListTable } from '../../../monitor/ping_list/ping_list_table'; import { TestResultHeader } from '../test_result_header'; diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/simple/use_simple_run_once_monitors.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/simple/use_simple_run_once_monitors.ts similarity index 94% rename from x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/simple/use_simple_run_once_monitors.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/simple/use_simple_run_once_monitors.ts index 3ca3691aef22c..f0282aaad47a2 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/simple/use_simple_run_once_monitors.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/simple/use_simple_run_once_monitors.ts @@ -7,9 +7,9 @@ import { useMemo, useRef } from 'react'; import { createEsParams, useEsSearch } from '@kbn/observability-plugin/public'; -import { Ping } from '../../../../../common/runtime_types'; +import { Ping } from '../../../../../../common/runtime_types'; import { useTickTick } from '../use_tick_tick'; -import { SYNTHETICS_INDEX_PATTERN } from '../../../../../common/constants'; +import { SYNTHETICS_INDEX_PATTERN } from '../../../../../../common/constants'; export const useSimpleRunOnceMonitors = ({ configId, diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/test_now_mode.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/test_now_mode.test.tsx similarity index 95% rename from x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/test_now_mode.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/test_now_mode.test.tsx index da06b41d16530..b040f7a27da33 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/test_now_mode.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/test_now_mode.test.tsx @@ -10,7 +10,7 @@ import { screen } from '@testing-library/react'; import { render } from '../../../lib/helper/rtl_helpers'; import { TestNowMode } from './test_now_mode'; import { kibanaService } from '../../../state/kibana_service'; -import { Locations, MonitorFields } from '../../../../common/runtime_types'; +import { Locations, MonitorFields } from '../../../../../common/runtime_types'; import * as runOnceErrorHooks from '../hooks/use_run_once_errors'; describe('TestNowMode', function () { diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/test_now_mode.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/test_now_mode.tsx similarity index 94% rename from x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/test_now_mode.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/test_now_mode.tsx index 0cc5f0658ff44..25a2f7d02a5fe 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/test_now_mode.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/test_now_mode.tsx @@ -18,7 +18,11 @@ import { import { useFetcher } from '@kbn/observability-plugin/public'; import { useRunOnceErrors } from '../hooks/use_run_once_errors'; import { TestRunResult } from './test_run_results'; -import { Locations, MonitorFields, ServiceLocationErrors } from '../../../../common/runtime_types'; +import { + Locations, + MonitorFields, + ServiceLocationErrors, +} from '../../../../../common/runtime_types'; import { runOnceMonitor } from '../../../state/api'; import { kibanaService } from '../../../state/kibana_service'; @@ -111,6 +115,6 @@ export function TestNowMode({ ); } -const PushingLabel = i18n.translate('xpack.uptime.testRun.pushing.description', { +const PushingLabel = i18n.translate('xpack.synthetics.testRun.pushing.description', { defaultMessage: 'Pushing the monitor to service...', }); diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/test_result_header.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/test_result_header.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/test_result_header.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/test_result_header.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/test_result_header.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/test_result_header.tsx similarity index 80% rename from x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/test_result_header.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/test_result_header.tsx index 7c53e99a6e9af..4cd4df567882d 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/test_result_header.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/test_result_header.tsx @@ -17,7 +17,7 @@ import { import { i18n } from '@kbn/i18n'; import * as React from 'react'; import { formatDuration } from '../../monitor/ping_list/ping_list'; -import { JourneyStep, Ping } from '../../../../common/runtime_types'; +import { JourneyStep, Ping } from '../../../../../common/runtime_types'; import { useUptimeSettingsContext } from '../../../contexts/uptime_settings_context'; interface Props { @@ -62,7 +62,7 @@ export function TestResultHeader({ - {i18n.translate('xpack.uptime.monitorManagement.timeTaken', { + {i18n.translate('xpack.synthetics.monitorManagement.timeTaken', { defaultMessage: 'Took {timeTaken}', values: { timeTaken: formatDuration(duration) }, })} @@ -93,26 +93,26 @@ export function TestResultHeader({ ); } -export const PENDING_LABEL = i18n.translate('xpack.uptime.monitorManagement.pending', { +export const PENDING_LABEL = i18n.translate('xpack.synthetics.monitorManagement.pending', { defaultMessage: 'PENDING', }); -const TEST_RESULT = i18n.translate('xpack.uptime.monitorManagement.testResult', { +const TEST_RESULT = i18n.translate('xpack.synthetics.monitorManagement.testResult', { defaultMessage: 'Test result', }); -const COMPLETED_LABEL = i18n.translate('xpack.uptime.monitorManagement.completed', { +const COMPLETED_LABEL = i18n.translate('xpack.synthetics.monitorManagement.completed', { defaultMessage: 'COMPLETED', }); -const FAILED_LABEL = i18n.translate('xpack.uptime.monitorManagement.failed', { +const FAILED_LABEL = i18n.translate('xpack.synthetics.monitorManagement.failed', { defaultMessage: 'FAILED', }); -export const IN_PROGRESS_LABEL = i18n.translate('xpack.uptime.monitorManagement.inProgress', { +export const IN_PROGRESS_LABEL = i18n.translate('xpack.synthetics.monitorManagement.inProgress', { defaultMessage: 'IN PROGRESS', }); -const VIEW_DETAILS = i18n.translate('xpack.uptime.monitorManagement.viewTestRunDetails', { +const VIEW_DETAILS = i18n.translate('xpack.synthetics.monitorManagement.viewTestRunDetails', { defaultMessage: 'View test result details', }); diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/test_run_results.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/test_run_results.tsx similarity index 93% rename from x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/test_run_results.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/test_run_results.tsx index b1a6d0aba8cfc..6e9ef292ad6b2 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/test_run_results.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/test_run_results.tsx @@ -6,7 +6,7 @@ */ import * as React from 'react'; -import { SyntheticsMonitor } from '../../../../common/runtime_types'; +import { SyntheticsMonitor } from '../../../../../common/runtime_types'; import { BrowserTestRunResult } from './browser/browser_test_results'; import { SimpleTestResults } from './simple/simple_test_results'; diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/use_tick_tick.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/use_tick_tick.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/monitor_management/test_now_mode/use_tick_tick.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/test_now_mode/use_tick_tick.ts diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/validation.test.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/validation.test.ts new file mode 100644 index 0000000000000..ce7c08a45dbaf --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/validation.test.ts @@ -0,0 +1,128 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + ConfigKey, + DataStream, + HTTPFields, + BrowserFields, + MonitorFields, + ScheduleUnit, + ServiceLocations, +} from '../../../../common/runtime_types'; +import { validate, validateCommon } from './validation'; + +describe('[Monitor Management] validation', () => { + const commonPropsValid: Partial = { + [ConfigKey.SCHEDULE]: { number: '5', unit: ScheduleUnit.MINUTES }, + [ConfigKey.TIMEOUT]: '3m', + [ConfigKey.LOCATIONS]: [ + { + id: 'test-service-location', + isServiceManaged: true, + url: 'https:test-url.com', + geo: { lat: 33.33432323, lon: 73.23424221 }, + label: 'EU West', + }, + ] as ServiceLocations, + [ConfigKey.NAME]: 'test-name', + [ConfigKey.NAMESPACE]: 'namespace', + }; + + describe('Common monitor fields', () => { + it('should return false for all valid props', () => { + const result = Object.values(validateCommon).map((validator) => { + return validator ? validator(commonPropsValid) : true; + }); + + expect(result.reduce((previous, current) => previous || current)).toBeFalsy(); + }); + + it('should invalidate on invalid namespace', () => { + const validatorFn = validateCommon[ConfigKey.NAMESPACE]; + const result = [undefined, null, '', '*/&<>:', 'A', 'a'.repeat(101)].map((testValue) => + validatorFn?.({ [ConfigKey.NAMESPACE]: testValue } as Partial) + ); + + expect(result.reduce((previous, current) => previous && current)).toBeTruthy(); + }); + }); + + describe('HTTP', () => { + const httpPropsValid: Partial = { + ...commonPropsValid, + [ConfigKey.RESPONSE_STATUS_CHECK]: ['200', '204'], + [ConfigKey.RESPONSE_HEADERS_CHECK]: { 'Content-Type': 'application/json' }, + [ConfigKey.REQUEST_HEADERS_CHECK]: { 'Accept-Language': 'en-GB,en-US;q=0.9,en;q=0.8' }, + [ConfigKey.MAX_REDIRECTS]: '3', + [ConfigKey.URLS]: 'https:// example-url.com', + }; + + it('should return false for all valid props', () => { + const validators = validate[DataStream.HTTP]; + const keysToValidate = [ + ConfigKey.SCHEDULE, + ConfigKey.TIMEOUT, + ConfigKey.LOCATIONS, + ConfigKey.RESPONSE_STATUS_CHECK, + ConfigKey.RESPONSE_HEADERS_CHECK, + ConfigKey.REQUEST_HEADERS_CHECK, + ConfigKey.MAX_REDIRECTS, + ConfigKey.URLS, + ]; + const validatorFns = keysToValidate.map((key) => validators[key]); + const result = validatorFns.map((fn) => fn?.(httpPropsValid) ?? true); + + expect(result).not.toEqual(expect.arrayContaining([true])); + }); + + it('should invalidate when locations is empty', () => { + const validators = validate[DataStream.HTTP]; + const validatorFn = validators[ConfigKey.LOCATIONS]; + const result = [undefined, null, []].map( + (testValue) => + validatorFn?.({ [ConfigKey.LOCATIONS]: testValue } as Partial) ?? false + ); + + expect(result).toEqual([true, true, true]); + }); + }); + + describe.each([ + [ConfigKey.SOURCE_INLINE, 'step(() => {});'], + [ConfigKey.SOURCE_ZIP_URL, 'https://test.zip'], + ])('Browser', (configKey, value) => { + const browserProps: Partial = { + ...commonPropsValid, + [ConfigKey.MONITOR_TYPE]: DataStream.BROWSER, + [ConfigKey.TIMEOUT]: undefined, + [configKey]: value, + }; + + it('should return false for all valid props', () => { + const validators = validate[DataStream.BROWSER]; + const keysToValidate = [ConfigKey.SCHEDULE, ConfigKey.TIMEOUT, configKey]; + const validatorFns = keysToValidate.map((key) => validators[key]); + const result = validatorFns.map((fn) => fn?.(browserProps) ?? true); + + expect(result).not.toEqual(expect.arrayContaining([true])); + }); + + it('should invalidate when locations is empty', () => { + const validators = validate[DataStream.BROWSER]; + const validatorFn = validators[ConfigKey.LOCATIONS]; + const result = [undefined, null, []].map( + (testValue) => + validatorFn?.({ [ConfigKey.LOCATIONS]: testValue } as Partial) ?? false + ); + + expect(result).toEqual([true, true, true]); + }); + }); + + // TODO: Add test for other monitor types if needed +}); diff --git a/x-pack/plugins/synthetics/public/components/monitor_management/validation.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/validation.ts similarity index 98% rename from x-pack/plugins/synthetics/public/components/monitor_management/validation.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/validation.ts index 78b0b8ba82b68..0975d00b38098 100644 --- a/x-pack/plugins/synthetics/public/components/monitor_management/validation.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/validation.ts @@ -11,8 +11,8 @@ import { ScheduleUnit, MonitorFields, isServiceLocationInvalid, -} from '../../../common/runtime_types'; -import { Validation } from '../../../common/types'; +} from '../../../../common/runtime_types'; +import { Validation } from '../../../../common/types'; export const digitsOnly = /^[0-9]*$/g; export const includesValidPort = /[^\:]+:[0-9]{1,5}$/g; diff --git a/x-pack/plugins/synthetics/public/components/overview/__snapshots__/snapshot_heading.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/__snapshots__/snapshot_heading.test.tsx.snap similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/__snapshots__/snapshot_heading.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/__snapshots__/snapshot_heading.test.tsx.snap diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/alert_expression_popover.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alert_expression_popover.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/alerts/alert_expression_popover.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alert_expression_popover.tsx diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/alert_field_number.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alert_field_number.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/alerts/alert_field_number.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alert_field_number.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/alert_field_number.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alert_field_number.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/alerts/alert_field_number.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alert_field_number.tsx diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alert_query_bar/query_bar.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alert_query_bar/query_bar.tsx new file mode 100644 index 0000000000000..288cd7232a3d5 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alert_query_bar/query_bar.tsx @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useEffect, useState } from 'react'; +import { EuiFlexItem } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { QueryStringInput } from '@kbn/unified-search-plugin/public'; +import { isValidKuery } from '../../query_bar/query_bar'; +import * as labels from '../translations'; +import { useUptimeDataView } from '../../../../hooks'; + +interface Props { + query: string; + onChange: (query: string) => void; +} + +export const AlertQueryBar = ({ query = '', onChange }: Props) => { + const dataView = useUptimeDataView(); + + const [inputVal, setInputVal] = useState(query); + + useEffect(() => { + onChange(query); + setInputVal(query); + }, [onChange, query]); + + return ( + + { + setInputVal(queryN?.query as string); + if (isValidKuery(queryN?.query as string)) { + // we want to submit when user clears or paste a complete kuery + onChange(queryN.query as string); + } + }} + onSubmit={(queryN) => { + if (queryN) onChange(queryN.query as string); + }} + query={{ query: inputVal, language: 'kuery' }} + aria-label={labels.ALERT_KUERY_BAR_ARIA} + dataTestSubj="xpack.synthetics.alerts.monitorStatus.filterBar" + autoSubmit={true} + disableLanguageSwitcher={true} + isInvalid={!!(inputVal && !query)} + placeholder={i18n.translate('xpack.synthetics.alerts.searchPlaceholder.kql', { + defaultMessage: 'Filter using kql syntax', + })} + /> + + ); +}; diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/alert_tls.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alert_tls.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/alerts/alert_tls.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alert_tls.tsx diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alerts_containers/alert_monitor_status.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alerts_containers/alert_monitor_status.tsx new file mode 100644 index 0000000000000..54a8010e30a1c --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alerts_containers/alert_monitor_status.tsx @@ -0,0 +1,90 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useEffect } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import { isRight } from 'fp-ts/lib/Either'; +import { selectedFiltersSelector } from '../../../../state/selectors'; +import { AlertMonitorStatusComponent } from '../monitor_status_alert/alert_monitor_status'; +import { setSearchTextAction } from '../../../../state/actions'; +import { + AtomicStatusCheckParamsType, + GetMonitorAvailabilityParamsType, +} from '../../../../../../common/runtime_types'; + +import { useSnapShotCount } from './use_snap_shot'; +import { FILTER_FIELDS } from '../../../../../../common/constants'; + +const { TYPE, TAGS, LOCATION, PORT } = FILTER_FIELDS; + +interface Props { + ruleParams: { [key: string]: any }; + enabled: boolean; + numTimes: number; + setRuleParams: (key: string, value: any) => void; + timerange: { + from: string; + to: string; + }; +} + +export const AlertMonitorStatus: React.FC = ({ + enabled, + numTimes, + setRuleParams, + timerange, + ruleParams, +}) => { + const dispatch = useDispatch(); + + useEffect(() => { + if (ruleParams.search) { + dispatch(setSearchTextAction(ruleParams.search)); + } + }, [ruleParams, dispatch]); + + const { count, loading } = useSnapShotCount({ + query: ruleParams.search, + filters: ruleParams.filters, + }); + + const isOldAlert = React.useMemo( + () => + Object.entries(ruleParams).length > 0 && + !isRight(AtomicStatusCheckParamsType.decode(ruleParams)) && + !isRight(GetMonitorAvailabilityParamsType.decode(ruleParams)), + [ruleParams] + ); + + const selectedFilters = useSelector(selectedFiltersSelector); + useEffect(() => { + if (!ruleParams.filters && selectedFilters !== null) { + setRuleParams('filters', { + [PORT]: selectedFilters?.ports ?? [], + [LOCATION]: selectedFilters?.locations ?? [], + [TYPE]: selectedFilters?.schemes ?? [], + [TAGS]: selectedFilters?.tags ?? [], + }); + } + }, [ruleParams, setRuleParams, selectedFilters]); + + return ( + + ); +}; + +// eslint-disable-next-line import/no-default-export +export { AlertMonitorStatus as default }; diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/alerts_containers/alert_tls.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alerts_containers/alert_tls.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/alerts/alerts_containers/alert_tls.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alerts_containers/alert_tls.tsx diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/alerts_containers/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alerts_containers/index.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/alerts/alerts_containers/index.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alerts_containers/index.ts diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/alerts_containers/toggle_alert_flyout_button.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alerts_containers/toggle_alert_flyout_button.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/alerts/alerts_containers/toggle_alert_flyout_button.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alerts_containers/toggle_alert_flyout_button.tsx diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/alerts_containers/uptime_alerts_flyout_wrapper.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alerts_containers/uptime_alerts_flyout_wrapper.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/alerts/alerts_containers/uptime_alerts_flyout_wrapper.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alerts_containers/uptime_alerts_flyout_wrapper.tsx diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/alerts_containers/use_snap_shot.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alerts_containers/use_snap_shot.ts similarity index 81% rename from x-pack/plugins/synthetics/public/components/overview/alerts/alerts_containers/use_snap_shot.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alerts_containers/use_snap_shot.ts index e6aee6207093e..7fd0f0b3a410b 100644 --- a/x-pack/plugins/synthetics/public/components/overview/alerts/alerts_containers/use_snap_shot.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alerts_containers/use_snap_shot.ts @@ -6,7 +6,7 @@ */ import { useFetcher } from '@kbn/observability-plugin/public'; -import { useIndexPattern, generateUpdatedKueryString } from '../../../../hooks'; +import { useUptimeDataView, generateUpdatedKueryString } from '../../../../hooks'; import { fetchSnapshotCount } from '../../../../state/api'; export const useSnapShotCount = ({ query, filters }: { query: string; filters: [] | string }) => { @@ -15,9 +15,9 @@ export const useSnapShotCount = ({ query, filters }: { query: string; filters: [ ? '' : JSON.stringify(Array.from(Object.entries(filters))); - const indexPattern = useIndexPattern(); + const dataView = useUptimeDataView(); - const [esKuery, error] = generateUpdatedKueryString(indexPattern, query, parsedFilters); + const [esKuery, error] = generateUpdatedKueryString(dataView, query, parsedFilters); const { data, loading } = useFetcher( () => diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/anomaly_alert/anomaly_alert.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/anomaly_alert/anomaly_alert.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/alerts/anomaly_alert/anomaly_alert.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/anomaly_alert/anomaly_alert.tsx diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/anomaly_alert/select_severity.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/anomaly_alert/select_severity.tsx similarity index 87% rename from x-pack/plugins/synthetics/public/components/overview/alerts/anomaly_alert/select_severity.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/anomaly_alert/select_severity.tsx index eed650fe6074a..a1c6b88042b77 100644 --- a/x-pack/plugins/synthetics/public/components/overview/alerts/anomaly_alert/select_severity.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/anomaly_alert/select_severity.tsx @@ -12,16 +12,16 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { EuiHealth, EuiSpacer, EuiSuperSelect, EuiText } from '@elastic/eui'; import { getSeverityColor } from '@kbn/ml-plugin/public'; -const warningLabel = i18n.translate('xpack.uptime.controls.selectSeverity.warningLabel', { +const warningLabel = i18n.translate('xpack.synthetics.controls.selectSeverity.warningLabel', { defaultMessage: 'warning', }); -const minorLabel = i18n.translate('xpack.uptime.controls.selectSeverity.minorLabel', { +const minorLabel = i18n.translate('xpack.synthetics.controls.selectSeverity.minorLabel', { defaultMessage: 'minor', }); -const majorLabel = i18n.translate('xpack.uptime.controls.selectSeverity.majorLabel', { +const majorLabel = i18n.translate('xpack.synthetics.controls.selectSeverity.majorLabel', { defaultMessage: 'major', }); -const criticalLabel = i18n.translate('xpack.uptime.controls.selectSeverity.criticalLabel', { +const criticalLabel = i18n.translate('xpack.synthetics.controls.selectSeverity.criticalLabel', { defaultMessage: 'critical', }); @@ -95,7 +95,7 @@ const getSeverityOptions = () =>

diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/anomaly_alert/translations.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/anomaly_alert/translations.ts new file mode 100644 index 0000000000000..ea9aac0ddb48b --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/anomaly_alert/translations.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const AnomalyTranslations = { + criteriaAriaLabel: i18n.translate( + 'xpack.synthetics.alerts.anomaly.criteriaExpression.ariaLabel', + { + defaultMessage: 'An expression displaying the criteria for a selected monitor.', + } + ), + whenMonitor: i18n.translate('xpack.synthetics.alerts.anomaly.criteriaExpression.description', { + defaultMessage: 'When monitor', + }), + scoreAriaLabel: i18n.translate('xpack.synthetics.alerts.anomaly.scoreExpression.ariaLabel', { + defaultMessage: 'An expression displaying the criteria for an anomaly alert threshold.', + }), + hasAnomalyWithSeverity: i18n.translate( + 'xpack.synthetics.alerts.anomaly.scoreExpression.description', + { + defaultMessage: 'has anomaly with severity', + description: 'An expression displaying the criteria for an anomaly alert threshold.', + } + ), +}; diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/index.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/alerts/index.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/index.ts diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/__snapshots__/down_number_select.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/__snapshots__/down_number_select.test.tsx.snap similarity index 83% rename from x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/__snapshots__/down_number_select.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/__snapshots__/down_number_select.test.tsx.snap index f9e169b976d1d..d22c2fb1bad4c 100644 --- a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/__snapshots__/down_number_select.test.tsx.snap +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/__snapshots__/down_number_select.test.tsx.snap @@ -11,7 +11,7 @@ exports[`DownNoExpressionSelect component should renders against props 1`] = ` } - data-test-subj="xpack.uptime.alerts.monitorStatus.numTimesExpression" + data-test-subj="xpack.synthetics.alerts.monitorStatus.numTimesExpression" description="matching monitors are down >" id="ping-count" value="5 times" diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/__snapshots__/time_expression_select.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/__snapshots__/time_expression_select.test.tsx.snap similarity index 78% rename from x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/__snapshots__/time_expression_select.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/__snapshots__/time_expression_select.test.tsx.snap index d7f04798198ce..5ff6e5773485b 100644 --- a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/__snapshots__/time_expression_select.test.tsx.snap +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/__snapshots__/time_expression_select.test.tsx.snap @@ -17,7 +17,7 @@ exports[`TimeExpressionSelect component should renders against props 1`] = ` } - data-test-subj="xpack.uptime.alerts.monitorStatus.timerangeValueExpression" + data-test-subj="xpack.synthetics.alerts.monitorStatus.timerangeValueExpression" description="within" id="timerange" value="last 15" @@ -95,33 +95,33 @@ exports[`TimeExpressionSelect component should shallow renders against props 1`] content={ } - data-test-subj="xpack.uptime.alerts.monitorStatus.timerangeUnitExpression" + data-test-subj="xpack.synthetics.alerts.monitorStatus.timerangeUnitExpression" description="" id="timerange-unit" value="minutes" diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/availability_expression_select.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/availability_expression_select.tsx similarity index 85% rename from x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/availability_expression_select.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/availability_expression_select.tsx index b125189230ed4..e6aef70beeaa0 100644 --- a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/availability_expression_select.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/availability_expression_select.tsx @@ -22,25 +22,28 @@ interface Props { const TimeRangeOptions: TimeRangeOption[] = [ { 'aria-label': labels.DAYS_TIME_RANGE, - 'data-test-subj': 'xpack.uptime.alerts.monitorStatus.availability.timerangeUnit.daysOption', + 'data-test-subj': 'xpack.synthetics.alerts.monitorStatus.availability.timerangeUnit.daysOption', key: 'd', label: labels.DAYS, }, { 'aria-label': labels.WEEKS_TIME_RANGE, - 'data-test-subj': 'xpack.uptime.alerts.monitorStatus.availability.timerangeUnit.weeksOption', + 'data-test-subj': + 'xpack.synthetics.alerts.monitorStatus.availability.timerangeUnit.weeksOption', key: 'w', label: labels.WEEKS, }, { 'aria-label': labels.MONTHS_TIME_RANGE, - 'data-test-subj': 'xpack.uptime.alerts.monitorStatus.availability.timerangeUnit.monthsOption', + 'data-test-subj': + 'xpack.synthetics.alerts.monitorStatus.availability.timerangeUnit.monthsOption', key: 'M', label: labels.MONTHS, }, { 'aria-label': labels.YEARS_TIME_RANGE, - 'data-test-subj': 'xpack.uptime.alerts.monitorStatus.availability.timerangeUnit.yearsOption', + 'data-test-subj': + 'xpack.synthetics.alerts.monitorStatus.availability.timerangeUnit.yearsOption', key: 'y', label: labels.YEARS, }, @@ -115,7 +118,7 @@ export const AvailabilityExpressionSelect: React.FC = ({ }} /> } - data-test-subj="xpack.uptime.alerts.monitorStatus.availability.threshold" + data-test-subj="xpack.synthetics.alerts.monitorStatus.availability.threshold" description={ hasFilters ? labels.ENTER_AVAILABILITY_THRESHOLD_DESCRIPTION @@ -135,13 +138,13 @@ export const AvailabilityExpressionSelect: React.FC = ({ content={ } - data-test-subj="xpack.uptime.alerts.monitorStatus.availability.timerangeExpression" + data-test-subj="xpack.synthetics.alerts.monitorStatus.availability.timerangeExpression" description={labels.ENTER_AVAILABILITY_RANGE_UNITS_DESCRIPTION} id="range" isEnabled={isEnabled} @@ -150,11 +153,11 @@ export const AvailabilityExpressionSelect: React.FC = ({ { @@ -168,7 +171,7 @@ export const AvailabilityExpressionSelect: React.FC = ({ timeRangeOptions={timerangeUnitOptions} /> } - data-test-subj="xpack.uptime.alerts.monitorStatus.availability.timerangeUnit" + data-test-subj="xpack.synthetics.alerts.monitorStatus.availability.timerangeUnit" description="" id="availability-unit" isEnabled={isEnabled} diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/down_number_select.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/down_number_select.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/down_number_select.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/down_number_select.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/down_number_select.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/down_number_select.tsx similarity index 89% rename from x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/down_number_select.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/down_number_select.tsx index a1d459f89f02e..e1feaf2449fd4 100644 --- a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/down_number_select.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/down_number_select.tsx @@ -35,13 +35,13 @@ export const DownNoExpressionSelect: React.FC = ({ content={ } - data-test-subj="xpack.uptime.alerts.monitorStatus.numTimesExpression" + data-test-subj="xpack.synthetics.alerts.monitorStatus.numTimesExpression" description={hasFilters ? labels.MATCHING_MONITORS_DOWN : labels.ANY_MONITOR_DOWN} id="ping-count" isEnabled={isEnabled} diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/filters_expression_select.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/filters_expression_select.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/filters_expression_select.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/filters_expression_select.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/filters_expression_select.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/filters_expression_select.tsx similarity index 95% rename from x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/filters_expression_select.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/filters_expression_select.tsx index e34caf1b95b8b..12b28352a503e 100644 --- a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/filters_expression_select.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/filters_expression_select.tsx @@ -10,8 +10,8 @@ import { EuiButtonIcon, EuiExpression, EuiFlexGroup, EuiFlexItem, EuiSpacer } fr import { FieldValueSuggestions } from '@kbn/observability-plugin/public'; import { filterLabels } from '../../filter_group/translations'; import { alertFilterLabels, filterAriaLabels } from './translations'; -import { useIndexPattern } from '../../../../contexts/uptime_index_pattern_context'; -import { FILTER_FIELDS } from '../../../../../common/constants'; +import { useUptimeDataView } from '../../../../contexts/uptime_data_view_context'; +import { FILTER_FIELDS } from '../../../../../../common/constants'; import { useGetUrlParams } from '../../../../hooks'; export interface FilterExpressionsSelectProps { @@ -122,7 +122,7 @@ export const FiltersExpressionsSelect: React.FC = (curr) => curr.selectedItems.length > 0 || newFilters?.includes(curr.fieldName) ); - const indexPattern = useIndexPattern(); + const dataView = useUptimeDataView(); return ( <> @@ -130,11 +130,11 @@ export const FiltersExpressionsSelect: React.FC = ({ description, id, title, value, fieldName, ariaLabel, selectedItems }) => ( - {indexPattern && ( + {dataView && ( { diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/index.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/index.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/index.ts diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/status_expression_select.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/status_expression_select.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/status_expression_select.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/status_expression_select.tsx diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/time_expression_select.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/time_expression_select.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/time_expression_select.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/time_expression_select.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/time_expression_select.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/time_expression_select.tsx similarity index 82% rename from x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/time_expression_select.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/time_expression_select.tsx index 957a289386564..f3729fd6ebfa9 100644 --- a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/time_expression_select.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/time_expression_select.tsx @@ -25,25 +25,25 @@ const DEFAULT_TIMERANGE_UNIT = 'm'; const TimeRangeOptions: TimeRangeOption[] = [ { 'aria-label': labels.SECONDS_TIME_RANGE, - 'data-test-subj': 'xpack.uptime.alerts.monitorStatus.timerangeUnitSelectable.secondsOption', + 'data-test-subj': 'xpack.synthetics.alerts.monitorStatus.timerangeUnitSelectable.secondsOption', key: 's', label: labels.SECONDS, }, { 'aria-label': labels.MINUTES_TIME_RANGE, - 'data-test-subj': 'xpack.uptime.alerts.monitorStatus.timerangeUnitSelectable.minutesOption', + 'data-test-subj': 'xpack.synthetics.alerts.monitorStatus.timerangeUnitSelectable.minutesOption', key: 'm', label: labels.MINUTES, }, { 'aria-label': labels.HOURS_TIME_RANGE, - 'data-test-subj': 'xpack.uptime.alerts.monitorStatus.timerangeUnitSelectable.hoursOption', + 'data-test-subj': 'xpack.synthetics.alerts.monitorStatus.timerangeUnitSelectable.hoursOption', key: 'h', label: labels.HOURS, }, { 'aria-label': labels.DAYS_TIME_RANGE, - 'data-test-subj': 'xpack.uptime.alerts.monitorStatus.timerangeUnitSelectable.daysOption', + 'data-test-subj': 'xpack.synthetics.alerts.monitorStatus.timerangeUnitSelectable.daysOption', key: 'd', label: labels.DAYS, }, @@ -77,13 +77,13 @@ export const TimeExpressionSelect: React.FC = ({ content={ } - data-test-subj="xpack.uptime.alerts.monitorStatus.timerangeValueExpression" + data-test-subj="xpack.synthetics.alerts.monitorStatus.timerangeValueExpression" description={labels.ENTER_NUMBER_OF_TIME_UNITS_DESCRIPTION} id="timerange" isEnabled={isEnabled} @@ -96,7 +96,7 @@ export const TimeExpressionSelect: React.FC = ({ content={ >) => { if (newOptions.reduce((acc, { checked }) => acc || checked === 'on', false)) { @@ -106,7 +106,7 @@ export const TimeExpressionSelect: React.FC = ({ timeRangeOptions={timerangeUnitOptions} /> } - data-test-subj="xpack.uptime.alerts.monitorStatus.timerangeUnitExpression" + data-test-subj="xpack.synthetics.alerts.monitorStatus.timerangeUnitExpression" description="" id="timerange-unit" isEnabled={isEnabled} diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/time_unit_selectable.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/time_unit_selectable.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/alerts/monitor_expressions/time_unit_selectable.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/time_unit_selectable.tsx diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/translations.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/translations.ts new file mode 100644 index 0000000000000..05d736826a48b --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_expressions/translations.ts @@ -0,0 +1,109 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const alertFilterLabels = { + USING: i18n.translate('xpack.synthetics.alerts.monitorStatus.filters.using', { + defaultMessage: 'Using', + }), + + USING_PORT: i18n.translate('xpack.synthetics.alerts.monitorStatus.filters.usingPort', { + defaultMessage: 'Using port', + }), + + ANY_PORT: i18n.translate('xpack.synthetics.alerts.monitorStatus.filters.anyPort', { + defaultMessage: 'any port', + }), + + WITH: i18n.translate('xpack.synthetics.alerts.monitorStatus.filters.with', { + defaultMessage: 'Using', + }), + + WITH_TAG: i18n.translate('xpack.synthetics.alerts.monitorStatus.filters.withTag', { + defaultMessage: 'With tag', + }), + + ANY_TAG: i18n.translate('xpack.synthetics.alerts.monitorStatus.filters.anyTag', { + defaultMessage: 'any tag', + }), + + OF: i18n.translate('xpack.synthetics.alerts.monitorStatus.filters.of', { + defaultMessage: 'Of', + }), + + OF_TYPE: i18n.translate('xpack.synthetics.alerts.monitorStatus.filters.ofType', { + defaultMessage: 'Of type', + }), + + ANY_TYPE: i18n.translate('xpack.synthetics.alerts.monitorStatus.filters.anyType', { + defaultMessage: 'any type', + }), + + FROM: i18n.translate('xpack.synthetics.alerts.monitorStatus.filters.from', { + defaultMessage: 'From', + }), + + FROM_LOCATION: i18n.translate('xpack.synthetics.alerts.monitorStatus.filters.fromLocation', { + defaultMessage: 'From location', + }), + + ANY_LOCATION: i18n.translate('xpack.synthetics.alerts.monitorStatus.filters.anyLocation', { + defaultMessage: 'any location', + }), + + REMOVE_FILTER_LABEL: (title: string) => + i18n.translate('xpack.synthetics.alerts.monitorExpression.label', { + defaultMessage: 'Remove filter {title}', + values: { title }, + }), +}; + +export const statusExpLabels = { + ENABLED_CHECKBOX: i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.statusEnabledCheck.label', + { + defaultMessage: 'Status check', + } + ), +}; + +export const timeExpLabels = { + OPEN_TIME_POPOVER: i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.timerangeUnitExpression.ariaLabel', + { + defaultMessage: 'Open the popover for time range unit select field', + } + ), + SELECT_TIME_RANGE_ARIA: i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.timerangeUnitSelectable', + { + defaultMessage: 'Selectable field for the time range units alerts should use', + } + ), + SELECT_TIME_RANGE_HEADLINE: i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.timerangeSelectionHeader', + { + defaultMessage: 'Select time range unit', + } + ), +}; + +export const filterAriaLabels = { + PORT: i18n.translate('xpack.synthetics.alerts.monitorStatus.filters.port.label', { + defaultMessage: `Select port filters to apply to the alert's query.`, + }), + TAG: i18n.translate('xpack.synthetics.alerts.monitorStatus.filters.tag.label', { + defaultMessage: `Select tag filters to apply to the alert's query.`, + }), + SCHEME: i18n.translate('xpack.synthetics.alerts.monitorStatus.filters.scheme.label', { + defaultMessage: `Select protocol scheme filters to apply to the alert's query.`, + }), + LOCATION: i18n.translate('xpack.synthetics.alerts.monitorStatus.filters.location.label', { + defaultMessage: `Select location filters to apply to the alert's query.`, + }), +}; diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_status_alert/add_filter_btn.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_status_alert/add_filter_btn.test.tsx similarity index 98% rename from x-pack/plugins/synthetics/public/components/overview/alerts/monitor_status_alert/add_filter_btn.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_status_alert/add_filter_btn.test.tsx index f8f9e5a84bc5c..a929489e6b715 100644 --- a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_status_alert/add_filter_btn.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_status_alert/add_filter_btn.test.tsx @@ -40,7 +40,6 @@ describe('AddFilterButton component', () => { panelPaddingSize="none" > { panelPaddingSize="none" > { panelPaddingSize="none" > diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_status_alert/add_filter_btn.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_status_alert/add_filter_btn.tsx similarity index 93% rename from x-pack/plugins/synthetics/public/components/overview/alerts/monitor_status_alert/add_filter_btn.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_status_alert/add_filter_btn.tsx index 58b8e7bb085da..81e782696d58f 100644 --- a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_status_alert/add_filter_btn.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_status_alert/add_filter_btn.tsx @@ -8,7 +8,7 @@ import React, { useState } from 'react'; import { EuiButtonEmpty, EuiContextMenuItem, EuiContextMenuPanel, EuiPopover } from '@elastic/eui'; import * as labels from '../translations'; -import { useIndexPattern } from '../../../../contexts/uptime_index_pattern_context'; +import { useUptimeDataView } from '../../../../contexts/uptime_data_view_context'; interface Props { newFilters: string[]; @@ -21,7 +21,7 @@ export const AddFilterButton: React.FC = ({ newFilters, onNewFilter, aler const getSelectedItems = (fieldName: string) => alertFilters?.[fieldName] ?? []; - const indexPattern = useIndexPattern(); + const dataView = useUptimeDataView(); const onButtonClick = () => { setPopover(!isPopoverOpen); @@ -65,7 +65,7 @@ export const AddFilterButton: React.FC = ({ newFilters, onNewFilter, aler onClick={onButtonClick} size="s" flush="left" - isLoading={!indexPattern} + isLoading={!dataView} > {labels.ADD_FILTER} diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_status_alert/alert_monitor_status.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_status_alert/alert_monitor_status.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/alerts/monitor_status_alert/alert_monitor_status.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_status_alert/alert_monitor_status.test.tsx diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_status_alert/alert_monitor_status.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_status_alert/alert_monitor_status.tsx new file mode 100644 index 0000000000000..80958e3bdd767 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_status_alert/alert_monitor_status.tsx @@ -0,0 +1,130 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useEffect, useState } from 'react'; +import { EuiCallOut, EuiSpacer, EuiHorizontalRule, EuiLoadingSpinner } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { FiltersExpressionsSelect, StatusExpressionSelect } from '../monitor_expressions'; +import { AddFilterButton } from './add_filter_btn'; +import { OldAlertCallOut } from './old_alert_call_out'; +import { AvailabilityExpressionSelect } from '../monitor_expressions/availability_expression_select'; +import { AlertQueryBar } from '../alert_query_bar/query_bar'; +import { useGetUrlParams } from '../../../../hooks'; +import { FILTER_FIELDS } from '../../../../../../common/constants'; + +export interface AlertMonitorStatusProps { + ruleParams: { [key: string]: any }; + enabled: boolean; + isOldAlert: boolean; + snapshotCount: number; + snapshotLoading?: boolean; + numTimes: number; + setRuleParams: (key: string, value: any) => void; + timerange: { + from: string; + to: string; + }; +} + +export const hasFilters = (filters?: { [key: string]: string[] }) => { + if (!filters || Object.keys(filters).length === 0) { + return false; + } + + return Object.values(FILTER_FIELDS).some((f) => filters[f].length); +}; + +export const AlertMonitorStatusComponent: React.FC = (props) => { + const { ruleParams, isOldAlert, setRuleParams, snapshotCount, snapshotLoading } = props; + + const alertFilters = ruleParams?.filters ?? {}; + const [newFilters, setNewFilters] = useState( + Object.keys(alertFilters).filter((f) => alertFilters[f].length) + ); + + const { search = '' } = useGetUrlParams(); + + useEffect(() => { + if (search) { + setRuleParams('search', search); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const onSearchChange = useCallback( + (value: string) => { + setRuleParams('search', value); + }, + [setRuleParams] + ); + + return ( + <> + + + + {' '} + {snapshotLoading && } + + } + iconType="iInCircle" + /> + + + + + + + + { + setNewFilters([...newFilters, newFilter]); + }} + /> + + { + if (newFilters.includes(removeFilter)) { + setNewFilters(newFilters.filter((item) => item !== removeFilter)); + } + }} + setRuleParams={setRuleParams} + shouldUpdateUrl={false} + /> + + + + + + + + + + + + ); +}; diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_status_alert/old_alert_call_out.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_status_alert/old_alert_call_out.tsx similarity index 91% rename from x-pack/plugins/synthetics/public/components/overview/alerts/monitor_status_alert/old_alert_call_out.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_status_alert/old_alert_call_out.tsx index bce33bea4cca3..d9d52496aaa80 100644 --- a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_status_alert/old_alert_call_out.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_status_alert/old_alert_call_out.tsx @@ -23,7 +23,7 @@ export const OldAlertCallOut: React.FC = ({ isOldAlert }) => { size="s" title={ } diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_status_alert/old_alert_callout.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_status_alert/old_alert_callout.test.tsx similarity index 93% rename from x-pack/plugins/synthetics/public/components/overview/alerts/monitor_status_alert/old_alert_callout.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_status_alert/old_alert_callout.test.tsx index f0c41480f5172..9145137b0d886 100644 --- a/x-pack/plugins/synthetics/public/components/overview/alerts/monitor_status_alert/old_alert_callout.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/monitor_status_alert/old_alert_callout.test.tsx @@ -26,7 +26,7 @@ describe('OldAlertCallOut', () => { title={ } diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/settings_message_expression_popover.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/settings_message_expression_popover.tsx similarity index 90% rename from x-pack/plugins/synthetics/public/components/overview/alerts/settings_message_expression_popover.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/settings_message_expression_popover.tsx index 71cdee07699c3..cf4775033443a 100644 --- a/x-pack/plugins/synthetics/public/components/overview/alerts/settings_message_expression_popover.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/settings_message_expression_popover.tsx @@ -31,7 +31,7 @@ export const SettingsMessageExpressionPopover: React.FC setIsOpen(false)} > + { setAlertFlyoutVisible(false); diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/toggle_alert_flyout_button.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/toggle_alert_flyout_button.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/alerts/toggle_alert_flyout_button.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/toggle_alert_flyout_button.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/toggle_alert_flyout_button.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/toggle_alert_flyout_button.tsx similarity index 87% rename from x-pack/plugins/synthetics/public/components/overview/alerts/toggle_alert_flyout_button.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/toggle_alert_flyout_button.tsx index 9aede506dde97..86b745c7d227f 100644 --- a/x-pack/plugins/synthetics/public/components/overview/alerts/toggle_alert_flyout_button.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/toggle_alert_flyout_button.tsx @@ -17,8 +17,8 @@ import React, { useState } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { CLIENT_ALERT_TYPES } from '../../../../common/constants/alerts'; -import { ClientPluginsStart } from '../../../apps/plugin'; +import { CLIENT_ALERT_TYPES } from '../../../../../common/constants/alerts'; +import { ClientPluginsStart } from '../../../../plugin'; import { ToggleFlyoutTranslations } from './translations'; import { ToggleAlertFlyoutButtonProps } from './alerts_containers'; @@ -33,7 +33,7 @@ const ALERT_CONTEXT_MAIN_PANEL_ID = 0; const ALERT_CONTEXT_SELECT_TYPE_PANEL_ID = 1; const noWritePermissionsTooltipContent = i18n.translate( - 'xpack.uptime.alertDropdown.noWritePermissions', + 'xpack.synthetics.alertDropdown.noWritePermissions', { defaultMessage: 'You need read-write access to Uptime to create alerts in this app.', } @@ -53,7 +53,7 @@ export const ToggleAlertFlyoutButtonComponent: React.FC = ({ const monitorStatusAlertContextMenuItem: EuiContextMenuPanelItemDescriptor = { 'aria-label': ToggleFlyoutTranslations.toggleMonitorStatusAriaLabel, - 'data-test-subj': 'xpack.uptime.toggleAlertFlyout', + 'data-test-subj': 'xpack.synthetics.toggleAlertFlyout', name: ToggleFlyoutTranslations.toggleMonitorStatusContent, onClick: () => { setAlertFlyoutVisible(CLIENT_ALERT_TYPES.MONITOR_STATUS); @@ -63,7 +63,7 @@ export const ToggleAlertFlyoutButtonComponent: React.FC = ({ const tlsAlertContextMenuItem: EuiContextMenuPanelItemDescriptor = { 'aria-label': ToggleFlyoutTranslations.toggleTlsAriaLabel, - 'data-test-subj': 'xpack.uptime.toggleTlsAlertFlyout', + 'data-test-subj': 'xpack.synthetics.toggleTlsAlertFlyout', name: ToggleFlyoutTranslations.toggleTlsContent, onClick: () => { setAlertFlyoutVisible(CLIENT_ALERT_TYPES.TLS); @@ -73,11 +73,11 @@ export const ToggleAlertFlyoutButtonComponent: React.FC = ({ const managementContextItem: EuiContextMenuPanelItemDescriptor = { 'aria-label': ToggleFlyoutTranslations.navigateToAlertingUIAriaLabel, - 'data-test-subj': 'xpack.uptime.navigateToAlertingUi', + 'data-test-subj': 'xpack.synthetics.navigateToAlertingUi', name: ( @@ -115,7 +115,7 @@ export const ToggleAlertFlyoutButtonComponent: React.FC = ({ items: [ { 'aria-label': ToggleFlyoutTranslations.openAlertContextPanelAriaLabel, - 'data-test-subj': 'xpack.uptime.openAlertContextPanel', + 'data-test-subj': 'xpack.synthetics.openAlertContextPanel', name: ToggleFlyoutTranslations.openAlertContextPanelLabel, icon: 'bell', panel: ALERT_CONTEXT_SELECT_TYPE_PANEL_ID, @@ -139,13 +139,13 @@ export const ToggleAlertFlyoutButtonComponent: React.FC = ({ setIsOpen(!isOpen)} > diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/translations.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/translations.ts new file mode 100644 index 0000000000000..0580528b6b38c --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/translations.ts @@ -0,0 +1,345 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const SECONDS_TIME_RANGE = i18n.translate( + 'xpack.synthetics.alerts.timerangeUnitSelectable.secondsOption.ariaLabel', + { + defaultMessage: '"Seconds" time range select item', + } +); + +export const SECONDS = i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.timerangeOption.seconds', + { + defaultMessage: 'seconds', + } +); + +export const MINUTES_TIME_RANGE = i18n.translate( + 'xpack.synthetics.alerts.timerangeUnitSelectable.minutesOption.ariaLabel', + { + defaultMessage: '"Minutes" time range select item', + } +); + +export const MINUTES = i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.timerangeOption.minutes', + { + defaultMessage: 'minutes', + } +); + +export const HOURS_TIME_RANGE = i18n.translate( + 'xpack.synthetics.alerts.timerangeUnitSelectable.hoursOption.ariaLabel', + { + defaultMessage: '"Hours" time range select item', + } +); + +export const HOURS = i18n.translate('xpack.synthetics.alerts.monitorStatus.timerangeOption.hours', { + defaultMessage: 'hours', +}); + +export const DAYS_TIME_RANGE = i18n.translate( + 'xpack.synthetics.alerts.timerangeUnitSelectable.daysOption.ariaLabel', + { + defaultMessage: '"Days" time range select item', + } +); + +export const DAYS = i18n.translate('xpack.synthetics.alerts.monitorStatus.timerangeOption.days', { + defaultMessage: 'days', +}); + +export const WEEKS_TIME_RANGE = i18n.translate( + 'xpack.synthetics.alerts.timerangeUnitSelectable.weeksOption.ariaLabel', + { + defaultMessage: '"Weeks" time range select item', + } +); + +export const WEEKS = i18n.translate('xpack.synthetics.alerts.monitorStatus.timerangeOption.weeks', { + defaultMessage: 'weeks', +}); + +export const MONTHS_TIME_RANGE = i18n.translate( + 'xpack.synthetics.alerts.timerangeUnitSelectable.monthsOption.ariaLabel', + { + defaultMessage: '"Months" time range select item', + } +); + +export const MONTHS = i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.timerangeOption.months', + { + defaultMessage: 'months', + } +); + +export const YEARS_TIME_RANGE = i18n.translate( + 'xpack.synthetics.alerts.timerangeUnitSelectable.yearsOption.ariaLabel', + { + defaultMessage: '"Years" time range select item', + } +); + +export const YEARS = i18n.translate('xpack.synthetics.alerts.monitorStatus.timerangeOption.years', { + defaultMessage: 'years', +}); + +export const ALERT_KUERY_BAR_ARIA = i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.filterBar.ariaLabel', + { + defaultMessage: 'Input that allows filtering criteria for the monitor status alert', + } +); + +export const OPEN_THE_POPOVER_DOWN_COUNT = i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.numTimesExpression.ariaLabel', + { + defaultMessage: 'Open the popover for down count input', + } +); + +export const ENTER_NUMBER_OF_DOWN_COUNTS = i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.numTimesField.ariaLabel', + { + defaultMessage: 'Enter number of down counts required to trigger the alert', + } +); + +export const MATCHING_MONITORS_DOWN = i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.numTimesExpression.matchingMonitors.description', + { + defaultMessage: 'matching monitors are down >', + } +); + +export const ANY_MONITOR_DOWN = i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.numTimesExpression.anyMonitors.description', + { + defaultMessage: 'any monitor is down >', + } +); + +export const OPEN_THE_POPOVER_TIME_RANGE_VALUE = i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.timerangeValueExpression.ariaLabel', + { + defaultMessage: 'Open the popover for time range value field', + } +); + +export const ENTER_NUMBER_OF_TIME_UNITS = i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.timerangeValueField.ariaLabel', + { + defaultMessage: `Enter the number of time units for the alert's range`, + } +); + +export const ENTER_NUMBER_OF_TIME_UNITS_DESCRIPTION = i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.timerangeValueField.expression', + { + defaultMessage: 'within', + } +); + +export const ENTER_NUMBER_OF_TIME_UNITS_VALUE = (value: number) => + i18n.translate('xpack.synthetics.alerts.monitorStatus.timerangeValueField.value', { + defaultMessage: 'last {value}', + values: { value }, + }); + +export const ENTER_AVAILABILITY_RANGE_ENABLED = i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.availability.isEnabledCheckbox.label', + { + defaultMessage: 'Availability', + } +); + +export const ENTER_AVAILABILITY_RANGE_POPOVER_ARIA_LABEL = i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.availability.timerangeValueField.popover.ariaLabel', + { + defaultMessage: 'Specify availability tracking time range', + } +); + +export const ENTER_AVAILABILITY_RANGE_UNITS_ARIA_LABEL = i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.availability.timerangeValueField.ariaLabel', + { + defaultMessage: `Enter the number of units for the alert's availability check.`, + } +); + +export const ENTER_AVAILABILITY_RANGE_UNITS_DESCRIPTION = i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.availability.timerangeValueField.expression', + { + defaultMessage: 'within the last', + } +); + +export const ENTER_AVAILABILITY_THRESHOLD_ARIA_LABEL = i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.availability.threshold.ariaLabel', + { + defaultMessage: 'Specify availability thresholds for this alert', + } +); + +export const ENTER_AVAILABILITY_THRESHOLD_INPUT_ARIA_LABEL = i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.availability.threshold.input.ariaLabel', + { + defaultMessage: 'Input an availability threshold to check for this alert', + } +); + +export const ENTER_AVAILABILITY_THRESHOLD_DESCRIPTION = i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.availability.threshold.description', + { + defaultMessage: 'matching monitors are up in', + description: + 'This fragment explains that an alert will fire for monitors matching user-specified criteria', + } +); + +export const ENTER_ANY_AVAILABILITY_THRESHOLD_DESCRIPTION = i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.availability.threshold.anyMonitorDescription', + { + defaultMessage: 'any monitor is up in', + description: + 'This fragment explains that an alert will fire for monitors matching user-specified criteria', + } +); + +export const ENTER_AVAILABILITY_THRESHOLD_VALUE = (value: string) => + i18n.translate('xpack.synthetics.alerts.monitorStatus.availability.threshold.value', { + defaultMessage: '< {value}% of checks', + description: + 'This fragment specifies criteria that will cause an alert to fire for uptime monitors', + values: { value }, + }); + +export const ENTER_AVAILABILITY_RANGE_SELECT_ARIA = i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.availability.unit.selectable', + { + defaultMessage: 'Use this select to set the availability range units for this alert', + } +); + +export const ENTER_AVAILABILITY_RANGE_SELECT_HEADLINE = i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.availability.unit.headline', + { + defaultMessage: 'Select time range unit', + } +); + +export const ADD_FILTER = i18n.translate('xpack.synthetics.alerts.monitorStatus.addFilter', { + defaultMessage: `Add filter`, +}); + +export const LOCATION = i18n.translate('xpack.synthetics.alerts.monitorStatus.addFilter.location', { + defaultMessage: `Location`, +}); + +export const TAG = i18n.translate('xpack.synthetics.alerts.monitorStatus.addFilter.tag', { + defaultMessage: `Tag`, +}); + +export const PORT = i18n.translate('xpack.synthetics.alerts.monitorStatus.addFilter.port', { + defaultMessage: `Port`, +}); + +export const TYPE = i18n.translate('xpack.synthetics.alerts.monitorStatus.addFilter.type', { + defaultMessage: `Type`, +}); + +export const TlsTranslations = { + criteriaAriaLabel: i18n.translate('xpack.synthetics.alerts.tls.criteriaExpression.ariaLabel', { + defaultMessage: + 'An expression displaying the criteria for monitor that are watched by this alert', + }), + criteriaDescription: i18n.translate( + 'xpack.synthetics.alerts.tls.criteriaExpression.description', + { + defaultMessage: 'when', + description: + 'The context of this `when` is in the conditional sense, like "when there are three cookies, eat them all".', + } + ), + criteriaValue: i18n.translate('xpack.synthetics.alerts.tls.criteriaExpression.value', { + defaultMessage: 'any monitor', + }), + expirationAriaLabel: i18n.translate( + 'xpack.synthetics.alerts.tls.expirationExpression.ariaLabel', + { + defaultMessage: + 'An expression displaying the threshold that will trigger the TLS alert for certificate expiration', + } + ), + expirationDescription: i18n.translate( + 'xpack.synthetics.alerts.tls.expirationExpression.description', + { + defaultMessage: 'has a certificate expiring within', + } + ), + expirationValue: (value?: number) => + i18n.translate('xpack.synthetics.alerts.tls.expirationExpression.value', { + defaultMessage: '{value} days', + values: { value }, + }), + ageAriaLabel: i18n.translate('xpack.synthetics.alerts.tls.ageExpression.ariaLabel', { + defaultMessage: + 'An expressing displaying the threshold that will trigger the TLS alert for old certificates', + }), + ageDescription: i18n.translate('xpack.synthetics.alerts.tls.ageExpression.description', { + defaultMessage: 'or older than', + }), + ageValue: (value?: number) => + i18n.translate('xpack.synthetics.alerts.tls.ageExpression.value', { + defaultMessage: '{value} days', + values: { value }, + }), +}; + +export const ToggleFlyoutTranslations = { + toggleButtonAriaLabel: i18n.translate('xpack.synthetics.alertsPopover.toggleButton.ariaLabel', { + defaultMessage: 'Open alerts and rules context menu', + }), + openAlertContextPanelAriaLabel: i18n.translate( + 'xpack.synthetics.openAlertContextPanel.ariaLabel', + { + defaultMessage: 'Open the rule context panel so you can choose a rule type', + } + ), + openAlertContextPanelLabel: i18n.translate('xpack.synthetics.openAlertContextPanel.label', { + defaultMessage: 'Create rule', + }), + toggleTlsAriaLabel: i18n.translate('xpack.synthetics.toggleTlsAlertButton.ariaLabel', { + defaultMessage: 'Open TLS rule flyout', + }), + toggleTlsContent: i18n.translate('xpack.synthetics.toggleTlsAlertButton.content', { + defaultMessage: 'TLS rule', + }), + toggleMonitorStatusAriaLabel: i18n.translate('xpack.synthetics.toggleAlertFlyout.ariaLabel', { + defaultMessage: 'Open add rule flyout', + }), + toggleMonitorStatusContent: i18n.translate('xpack.synthetics.toggleAlertButton.content', { + defaultMessage: 'Monitor status rule', + }), + navigateToAlertingUIAriaLabel: i18n.translate('xpack.synthetics.navigateToAlertingUi', { + defaultMessage: 'Leave Uptime and go to Alerting Management page', + }), + navigateToAlertingButtonContent: i18n.translate( + 'xpack.synthetics.navigateToAlertingButton.content', + { + defaultMessage: 'Manage rules', + } + ), + toggleAlertFlyoutButtonLabel: i18n.translate('xpack.synthetics.alerts.createRulesPanel.title', { + defaultMessage: 'Create rules', + }), +}; diff --git a/x-pack/plugins/synthetics/public/components/overview/alerts/uptime_alerts_flyout_wrapper.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/uptime_alerts_flyout_wrapper.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/alerts/uptime_alerts_flyout_wrapper.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/uptime_alerts_flyout_wrapper.tsx diff --git a/x-pack/plugins/synthetics/public/components/overview/empty_state/empty_state_error.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/empty_state/empty_state_error.tsx similarity index 91% rename from x-pack/plugins/synthetics/public/components/overview/empty_state/empty_state_error.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/empty_state/empty_state_error.tsx index bf1459cbcd789..3f2150169e2df 100644 --- a/x-pack/plugins/synthetics/public/components/overview/empty_state/empty_state_error.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/empty_state/empty_state_error.tsx @@ -30,14 +30,14 @@ export const EmptyStateError = ({ errors }: EmptyStateErrorProps) => { {unauthorized ? (

- {i18n.translate('xpack.uptime.emptyStateError.notAuthorized', { + {i18n.translate('xpack.synthetics.emptyStateError.notAuthorized', { defaultMessage: 'You are not authorized to view Uptime data, please contact your system administrator.', })}

) : (

- {i18n.translate('xpack.uptime.emptyStateError.title', { + {i18n.translate('xpack.synthetics.emptyStateError.title', { defaultMessage: 'Error', })}

diff --git a/x-pack/plugins/synthetics/public/components/overview/empty_state/empty_state_loading.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/empty_state/empty_state_loading.tsx similarity index 90% rename from x-pack/plugins/synthetics/public/components/overview/empty_state/empty_state_loading.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/empty_state/empty_state_loading.tsx index 0943f581f049b..0f71c9bafa962 100644 --- a/x-pack/plugins/synthetics/public/components/overview/empty_state/empty_state_loading.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/empty_state/empty_state_loading.tsx @@ -17,7 +17,7 @@ export const EmptyStateLoading = () => (

- {i18n.translate('xpack.uptime.emptyState.loadingMessage', { + {i18n.translate('xpack.synthetics.emptyState.loadingMessage', { defaultMessage: 'Loading…', })}

diff --git a/x-pack/plugins/synthetics/public/components/overview/empty_state/use_has_data.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/empty_state/use_has_data.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/empty_state/use_has_data.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/empty_state/use_has_data.tsx diff --git a/x-pack/plugins/synthetics/public/components/overview/filter_group/filter_group.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/filter_group/filter_group.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/filter_group/filter_group.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/filter_group/filter_group.test.tsx diff --git a/x-pack/plugins/synthetics/public/components/overview/filter_group/filter_group.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/filter_group/filter_group.tsx similarity index 90% rename from x-pack/plugins/synthetics/public/components/overview/filter_group/filter_group.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/filter_group/filter_group.tsx index d73c2df73919b..16ab92a6862c2 100644 --- a/x-pack/plugins/synthetics/public/components/overview/filter_group/filter_group.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/filter_group/filter_group.tsx @@ -13,9 +13,9 @@ import { FieldValueSuggestions, useInspectorContext } from '@kbn/observability-p import { useFilterUpdate } from '../../../hooks/use_filter_update'; import { useSelectedFilters } from '../../../hooks/use_selected_filters'; import { SelectedFilters } from './selected_filters'; -import { useIndexPattern } from '../../../contexts/uptime_index_pattern_context'; +import { useUptimeDataView } from '../../../contexts/uptime_data_view_context'; import { useGetUrlParams } from '../../../hooks'; -import { EXCLUDE_RUN_ONCE_FILTER } from '../../../../common/constants/client_defaults'; +import { EXCLUDE_RUN_ONCE_FILTER } from '../../../../../common/constants/client_defaults'; const Container = styled(EuiFilterGroup)` margin-bottom: 10px; @@ -40,7 +40,7 @@ export const FilterGroup = () => { const { filtersList } = useSelectedFilters(); - const indexPattern = useIndexPattern(); + const dataView = useUptimeDataView(); const onFilterFieldChange = useCallback( (fieldName: string, values: string[], notValues: string[]) => { @@ -52,12 +52,12 @@ export const FilterGroup = () => { return ( <> - {indexPattern && + {dataView && filtersList.map(({ field, label, selectedItems, excludedItems }) => ( void; } export const SelectedFilters = ({ onChange }: Props) => { - const indexPattern = useIndexPattern(); + const dataView = useUptimeDataView(); const { filtersList } = useSelectedFilters(); - if (!indexPattern) return null; + if (!dataView) return null; return ( @@ -26,7 +26,7 @@ export const SelectedFilters = ({ onChange }: Props) => { ...selectedItems.map((value) => ( { onChange( field, @@ -51,7 +51,7 @@ export const SelectedFilters = ({ onChange }: Props) => { ...excludedItems.map((value) => ( { onChange( field, diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/filter_group/translations.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/filter_group/translations.tsx new file mode 100644 index 0000000000000..e1cf5e20e14c3 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/filter_group/translations.tsx @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const filterLabels = { + LOCATION: i18n.translate('xpack.synthetics.filterBar.options.location.name', { + defaultMessage: 'Location', + }), + + PORT: i18n.translate('xpack.synthetics.filterBar.options.portLabel', { defaultMessage: 'Port' }), + + SCHEME: i18n.translate('xpack.synthetics.filterBar.options.schemeLabel', { + defaultMessage: 'Scheme', + }), + + TAG: i18n.translate('xpack.synthetics.filterBar.options.tagsLabel', { + defaultMessage: 'Tag', + }), +}; diff --git a/x-pack/plugins/synthetics/public/components/overview/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/index.ts similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/index.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/index.ts diff --git a/x-pack/plugins/synthetics/public/components/overview/monitor_list/__snapshots__/filter_status_button.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/__snapshots__/filter_status_button.test.tsx.snap similarity index 100% rename from x-pack/plugins/synthetics/public/components/overview/monitor_list/__snapshots__/filter_status_button.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/__snapshots__/filter_status_button.test.tsx.snap diff --git a/x-pack/plugins/synthetics/public/components/overview/monitor_list/__snapshots__/status_filter.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/__snapshots__/status_filter.test.tsx.snap similarity index 95% rename from x-pack/plugins/synthetics/public/components/overview/monitor_list/__snapshots__/status_filter.test.tsx.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/__snapshots__/status_filter.test.tsx.snap index ed344510c1cd7..98a60c79ca490 100644 --- a/x-pack/plugins/synthetics/public/components/overview/monitor_list/__snapshots__/status_filter.test.tsx.snap +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/__snapshots__/status_filter.test.tsx.snap @@ -6,7 +6,7 @@ exports[`StatusFilterComponent renders without errors for valid props 1`] = ` >

} + body={

{PUBLIC_BETA_DESCRIPTION}

} + actions={[ + + {REQUEST_ACCESS_LABEL} + , + ]} + /> + ); + } + + return ( + <> + {loading && ( + } + title={

{LOADING_MONITOR_MANAGEMENT_LABEL}

} + /> + )} +
{children}
+ + ); +}; + +const REQUEST_ACCESS_LABEL = i18n.translate('xpack.synthetics.monitorManagement.requestAccess', { + defaultMessage: 'Request access', +}); + +export const MONITOR_MANAGEMENT_LABEL = i18n.translate('xpack.synthetics.monitorManagement.label', { + defaultMessage: 'Monitor Management', +}); + +const LOADING_MONITOR_MANAGEMENT_LABEL = i18n.translate( + 'xpack.synthetics.monitorManagement.loading.label', + { + defaultMessage: 'Loading Monitor Management', + } +); + +export const PUBLIC_BETA_DESCRIPTION = i18n.translate( + 'xpack.synthetics.monitorManagement.publicBetaDescription', + { + defaultMessage: + "We've got a brand new app on the way. In the meantime, we're excited to give you early access to our globally managed testing infrastructure. This will allow you to upload synthetic monitors using our new point and click script recorder and manage your monitors with a new UI.", + } +); diff --git a/x-pack/plugins/synthetics/public/pages/monitor_management/use_monitor_management_breadcrumbs.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/pages/monitor_management/use_monitor_management_breadcrumbs.tsx similarity index 76% rename from x-pack/plugins/synthetics/public/pages/monitor_management/use_monitor_management_breadcrumbs.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/pages/monitor_management/use_monitor_management_breadcrumbs.tsx index 7fd6cc421c3b6..2c7a4fe7a8259 100644 --- a/x-pack/plugins/synthetics/public/pages/monitor_management/use_monitor_management_breadcrumbs.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/pages/monitor_management/use_monitor_management_breadcrumbs.tsx @@ -7,8 +7,8 @@ import { i18n } from '@kbn/i18n'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { useBreadcrumbs } from '../../hooks/use_breadcrumbs'; -import { MONITOR_MANAGEMENT_ROUTE } from '../../../common/constants'; -import { PLUGIN } from '../../../common/constants/plugin'; +import { MONITOR_MANAGEMENT_ROUTE } from '../../../../common/constants'; +import { PLUGIN } from '../../../../common/constants/plugin'; export const useMonitorManagementBreadcrumbs = ({ isAddMonitor, @@ -46,18 +46,21 @@ export const useMonitorManagementBreadcrumbs = ({ }; export const MONITOR_MANAGEMENT_CRUMB = i18n.translate( - 'xpack.uptime.monitorManagement.monitorManagementCrumb', + 'xpack.synthetics.monitorManagement.monitorManagementCrumb', { defaultMessage: 'Monitor Management', } ); -export const ADD_MONITOR_CRUMB = i18n.translate('xpack.uptime.monitorManagement.addMonitorCrumb', { - defaultMessage: 'Add monitor', -}); +export const ADD_MONITOR_CRUMB = i18n.translate( + 'xpack.synthetics.monitorManagement.addMonitorCrumb', + { + defaultMessage: 'Add monitor', + } +); export const EDIT_MONITOR_CRUMB = i18n.translate( - 'xpack.uptime.monitorManagement.editMonitorCrumb', + 'xpack.synthetics.monitorManagement.editMonitorCrumb', { defaultMessage: 'Edit monitor', } diff --git a/x-pack/plugins/synthetics/public/pages/not_found.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/pages/not_found.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/pages/not_found.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/pages/not_found.test.tsx diff --git a/x-pack/plugins/synthetics/public/pages/not_found.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/pages/not_found.tsx similarity index 90% rename from x-pack/plugins/synthetics/public/pages/not_found.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/pages/not_found.tsx index 936781323256f..c94a7a7a06b6a 100644 --- a/x-pack/plugins/synthetics/public/pages/not_found.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/pages/not_found.tsx @@ -31,7 +31,7 @@ export const NotFoundPage = () => {

@@ -40,7 +40,7 @@ export const NotFoundPage = () => { } diff --git a/x-pack/plugins/synthetics/public/pages/overview.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/pages/overview.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/pages/overview.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/pages/overview.test.tsx diff --git a/x-pack/plugins/synthetics/public/pages/overview.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/pages/overview.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/pages/overview.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/pages/overview.tsx diff --git a/x-pack/plugins/synthetics/public/pages/settings.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/pages/settings.test.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/pages/settings.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/pages/settings.test.tsx diff --git a/x-pack/plugins/synthetics/public/pages/settings.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/pages/settings.tsx similarity index 97% rename from x-pack/plugins/synthetics/public/pages/settings.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/pages/settings.tsx index a12b615bb703d..6726a10ab8747 100644 --- a/x-pack/plugins/synthetics/public/pages/settings.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/pages/settings.tsx @@ -11,7 +11,7 @@ import { useDispatch, useSelector } from 'react-redux'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { selectDynamicSettings } from '../state/selectors'; import { getDynamicSettings, setDynamicSettings } from '../state/actions/dynamic_settings'; -import { DynamicSettings } from '../../common/runtime_types'; +import { DynamicSettings } from '../../../common/runtime_types'; import { useBreadcrumbs } from '../hooks/use_breadcrumbs'; import { IndicesForm } from '../components/settings/indices_form'; import { @@ -23,7 +23,7 @@ import * as Translations from './translations'; import { VALUE_MUST_BE_GREATER_THAN_ZERO, VALUE_MUST_BE_AN_INTEGER, -} from '../../common/translations'; +} from '../../../common/translations'; import { AlertDefaultsForm } from '../components/settings/alert_defaults_form'; import { SettingsActionBarPortal } from '../components/settings/settings_bottom_bar'; import { useSettingsErrors } from '../components/settings/use_settings_errors'; diff --git a/x-pack/plugins/synthetics/public/pages/synthetics/checks_navigation.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/pages/synthetics/checks_navigation.tsx similarity index 90% rename from x-pack/plugins/synthetics/public/pages/synthetics/checks_navigation.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/pages/synthetics/checks_navigation.tsx index 63e8ff6f45654..ee33191c3799e 100644 --- a/x-pack/plugins/synthetics/public/pages/synthetics/checks_navigation.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/pages/synthetics/checks_navigation.tsx @@ -10,7 +10,7 @@ import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui import { FormattedMessage } from '@kbn/i18n-react'; import { useHistory } from 'react-router-dom'; import moment from 'moment'; -import { SyntheticsJourneyApiResponse } from '../../../common/runtime_types/ping'; +import { SyntheticsJourneyApiResponse } from '../../../../common/runtime_types/ping'; import { getShortTimeStamp } from '../../components/overview/monitor_list/columns/monitor_status_column'; import { useBreakpoints } from '../../hooks/use_breakpoints'; @@ -37,7 +37,7 @@ export const ChecksNavigation = ({ timestamp, details }: Props) => { }} > @@ -58,7 +58,7 @@ export const ChecksNavigation = ({ timestamp, details }: Props) => { }} > diff --git a/x-pack/plugins/synthetics/public/pages/synthetics/step_detail_page.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/pages/synthetics/step_detail_page.tsx similarity index 98% rename from x-pack/plugins/synthetics/public/pages/synthetics/step_detail_page.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/pages/synthetics/step_detail_page.tsx index 2ded527f7bb57..7caa521e434f4 100644 --- a/x-pack/plugins/synthetics/public/pages/synthetics/step_detail_page.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/pages/synthetics/step_detail_page.tsx @@ -14,7 +14,7 @@ import { useInitApp } from '../../hooks/use_init_app'; import { StepDetailContainer } from '../../components/monitor/synthetics/step_detail/step_detail_container'; import { journeySelector } from '../../state/selectors'; import { JourneyState } from '../../state/reducers/journey'; -import { JourneyStep } from '../../../common/runtime_types/ping/synthetics'; +import { JourneyStep } from '../../../../common/runtime_types/ping/synthetics'; import { StepPageNavigation } from '../../components/monitor/synthetics/step_detail/step_page_nav'; import { StepPageTitleContent } from '../../components/monitor/synthetics/step_detail/step_page_title'; import { getJourneySteps } from '../../state/actions/journey'; diff --git a/x-pack/plugins/synthetics/public/pages/synthetics/synthetics_checks.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/pages/synthetics/synthetics_checks.test.tsx similarity index 98% rename from x-pack/plugins/synthetics/public/pages/synthetics/synthetics_checks.test.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/pages/synthetics/synthetics_checks.test.tsx index 290cdd453bd3c..312c10886c572 100644 --- a/x-pack/plugins/synthetics/public/pages/synthetics/synthetics_checks.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/pages/synthetics/synthetics_checks.test.tsx @@ -14,7 +14,7 @@ import { } from './synthetics_checks'; import { fetchJourneySteps } from '../../state/api/journey'; import { createMemoryHistory } from 'history'; -import { SYNTHETIC_CHECK_STEPS_ROUTE } from '../../../common/constants'; +import { SYNTHETIC_CHECK_STEPS_ROUTE } from '../../../../common/constants'; jest.mock('../../state/api/journey', () => ({ fetchJourneySteps: jest.fn(), diff --git a/x-pack/plugins/synthetics/public/pages/synthetics/synthetics_checks.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/pages/synthetics/synthetics_checks.tsx similarity index 100% rename from x-pack/plugins/synthetics/public/pages/synthetics/synthetics_checks.tsx rename to x-pack/plugins/synthetics/public/legacy_uptime/pages/synthetics/synthetics_checks.tsx diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/pages/translations.ts b/x-pack/plugins/synthetics/public/legacy_uptime/pages/translations.ts new file mode 100644 index 0000000000000..c0c57a3838a25 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/pages/translations.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const REFRESH_CERT = i18n.translate('xpack.synthetics.certificates.refresh', { + defaultMessage: 'Refresh', +}); + +export const settings = { + breadcrumbText: i18n.translate('xpack.synthetics.settingsBreadcrumbText', { + defaultMessage: 'Settings', + }), + editNoticeTitle: i18n.translate('xpack.synthetics.settings.cannotEditTitle', { + defaultMessage: 'You do not have permission to edit settings.', + }), + editNoticeText: i18n.translate('xpack.synthetics.settings.cannotEditText', { + defaultMessage: + "Your user currently has 'Read' permissions for the Uptime app. Enable a permissions-level of 'All' to edit these settings.", + }), + mustBeNumber: i18n.translate('xpack.synthetics.settings.blankNumberField.error', { + defaultMessage: 'Must be a number.', + }), +}; + +export const BLANK_STR = i18n.translate('xpack.synthetics.settings.blank.error', { + defaultMessage: 'May not be blank.', +}); + +export const SPACE_STR = i18n.translate('xpack.synthetics.settings.noSpace.error', { + defaultMessage: 'Index names must not contain space', +}); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/routes.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/routes.tsx new file mode 100644 index 0000000000000..1b8706ad4cb00 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/routes.tsx @@ -0,0 +1,329 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { FC, useEffect } from 'react'; +import { EuiPageTemplateProps, EuiBetaBadge, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { Route, Switch } from 'react-router-dom'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { i18n } from '@kbn/i18n'; +import { APP_WRAPPER_CLASS } from '@kbn/core/public'; +import { useInspectorContext } from '@kbn/observability-plugin/public'; +import { + CERTIFICATES_ROUTE, + MAPPING_ERROR_ROUTE, + MONITOR_ROUTE, + MONITOR_ADD_ROUTE, + MONITOR_EDIT_ROUTE, + MONITOR_MANAGEMENT_ROUTE, + OVERVIEW_ROUTE, + SETTINGS_ROUTE, + STEP_DETAIL_ROUTE, + SYNTHETIC_CHECK_STEPS_ROUTE, +} from '../../common/constants'; +import { + MappingErrorPage, + MonitorPage, + AddMonitorPage, + EditMonitorPage, + MonitorManagementPage, + StepDetailPage, + NotFoundPage, + SettingsPage, + MonitorManagementBottomBar, +} from './pages'; +import { CertificatesPage } from './pages/certificates'; +import { UptimePage, useUptimeTelemetry } from './hooks'; +import { OverviewPageComponent } from './pages/overview'; +import { + SyntheticsCheckSteps, + SyntheticsCheckStepsPageHeader, + SyntheticsCheckStepsPageRightSideItem, +} from './pages/synthetics/synthetics_checks'; +import { MonitorPageTitle, MonitorPageTitleContent } from './components/monitor/monitor_title'; +import { UptimeDatePicker } from './components/common/uptime_date_picker'; +import { CertRefreshBtn } from './components/certificates/cert_refresh_btn'; +import { CertificateTitle } from './components/certificates/certificate_title'; +import { SyntheticsCallout } from './components/overview/synthetics_callout'; +import { + StepDetailPageChildren, + StepDetailPageHeader, + StepDetailPageRightSideItem, +} from './pages/synthetics/step_detail_page'; +import { UptimePageTemplateComponent } from './app/uptime_page_template'; +import { apiService } from './state/api/utils'; +import { AddMonitorBtn } from './components/monitor_management/add_monitor_btn'; +import { SettingsBottomBar } from './components/settings/settings_bottom_bar'; +import { ServiceAllowedWrapper } from './pages/monitor_management/service_allowed_wrapper'; + +type RouteProps = { + path: string; + component: React.FC; + dataTestSubj: string; + title: string; + telemetryId: UptimePage; + pageHeader: { + pageTitle: string | JSX.Element; + children?: JSX.Element; + rightSideItems?: JSX.Element[]; + }; +} & EuiPageTemplateProps; + +const baseTitle = i18n.translate('xpack.synthetics.routes.baseTitle', { + defaultMessage: 'Uptime - Kibana', +}); + +export const MONITORING_OVERVIEW_LABEL = i18n.translate('xpack.synthetics.overview.heading', { + defaultMessage: 'Monitors', +}); + +const getRoutes = (): RouteProps[] => { + return [ + { + title: i18n.translate('xpack.synthetics.monitorRoute.title', { + defaultMessage: 'Monitor | {baseTitle}', + values: { baseTitle }, + }), + path: MONITOR_ROUTE, + component: MonitorPage, + dataTestSubj: 'uptimeMonitorPage', + telemetryId: UptimePage.Monitor, + pageHeader: { + children: , + pageTitle: , + rightSideItems: [], + }, + }, + { + title: i18n.translate('xpack.synthetics.settingsRoute.title', { + defaultMessage: `Settings | {baseTitle}`, + values: { baseTitle }, + }), + path: SETTINGS_ROUTE, + component: SettingsPage, + dataTestSubj: 'uptimeSettingsPage', + telemetryId: UptimePage.Settings, + pageHeader: { + pageTitle: ( + + ), + }, + bottomBar: , + bottomBarProps: { paddingSize: 'm' as const }, + }, + { + title: i18n.translate('xpack.synthetics.certificatesRoute.title', { + defaultMessage: `Certificates | {baseTitle}`, + values: { baseTitle }, + }), + path: CERTIFICATES_ROUTE, + component: CertificatesPage, + dataTestSubj: 'uptimeCertificatesPage', + telemetryId: UptimePage.Certificates, + pageHeader: { + pageTitle: , + rightSideItems: [], + }, + }, + { + title: i18n.translate('xpack.synthetics.stepDetailRoute.title', { + defaultMessage: 'Synthetics detail | {baseTitle}', + values: { baseTitle }, + }), + path: STEP_DETAIL_ROUTE, + component: StepDetailPage, + dataTestSubj: 'uptimeStepDetailPage', + telemetryId: UptimePage.StepDetail, + pageHeader: { + children: , + pageTitle: , + rightSideItems: [], + }, + }, + { + title: baseTitle, + path: SYNTHETIC_CHECK_STEPS_ROUTE, + component: SyntheticsCheckSteps, + dataTestSubj: 'uptimeSyntheticCheckStepsPage', + telemetryId: UptimePage.SyntheticCheckStepsPage, + pageHeader: { + pageTitle: , + rightSideItems: [], + }, + }, + { + title: baseTitle, + path: OVERVIEW_ROUTE, + component: OverviewPageComponent, + dataTestSubj: 'uptimeOverviewPage', + telemetryId: UptimePage.Overview, + pageHeader: { + pageTitle: MONITORING_OVERVIEW_LABEL, + rightSideItems: [], + }, + }, + { + title: i18n.translate('xpack.synthetics.mappingErrorRoute.title', { + defaultMessage: 'Synthetics | mapping error', + }), + path: MAPPING_ERROR_ROUTE, + component: MappingErrorPage, + dataTestSubj: 'uptimeMappingErrorPage', + telemetryId: UptimePage.MappingError, + pageHeader: { + pageTitle: ( +
+ +
+ ), + rightSideItems: [], + }, + }, + { + title: i18n.translate('xpack.synthetics.addMonitorRoute.title', { + defaultMessage: 'Add Monitor | {baseTitle}', + values: { baseTitle }, + }), + path: MONITOR_ADD_ROUTE, + component: () => ( + + + + ), + dataTestSubj: 'uptimeMonitorAddPage', + telemetryId: UptimePage.MonitorAdd, + pageHeader: { + pageTitle: ( + + ), + }, + bottomBar: , + bottomBarProps: { paddingSize: 'm' as const }, + }, + { + title: i18n.translate('xpack.synthetics.editMonitorRoute.title', { + defaultMessage: 'Edit Monitor | {baseTitle}', + values: { baseTitle }, + }), + path: MONITOR_EDIT_ROUTE, + component: () => ( + + + + ), + dataTestSubj: 'uptimeMonitorEditPage', + telemetryId: UptimePage.MonitorEdit, + pageHeader: { + pageTitle: ( + + ), + }, + bottomBar: , + bottomBarProps: { paddingSize: 'm' as const }, + }, + { + title: i18n.translate('xpack.synthetics.monitorManagementRoute.title', { + defaultMessage: 'Monitor Management | {baseTitle}', + values: { baseTitle }, + }), + path: MONITOR_MANAGEMENT_ROUTE + '/:type', + component: () => ( + + + + ), + dataTestSubj: 'uptimeMonitorManagementListPage', + telemetryId: UptimePage.MonitorManagement, + pageHeader: { + pageTitle: ( + + + + + + + + + ), + rightSideItems: [], + }, + }, + ]; +}; + +const RouteInit: React.FC> = ({ + path, + title, + telemetryId, +}) => { + useUptimeTelemetry(telemetryId); + useEffect(() => { + document.title = title; + }, [path, title]); + return null; +}; + +export const PageRouter: FC = () => { + const routes = getRoutes(); + const { addInspectorRequest } = useInspectorContext(); + + apiService.addInspectorRequest = addInspectorRequest; + + return ( + + {routes.map( + ({ + title, + path, + component: RouteComponent, + dataTestSubj, + telemetryId, + pageHeader, + ...pageTemplateProps + }) => ( + +
+ + + + + +
+
+ ) + )} + +
+ ); +}; diff --git a/x-pack/plugins/synthetics/public/state/actions/alerts.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/alerts.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/actions/alerts.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/actions/alerts.ts diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/dynamic_settings.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/dynamic_settings.ts new file mode 100644 index 0000000000000..6be8cc4547559 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/dynamic_settings.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createAction } from 'redux-actions'; +import { DynamicSettings } from '../../../../common/runtime_types'; + +export const getDynamicSettings = createAction('GET_DYNAMIC_SETTINGS'); +export const getDynamicSettingsSuccess = createAction( + 'GET_DYNAMIC_SETTINGS_SUCCESS' +); +export const getDynamicSettingsFail = createAction('GET_DYNAMIC_SETTINGS_FAIL'); + +export const setDynamicSettings = createAction('SET_DYNAMIC_SETTINGS'); +export const setDynamicSettingsSuccess = createAction( + 'SET_DYNAMIC_SETTINGS_SUCCESS' +); +export const setDynamicSettingsFail = createAction('SET_DYNAMIC_SETTINGS_FAIL'); diff --git a/x-pack/plugins/synthetics/public/state/actions/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/index.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/actions/index.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/actions/index.ts diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/index_status.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/index_status.ts new file mode 100644 index 0000000000000..2de91a82c6762 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/index_status.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createAsyncAction } from './utils'; +import { StatesIndexStatus } from '../../../../common/runtime_types'; + +export const indexStatusAction = createAsyncAction('GET INDEX STATUS'); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/journey.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/journey.ts new file mode 100644 index 0000000000000..c9833ee25f95d --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/journey.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createAction } from 'redux-actions'; +import { SyntheticsJourneyApiResponse } from '../../../../common/runtime_types'; + +export interface FetchJourneyStepsParams { + checkGroup: string; + syntheticEventTypes?: string[]; +} + +export interface GetJourneyFailPayload { + checkGroup: string; + error: Error; +} + +export const getJourneySteps = createAction('GET_JOURNEY_STEPS'); +export const getJourneyStepsSuccess = createAction( + 'GET_JOURNEY_STEPS_SUCCESS' +); +export const getJourneyStepsFail = createAction('GET_JOURNEY_STEPS_FAIL'); +export const pruneJourneyState = createAction('PRUNE_JOURNEY_STATE'); diff --git a/x-pack/plugins/synthetics/public/state/actions/ml_anomaly.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/ml_anomaly.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/actions/ml_anomaly.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/actions/ml_anomaly.ts diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/monitor.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/monitor.ts new file mode 100644 index 0000000000000..5fd74737d96a7 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/monitor.ts @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createAction } from 'redux-actions'; +import { MonitorDetailsActionPayload } from './types'; +import { PingError } from '../../../../common/runtime_types'; +import { MonitorLocations } from '../../../../common/runtime_types'; +import { QueryParams } from './types'; +import { createAsyncAction } from './utils'; + +export interface MonitorLocationsPayload extends QueryParams { + monitorId: string; +} + +export interface MonitorDetailsState { + monitorId: string; + error: PingError; +} + +export const getMonitorDetailsAction = createAsyncAction< + MonitorDetailsActionPayload, + MonitorDetailsState +>('GET_MONITOR_DETAILS'); + +export const getMonitorLocationsAction = + createAction('GET_MONITOR_LOCATIONS'); +export const getMonitorLocationsActionSuccess = createAction( + 'GET_MONITOR_LOCATIONS_SUCCESS' +); +export const getMonitorLocationsActionFail = createAction('GET_MONITOR_LOCATIONS_FAIL'); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/monitor_duration.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/monitor_duration.ts new file mode 100644 index 0000000000000..52583e79f9ec3 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/monitor_duration.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createAction } from 'redux-actions'; +import { IHttpFetchError } from '@kbn/core/public'; +import { QueryParams } from './types'; +import { MonitorDurationResult } from '../../../../common/types'; + +type MonitorQueryParams = QueryParams & { monitorId: string }; + +export const getMonitorDurationAction = createAction('GET_MONITOR_DURATION'); +export const getMonitorDurationActionSuccess = createAction( + 'GET_MONITOR_DURATION_SUCCESS' +); +export const getMonitorDurationActionFail = createAction( + 'GET_MONITOR_DURATION_FAIL' +); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/monitor_list.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/monitor_list.ts new file mode 100644 index 0000000000000..c123ca95a5acd --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/monitor_list.ts @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createAction } from 'redux-actions'; +import { + FetchMonitorStatesQueryArgs, + MonitorSummariesResult, +} from '../../../../common/runtime_types'; +import { createAsyncAction } from './utils'; +import { TestNowResponse } from '../api'; + +export const getMonitorList = createAction('GET_MONITOR_LIST'); +export const getMonitorListSuccess = createAction( + 'GET_MONITOR_LIST_SUCCESS' +); +export const getMonitorListFailure = createAction('GET_MONITOR_LIST_FAIL'); + +export const setUpdatingMonitorId = createAction('SET_UPDATING_MONITOR_ID'); +export const clearRefreshedMonitorId = createAction('CLEAR_REFRESH_MONITOR_ID'); + +export const testNowMonitorAction = createAsyncAction( + 'TEST_NOW_MONITOR_ACTION' +); + +export const clearTestNowMonitorAction = createAction('CLEAR_TEST_NOW_MONITOR_ACTION'); + +export const getUpdatedMonitor = createAsyncAction< + FetchMonitorStatesQueryArgs, + MonitorSummariesResult +>('GET_UPDATED_MONITOR'); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/monitor_management.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/monitor_management.ts new file mode 100644 index 0000000000000..79bec6f3e1b65 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/monitor_management.ts @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createAction } from '@reduxjs/toolkit'; +import { + MonitorManagementListResult, + ServiceLocations, + ThrottlingOptions, + FetchMonitorManagementListQueryArgs, +} from '../../../../common/runtime_types'; +import { createAsyncAction } from './utils'; +import { SyntheticsServiceAllowed } from '../../../../common/types'; + +export const getMonitors = createAction( + 'GET_MONITOR_MANAGEMENT_LIST' +); +export const getMonitorsSuccess = createAction( + 'GET_MONITOR_MANAGEMENT_LIST_SUCCESS' +); +export const getMonitorsFailure = createAction('GET_MONITOR_MANAGEMENT_LIST_FAILURE'); + +export const getServiceLocations = createAction('GET_SERVICE_LOCATIONS_LIST'); +export const getServiceLocationsSuccess = createAction<{ + throttling: ThrottlingOptions | undefined; + locations: ServiceLocations; +}>('GET_SERVICE_LOCATIONS_LIST_SUCCESS'); +export const getServiceLocationsFailure = createAction('GET_SERVICE_LOCATIONS_LIST_FAILURE'); + +export const getSyntheticsEnablement = createAction('GET_SYNTHETICS_ENABLEMENT'); +export const getSyntheticsEnablementSuccess = createAction( + 'GET_SYNTHETICS_ENABLEMENT_SUCCESS' +); +export const getSyntheticsEnablementFailure = createAction( + 'GET_SYNTHETICS_ENABLEMENT_FAILURE' +); + +export const disableSynthetics = createAction('DISABLE_SYNTHETICS'); +export const disableSyntheticsSuccess = createAction('DISABLE_SYNTEHTICS_SUCCESS'); +export const disableSyntheticsFailure = createAction('DISABLE_SYNTHETICS_FAILURE'); + +export const enableSynthetics = createAction('ENABLE_SYNTHETICS'); +export const enableSyntheticsSuccess = createAction('ENABLE_SYNTEHTICS_SUCCESS'); +export const enableSyntheticsFailure = createAction('ENABLE_SYNTHETICS_FAILURE'); + +export const getSyntheticsServiceAllowed = createAsyncAction( + 'GET_SYNTHETICS_SERVICE_ALLOWED' +); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/monitor_status.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/monitor_status.ts new file mode 100644 index 0000000000000..e9fcf67a7b678 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/monitor_status.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createAction } from 'redux-actions'; +import { QueryParams } from './types'; +import { Ping } from '../../../../common/runtime_types'; + +export const getMonitorStatusAction = createAction('GET_MONITOR_STATUS'); +export const getMonitorStatusActionSuccess = createAction('GET_MONITOR_STATUS_SUCCESS'); +export const getMonitorStatusActionFail = createAction('GET_MONITOR_STATUS_FAIL'); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/network_events.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/network_events.ts new file mode 100644 index 0000000000000..1467289abe1e8 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/network_events.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createAction } from 'redux-actions'; +import { SyntheticsNetworkEventsApiResponse } from '../../../../common/runtime_types'; + +export interface FetchNetworkEventsParams { + checkGroup: string; + stepIndex: number; +} + +export interface FetchNetworkEventsFailPayload { + checkGroup: string; + stepIndex: number; + error: Error; +} + +export const getNetworkEvents = createAction('GET_NETWORK_EVENTS'); +export const getNetworkEventsSuccess = createAction< + Pick & SyntheticsNetworkEventsApiResponse +>('GET_NETWORK_EVENTS_SUCCESS'); +export const getNetworkEventsFail = + createAction('GET_NETWORK_EVENTS_FAIL'); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/ping.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/ping.ts new file mode 100644 index 0000000000000..73be085a86e03 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/ping.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createAction } from 'redux-actions'; +import { + GetPingHistogramParams, + HistogramResult, + PingsResponse, + GetPingsParams, +} from '../../../../common/runtime_types'; +import { createAsyncAction } from './utils'; + +export const clearPings = createAction('CLEAR PINGS'); + +export const getPingHistogram = createAsyncAction( + 'GET_PING_HISTOGRAM' +); + +export const getPings = createAction('GET PINGS'); +export const getPingsSuccess = createAction('GET PINGS SUCCESS'); +export const getPingsFail = createAction('GET PINGS FAIL'); diff --git a/x-pack/plugins/synthetics/public/state/actions/selected_filters.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/selected_filters.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/actions/selected_filters.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/actions/selected_filters.ts diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/snapshot.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/snapshot.ts new file mode 100644 index 0000000000000..a495c917223a2 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/snapshot.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Snapshot } from '../../../../common/runtime_types'; +import { createAsyncAction } from './utils'; +import { SnapShotQueryParams } from '../api'; + +export const getSnapshotCountAction = createAsyncAction( + 'GET_SNAPSHOT_COUNT' +); diff --git a/x-pack/plugins/synthetics/public/state/actions/types.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/types.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/actions/types.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/actions/types.ts diff --git a/x-pack/plugins/synthetics/public/state/actions/ui.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/ui.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/actions/ui.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/actions/ui.ts diff --git a/x-pack/plugins/synthetics/public/state/actions/utils.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/actions/utils.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/actions/utils.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/actions/utils.ts diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/alerts/alerts.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/alerts/alerts.ts new file mode 100644 index 0000000000000..56ee6339d1331 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/alerts/alerts.ts @@ -0,0 +1,175 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { handleActions, Action } from 'redux-actions'; +import { call, put, select, takeLatest } from 'redux-saga/effects'; +import type { + ActionConnector as RawActionConnector, + Rule, +} from '@kbn/triggers-actions-ui-plugin/public'; +import { createAsyncAction } from '../actions/utils'; +import { asyncInitState, handleAsyncAction } from '../reducers/utils'; +import type { AppState } from '..'; +import { AsyncInitState } from '../reducers/types'; +import { fetchEffectFactory } from '../effects/fetch_effect'; +import { + createAlert, + disableAlertById, + fetchAlertRecords, + fetchConnectors, + fetchMonitorAlertRecords, + NewAlertParams, +} from '../api/alerts'; +import { kibanaService } from '../kibana_service'; +import { monitorIdSelector } from '../selectors'; +import { AlertsResult, MonitorIdParam } from '../actions/types'; +import { simpleAlertEnabled } from '../../lib/alert_types/alert_messages'; + +export type ActionConnector = Omit; + +/** + * TODO: Use actual AlertType Params type that's specific to Uptime instead of `any` + */ +export type UptimeAlertTypeParams = Record; + +export const createAlertAction = createAsyncAction< + NewAlertParams, + Rule | null +>('CREATE ALERT'); +export const getConnectorsAction = createAsyncAction<{}, ActionConnector[]>('GET CONNECTORS'); +export const getMonitorAlertsAction = createAsyncAction<{}, AlertsResult | null>('GET ALERTS'); + +export const getAnomalyAlertAction = createAsyncAction>( + 'GET EXISTING ALERTS' +); +export const deleteAlertAction = createAsyncAction<{ alertId: string }, string | null>( + 'DELETE ALERTS' +); +export const deleteAnomalyAlertAction = createAsyncAction<{ alertId: string }, any>( + 'DELETE ANOMALY ALERT' +); + +export interface AlertState { + connectors: AsyncInitState; + newAlert: AsyncInitState>; + alerts: AsyncInitState; + anomalyAlert: AsyncInitState>; + alertDeletion: AsyncInitState; + anomalyAlertDeletion: AsyncInitState; +} + +const initialState = { + connectors: asyncInitState(), + newAlert: asyncInitState(), + alerts: asyncInitState(), + anomalyAlert: asyncInitState(), + alertDeletion: asyncInitState(), + anomalyAlertDeletion: asyncInitState(), +}; + +export const alertsReducer = handleActions( + { + ...handleAsyncAction('connectors', getConnectorsAction), + ...handleAsyncAction('newAlert', createAlertAction), + ...handleAsyncAction('alerts', getMonitorAlertsAction), + ...handleAsyncAction('anomalyAlert', getAnomalyAlertAction), + ...handleAsyncAction('alertDeletion', deleteAlertAction), + ...handleAsyncAction('anomalyAlertDeletion', deleteAnomalyAlertAction), + }, + initialState +); + +const showAlertDisabledSuccess = () => { + kibanaService.core.notifications.toasts.addSuccess( + i18n.translate('xpack.synthetics.overview.alerts.disabled.success', { + defaultMessage: 'Rule successfully disabled!', + }) + ); +}; + +const showAlertDisabledFailed = (err: Error) => { + kibanaService.core.notifications.toasts.addError(err, { + title: i18n.translate('xpack.synthetics.overview.alerts.disabled.failed', { + defaultMessage: 'Rule cannot be disabled!', + }), + }); +}; + +export function* fetchAlertsEffect() { + yield takeLatest( + getAnomalyAlertAction.get, + fetchEffectFactory(fetchAlertRecords, getAnomalyAlertAction.success, getAnomalyAlertAction.fail) + ); + + yield takeLatest(deleteAnomalyAlertAction.get, function* (action: Action<{ alertId: string }>) { + try { + yield call(disableAlertById, action.payload); + yield put(deleteAnomalyAlertAction.success(action.payload.alertId)); + showAlertDisabledSuccess(); + const monitorId = (yield select(monitorIdSelector)) as AppState['ui']['monitorId']; + yield put(getAnomalyAlertAction.get({ monitorId })); + } catch (err) { + showAlertDisabledFailed(err); + yield put(deleteAnomalyAlertAction.fail(err)); + } + }); + + yield takeLatest(deleteAlertAction.get, function* (action: Action<{ alertId: string }>) { + try { + yield call(disableAlertById, action.payload); + // clear previous state + yield put(createAlertAction.success(null)); + yield put(deleteAlertAction.success(action.payload.alertId)); + + showAlertDisabledSuccess(); + yield put(getMonitorAlertsAction.get()); + } catch (err) { + showAlertDisabledFailed(err); + yield put(deleteAlertAction.fail(err)); + } + }); + + yield takeLatest( + getConnectorsAction.get, + fetchEffectFactory(fetchConnectors, getConnectorsAction.success, getConnectorsAction.fail) + ); + yield takeLatest( + getMonitorAlertsAction.get, + fetchEffectFactory( + fetchMonitorAlertRecords, + getMonitorAlertsAction.success, + getMonitorAlertsAction.fail + ) + ); + yield takeLatest(createAlertAction.get, function* (action: Action): Generator { + try { + const response = (yield call(createAlert, action.payload)) as Rule; + yield put(createAlertAction.success(response)); + + kibanaService.core.notifications.toasts.addSuccess( + simpleAlertEnabled(action.payload.defaultActions, kibanaService.theme, response) + ); + yield put(getMonitorAlertsAction.get()); + } catch (err) { + kibanaService.core.notifications.toasts.addError(err, { + title: i18n.translate('xpack.synthetics.overview.alerts.enabled.failed', { + defaultMessage: 'Rule cannot be enabled!', + }), + }); + yield put(createAlertAction.fail(err)); + } + }); +} + +export const connectorsSelector = ({ alerts }: AppState) => alerts.connectors; +export const newAlertSelector = ({ alerts }: AppState) => alerts.newAlert; +export const alertsSelector = ({ alerts }: AppState) => alerts.alerts; +export const isAlertDeletedSelector = ({ alerts }: AppState) => alerts.alertDeletion; + +export const anomalyAlertSelector = ({ alerts }: AppState) => alerts.anomalyAlert; +export const isAnomalyAlertDeleting = ({ alerts }: AppState) => alerts.anomalyAlertDeletion.loading; diff --git a/x-pack/plugins/synthetics/public/state/api/__snapshots__/snapshot.test.ts.snap b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/__snapshots__/snapshot.test.ts.snap similarity index 100% rename from x-pack/plugins/synthetics/public/state/api/__snapshots__/snapshot.test.ts.snap rename to x-pack/plugins/synthetics/public/legacy_uptime/state/api/__snapshots__/snapshot.test.ts.snap diff --git a/x-pack/plugins/synthetics/public/state/api/alert_actions.test.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/alert_actions.test.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/api/alert_actions.test.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/api/alert_actions.test.ts diff --git a/x-pack/plugins/synthetics/public/state/api/alert_actions.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/alert_actions.ts similarity index 94% rename from x-pack/plugins/synthetics/public/state/api/alert_actions.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/api/alert_actions.ts index 5e65231388119..eabfe42691e8d 100644 --- a/x-pack/plugins/synthetics/public/state/api/alert_actions.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/alert_actions.ts @@ -18,11 +18,11 @@ import { // eslint-disable-next-line @kbn/eslint/no-restricted-paths } from '@kbn/actions-plugin/server'; import { NewAlertParams } from './alerts'; -import { ACTION_GROUP_DEFINITIONS } from '../../../common/constants/alerts'; -import { MonitorStatusTranslations } from '../../../common/translations'; +import { ACTION_GROUP_DEFINITIONS } from '../../../../common/constants/alerts'; +import { MonitorStatusTranslations } from '../../../../common/translations'; import { ActionTypeId } from '../../components/settings/types'; -import { Ping } from '../../../common/runtime_types/ping'; -import { DefaultEmail } from '../../../common/runtime_types'; +import { Ping } from '../../../../common/runtime_types/ping'; +import { DefaultEmail } from '../../../../common/runtime_types'; export const SLACK_ACTION_ID: ActionTypeId = '.slack'; export const PAGER_DUTY_ACTION_ID: ActionTypeId = '.pagerduty'; @@ -39,7 +39,7 @@ const { MONITOR_STATUS } = ACTION_GROUP_DEFINITIONS; export type RuleAction = Omit; const getRecoveryMessage = (selectedMonitor: Ping) => { - return i18n.translate('xpack.uptime.alerts.monitorStatus.recoveryMessage', { + return i18n.translate('xpack.synthetics.alerts.monitorStatus.recoveryMessage', { defaultMessage: 'Monitor {monitor} with url {url} has recovered with status Up', values: { monitor: selectedMonitor?.monitor?.name || selectedMonitor?.monitor?.id, @@ -233,7 +233,7 @@ function getEmailActionParams( ): EmailActionParams { return { to: defaultEmail.to, - subject: i18n.translate('xpack.uptime.monitor.simpleStatusAlert.email.subject', { + subject: i18n.translate('xpack.synthetics.monitor.simpleStatusAlert.email.subject', { defaultMessage: 'Monitor {monitor} with url {url} is down', values: { monitor: selectedMonitor?.monitor?.name || selectedMonitor?.monitor?.id, diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/api/alerts.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/alerts.ts new file mode 100644 index 0000000000000..2d5d47578a57b --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/alerts.ts @@ -0,0 +1,169 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ActionType, AsApiContract, Rule } from '@kbn/triggers-actions-ui-plugin/public'; +import { RuleTypeParams } from '@kbn/alerting-plugin/common'; +import { CLIENT_ALERT_TYPES } from '../../../../common/constants/alerts'; +import { apiService } from './utils'; +import { ActionConnector } from '../alerts/alerts'; + +import { AlertsResult, MonitorIdParam } from '../actions/types'; +import { API_URLS } from '../../../../common/constants'; +import { AtomicStatusCheckParams } from '../../../../common/runtime_types/alerts'; + +import { populateAlertActions, RuleAction } from './alert_actions'; +import { Ping } from '../../../../common/runtime_types/ping'; +import { DefaultEmail } from '../../../../common/runtime_types'; + +const UPTIME_AUTO_ALERT = 'UPTIME_AUTO'; + +export const fetchConnectors = async (): Promise => { + const response = (await apiService.get(API_URLS.RULE_CONNECTORS)) as Array< + AsApiContract + >; + return response.map( + ({ + connector_type_id: actionTypeId, + referenced_by_count: referencedByCount, + is_preconfigured: isPreconfigured, + is_deprecated: isDeprecated, + is_missing_secrets: isMissingSecrets, + ...res + }) => ({ + ...res, + actionTypeId, + referencedByCount, + isDeprecated, + isPreconfigured, + isMissingSecrets, + }) + ); +}; + +export interface NewAlertParams extends RuleTypeParams { + selectedMonitor: Ping; + defaultActions: ActionConnector[]; + defaultEmail?: DefaultEmail; +} + +type NewMonitorStatusAlert = Omit< + Rule, + | 'id' + | 'createdBy' + | 'updatedBy' + | 'createdAt' + | 'updatedAt' + | 'apiKey' + | 'apiKeyOwner' + | 'muteAll' + | 'mutedInstanceIds' + | 'executionStatus' + | 'ruleTypeId' + | 'notifyWhen' + | 'actions' +> & { + rule_type_id: Rule['ruleTypeId']; + notify_when: Rule['notifyWhen']; + actions: RuleAction[]; +}; + +export const createAlert = async ({ + defaultActions, + monitorId, + selectedMonitor, + defaultEmail, +}: NewAlertParams): Promise => { + const actions: RuleAction[] = populateAlertActions({ + defaultActions, + selectedMonitor, + defaultEmail, + }); + + const data: NewMonitorStatusAlert = { + actions, + params: { + numTimes: 1, + timerangeUnit: 'm', + timerangeCount: 1, + shouldCheckStatus: true, + shouldCheckAvailability: false, + isAutoGenerated: true, + search: `monitor.id : ${monitorId} `, + filters: { 'url.port': [], 'observer.geo.name': [], 'monitor.type': [], tags: [] }, + }, + consumer: 'uptime', + rule_type_id: CLIENT_ALERT_TYPES.MONITOR_STATUS, + schedule: { interval: '1m' }, + notify_when: 'onActionGroupChange', + tags: [UPTIME_AUTO_ALERT], + name: `${selectedMonitor?.monitor.name || selectedMonitor?.url?.full}(Simple status alert)`, + enabled: true, + throttle: null, + }; + + return await apiService.post(API_URLS.CREATE_RULE, data); +}; + +export const fetchMonitorAlertRecords = async (): Promise => { + const data = { + page: 1, + per_page: 500, + filter: `alert.attributes.alertTypeId:(${CLIENT_ALERT_TYPES.MONITOR_STATUS})`, + default_search_operator: 'AND', + sort_field: 'name.keyword', + sort_order: 'asc', + search_fields: ['name', 'tags'], + search: 'UPTIME_AUTO', + }; + return await apiService.get(API_URLS.RULES_FIND, data); +}; + +export const fetchAlertRecords = async ({ + monitorId, +}: MonitorIdParam): Promise> => { + const data = { + page: 1, + per_page: 500, + filter: `alert.attributes.alertTypeId:(${CLIENT_ALERT_TYPES.DURATION_ANOMALY})`, + default_search_operator: 'AND', + sort_field: 'name.keyword', + sort_order: 'asc', + }; + const rawRules = await apiService.get<{ + data: Array & { rule_type_id: string }>; + }>(API_URLS.RULES_FIND, data); + const monitorRule = rawRules.data.find( + (rule) => rule.params.monitorId === monitorId + ) as Rule & { rule_type_id: string }; + return { + ...monitorRule, + ruleTypeId: monitorRule.rule_type_id, + }; +}; + +export const disableAlertById = async ({ alertId }: { alertId: string }) => { + return await apiService.delete(API_URLS.DELETE_RULE + alertId); +}; + +export const fetchActionTypes = async (): Promise => { + const response = (await apiService.get(API_URLS.CONNECTOR_TYPES)) as Array< + AsApiContract + >; + return response.map( + ({ + enabled_in_config: enabledInConfig, + enabled_in_license: enabledInLicense, + minimum_license_required: minimumLicenseRequired, + ...res + }: AsApiContract) => ({ + ...res, + enabledInConfig, + enabledInLicense, + minimumLicenseRequired, + }) + ); +}; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/api/dynamic_settings.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/dynamic_settings.ts new file mode 100644 index 0000000000000..e3c14adf1de74 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/dynamic_settings.ts @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + DynamicSettingsType, + DynamicSettings, + DynamicSettingsSaveResponse, + DynamicSettingsSaveType, +} from '../../../../common/runtime_types'; +import { apiService } from './utils'; +import { API_URLS } from '../../../../common/constants'; + +const apiPath = API_URLS.DYNAMIC_SETTINGS; + +interface SaveApiRequest { + settings: DynamicSettings; +} + +export const getDynamicSettings = async (): Promise => { + return await apiService.get(apiPath, undefined, DynamicSettingsType); +}; + +export const setDynamicSettings = async ({ + settings, +}: SaveApiRequest): Promise => { + return await apiService.post(apiPath, settings, DynamicSettingsSaveType); +}; diff --git a/x-pack/plugins/synthetics/public/state/api/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/index.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/api/index.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/api/index.ts diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/api/index_status.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/index_status.ts new file mode 100644 index 0000000000000..857915deb9023 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/index_status.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { API_URLS } from '../../../../common/constants'; +import { StatesIndexStatus, StatesIndexStatusType } from '../../../../common/runtime_types'; +import { apiService } from './utils'; + +export const fetchIndexStatus = async (): Promise => { + return await apiService.get(API_URLS.INDEX_STATUS, undefined, StatesIndexStatusType); +}; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/api/journey.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/journey.ts new file mode 100644 index 0000000000000..64a156eb26ed5 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/journey.ts @@ -0,0 +1,100 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { apiService } from './utils'; +import { FetchJourneyStepsParams } from '../actions/journey'; +import { Ping, PingType } from '../../../../common/runtime_types/ping/ping'; +import { + FailedStepsApiResponse, + FailedStepsApiResponseType, + ScreenshotBlockDoc, + ScreenshotImageBlob, + ScreenshotRefImageData, + SyntheticsJourneyApiResponse, + SyntheticsJourneyApiResponseType, +} from '../../../../common/runtime_types/ping/synthetics'; +import { API_URLS } from '../../../../common/constants'; + +export async function fetchScreenshotBlockSet(params: string[]): Promise { + return apiService.post(API_URLS.JOURNEY_SCREENSHOT_BLOCKS, { + hashes: params, + }); +} + +export async function fetchJourneySteps( + params: FetchJourneyStepsParams +): Promise { + return apiService.get( + `/internal/uptime/journey/${params.checkGroup}`, + { syntheticEventTypes: params.syntheticEventTypes }, + SyntheticsJourneyApiResponseType + ); +} + +export async function fetchJourneysFailedSteps({ + checkGroups, +}: { + checkGroups: string[]; +}): Promise { + return apiService.get(API_URLS.JOURNEY_FAILED_STEPS, { checkGroups }, FailedStepsApiResponseType); +} + +export async function fetchLastSuccessfulCheck({ + monitorId, + timestamp, + stepIndex, + location, +}: { + monitorId: string; + timestamp: string; + stepIndex: number; + location?: string; +}): Promise { + return await apiService.get( + API_URLS.SYNTHETICS_SUCCESSFUL_CHECK, + { + monitorId, + timestamp, + stepIndex, + location, + }, + PingType + ); +} + +export async function getJourneyScreenshot( + imgSrc: string +): Promise { + try { + const imgRequest = new Request(imgSrc); + + const response = await fetch(imgRequest); + + if (response.status !== 200) { + return null; + } + + const contentType = response.headers.get('content-type'); + const stepName = response.headers.get('caption-name'); + const maxSteps = Number(response.headers.get('max-steps') ?? 0); + if (contentType?.indexOf('application/json') !== -1) { + return { + stepName, + maxSteps, + ref: await response.json(), + }; + } else { + return { + stepName, + maxSteps, + src: URL.createObjectURL(await response.blob()), + }; + } + } catch (e) { + return null; + } +} diff --git a/x-pack/plugins/synthetics/public/state/api/ml_anomaly.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/ml_anomaly.ts similarity index 95% rename from x-pack/plugins/synthetics/public/state/api/ml_anomaly.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/api/ml_anomaly.ts index e7655f37d3f01..18ce74d9823bb 100644 --- a/x-pack/plugins/synthetics/public/state/api/ml_anomaly.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/ml_anomaly.ts @@ -14,14 +14,14 @@ import { import { extractErrorMessage } from '@kbn/ml-plugin/common'; import { apiService } from './utils'; import { AnomalyRecords, AnomalyRecordsParams } from '../actions'; -import { API_URLS, ML_MODULE_ID } from '../../../common/constants'; +import { API_URLS, ML_MODULE_ID } from '../../../../common/constants'; import { CreateMLJobSuccess, DeleteJobResults, HeartbeatIndicesParam, MonitorIdParam, } from '../actions/types'; -import { getJobPrefix, getMLJobId } from '../../../common/lib/ml'; +import { getJobPrefix, getMLJobId } from '../../../../common/lib/ml'; export const getMLCapabilities = async (): Promise => { return await apiService.get(API_URLS.ML_CAPABILITIES); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/api/monitor.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/monitor.ts new file mode 100644 index 0000000000000..5dfb200444134 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/monitor.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { BaseParams } from './types'; +import { MonitorDetailsType, MonitorLocationsType } from '../../../../common/runtime_types'; +import { QueryParams } from '../actions/types'; +import { apiService } from './utils'; +import { API_URLS } from '../../../../common/constants'; + +interface ApiRequest { + monitorId: string; +} + +export type MonitorQueryParams = BaseParams & ApiRequest; + +export const fetchMonitorDetails = async ({ + monitorId, + dateStart, + dateEnd, +}: MonitorQueryParams) => { + const params = { + monitorId, + dateStart, + dateEnd, + }; + return await apiService.get(API_URLS.MONITOR_DETAILS, params, MonitorDetailsType); +}; + +type ApiParams = QueryParams & ApiRequest; + +export const fetchMonitorLocations = async ({ monitorId, dateStart, dateEnd }: ApiParams) => { + const params = { + dateStart, + dateEnd, + monitorId, + }; + return await apiService.get(API_URLS.MONITOR_LOCATIONS, params, MonitorLocationsType); +}; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/api/monitor_duration.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/monitor_duration.ts new file mode 100644 index 0000000000000..3fc046170757c --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/monitor_duration.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { BaseParams } from './types'; +import { apiService } from './utils'; +import { API_URLS } from '../../../../common/constants'; + +export const fetchMonitorDuration = async ({ monitorId, dateStart, dateEnd }: BaseParams) => { + const queryParams = { + monitorId, + dateStart, + dateEnd, + }; + + return await apiService.get(API_URLS.MONITOR_DURATION, queryParams); +}; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/api/monitor_list.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/monitor_list.ts new file mode 100644 index 0000000000000..e328132abe465 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/monitor_list.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { API_URLS } from '../../../../common/constants'; +import { apiService } from './utils'; +import { + FetchMonitorStatesQueryArgs, + MonitorSummariesResult, + MonitorSummariesResultType, +} from '../../../../common/runtime_types'; + +export const fetchMonitorList = async ( + params: FetchMonitorStatesQueryArgs +): Promise => { + return await apiService.get(API_URLS.MONITOR_LIST, params, MonitorSummariesResultType); +}; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/api/monitor_management.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/monitor_management.ts new file mode 100644 index 0000000000000..c38fff649048b --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/monitor_management.ts @@ -0,0 +1,121 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { API_URLS } from '../../../../common/constants'; +import { + FetchMonitorManagementListQueryArgs, + MonitorManagementListResultCodec, + MonitorManagementListResult, + MonitorManagementEnablementResultCodec, + MonitorManagementEnablementResult, + ServiceLocations, + SyntheticsMonitor, + EncryptedSyntheticsMonitor, + ServiceLocationsApiResponseCodec, + ServiceLocationErrors, + ThrottlingOptions, + Locations, + SyntheticsMonitorSchedule, +} from '../../../../common/runtime_types'; +import { + DecryptedSyntheticsMonitorSavedObject, + SyntheticsServiceAllowed, +} from '../../../../common/types'; +import { apiService } from './utils'; + +export const setMonitor = async ({ + monitor, + id, +}: { + monitor: SyntheticsMonitor | EncryptedSyntheticsMonitor; + id?: string; +}): Promise<{ attributes: { errors: ServiceLocationErrors } } | SyntheticsMonitor> => { + if (id) { + return await apiService.put(`${API_URLS.SYNTHETICS_MONITORS}/${id}`, monitor); + } else { + return await apiService.post(API_URLS.SYNTHETICS_MONITORS, monitor); + } +}; + +export const getMonitor = async ({ + id, +}: { + id: string; +}): Promise => { + return await apiService.get(`${API_URLS.SYNTHETICS_MONITORS}/${id}`); +}; + +export const deleteMonitor = async ({ id }: { id: string }): Promise => { + return await apiService.delete(`${API_URLS.SYNTHETICS_MONITORS}/${id}`); +}; + +export const fetchMonitorManagementList = async ( + params: FetchMonitorManagementListQueryArgs +): Promise => { + return await apiService.get( + API_URLS.SYNTHETICS_MONITORS, + params, + MonitorManagementListResultCodec + ); +}; + +export const fetchServiceLocations = async (): Promise<{ + throttling: ThrottlingOptions | undefined; + locations: ServiceLocations; +}> => { + const { throttling, locations } = await apiService.get( + API_URLS.SERVICE_LOCATIONS, + undefined, + ServiceLocationsApiResponseCodec + ); + return { throttling, locations }; +}; + +export const runOnceMonitor = async ({ + monitor, + id, +}: { + monitor: SyntheticsMonitor; + id: string; +}): Promise<{ errors: Array<{ error: Error }> }> => { + return await apiService.post(API_URLS.RUN_ONCE_MONITOR + `/${id}`, monitor); +}; + +export interface TestNowResponse { + schedule: SyntheticsMonitorSchedule; + locations: Locations; + errors?: ServiceLocationErrors; + testRunId: string; + monitorId: string; +} + +export const triggerTestNowMonitor = async ( + configId: string +): Promise => { + return await apiService.get(API_URLS.TRIGGER_MONITOR + `/${configId}`); +}; + +export const fetchGetSyntheticsEnablement = + async (): Promise => { + return await apiService.get( + API_URLS.SYNTHETICS_ENABLEMENT, + undefined, + MonitorManagementEnablementResultCodec + ); + }; + +export const fetchDisableSynthetics = async (): Promise => { + return await apiService.delete(API_URLS.SYNTHETICS_ENABLEMENT); +}; + +export const fetchEnableSynthetics = async (): Promise => { + return await apiService.post(API_URLS.SYNTHETICS_ENABLEMENT); +}; + +export const fetchServiceAllowed = async (): Promise => { + return await apiService.get(API_URLS.SERVICE_ALLOWED); +}; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/api/monitor_status.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/monitor_status.ts new file mode 100644 index 0000000000000..10534c18b7d38 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/monitor_status.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { QueryParams } from '../actions/types'; +import { Ping } from '../../../../common/runtime_types'; +import { API_URLS } from '../../../../common/constants'; +import { apiService } from './utils'; + +export const fetchMonitorStatus = async ({ + monitorId, + dateStart, + dateEnd, +}: QueryParams): Promise => { + const queryParams = { + monitorId, + dateStart, + dateEnd, + }; + + return await apiService.get(API_URLS.MONITOR_STATUS, queryParams); +}; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/api/network_events.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/network_events.ts new file mode 100644 index 0000000000000..82dcd572ad624 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/network_events.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { apiService } from './utils'; +import { FetchNetworkEventsParams } from '../actions/network_events'; +import { + SyntheticsNetworkEventsApiResponse, + SyntheticsNetworkEventsApiResponseType, +} from '../../../../common/runtime_types'; +import { API_URLS } from '../../../../common/constants'; + +export async function fetchNetworkEvents( + params: FetchNetworkEventsParams +): Promise { + return (await apiService.get( + API_URLS.NETWORK_EVENTS, + { + checkGroup: params.checkGroup, + stepIndex: params.stepIndex, + }, + SyntheticsNetworkEventsApiResponseType + )) as SyntheticsNetworkEventsApiResponse; +} diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/api/ping.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/ping.ts new file mode 100644 index 0000000000000..969102a8d77c6 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/ping.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { APIFn } from './types'; +import { + PingsResponseType, + PingsResponse, + GetPingsParams, + GetPingHistogramParams, + HistogramResult, +} from '../../../../common/runtime_types'; +import { apiService } from './utils'; +import { API_URLS } from '../../../../common/constants'; + +export const fetchPings: APIFn = async ({ + dateRange: { from, to }, + ...optional +}) => await apiService.get(API_URLS.PINGS, { from, to, ...optional }, PingsResponseType); + +export const fetchPingHistogram: APIFn = async ({ + monitorId, + dateStart, + dateEnd, + filters, + bucketSize, + query, +}) => { + const queryParams = { + dateStart, + dateEnd, + monitorId, + filters, + bucketSize, + query, + }; + + return await apiService.get(API_URLS.PING_HISTOGRAM, queryParams); +}; diff --git a/x-pack/plugins/synthetics/public/state/api/snapshot.test.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/snapshot.test.ts similarity index 97% rename from x-pack/plugins/synthetics/public/state/api/snapshot.test.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/api/snapshot.test.ts index 20a0a0d7a477c..97578deeb6fb7 100644 --- a/x-pack/plugins/synthetics/public/state/api/snapshot.test.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/snapshot.test.ts @@ -8,7 +8,7 @@ import { HttpFetchError } from '@kbn/core/public'; import { fetchSnapshotCount } from './snapshot'; import { apiService } from './utils'; -import { API_URLS } from '../../../common/constants'; +import { API_URLS } from '../../../../common/constants'; describe('snapshot API', () => { let fetchMock: jest.SpyInstance>; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/api/snapshot.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/snapshot.ts new file mode 100644 index 0000000000000..7734a0cec79b2 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/snapshot.ts @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { SnapshotType, Snapshot } from '../../../../common/runtime_types'; +import { apiService } from './utils'; +import { API_URLS } from '../../../../common/constants'; + +export interface SnapShotQueryParams { + dateRangeStart: string; + dateRangeEnd: string; + filters?: string; + query?: string; +} + +export const fetchSnapshotCount = async ({ + dateRangeStart, + dateRangeEnd, + filters, + query, +}: SnapShotQueryParams): Promise => { + const queryParams = { + dateRangeStart, + dateRangeEnd, + ...(filters && { filters }), + ...(query && { query }), + }; + + return await apiService.get(API_URLS.SNAPSHOT_COUNT, queryParams, SnapshotType); +}; diff --git a/x-pack/plugins/synthetics/public/state/api/types.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/types.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/api/types.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/api/types.ts diff --git a/x-pack/plugins/synthetics/public/state/api/utils.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/utils.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/api/utils.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/api/utils.ts diff --git a/x-pack/plugins/synthetics/public/state/certificates/certificates.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/certificates/certificates.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/certificates/certificates.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/certificates/certificates.ts diff --git a/x-pack/plugins/synthetics/public/state/effects/alerts.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/alerts.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/effects/alerts.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/effects/alerts.ts diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/dynamic_settings.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/dynamic_settings.ts new file mode 100644 index 0000000000000..1200633976c6f --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/dynamic_settings.ts @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { takeLeading, put, call, takeLatest } from 'redux-saga/effects'; +import { Action } from 'redux-actions'; +import { i18n } from '@kbn/i18n'; +import { fetchEffectFactory } from './fetch_effect'; +import { + getDynamicSettings, + getDynamicSettingsSuccess, + getDynamicSettingsFail, + setDynamicSettingsSuccess, + setDynamicSettingsFail, + setDynamicSettings, +} from '../actions/dynamic_settings'; +import { + getDynamicSettings as getDynamicSettingsAPI, + setDynamicSettings as setDynamicSettingsAPI, +} from '../api'; +import { DynamicSettings } from '../../../../common/runtime_types'; +import { kibanaService } from '../kibana_service'; + +export function* fetchDynamicSettingsEffect() { + yield takeLeading( + String(getDynamicSettings), + fetchEffectFactory(getDynamicSettingsAPI, getDynamicSettingsSuccess, getDynamicSettingsFail) + ); +} + +export function* setDynamicSettingsEffect() { + const couldNotSaveSettingsText = i18n.translate('xpack.synthetics.settings.error.couldNotSave', { + defaultMessage: 'Could not save settings!', + }); + yield takeLatest(String(setDynamicSettings), function* (action: Action) { + try { + if (!action.payload) { + const err = new Error('Cannot fetch effect without a payload'); + yield put(setDynamicSettingsFail(err)); + + kibanaService.core.notifications.toasts.addError(err, { + title: couldNotSaveSettingsText, + }); + return; + } + yield call(setDynamicSettingsAPI, { settings: action.payload }); + yield put(setDynamicSettingsSuccess(action.payload)); + kibanaService.core.notifications.toasts.addSuccess( + i18n.translate('xpack.synthetics.settings.saveSuccess', { + defaultMessage: 'Settings saved!', + }) + ); + } catch (err) { + kibanaService.core.notifications.toasts.addError(err, { + title: couldNotSaveSettingsText, + }); + yield put(setDynamicSettingsFail(err)); + } + }); +} diff --git a/x-pack/plugins/synthetics/public/state/effects/fetch_effect.test.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/fetch_effect.test.ts similarity index 97% rename from x-pack/plugins/synthetics/public/state/effects/fetch_effect.test.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/effects/fetch_effect.test.ts index 5216260714cc8..4a19cfae58f6a 100644 --- a/x-pack/plugins/synthetics/public/state/effects/fetch_effect.test.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/fetch_effect.test.ts @@ -9,7 +9,7 @@ import { call, put } from 'redux-saga/effects'; import { fetchEffectFactory } from './fetch_effect'; import { indexStatusAction } from '../actions'; import { HttpFetchError } from '@kbn/core/public'; -import { StatesIndexStatus } from '../../../common/runtime_types'; +import { StatesIndexStatus } from '../../../../common/runtime_types'; import { fetchIndexStatus } from '../api'; describe('fetch saga effect factory', () => { diff --git a/x-pack/plugins/synthetics/public/state/effects/fetch_effect.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/fetch_effect.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/effects/fetch_effect.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/effects/fetch_effect.ts diff --git a/x-pack/plugins/synthetics/public/state/effects/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/index.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/effects/index.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/effects/index.ts diff --git a/x-pack/plugins/synthetics/public/state/effects/index_status.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/index_status.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/effects/index_status.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/effects/index_status.ts diff --git a/x-pack/plugins/synthetics/public/state/effects/journey.test.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/journey.test.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/effects/journey.test.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/effects/journey.test.ts diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/journey.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/journey.ts new file mode 100644 index 0000000000000..14d3ce91a32de --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/journey.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Action } from 'redux-actions'; +import { call, put, takeEvery } from 'redux-saga/effects'; +import { + getJourneySteps, + getJourneyStepsSuccess, + getJourneyStepsFail, + FetchJourneyStepsParams, +} from '../actions/journey'; +import { fetchJourneySteps } from '../api/journey'; +import type { SyntheticsJourneyApiResponse } from '../../../../common/runtime_types'; + +const inFlightStepRequests: Record = {}; + +export function* fetchJourneyStepsEffect(): Generator { + yield takeEvery(getJourneySteps, function* (action: Action) { + if (inFlightStepRequests[action.payload.checkGroup]) return; + + try { + inFlightStepRequests[action.payload.checkGroup] = true; + const response = (yield call( + fetchJourneySteps, + action.payload + )) as SyntheticsJourneyApiResponse; + yield put(getJourneyStepsSuccess(response)); + } catch (e) { + yield put(getJourneyStepsFail({ checkGroup: action.payload.checkGroup, error: e })); + } finally { + delete inFlightStepRequests[action.payload.checkGroup]; + } + }); +} diff --git a/x-pack/plugins/synthetics/public/state/effects/ml_anomaly.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/ml_anomaly.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/effects/ml_anomaly.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/effects/ml_anomaly.ts diff --git a/x-pack/plugins/synthetics/public/state/effects/monitor.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/monitor.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/effects/monitor.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/effects/monitor.ts diff --git a/x-pack/plugins/synthetics/public/state/effects/monitor_duration.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/monitor_duration.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/effects/monitor_duration.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/effects/monitor_duration.ts diff --git a/x-pack/plugins/synthetics/public/state/effects/monitor_list.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/monitor_list.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/effects/monitor_list.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/effects/monitor_list.ts diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/monitor_management.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/monitor_management.ts new file mode 100644 index 0000000000000..b5ee599b0a4f9 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/monitor_management.ts @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { takeLatest, takeLeading } from 'redux-saga/effects'; +import { + getMonitors, + getMonitorsSuccess, + getMonitorsFailure, + getServiceLocations, + getServiceLocationsSuccess, + getServiceLocationsFailure, + getSyntheticsEnablement, + getSyntheticsEnablementSuccess, + getSyntheticsEnablementFailure, + disableSynthetics, + disableSyntheticsSuccess, + disableSyntheticsFailure, + enableSynthetics, + enableSyntheticsSuccess, + enableSyntheticsFailure, + getSyntheticsServiceAllowed, +} from '../actions'; +import { + fetchMonitorManagementList, + fetchServiceLocations, + fetchServiceAllowed, + fetchGetSyntheticsEnablement, + fetchDisableSynthetics, + fetchEnableSynthetics, +} from '../api'; +import { fetchEffectFactory } from './fetch_effect'; + +export function* fetchMonitorManagementEffect() { + yield takeLeading( + getMonitors, + fetchEffectFactory(fetchMonitorManagementList, getMonitorsSuccess, getMonitorsFailure) + ); + yield takeLeading( + getServiceLocations, + fetchEffectFactory( + fetchServiceLocations, + getServiceLocationsSuccess, + getServiceLocationsFailure + ) + ); + yield takeLeading( + getSyntheticsEnablement, + fetchEffectFactory( + fetchGetSyntheticsEnablement, + getSyntheticsEnablementSuccess, + getSyntheticsEnablementFailure + ) + ); + yield takeLatest( + disableSynthetics, + fetchEffectFactory(fetchDisableSynthetics, disableSyntheticsSuccess, disableSyntheticsFailure) + ); + yield takeLatest( + enableSynthetics, + fetchEffectFactory(fetchEnableSynthetics, enableSyntheticsSuccess, enableSyntheticsFailure) + ); +} + +export function* fetchSyntheticsServiceAllowedEffect() { + yield takeLeading( + getSyntheticsServiceAllowed.get, + fetchEffectFactory( + fetchServiceAllowed, + getSyntheticsServiceAllowed.success, + getSyntheticsServiceAllowed.fail + ) + ); +} diff --git a/x-pack/plugins/synthetics/public/state/effects/monitor_status.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/monitor_status.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/effects/monitor_status.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/effects/monitor_status.ts diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/network_events.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/network_events.ts new file mode 100644 index 0000000000000..8c74e753c162c --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/network_events.ts @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Action } from 'redux-actions'; +import { call, put, takeLatest } from 'redux-saga/effects'; +import { + getNetworkEvents, + getNetworkEventsSuccess, + getNetworkEventsFail, + FetchNetworkEventsParams, +} from '../actions/network_events'; +import { fetchNetworkEvents } from '../api/network_events'; +import type { SyntheticsNetworkEventsApiResponse } from '../../../../common/runtime_types'; + +export function* fetchNetworkEventsEffect() { + yield takeLatest( + getNetworkEvents, + function* (action: Action): Generator { + try { + const response = (yield call( + fetchNetworkEvents, + action.payload + )) as SyntheticsNetworkEventsApiResponse; + + yield put( + getNetworkEventsSuccess({ + checkGroup: action.payload.checkGroup, + stepIndex: action.payload.stepIndex, + ...response, + }) + ); + } catch (e) { + yield put( + getNetworkEventsFail({ + checkGroup: action.payload.checkGroup, + stepIndex: action.payload.stepIndex, + error: e, + }) + ); + } + } + ); +} diff --git a/x-pack/plugins/synthetics/public/state/effects/ping.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/ping.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/effects/ping.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/effects/ping.ts diff --git a/x-pack/plugins/synthetics/public/state/effects/synthetic_journey_blocks.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/synthetic_journey_blocks.ts similarity index 96% rename from x-pack/plugins/synthetics/public/state/effects/synthetic_journey_blocks.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/effects/synthetic_journey_blocks.ts index 829048747ddf7..6ffbeb6978f75 100644 --- a/x-pack/plugins/synthetics/public/state/effects/synthetic_journey_blocks.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/synthetic_journey_blocks.ts @@ -7,7 +7,7 @@ import { Action } from 'redux-actions'; import { call, fork, put, select, takeEvery, throttle } from 'redux-saga/effects'; -import { ScreenshotBlockDoc } from '../../../common/runtime_types/ping/synthetics'; +import { ScreenshotBlockDoc } from '../../../../common/runtime_types/ping/synthetics'; import { fetchScreenshotBlockSet } from '../api/journey'; import { fetchBlocksAction, diff --git a/x-pack/plugins/synthetics/public/state/effects/test_now_runs.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/effects/test_now_runs.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/effects/test_now_runs.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/effects/test_now_runs.ts diff --git a/x-pack/plugins/synthetics/public/state/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/index.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/index.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/index.ts diff --git a/x-pack/plugins/synthetics/public/state/kibana_service.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/kibana_service.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/kibana_service.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/kibana_service.ts diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/dynamic_settings.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/dynamic_settings.ts new file mode 100644 index 0000000000000..d7c20b8edf7a3 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/dynamic_settings.ts @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { handleActions, Action } from 'redux-actions'; +import { + getDynamicSettings, + getDynamicSettingsSuccess, + getDynamicSettingsFail, + setDynamicSettings, + setDynamicSettingsSuccess, + setDynamicSettingsFail, +} from '../actions/dynamic_settings'; +import { DynamicSettings } from '../../../../common/runtime_types'; + +export interface DynamicSettingsState { + settings?: DynamicSettings; + loadError?: Error; + saveError?: Error; + loading: boolean; +} + +const initialState: DynamicSettingsState = { + loading: true, +}; + +export const dynamicSettingsReducer = handleActions( + { + [String(getDynamicSettings)]: (state) => ({ + ...state, + loading: true, + }), + [String(getDynamicSettingsSuccess)]: (_state, action: Action) => ({ + loading: false, + settings: action.payload, + }), + [String(getDynamicSettingsFail)]: (_state, action: Action) => ({ + loading: false, + loadError: action.payload, + }), + [String(setDynamicSettings)]: (state) => ({ + ...state, + loading: true, + }), + [String(setDynamicSettingsSuccess)]: (_state, action: Action) => ({ + settings: action.payload, + saveSucceded: true, + loading: false, + }), + [String(setDynamicSettingsFail)]: (state, action: Action) => ({ + ...state, + loading: false, + saveSucceeded: false, + saveError: action.payload, + }), + }, + initialState +); diff --git a/x-pack/plugins/synthetics/public/state/reducers/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/index.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/reducers/index.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/index.ts diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/index_status.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/index_status.ts new file mode 100644 index 0000000000000..29ea59cabb9e5 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/index_status.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { handleActions } from 'redux-actions'; +import { indexStatusAction } from '../actions'; +import { asyncInitState, handleAsyncAction } from './utils'; +import { AsyncInitState } from './types'; +import { StatesIndexStatus } from '../../../../common/runtime_types'; + +export interface IndexStatusState { + indexStatus: AsyncInitState; +} + +const initialState: IndexStatusState = { + indexStatus: asyncInitState(), +}; + +type PayLoad = StatesIndexStatus & Error; + +export const indexStatusReducer = handleActions( + { + ...handleAsyncAction('indexStatus', indexStatusAction), + }, + initialState +); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/journey.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/journey.ts new file mode 100644 index 0000000000000..ae781b5839593 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/journey.ts @@ -0,0 +1,101 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { handleActions, Action } from 'redux-actions'; +import { JourneyStep, SyntheticsJourneyApiResponse } from '../../../../common/runtime_types'; +import { pruneJourneyState } from '../actions/journey'; +import { + FetchJourneyStepsParams, + GetJourneyFailPayload, + getJourneySteps, + getJourneyStepsFail, + getJourneyStepsSuccess, +} from '../actions/journey'; + +export interface JourneyState { + checkGroup: string; + steps: JourneyStep[]; + details?: SyntheticsJourneyApiResponse['details']; + loading: boolean; + error?: Error; +} + +export interface JourneyKVP { + [checkGroup: string]: JourneyState; +} + +const initialState: JourneyKVP = {}; + +type Payload = FetchJourneyStepsParams & + SyntheticsJourneyApiResponse & + GetJourneyFailPayload & + string[]; + +export const journeyReducer = handleActions( + { + [String(getJourneySteps)]: ( + state: JourneyKVP, + { payload: { checkGroup } }: Action + ) => ({ + ...state, + // add an empty entry while fetching the check group, + // or update the previously-loaded entry to a new loading state + [checkGroup]: state[checkGroup] + ? { + ...state[checkGroup], + loading: true, + } + : { + checkGroup, + steps: [], + loading: true, + }, + }), + + [String(getJourneyStepsSuccess)]: ( + state: JourneyKVP, + { payload: { checkGroup, steps, details } }: Action + ) => ({ + ...state, + [checkGroup]: { + loading: false, + checkGroup, + steps, + details, + }, + }), + + [String(getJourneyStepsFail)]: ( + state: JourneyKVP, + { payload: { checkGroup, error } }: Action + ) => ({ + ...state, + [checkGroup]: state[checkGroup] + ? { + ...state[checkGroup], + loading: false, + error, + } + : { + checkGroup, + loading: false, + steps: [], + error, + }, + }), + + [String(pruneJourneyState)]: (state: JourneyKVP, action: Action) => + action.payload.reduce( + (prev, cur) => ({ + ...prev, + [cur]: state[cur], + }), + {} + ), + }, + initialState +); diff --git a/x-pack/plugins/synthetics/public/state/reducers/ml_anomaly.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/ml_anomaly.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/reducers/ml_anomaly.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/ml_anomaly.ts diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/monitor.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/monitor.ts new file mode 100644 index 0000000000000..23f2aac045b29 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/monitor.ts @@ -0,0 +1,78 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Action } from 'redux-actions'; +import { + MonitorDetailsState, + getMonitorDetailsAction, + getMonitorLocationsAction, + getMonitorLocationsActionSuccess, + getMonitorLocationsActionFail, +} from '../actions/monitor'; +import { MonitorLocations } from '../../../../common/runtime_types'; + +type MonitorLocationsList = Map; + +export interface MonitorState { + loading: boolean; + errors: any[]; + monitorDetailsList: MonitorDetailsState[]; + monitorLocationsList: MonitorLocationsList; +} + +const initialState: MonitorState = { + monitorDetailsList: [], + monitorLocationsList: new Map(), + loading: false, + errors: [], +}; + +export function monitorReducer(state = initialState, action: Action): MonitorState { + switch (action.type) { + case String(getMonitorDetailsAction.get): + return { + ...state, + loading: true, + }; + case String(getMonitorDetailsAction.success): + const { monitorId } = action.payload; + return { + ...state, + monitorDetailsList: { + ...state.monitorDetailsList, + [monitorId]: action.payload, + }, + loading: false, + }; + case String(getMonitorDetailsAction.fail): + return { + ...state, + errors: [...state.errors, action.payload], + loading: false, + }; + case String(getMonitorLocationsAction): + return { + ...state, + loading: true, + }; + case String(getMonitorLocationsActionSuccess): + const monLocations = state.monitorLocationsList; + monLocations.set(action.payload.monitorId, action.payload); + return { + ...state, + monitorLocationsList: monLocations, + loading: false, + }; + case String(getMonitorLocationsActionFail): + return { + ...state, + errors: [...state.errors, action.payload], + }; + default: + return state; + } +} diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/monitor_duration.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/monitor_duration.ts new file mode 100644 index 0000000000000..71fa50b75f5d6 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/monitor_duration.ts @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { handleActions, Action } from 'redux-actions'; +import { + getMonitorDurationAction, + getMonitorDurationActionSuccess, + getMonitorDurationActionFail, +} from '../actions'; +import { MonitorDurationResult } from '../../../../common/types'; + +export interface MonitorDuration { + durationLines: MonitorDurationResult | null; + errors: any[]; + loading: boolean; +} + +const initialState: MonitorDuration = { + durationLines: null, + loading: false, + errors: [], +}; + +type Payload = MonitorDurationResult & Error; + +export const monitorDurationReducer = handleActions( + { + [String(getMonitorDurationAction)]: (state: MonitorDuration) => ({ + ...state, + loading: true, + }), + + [String(getMonitorDurationActionSuccess)]: ( + state: MonitorDuration, + action: Action + ) => ({ + ...state, + loading: false, + durationLines: { ...action.payload }, + }), + + [String(getMonitorDurationActionFail)]: (state: MonitorDuration, action: Action) => ({ + ...state, + errors: [...state.errors, action.payload], + loading: false, + }), + }, + initialState +); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/monitor_list.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/monitor_list.ts new file mode 100644 index 0000000000000..6e325a699a114 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/monitor_list.ts @@ -0,0 +1,128 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { handleActions, Action } from 'redux-actions'; +import { IHttpFetchError, ResponseErrorBody } from '@kbn/core/public'; +import { + getMonitorList, + getMonitorListSuccess, + getMonitorListFailure, + getUpdatedMonitor, + clearRefreshedMonitorId, + setUpdatingMonitorId, +} from '../actions'; +import { MonitorSummariesResult } from '../../../../common/runtime_types'; +import { AppState } from '..'; +import { TestNowResponse } from '../api'; + +export interface MonitorList { + loading: boolean; + refreshedMonitorIds?: string[]; + isUpdating?: string[]; + list: MonitorSummariesResult; + error?: IHttpFetchError; +} + +export const initialState: MonitorList = { + list: { + nextPagePagination: null, + prevPagePagination: null, + summaries: [], + }, + loading: false, + refreshedMonitorIds: [], +}; + +type Payload = MonitorSummariesResult & + IHttpFetchError & + string & + TestNowResponse; + +export const monitorListReducer = handleActions( + { + [String(getMonitorList)]: (state: MonitorList) => ({ + ...state, + loading: true, + }), + [String(getMonitorListSuccess)]: ( + state: MonitorList, + action: Action + ) => ({ + ...state, + loading: false, + error: undefined, + list: { ...action.payload }, + }), + [String(getMonitorListFailure)]: ( + state: MonitorList, + action: Action> + ) => ({ + ...state, + error: action.payload, + loading: false, + }), + [String(setUpdatingMonitorId)]: (state: MonitorList, action: Action) => ({ + ...state, + isUpdating: [...(state.isUpdating ?? []), action.payload], + }), + [String(getUpdatedMonitor.get)]: (state: MonitorList) => ({ + ...state, + }), + [String(getUpdatedMonitor.success)]: ( + state: MonitorList, + action: Action + ) => { + const summaries = state.list.summaries; + + const newSummary = action.payload.summaries?.[0]; + + if (!newSummary) { + return { ...state, isUpdating: [] }; + } + + return { + ...state, + loading: false, + error: undefined, + isUpdating: state.isUpdating?.filter((item) => item !== newSummary.monitor_id), + refreshedMonitorIds: [...(state.refreshedMonitorIds ?? []), newSummary.monitor_id], + list: { + ...state.list, + summaries: summaries.map((summary) => { + if (summary.monitor_id === newSummary.monitor_id) { + return newSummary; + } + return summary; + }), + }, + }; + }, + [String(getUpdatedMonitor.fail)]: ( + state: MonitorList, + action: Action> + ) => ({ + ...state, + error: action.payload, + loading: false, + isUpdating: [], + }), + [String(clearRefreshedMonitorId)]: (state: MonitorList, action: Action) => ({ + ...state, + refreshedMonitorIds: (state.refreshedMonitorIds ?? []).filter( + (item) => item !== action.payload + ), + }), + }, + initialState +); + +export const refreshedMonitorSelector = ({ monitorList }: AppState) => { + return monitorList.refreshedMonitorIds ?? []; +}; + +export const isUpdatingMonitorSelector = ({ monitorList }: AppState) => + monitorList.isUpdating ?? []; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/monitor_management.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/monitor_management.ts new file mode 100644 index 0000000000000..18c247a655275 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/monitor_management.ts @@ -0,0 +1,304 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createReducer, PayloadAction } from '@reduxjs/toolkit'; +import { WritableDraft } from 'immer/dist/types/types-external'; +import { + getMonitors, + getMonitorsSuccess, + getMonitorsFailure, + getServiceLocations, + getServiceLocationsSuccess, + getServiceLocationsFailure, + getSyntheticsEnablement, + getSyntheticsEnablementSuccess, + getSyntheticsEnablementFailure, + disableSynthetics, + disableSyntheticsSuccess, + disableSyntheticsFailure, + enableSynthetics, + enableSyntheticsSuccess, + enableSyntheticsFailure, + getSyntheticsServiceAllowed, +} from '../actions'; +import { + MonitorManagementEnablementResult, + MonitorManagementListResult, + ServiceLocations, + ThrottlingOptions, + DEFAULT_THROTTLING, +} from '../../../../common/runtime_types'; +import { SyntheticsServiceAllowed } from '../../../../common/types'; + +export interface MonitorManagementList { + error: Record<'monitorList' | 'serviceLocations' | 'enablement', Error | null>; + loading: Record<'monitorList' | 'serviceLocations' | 'enablement', boolean>; + list: MonitorManagementListResult; + locations: ServiceLocations; + enablement: MonitorManagementEnablementResult | null; + syntheticsService: { isAllowed?: boolean; signupUrl: string | null; loading: boolean }; + throttling: ThrottlingOptions; +} + +export const initialState: MonitorManagementList = { + list: { + page: 1, + perPage: 10, + total: null, + monitors: [], + syncErrors: [], + }, + locations: [], + enablement: null, + loading: { + monitorList: false, + serviceLocations: false, + enablement: false, + }, + error: { + monitorList: null, + serviceLocations: null, + enablement: null, + }, + syntheticsService: { + signupUrl: null, + loading: false, + }, + throttling: DEFAULT_THROTTLING, +}; + +export const monitorManagementListReducer = createReducer(initialState, (builder) => { + builder + .addCase(getMonitors, (state: WritableDraft) => ({ + ...state, + loading: { + ...state.loading, + monitorList: true, + }, + })) + .addCase( + getMonitorsSuccess, + ( + state: WritableDraft, + action: PayloadAction + ) => ({ + ...state, + loading: { + ...state.loading, + monitorList: false, + }, + error: { + ...state.error, + monitorList: null, + }, + list: { ...action.payload }, + }) + ) + .addCase( + getMonitorsFailure, + (state: WritableDraft, action: PayloadAction) => ({ + ...state, + loading: { + ...state.loading, + monitorList: false, + }, + error: { + ...state.error, + monitorList: action.payload, + }, + }) + ) + .addCase(getServiceLocations, (state: WritableDraft) => ({ + ...state, + loading: { + ...state.loading, + serviceLocations: true, + }, + })) + .addCase( + getServiceLocationsSuccess, + ( + state: WritableDraft, + action: PayloadAction<{ + throttling: ThrottlingOptions | undefined; + locations: ServiceLocations; + }> + ) => ({ + ...state, + loading: { + ...state.loading, + serviceLocations: false, + }, + error: { + ...state.error, + serviceLocations: null, + }, + locations: action.payload.locations, + throttling: action.payload.throttling || DEFAULT_THROTTLING, + }) + ) + .addCase( + getServiceLocationsFailure, + (state: WritableDraft, action: PayloadAction) => ({ + ...state, + loading: { + ...state.loading, + serviceLocations: false, + }, + error: { + ...state.error, + serviceLocations: action.payload, + }, + }) + ) + .addCase(getSyntheticsEnablement, (state: WritableDraft) => ({ + ...state, + loading: { + ...state.loading, + enablement: true, + }, + })) + .addCase( + getSyntheticsEnablementSuccess, + (state: WritableDraft, action: PayloadAction) => ({ + ...state, + loading: { + ...state.loading, + enablement: false, + }, + error: { + ...state.error, + enablement: null, + }, + enablement: action.payload, + }) + ) + .addCase( + getSyntheticsEnablementFailure, + (state: WritableDraft, action: PayloadAction) => ({ + ...state, + loading: { + ...state.loading, + enablement: false, + }, + error: { + ...state.error, + enablement: action.payload, + }, + }) + ) + .addCase(disableSynthetics, (state: WritableDraft) => ({ + ...state, + loading: { + ...state.loading, + enablement: true, + }, + })) + .addCase(disableSyntheticsSuccess, (state: WritableDraft) => ({ + ...state, + loading: { + ...state.loading, + enablement: false, + }, + error: { + ...state.error, + enablement: null, + }, + enablement: { + canEnable: state.enablement?.canEnable || false, + areApiKeysEnabled: state.enablement?.areApiKeysEnabled || false, + isEnabled: false, + }, + })) + .addCase( + disableSyntheticsFailure, + (state: WritableDraft, action: PayloadAction) => ({ + ...state, + loading: { + ...state.loading, + enablement: false, + }, + error: { + ...state.error, + enablement: action.payload, + }, + }) + ) + .addCase(enableSynthetics, (state: WritableDraft) => ({ + ...state, + loading: { + ...state.loading, + enablement: true, + }, + })) + .addCase(enableSyntheticsSuccess, (state: WritableDraft) => ({ + ...state, + loading: { + ...state.loading, + enablement: false, + }, + error: { + ...state.error, + enablement: null, + }, + enablement: { + canEnable: state.enablement?.canEnable || false, + areApiKeysEnabled: state.enablement?.areApiKeysEnabled || false, + isEnabled: true, + }, + })) + .addCase( + enableSyntheticsFailure, + (state: WritableDraft, action: PayloadAction) => ({ + ...state, + loading: { + ...state.loading, + enablement: false, + }, + error: { + ...state.error, + enablement: action.payload, + }, + }) + ) + .addCase( + String(getSyntheticsServiceAllowed.get), + (state: WritableDraft) => ({ + ...state, + syntheticsService: { + isAllowed: state.syntheticsService?.isAllowed, + signupUrl: state.syntheticsService?.signupUrl, + loading: true, + }, + }) + ) + .addCase( + String(getSyntheticsServiceAllowed.success), + ( + state: WritableDraft, + action: PayloadAction + ) => ({ + ...state, + syntheticsService: { + isAllowed: action.payload.serviceAllowed, + signupUrl: action.payload.signupUrl, + loading: false, + }, + }) + ) + .addCase( + String(getSyntheticsServiceAllowed.fail), + (state: WritableDraft, action: PayloadAction) => ({ + ...state, + syntheticsService: { + isAllowed: false, + signupUrl: null, + loading: false, + }, + }) + ); +}); diff --git a/x-pack/plugins/synthetics/public/state/reducers/monitor_status.test.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/monitor_status.test.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/reducers/monitor_status.test.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/monitor_status.test.ts diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/monitor_status.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/monitor_status.ts new file mode 100644 index 0000000000000..cd32a410503a3 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/monitor_status.ts @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { handleActions, Action } from 'redux-actions'; +import { + getMonitorStatusAction, + getMonitorStatusActionSuccess, + getMonitorStatusActionFail, +} from '../actions'; +import { Ping } from '../../../../common/runtime_types'; +import { QueryParams } from '../actions/types'; + +export interface MonitorStatusState { + status: Ping | null; + loading: boolean; +} + +export const initialState: MonitorStatusState = { + status: null, + loading: false, +}; + +export type MonitorStatusPayload = QueryParams & Ping; + +export const monitorStatusReducer = handleActions( + { + [String(getMonitorStatusAction)]: (state, action) => ({ + ...state, + // reset state if monitorId changes + status: action.payload.monitorId === state?.status?.monitor?.id ? state.status : null, + loading: true, + }), + + [String(getMonitorStatusActionSuccess)]: (state, action: Action) => { + return { + ...state, + loading: false, + // Keeping url from prev request to display, if there is no latest status + status: { + url: action.payload?.url || state.status?.url, + ...action.payload, + } as Ping, + }; + }, + + [String(getMonitorStatusActionFail)]: (state) => ({ + ...state, + loading: false, + }), + }, + initialState +); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/network_events.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/network_events.ts new file mode 100644 index 0000000000000..0abe4aeb2c7be --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/network_events.ts @@ -0,0 +1,154 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { handleActions, Action } from 'redux-actions'; +import { NetworkEvent, SyntheticsNetworkEventsApiResponse } from '../../../../common/runtime_types'; +import { + FetchNetworkEventsParams, + FetchNetworkEventsFailPayload, + getNetworkEvents, + getNetworkEventsFail, + getNetworkEventsSuccess, +} from '../actions/network_events'; + +export interface NetworkEventsState { + [checkGroup: string]: { + [stepIndex: number]: { + events: NetworkEvent[]; + total: number; + loading: boolean; + error?: Error; + isWaterfallSupported: boolean; + hasNavigationRequest?: boolean; + }; + }; +} + +const initialState: NetworkEventsState = {}; + +type Payload = FetchNetworkEventsParams & + SyntheticsNetworkEventsApiResponse & + FetchNetworkEventsFailPayload & + string[]; + +export const networkEventsReducer = handleActions( + { + [String(getNetworkEvents)]: ( + state: NetworkEventsState, + { payload: { checkGroup, stepIndex } }: Action + ) => ({ + ...state, + [checkGroup]: state[checkGroup] + ? { + [stepIndex]: state[checkGroup][stepIndex] + ? { + ...state[checkGroup][stepIndex], + loading: true, + events: [], + total: 0, + isWaterfallSupported: true, + } + : { + loading: true, + events: [], + total: 0, + isWaterfallSupported: true, + }, + } + : { + [stepIndex]: { + loading: true, + events: [], + total: 0, + isWaterfallSupported: true, + }, + }, + }), + + [String(getNetworkEventsSuccess)]: ( + state: NetworkEventsState, + { + payload: { + events, + total, + checkGroup, + stepIndex, + isWaterfallSupported, + hasNavigationRequest, + }, + }: Action + ) => { + return { + ...state, + [checkGroup]: state[checkGroup] + ? { + [stepIndex]: state[checkGroup][stepIndex] + ? { + ...state[checkGroup][stepIndex], + loading: false, + events, + total, + isWaterfallSupported, + hasNavigationRequest, + } + : { + loading: false, + events, + total, + isWaterfallSupported, + hasNavigationRequest, + }, + } + : { + [stepIndex]: { + loading: false, + events, + total, + isWaterfallSupported, + hasNavigationRequest, + }, + }, + }; + }, + + [String(getNetworkEventsFail)]: ( + state: NetworkEventsState, + { payload: { checkGroup, stepIndex, error } }: Action + ) => ({ + ...state, + [checkGroup]: state[checkGroup] + ? { + [stepIndex]: state[checkGroup][stepIndex] + ? { + ...state[checkGroup][stepIndex], + loading: false, + events: [], + total: 0, + error, + isWaterfallSupported: true, + } + : { + loading: false, + events: [], + total: 0, + error, + isWaterfallSupported: true, + }, + } + : { + [stepIndex]: { + loading: false, + events: [], + total: 0, + error, + isWaterfallSupported: true, + }, + }, + }), + }, + initialState +); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/ping.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/ping.ts new file mode 100644 index 0000000000000..f156a5596a84e --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/ping.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { handleActions, Action } from 'redux-actions'; +import { getPingHistogram } from '../actions'; +import { HistogramResult } from '../../../../common/runtime_types'; + +export interface PingState { + pingHistogram: HistogramResult | null; + errors: any[]; + loading: boolean; +} + +const initialState: PingState = { + pingHistogram: null, + loading: false, + errors: [], +}; + +type MonitorStatusPayload = HistogramResult & Error; + +export const pingReducer = handleActions( + { + [String(getPingHistogram.get)]: (state) => ({ + ...state, + loading: true, + }), + + [String(getPingHistogram.success)]: (state: PingState, action: Action) => ({ + ...state, + loading: false, + pingHistogram: { ...action.payload }, + }), + + [String(getPingHistogram.fail)]: (state, action: Action) => ({ + ...state, + errors: [...state.errors, action.payload], + loading: false, + }), + }, + initialState +); diff --git a/x-pack/plugins/synthetics/public/state/reducers/ping_list.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/ping_list.ts similarity index 94% rename from x-pack/plugins/synthetics/public/state/reducers/ping_list.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/ping_list.ts index 09d9347cedd3b..4403c2484dedb 100644 --- a/x-pack/plugins/synthetics/public/state/reducers/ping_list.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/ping_list.ts @@ -6,7 +6,7 @@ */ import { handleActions, Action } from 'redux-actions'; -import { PingsResponse } from '../../../common/runtime_types'; +import { PingsResponse } from '../../../../common/runtime_types'; import { clearPings, getPings, getPingsSuccess, getPingsFail } from '../actions'; export interface PingListState { diff --git a/x-pack/plugins/synthetics/public/state/reducers/selected_filters.test.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/selected_filters.test.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/reducers/selected_filters.test.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/selected_filters.test.ts diff --git a/x-pack/plugins/synthetics/public/state/reducers/selected_filters.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/selected_filters.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/reducers/selected_filters.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/selected_filters.ts diff --git a/x-pack/plugins/synthetics/public/state/reducers/synthetics.test.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/synthetics.test.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/reducers/synthetics.test.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/synthetics.test.ts diff --git a/x-pack/plugins/synthetics/public/state/reducers/synthetics.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/synthetics.ts similarity index 99% rename from x-pack/plugins/synthetics/public/state/reducers/synthetics.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/synthetics.ts index 1e97c3972444b..2a0cf7188a9e8 100644 --- a/x-pack/plugins/synthetics/public/state/reducers/synthetics.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/synthetics.ts @@ -9,7 +9,7 @@ import { createAction, handleActions, Action } from 'redux-actions'; import { isScreenshotBlockDoc, ScreenshotBlockDoc, -} from '../../../common/runtime_types/ping/synthetics'; +} from '../../../../common/runtime_types/ping/synthetics'; export interface PendingBlock { status: 'pending' | 'loading'; diff --git a/x-pack/plugins/synthetics/public/state/reducers/test_now_runs.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/test_now_runs.ts similarity index 98% rename from x-pack/plugins/synthetics/public/state/reducers/test_now_runs.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/test_now_runs.ts index d081039e4d901..ffe49ff017259 100644 --- a/x-pack/plugins/synthetics/public/state/reducers/test_now_runs.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/test_now_runs.ts @@ -13,7 +13,7 @@ import { ScheduleUnit, ServiceLocationErrors, SyntheticsMonitorSchedule, -} from '../../../common/runtime_types'; +} from '../../../../common/runtime_types'; import { clearTestNowMonitorAction, testNowMonitorAction } from '../actions'; import { TestNowResponse } from '../api'; import { AppState } from '..'; diff --git a/x-pack/plugins/synthetics/public/state/reducers/types.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/types.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/reducers/types.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/types.ts diff --git a/x-pack/plugins/synthetics/public/state/reducers/ui.test.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/ui.test.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/reducers/ui.test.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/ui.test.ts diff --git a/x-pack/plugins/synthetics/public/state/reducers/ui.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/ui.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/reducers/ui.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/ui.ts diff --git a/x-pack/plugins/synthetics/public/state/reducers/utils.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/utils.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/reducers/utils.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/utils.ts diff --git a/x-pack/plugins/synthetics/public/state/selectors/index.test.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/selectors/index.test.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/selectors/index.test.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/selectors/index.test.ts diff --git a/x-pack/plugins/synthetics/public/state/selectors/index.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/selectors/index.ts similarity index 100% rename from x-pack/plugins/synthetics/public/state/selectors/index.ts rename to x-pack/plugins/synthetics/public/legacy_uptime/state/selectors/index.ts diff --git a/x-pack/plugins/synthetics/public/lib/alert_types/duration_anomaly.tsx b/x-pack/plugins/synthetics/public/lib/alert_types/duration_anomaly.tsx deleted file mode 100644 index 79b2b28652497..0000000000000 --- a/x-pack/plugins/synthetics/public/lib/alert_types/duration_anomaly.tsx +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import moment from 'moment'; - -import { ALERT_END, ALERT_STATUS, ALERT_STATUS_ACTIVE, ALERT_REASON } from '@kbn/rule-data-utils'; - -import { ObservabilityRuleTypeModel } from '@kbn/observability-plugin/public'; -import { AlertTypeInitializer } from '.'; -import { getMonitorRouteFromMonitorId } from '../../../common/utils/get_monitor_url'; -import { CLIENT_ALERT_TYPES } from '../../../common/constants/alerts'; -import { DurationAnomalyTranslations } from '../../../common/translations'; - -const { defaultActionMessage, description } = DurationAnomalyTranslations; -const DurationAnomalyAlert = React.lazy(() => import('./lazy_wrapper/duration_anomaly')); - -export const initDurationAnomalyAlertType: AlertTypeInitializer = ({ - core, - plugins, -}): ObservabilityRuleTypeModel => ({ - id: CLIENT_ALERT_TYPES.DURATION_ANOMALY, - iconClass: 'uptimeApp', - documentationUrl(docLinks) { - return `${docLinks.links.observability.uptimeDurationAnomaly}`; - }, - ruleParamsExpression: (params: unknown) => ( - - ), - description, - validate: () => ({ errors: {} }), - defaultActionMessage, - requiresAppContext: true, - format: ({ fields }) => ({ - reason: fields[ALERT_REASON] || '', - link: getMonitorRouteFromMonitorId({ - monitorId: fields['monitor.id']!, - dateRangeEnd: fields[ALERT_STATUS] === ALERT_STATUS_ACTIVE ? 'now' : fields[ALERT_END]!, - dateRangeStart: moment(new Date(fields['anomaly.start']!)).subtract('5', 'm').toISOString(), - }), - }), -}); diff --git a/x-pack/plugins/synthetics/public/lib/alert_types/index.ts b/x-pack/plugins/synthetics/public/lib/alert_types/index.ts deleted file mode 100644 index 7217e0a083e6b..0000000000000 --- a/x-pack/plugins/synthetics/public/lib/alert_types/index.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { CoreStart } from '@kbn/core/public'; -import { ObservabilityRuleTypeModel } from '@kbn/observability-plugin/public'; -import { RuleTypeModel } from '@kbn/triggers-actions-ui-plugin/public'; -import { initMonitorStatusAlertType } from './monitor_status'; -import { initTlsAlertType } from './tls'; -import { initTlsLegacyAlertType } from './tls_legacy'; -import { ClientPluginsStart } from '../../apps/plugin'; -import { initDurationAnomalyAlertType } from './duration_anomaly'; - -export type AlertTypeInitializer = (dependenies: { - core: CoreStart; - plugins: ClientPluginsStart; -}) => TAlertTypeModel; - -export const alertTypeInitializers: AlertTypeInitializer[] = [ - initMonitorStatusAlertType, - initTlsAlertType, - initDurationAnomalyAlertType, -]; - -export const legacyAlertTypeInitializers: Array> = [ - initTlsLegacyAlertType, -]; diff --git a/x-pack/plugins/synthetics/public/lib/alert_types/lazy_wrapper/duration_anomaly.tsx b/x-pack/plugins/synthetics/public/lib/alert_types/lazy_wrapper/duration_anomaly.tsx deleted file mode 100644 index bb1f84a45114d..0000000000000 --- a/x-pack/plugins/synthetics/public/lib/alert_types/lazy_wrapper/duration_anomaly.tsx +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { Provider as ReduxProvider } from 'react-redux'; -import { CoreStart } from '@kbn/core/public'; -import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; -import { store } from '../../../state'; -import { AnomalyAlertComponent } from '../../../components/overview/alerts/anomaly_alert/anomaly_alert'; -import { ClientPluginsStart } from '../../../apps/plugin'; -import { kibanaService } from '../../../state/kibana_service'; - -interface Props { - core: CoreStart; - plugins: ClientPluginsStart; - params: any; -} - -// eslint-disable-next-line import/no-default-export -export default function DurationAnomalyAlert({ core, plugins, params }: Props) { - kibanaService.core = core; - return ( - - - - - - ); -} diff --git a/x-pack/plugins/synthetics/public/lib/alert_types/lazy_wrapper/monitor_status.tsx b/x-pack/plugins/synthetics/public/lib/alert_types/lazy_wrapper/monitor_status.tsx deleted file mode 100644 index 3c8c8946fa06d..0000000000000 --- a/x-pack/plugins/synthetics/public/lib/alert_types/lazy_wrapper/monitor_status.tsx +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { Provider as ReduxProvider } from 'react-redux'; -import { CoreStart } from '@kbn/core/public'; -import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; -import { store } from '../../../state'; -import { ClientPluginsStart } from '../../../apps/plugin'; -import { kibanaService } from '../../../state/kibana_service'; -import { AlertMonitorStatus } from '../../../components/overview/alerts/alerts_containers/alert_monitor_status'; -import { UptimeIndexPatternContextProvider } from '../../../contexts/uptime_index_pattern_context'; - -interface Props { - core: CoreStart; - plugins: ClientPluginsStart; - params: any; -} - -// eslint-disable-next-line import/no-default-export -export default function MonitorStatusAlert({ core, plugins, params }: Props) { - kibanaService.core = core; - return ( - - - - - - - - ); -} diff --git a/x-pack/plugins/synthetics/public/lib/alert_types/monitor_status.tsx b/x-pack/plugins/synthetics/public/lib/alert_types/monitor_status.tsx deleted file mode 100644 index 99d8e22f11cdb..0000000000000 --- a/x-pack/plugins/synthetics/public/lib/alert_types/monitor_status.tsx +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import moment from 'moment'; - -import { - ALERT_END, - ALERT_START, - ALERT_STATUS, - ALERT_STATUS_ACTIVE, - ALERT_REASON, -} from '@kbn/rule-data-utils'; - -import { ObservabilityRuleTypeModel } from '@kbn/observability-plugin/public'; -import { ValidationResult } from '@kbn/triggers-actions-ui-plugin/public'; -import { AlertTypeInitializer } from '.'; -import { getMonitorRouteFromMonitorId } from '../../../common/utils/get_monitor_url'; -import { MonitorStatusTranslations } from '../../../common/translations'; -import { CLIENT_ALERT_TYPES } from '../../../common/constants/alerts'; - -const { defaultActionMessage, description } = MonitorStatusTranslations; - -const MonitorStatusAlert = React.lazy(() => import('./lazy_wrapper/monitor_status')); - -let validateFunc: (ruleParams: any) => ValidationResult; - -export const initMonitorStatusAlertType: AlertTypeInitializer = ({ - core, - plugins, -}): ObservabilityRuleTypeModel => ({ - id: CLIENT_ALERT_TYPES.MONITOR_STATUS, - description, - iconClass: 'uptimeApp', - documentationUrl(docLinks) { - return `${docLinks.links.observability.monitorStatus}`; - }, - ruleParamsExpression: (params: any) => ( - - ), - validate: (ruleParams: any) => { - if (!validateFunc) { - (async function loadValidate() { - const { validateMonitorStatusParams } = await import( - './lazy_wrapper/validate_monitor_status' - ); - validateFunc = validateMonitorStatusParams; - })(); - } - return validateFunc ? validateFunc(ruleParams) : ({} as ValidationResult); - }, - defaultActionMessage, - requiresAppContext: false, - format: ({ fields }) => ({ - reason: fields[ALERT_REASON] || '', - link: getMonitorRouteFromMonitorId({ - monitorId: fields['monitor.id']!, - dateRangeEnd: fields[ALERT_STATUS] === ALERT_STATUS_ACTIVE ? 'now' : fields[ALERT_END]!, - dateRangeStart: moment(new Date(fields[ALERT_START]!)).subtract('5', 'm').toISOString(), - filters: { - 'observer.geo.name': [fields['observer.geo.name'][0]], - }, - }), - }), -}); diff --git a/x-pack/plugins/synthetics/public/lib/lib.ts b/x-pack/plugins/synthetics/public/lib/lib.ts deleted file mode 100644 index 80be43e97b82b..0000000000000 --- a/x-pack/plugins/synthetics/public/lib/lib.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { UMBadge } from '../badge'; - -export type UMUpdateBadge = (badge: UMBadge) => void; diff --git a/x-pack/plugins/synthetics/public/pages/monitor_management/monitor_management.tsx b/x-pack/plugins/synthetics/public/pages/monitor_management/monitor_management.tsx deleted file mode 100644 index 5c8efb14dac2f..0000000000000 --- a/x-pack/plugins/synthetics/public/pages/monitor_management/monitor_management.tsx +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useEffect, useRef, useState } from 'react'; -import { i18n } from '@kbn/i18n'; -import { useDispatch, useSelector } from 'react-redux'; -import { EuiCallOut, EuiButton, EuiSpacer, EuiLink } from '@elastic/eui'; -import { useTrackPageview } from '@kbn/observability-plugin/public'; -import { ConfigKey } from '../../../common/runtime_types'; -import { getMonitors } from '../../state/actions'; -import { monitorManagementListSelector } from '../../state/selectors'; -import { useMonitorManagementBreadcrumbs } from './use_monitor_management_breadcrumbs'; -import { MonitorListContainer } from '../../components/monitor_management/monitor_list/monitor_list_container'; -import { EnablementEmptyState } from '../../components/monitor_management/monitor_list/enablement_empty_state'; -import { useEnablement } from '../../components/monitor_management/hooks/use_enablement'; -import { useLocations } from '../../components/monitor_management/hooks/use_locations'; -import { Loader } from '../../components/monitor_management/loader/loader'; -import { ERROR_HEADING_LABEL } from './content'; - -export const MonitorManagementPage: React.FC = () => { - useTrackPageview({ app: 'uptime', path: 'manage-monitors' }); - useTrackPageview({ app: 'uptime', path: 'manage-monitors', delay: 15000 }); - useMonitorManagementBreadcrumbs(); - const dispatch = useDispatch(); - const [shouldFocusEnablementButton, setShouldFocusEnablementButton] = useState(false); - - const { - error: enablementError, - enablement, - loading: enablementLoading, - enableSynthetics, - } = useEnablement(); - const { loading: locationsLoading } = useLocations(); - const { list: monitorList } = useSelector(monitorManagementListSelector); - const { isEnabled } = enablement; - - const isEnabledRef = useRef(isEnabled); - - useEffect(() => { - if (monitorList.total === null) { - dispatch( - getMonitors({ - page: 1, // saved objects page index is base 1 - perPage: 10, - sortOrder: 'asc', - sortField: `${ConfigKey.NAME}.keyword`, - }) - ); - } - }, [dispatch, monitorList.total]); - - useEffect(() => { - if (!isEnabled && isEnabledRef.current === true) { - /* shift focus to enable button when enable toggle disappears. Prevent - * focus loss on the page */ - setShouldFocusEnablementButton(true); - } - isEnabledRef.current = Boolean(isEnabled); - }, [isEnabled]); - - return ( - <> - - {!isEnabled && monitorList.total && monitorList.total > 0 ? ( - <> - -

{CALLOUT_MANAGEMENT_DESCRIPTION}

- {enablement.canEnable ? ( - { - enableSynthetics(); - }} - > - {SYNTHETICS_ENABLE_LABEL} - - ) : ( -

- {CALLOUT_MANAGEMENT_CONTACT_ADMIN}{' '} - - {LEARN_MORE_LABEL} - -

- )} -
- - - ) : null} - {isEnabled || (!isEnabled && monitorList.total) ? : null} -
- {isEnabled !== undefined && monitorList.total === 0 && ( - - )} - - ); -}; - -const LOADING_LABEL = i18n.translate('xpack.uptime.monitorManagement.manageMonitorLoadingLabel', { - defaultMessage: 'Loading Monitor Management', -}); - -const LEARN_MORE_LABEL = i18n.translate( - 'xpack.uptime.monitorManagement.manageMonitorLoadingLabel.callout.learnMore', - { - defaultMessage: 'Learn more.', - } -); - -const CALLOUT_MANAGEMENT_DISABLED = i18n.translate( - 'xpack.uptime.monitorManagement.callout.disabled', - { - defaultMessage: 'Monitor Management is disabled', - } -); - -const CALLOUT_MANAGEMENT_CONTACT_ADMIN = i18n.translate( - 'xpack.uptime.monitorManagement.callout.disabled.adminContact', - { - defaultMessage: 'Please contact your administrator to enable Monitor Management.', - } -); - -const CALLOUT_MANAGEMENT_DESCRIPTION = i18n.translate( - 'xpack.uptime.monitorManagement.callout.description.disabled', - { - defaultMessage: - 'Monitor Management is currently disabled. To run your monitors on Elastic managed Synthetics service, enable Monitor Management. Your existing monitors are paused.', - } -); - -const ERROR_HEADING_BODY = i18n.translate( - 'xpack.uptime.monitorManagement.editMonitorError.description', - { - defaultMessage: 'Monitor Management settings could not be loaded. Please contact Support.', - } -); - -const SYNTHETICS_ENABLE_LABEL = i18n.translate( - 'xpack.uptime.monitorManagement.syntheticsEnableLabel.management', - { - defaultMessage: 'Enable Monitor Management', - } -); diff --git a/x-pack/plugins/synthetics/public/pages/monitor_management/service_allowed_wrapper.tsx b/x-pack/plugins/synthetics/public/pages/monitor_management/service_allowed_wrapper.tsx deleted file mode 100644 index 4869b28495183..0000000000000 --- a/x-pack/plugins/synthetics/public/pages/monitor_management/service_allowed_wrapper.tsx +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { i18n } from '@kbn/i18n'; -import { EuiButton, EuiEmptyPrompt, EuiLoadingLogo } from '@elastic/eui'; -import { useSyntheticsServiceAllowed } from '../../components/monitor_management/hooks/use_service_allowed'; - -export const ServiceAllowedWrapper: React.FC = ({ children }) => { - const { isAllowed, signupUrl, loading } = useSyntheticsServiceAllowed(); - - if (loading) { - return ( - } - title={

{LOADING_MONITOR_MANAGEMENT_LABEL}

} - /> - ); - } - - // checking for explicit false - if (isAllowed === false) { - return ( - {MONITOR_MANAGEMENT_LABEL}

} - body={

{PUBLIC_BETA_DESCRIPTION}

} - actions={[ - - {REQUEST_ACCESS_LABEL} - , - ]} - /> - ); - } - - return <>{children}; -}; - -const REQUEST_ACCESS_LABEL = i18n.translate('xpack.uptime.monitorManagement.requestAccess', { - defaultMessage: 'Request access', -}); - -export const MONITOR_MANAGEMENT_LABEL = i18n.translate('xpack.uptime.monitorManagement.label', { - defaultMessage: 'Monitor Management', -}); - -const LOADING_MONITOR_MANAGEMENT_LABEL = i18n.translate( - 'xpack.uptime.monitorManagement.loading.label', - { - defaultMessage: 'Loading Monitor Management', - } -); - -export const PUBLIC_BETA_DESCRIPTION = i18n.translate( - 'xpack.uptime.monitorManagement.publicBetaDescription', - { - defaultMessage: - "We've got a brand new app on the way. In the meantime, we're excited to give you early access to our globally managed testing infrastructure. This will allow you to upload synthetic monitors using our new point and click script recorder and manage your monitors with a new UI.", - } -); diff --git a/x-pack/plugins/synthetics/public/pages/translations.ts b/x-pack/plugins/synthetics/public/pages/translations.ts deleted file mode 100644 index 95a8dd8ee3696..0000000000000 --- a/x-pack/plugins/synthetics/public/pages/translations.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const REFRESH_CERT = i18n.translate('xpack.uptime.certificates.refresh', { - defaultMessage: 'Refresh', -}); - -export const settings = { - breadcrumbText: i18n.translate('xpack.uptime.settingsBreadcrumbText', { - defaultMessage: 'Settings', - }), - editNoticeTitle: i18n.translate('xpack.uptime.settings.cannotEditTitle', { - defaultMessage: 'You do not have permission to edit settings.', - }), - editNoticeText: i18n.translate('xpack.uptime.settings.cannotEditText', { - defaultMessage: - "Your user currently has 'Read' permissions for the Uptime app. Enable a permissions-level of 'All' to edit these settings.", - }), - mustBeNumber: i18n.translate('xpack.uptime.settings.blankNumberField.error', { - defaultMessage: 'Must be a number.', - }), -}; - -export const BLANK_STR = i18n.translate('xpack.uptime.settings.blank.error', { - defaultMessage: 'May not be blank.', -}); - -export const SPACE_STR = i18n.translate('xpack.uptime.settings.noSpace.error', { - defaultMessage: 'Index names must not contain space', -}); diff --git a/x-pack/plugins/synthetics/public/plugin.ts b/x-pack/plugins/synthetics/public/plugin.ts new file mode 100644 index 0000000000000..88238b1bfbf37 --- /dev/null +++ b/x-pack/plugins/synthetics/public/plugin.ts @@ -0,0 +1,272 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + CoreSetup, + CoreStart, + Plugin, + PluginInitializerContext, + AppMountParameters, +} from '@kbn/core/public'; +import { from } from 'rxjs'; +import { map } from 'rxjs/operators'; +import { i18n } from '@kbn/i18n'; +import { SharePluginSetup, SharePluginStart } from '@kbn/share-plugin/public'; +import { DiscoverStart } from '@kbn/discover-plugin/public'; +import { DEFAULT_APP_CATEGORIES } from '@kbn/core/public'; + +import type { HomePublicPluginSetup } from '@kbn/home-plugin/public'; +import { EmbeddableStart } from '@kbn/embeddable-plugin/public'; +import { + TriggersAndActionsUIPublicPluginSetup, + TriggersAndActionsUIPublicPluginStart, +} from '@kbn/triggers-actions-ui-plugin/public'; +import { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; +import { DataPublicPluginSetup, DataPublicPluginStart } from '@kbn/data-plugin/public'; + +import { FleetStart } from '@kbn/fleet-plugin/public'; +import { + FetchDataParams, + ObservabilityPublicSetup, + ObservabilityPublicStart, +} from '@kbn/observability-plugin/public'; +import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; +import { Start as InspectorPluginStart } from '@kbn/inspector-plugin/public'; +import { CasesUiStart } from '@kbn/cases-plugin/public'; +import { CloudSetup } from '@kbn/cloud-plugin/public'; +import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; +import { PLUGIN } from '../common/constants/plugin'; +import { + LazySyntheticsPolicyCreateExtension, + LazySyntheticsPolicyEditExtension, +} from './legacy_uptime/components/fleet_package'; +import { LazySyntheticsCustomAssetsExtension } from './legacy_uptime/components/fleet_package/lazy_synthetics_custom_assets_extension'; +import { uptimeOverviewNavigatorParams } from './apps/locators/overview'; +import { + alertTypeInitializers, + legacyAlertTypeInitializers, +} from './legacy_uptime/lib/alert_types'; + +export interface ClientPluginsSetup { + home?: HomePublicPluginSetup; + data: DataPublicPluginSetup; + observability: ObservabilityPublicSetup; + share: SharePluginSetup; + triggersActionsUi: TriggersAndActionsUIPublicPluginSetup; + cloud?: CloudSetup; +} + +export interface ClientPluginsStart { + fleet?: FleetStart; + data: DataPublicPluginStart; + unifiedSearch: UnifiedSearchPublicPluginStart; + discover: DiscoverStart; + inspector: InspectorPluginStart; + embeddable: EmbeddableStart; + observability: ObservabilityPublicStart; + share: SharePluginStart; + triggersActionsUi: TriggersAndActionsUIPublicPluginStart; + cases: CasesUiStart; + dataViews: DataViewsPublicPluginStart; +} + +export interface UptimePluginServices extends Partial { + embeddable: EmbeddableStart; + data: DataPublicPluginStart; + triggersActionsUi: TriggersAndActionsUIPublicPluginStart; + storage: IStorageWrapper; +} + +export type ClientSetup = void; +export type ClientStart = void; + +export class UptimePlugin + implements Plugin +{ + constructor(private readonly initContext: PluginInitializerContext) {} + + public setup(core: CoreSetup, plugins: ClientPluginsSetup): void { + if (plugins.home) { + plugins.home.featureCatalogue.register({ + id: PLUGIN.ID, + title: PLUGIN.TITLE, + description: PLUGIN.DESCRIPTION, + icon: 'uptimeApp', + path: '/app/uptime', + showOnHomePage: false, + category: 'data', + }); + } + const getUptimeDataHelper = async () => { + const [coreStart] = await core.getStartServices(); + const { UptimeDataHelper } = await import('./legacy_uptime/app/uptime_overview_fetcher'); + + return UptimeDataHelper(coreStart); + }; + + plugins.share.url.locators.create(uptimeOverviewNavigatorParams); + + plugins.observability.dashboard.register({ + appName: 'synthetics', + hasData: async () => { + const dataHelper = await getUptimeDataHelper(); + const status = await dataHelper.indexStatus(); + return { hasData: status.docCount > 0, indices: status.indices }; + }, + fetchData: async (params: FetchDataParams) => { + const dataHelper = await getUptimeDataHelper(); + return await dataHelper.overviewData(params); + }, + }); + + plugins.observability.navigation.registerSections( + from(core.getStartServices()).pipe( + map(([coreStart]) => { + if (coreStart.application.capabilities.uptime.show) { + return [ + { + label: 'Uptime', + sortKey: 500, + entries: [ + { + label: i18n.translate('xpack.synthetics.overview.heading', { + defaultMessage: 'Monitors', + }), + app: 'uptime', + path: '/', + matchFullPath: true, + ignoreTrailingSlash: true, + }, + { + label: i18n.translate('xpack.synthetics.certificatesPage.heading', { + defaultMessage: 'TLS Certificates', + }), + app: 'uptime', + path: '/certificates', + matchFullPath: true, + }, + ], + }, + ]; + } + + return []; + }) + ) + ); + + const { observabilityRuleTypeRegistry } = plugins.observability; + + core.getStartServices().then(([coreStart, clientPluginsStart]) => { + alertTypeInitializers.forEach((init) => { + const alertInitializer = init({ + core: coreStart, + plugins: clientPluginsStart, + }); + if ( + clientPluginsStart.triggersActionsUi && + !clientPluginsStart.triggersActionsUi.ruleTypeRegistry.has(alertInitializer.id) + ) { + observabilityRuleTypeRegistry.register(alertInitializer); + } + }); + + legacyAlertTypeInitializers.forEach((init) => { + const alertInitializer = init({ + core: coreStart, + plugins: clientPluginsStart, + }); + if ( + clientPluginsStart.triggersActionsUi && + !clientPluginsStart.triggersActionsUi.ruleTypeRegistry.has(alertInitializer.id) + ) { + plugins.triggersActionsUi.ruleTypeRegistry.register(alertInitializer); + } + }); + }); + + const appKeywords = [ + 'Synthetics', + 'pings', + 'checks', + 'availability', + 'response duration', + 'response time', + 'outside in', + 'reachability', + 'reachable', + 'digital', + 'performance', + 'web performance', + 'web perf', + ]; + + core.application.register({ + id: PLUGIN.ID, + euiIconType: 'logoObservability', + order: 8400, + title: PLUGIN.TITLE, + category: DEFAULT_APP_CATEGORIES.observability, + keywords: appKeywords, + deepLinks: [ + { id: 'Down monitors', title: 'Down monitors', path: '/?statusFilter=down' }, + { id: 'Certificates', title: 'TLS Certificates', path: '/certificates' }, + { id: 'Settings', title: 'Settings', path: '/settings' }, + ], + mount: async (params: AppMountParameters) => { + const [coreStart, corePlugins] = await core.getStartServices(); + + const { renderApp } = await import('./legacy_uptime/app/render_app'); + return renderApp(coreStart, plugins, corePlugins, params, this.initContext.env.mode.dev); + }, + }); + + // Register the Synthetics UI plugin + core.application.register({ + id: 'synthetics', + euiIconType: 'logoObservability', + order: 8400, + title: PLUGIN.SYNTHETICS, + category: DEFAULT_APP_CATEGORIES.observability, + keywords: appKeywords, + deepLinks: [], + mount: async (params: AppMountParameters) => { + const [coreStart, corePlugins] = await core.getStartServices(); + + const { renderApp } = await import('./apps/synthetics/render_app'); + return renderApp(coreStart, plugins, corePlugins, params, this.initContext.env.mode.dev); + }, + }); + } + + public start(start: CoreStart, plugins: ClientPluginsStart): void { + if (plugins.fleet) { + const { registerExtension } = plugins.fleet; + + registerExtension({ + package: 'synthetics', + view: 'package-policy-create', + Component: LazySyntheticsPolicyCreateExtension, + }); + + registerExtension({ + package: 'synthetics', + view: 'package-policy-edit', + useLatestPackageVersion: true, + Component: LazySyntheticsPolicyEditExtension, + }); + + registerExtension({ + package: 'synthetics', + view: 'package-detail-assets', + Component: LazySyntheticsCustomAssetsExtension, + }); + } + } + + public stop(): void {} +} diff --git a/x-pack/plugins/synthetics/public/routes.tsx b/x-pack/plugins/synthetics/public/routes.tsx deleted file mode 100644 index a8610462e4363..0000000000000 --- a/x-pack/plugins/synthetics/public/routes.tsx +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { FC, useEffect } from 'react'; -import { EuiPageTemplateProps, EuiBetaBadge, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { Route, Switch } from 'react-router-dom'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { i18n } from '@kbn/i18n'; -import { APP_WRAPPER_CLASS } from '@kbn/core/public'; -import { useInspectorContext } from '@kbn/observability-plugin/public'; -import { - CERTIFICATES_ROUTE, - MAPPING_ERROR_ROUTE, - MONITOR_ROUTE, - MONITOR_ADD_ROUTE, - MONITOR_EDIT_ROUTE, - MONITOR_MANAGEMENT_ROUTE, - OVERVIEW_ROUTE, - SETTINGS_ROUTE, - STEP_DETAIL_ROUTE, - SYNTHETIC_CHECK_STEPS_ROUTE, -} from '../common/constants'; -import { - MappingErrorPage, - MonitorPage, - AddMonitorPage, - EditMonitorPage, - MonitorManagementPage, - StepDetailPage, - NotFoundPage, - SettingsPage, - MonitorManagementBottomBar, -} from './pages'; -import { CertificatesPage } from './pages/certificates'; -import { UptimePage, useUptimeTelemetry } from './hooks'; -import { OverviewPageComponent } from './pages/overview'; -import { - SyntheticsCheckSteps, - SyntheticsCheckStepsPageHeader, - SyntheticsCheckStepsPageRightSideItem, -} from './pages/synthetics/synthetics_checks'; -import { MonitorPageTitle, MonitorPageTitleContent } from './components/monitor/monitor_title'; -import { UptimeDatePicker } from './components/common/uptime_date_picker'; -import { CertRefreshBtn } from './components/certificates/cert_refresh_btn'; -import { CertificateTitle } from './components/certificates/certificate_title'; -import { SyntheticsCallout } from './components/overview/synthetics_callout'; -import { - StepDetailPageChildren, - StepDetailPageHeader, - StepDetailPageRightSideItem, -} from './pages/synthetics/step_detail_page'; -import { UptimePageTemplateComponent } from './apps/uptime_page_template'; -import { apiService } from './state/api/utils'; -import { AddMonitorBtn } from './components/monitor_management/add_monitor_btn'; -import { SettingsBottomBar } from './components/settings/settings_bottom_bar'; -import { ServiceAllowedWrapper } from './pages/monitor_management/service_allowed_wrapper'; - -type RouteProps = { - path: string; - component: React.FC; - dataTestSubj: string; - title: string; - telemetryId: UptimePage; - pageHeader: { - pageTitle: string | JSX.Element; - children?: JSX.Element; - rightSideItems?: JSX.Element[]; - }; -} & EuiPageTemplateProps; - -const baseTitle = i18n.translate('xpack.uptime.routes.baseTitle', { - defaultMessage: 'Uptime - Kibana', -}); - -export const MONITORING_OVERVIEW_LABEL = i18n.translate('xpack.uptime.overview.heading', { - defaultMessage: 'Monitors', -}); - -const getRoutes = (): RouteProps[] => { - return [ - { - title: i18n.translate('xpack.uptime.monitorRoute.title', { - defaultMessage: 'Monitor | {baseTitle}', - values: { baseTitle }, - }), - path: MONITOR_ROUTE, - component: MonitorPage, - dataTestSubj: 'uptimeMonitorPage', - telemetryId: UptimePage.Monitor, - pageHeader: { - children: , - pageTitle: , - rightSideItems: [], - }, - }, - { - title: i18n.translate('xpack.uptime.settingsRoute.title', { - defaultMessage: `Settings | {baseTitle}`, - values: { baseTitle }, - }), - path: SETTINGS_ROUTE, - component: SettingsPage, - dataTestSubj: 'uptimeSettingsPage', - telemetryId: UptimePage.Settings, - pageHeader: { - pageTitle: ( - - ), - }, - bottomBar: , - bottomBarProps: { paddingSize: 'm' as const }, - }, - { - title: i18n.translate('xpack.uptime.certificatesRoute.title', { - defaultMessage: `Certificates | {baseTitle}`, - values: { baseTitle }, - }), - path: CERTIFICATES_ROUTE, - component: CertificatesPage, - dataTestSubj: 'uptimeCertificatesPage', - telemetryId: UptimePage.Certificates, - pageHeader: { - pageTitle: , - rightSideItems: [], - }, - }, - { - title: i18n.translate('xpack.uptime.stepDetailRoute.title', { - defaultMessage: 'Synthetics detail | {baseTitle}', - values: { baseTitle }, - }), - path: STEP_DETAIL_ROUTE, - component: StepDetailPage, - dataTestSubj: 'uptimeStepDetailPage', - telemetryId: UptimePage.StepDetail, - pageHeader: { - children: , - pageTitle: , - rightSideItems: [], - }, - }, - { - title: baseTitle, - path: SYNTHETIC_CHECK_STEPS_ROUTE, - component: SyntheticsCheckSteps, - dataTestSubj: 'uptimeSyntheticCheckStepsPage', - telemetryId: UptimePage.SyntheticCheckStepsPage, - pageHeader: { - pageTitle: , - rightSideItems: [], - }, - }, - { - title: baseTitle, - path: OVERVIEW_ROUTE, - component: OverviewPageComponent, - dataTestSubj: 'uptimeOverviewPage', - telemetryId: UptimePage.Overview, - pageHeader: { - pageTitle: MONITORING_OVERVIEW_LABEL, - rightSideItems: [], - }, - }, - { - title: i18n.translate('xpack.uptime.mappingErrorRoute.title', { - defaultMessage: 'Synthetics | mapping error', - }), - path: MAPPING_ERROR_ROUTE, - component: MappingErrorPage, - dataTestSubj: 'uptimeMappingErrorPage', - telemetryId: UptimePage.MappingError, - pageHeader: { - pageTitle: ( -
- -
- ), - rightSideItems: [], - }, - }, - { - title: i18n.translate('xpack.uptime.addMonitorRoute.title', { - defaultMessage: 'Add Monitor | {baseTitle}', - values: { baseTitle }, - }), - path: MONITOR_ADD_ROUTE, - component: () => ( - - - - ), - dataTestSubj: 'uptimeMonitorAddPage', - telemetryId: UptimePage.MonitorAdd, - pageHeader: { - pageTitle: ( - - ), - }, - bottomBar: , - bottomBarProps: { paddingSize: 'm' as const }, - }, - { - title: i18n.translate('xpack.uptime.editMonitorRoute.title', { - defaultMessage: 'Edit Monitor | {baseTitle}', - values: { baseTitle }, - }), - path: MONITOR_EDIT_ROUTE, - component: () => ( - - - - ), - dataTestSubj: 'uptimeMonitorEditPage', - telemetryId: UptimePage.MonitorEdit, - pageHeader: { - pageTitle: ( - - ), - }, - bottomBar: , - bottomBarProps: { paddingSize: 'm' as const }, - }, - { - title: i18n.translate('xpack.uptime.monitorManagementRoute.title', { - defaultMessage: 'Monitor Management | {baseTitle}', - values: { baseTitle }, - }), - path: MONITOR_MANAGEMENT_ROUTE + '/:type', - component: () => ( - - - - ), - dataTestSubj: 'uptimeMonitorManagementListPage', - telemetryId: UptimePage.MonitorManagement, - pageHeader: { - pageTitle: ( - - - - - - - - - ), - rightSideItems: [], - }, - }, - ]; -}; - -const RouteInit: React.FC> = ({ - path, - title, - telemetryId, -}) => { - useUptimeTelemetry(telemetryId); - useEffect(() => { - document.title = title; - }, [path, title]); - return null; -}; - -export const PageRouter: FC = () => { - const routes = getRoutes(); - const { addInspectorRequest } = useInspectorContext(); - - apiService.addInspectorRequest = addInspectorRequest; - - return ( - - {routes.map( - ({ - title, - path, - component: RouteComponent, - dataTestSubj, - telemetryId, - pageHeader, - ...pageTemplateProps - }) => ( - -
- - - - - -
-
- ) - )} - -
- ); -}; diff --git a/x-pack/plugins/synthetics/public/state/actions/dynamic_settings.ts b/x-pack/plugins/synthetics/public/state/actions/dynamic_settings.ts deleted file mode 100644 index 7b7939688010f..0000000000000 --- a/x-pack/plugins/synthetics/public/state/actions/dynamic_settings.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { createAction } from 'redux-actions'; -import { DynamicSettings } from '../../../common/runtime_types'; - -export const getDynamicSettings = createAction('GET_DYNAMIC_SETTINGS'); -export const getDynamicSettingsSuccess = createAction( - 'GET_DYNAMIC_SETTINGS_SUCCESS' -); -export const getDynamicSettingsFail = createAction('GET_DYNAMIC_SETTINGS_FAIL'); - -export const setDynamicSettings = createAction('SET_DYNAMIC_SETTINGS'); -export const setDynamicSettingsSuccess = createAction( - 'SET_DYNAMIC_SETTINGS_SUCCESS' -); -export const setDynamicSettingsFail = createAction('SET_DYNAMIC_SETTINGS_FAIL'); diff --git a/x-pack/plugins/synthetics/public/state/actions/index_status.ts b/x-pack/plugins/synthetics/public/state/actions/index_status.ts deleted file mode 100644 index 306565c1f507f..0000000000000 --- a/x-pack/plugins/synthetics/public/state/actions/index_status.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { createAsyncAction } from './utils'; -import { StatesIndexStatus } from '../../../common/runtime_types'; - -export const indexStatusAction = createAsyncAction('GET INDEX STATUS'); diff --git a/x-pack/plugins/synthetics/public/state/actions/journey.ts b/x-pack/plugins/synthetics/public/state/actions/journey.ts deleted file mode 100644 index bc03c443331c1..0000000000000 --- a/x-pack/plugins/synthetics/public/state/actions/journey.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { createAction } from 'redux-actions'; -import { SyntheticsJourneyApiResponse } from '../../../common/runtime_types'; - -export interface FetchJourneyStepsParams { - checkGroup: string; - syntheticEventTypes?: string[]; -} - -export interface GetJourneyFailPayload { - checkGroup: string; - error: Error; -} - -export const getJourneySteps = createAction('GET_JOURNEY_STEPS'); -export const getJourneyStepsSuccess = createAction( - 'GET_JOURNEY_STEPS_SUCCESS' -); -export const getJourneyStepsFail = createAction('GET_JOURNEY_STEPS_FAIL'); -export const pruneJourneyState = createAction('PRUNE_JOURNEY_STATE'); diff --git a/x-pack/plugins/synthetics/public/state/actions/monitor.ts b/x-pack/plugins/synthetics/public/state/actions/monitor.ts deleted file mode 100644 index f9dcd4bd57538..0000000000000 --- a/x-pack/plugins/synthetics/public/state/actions/monitor.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { createAction } from 'redux-actions'; -import { MonitorDetailsActionPayload } from './types'; -import { PingError } from '../../../common/runtime_types'; -import { MonitorLocations } from '../../../common/runtime_types'; -import { QueryParams } from './types'; -import { createAsyncAction } from './utils'; - -export interface MonitorLocationsPayload extends QueryParams { - monitorId: string; -} - -export interface MonitorDetailsState { - monitorId: string; - error: PingError; -} - -export const getMonitorDetailsAction = createAsyncAction< - MonitorDetailsActionPayload, - MonitorDetailsState ->('GET_MONITOR_DETAILS'); - -export const getMonitorLocationsAction = - createAction('GET_MONITOR_LOCATIONS'); -export const getMonitorLocationsActionSuccess = createAction( - 'GET_MONITOR_LOCATIONS_SUCCESS' -); -export const getMonitorLocationsActionFail = createAction('GET_MONITOR_LOCATIONS_FAIL'); diff --git a/x-pack/plugins/synthetics/public/state/actions/monitor_duration.ts b/x-pack/plugins/synthetics/public/state/actions/monitor_duration.ts deleted file mode 100644 index 1dd88c663cec5..0000000000000 --- a/x-pack/plugins/synthetics/public/state/actions/monitor_duration.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { createAction } from 'redux-actions'; -import { IHttpFetchError } from '@kbn/core/public'; -import { QueryParams } from './types'; -import { MonitorDurationResult } from '../../../common/types'; - -type MonitorQueryParams = QueryParams & { monitorId: string }; - -export const getMonitorDurationAction = createAction('GET_MONITOR_DURATION'); -export const getMonitorDurationActionSuccess = createAction( - 'GET_MONITOR_DURATION_SUCCESS' -); -export const getMonitorDurationActionFail = createAction( - 'GET_MONITOR_DURATION_FAIL' -); diff --git a/x-pack/plugins/synthetics/public/state/actions/monitor_list.ts b/x-pack/plugins/synthetics/public/state/actions/monitor_list.ts deleted file mode 100644 index b86853dcfbefe..0000000000000 --- a/x-pack/plugins/synthetics/public/state/actions/monitor_list.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { createAction } from 'redux-actions'; -import { FetchMonitorStatesQueryArgs, MonitorSummariesResult } from '../../../common/runtime_types'; -import { createAsyncAction } from './utils'; -import { TestNowResponse } from '../api'; - -export const getMonitorList = createAction('GET_MONITOR_LIST'); -export const getMonitorListSuccess = createAction( - 'GET_MONITOR_LIST_SUCCESS' -); -export const getMonitorListFailure = createAction('GET_MONITOR_LIST_FAIL'); - -export const setUpdatingMonitorId = createAction('SET_UPDATING_MONITOR_ID'); -export const clearRefreshedMonitorId = createAction('CLEAR_REFRESH_MONITOR_ID'); - -export const testNowMonitorAction = createAsyncAction( - 'TEST_NOW_MONITOR_ACTION' -); - -export const clearTestNowMonitorAction = createAction('CLEAR_TEST_NOW_MONITOR_ACTION'); - -export const getUpdatedMonitor = createAsyncAction< - FetchMonitorStatesQueryArgs, - MonitorSummariesResult ->('GET_UPDATED_MONITOR'); diff --git a/x-pack/plugins/synthetics/public/state/actions/monitor_management.ts b/x-pack/plugins/synthetics/public/state/actions/monitor_management.ts deleted file mode 100644 index 278f8fe9a4b99..0000000000000 --- a/x-pack/plugins/synthetics/public/state/actions/monitor_management.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { createAction } from '@reduxjs/toolkit'; -import { - MonitorManagementListResult, - ServiceLocations, - ThrottlingOptions, - FetchMonitorManagementListQueryArgs, -} from '../../../common/runtime_types'; -import { createAsyncAction } from './utils'; -import { SyntheticsServiceAllowed } from '../../../common/types'; - -export const getMonitors = createAction( - 'GET_MONITOR_MANAGEMENT_LIST' -); -export const getMonitorsSuccess = createAction( - 'GET_MONITOR_MANAGEMENT_LIST_SUCCESS' -); -export const getMonitorsFailure = createAction('GET_MONITOR_MANAGEMENT_LIST_FAILURE'); - -export const getServiceLocations = createAction('GET_SERVICE_LOCATIONS_LIST'); -export const getServiceLocationsSuccess = createAction<{ - throttling: ThrottlingOptions | undefined; - locations: ServiceLocations; -}>('GET_SERVICE_LOCATIONS_LIST_SUCCESS'); -export const getServiceLocationsFailure = createAction('GET_SERVICE_LOCATIONS_LIST_FAILURE'); - -export const getSyntheticsEnablement = createAction('GET_SYNTHETICS_ENABLEMENT'); -export const getSyntheticsEnablementSuccess = createAction( - 'GET_SYNTHETICS_ENABLEMENT_SUCCESS' -); -export const getSyntheticsEnablementFailure = createAction( - 'GET_SYNTHETICS_ENABLEMENT_FAILURE' -); - -export const disableSynthetics = createAction('DISABLE_SYNTHETICS'); -export const disableSyntheticsSuccess = createAction('DISABLE_SYNTEHTICS_SUCCESS'); -export const disableSyntheticsFailure = createAction('DISABLE_SYNTHETICS_FAILURE'); - -export const enableSynthetics = createAction('ENABLE_SYNTHETICS'); -export const enableSyntheticsSuccess = createAction('ENABLE_SYNTEHTICS_SUCCESS'); -export const enableSyntheticsFailure = createAction('ENABLE_SYNTHETICS_FAILURE'); - -export const getSyntheticsServiceAllowed = createAsyncAction( - 'GET_SYNTHETICS_SERVICE_ALLOWED' -); diff --git a/x-pack/plugins/synthetics/public/state/actions/monitor_status.ts b/x-pack/plugins/synthetics/public/state/actions/monitor_status.ts deleted file mode 100644 index 3928cd539a5c0..0000000000000 --- a/x-pack/plugins/synthetics/public/state/actions/monitor_status.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { createAction } from 'redux-actions'; -import { QueryParams } from './types'; -import { Ping } from '../../../common/runtime_types'; - -export const getMonitorStatusAction = createAction('GET_MONITOR_STATUS'); -export const getMonitorStatusActionSuccess = createAction('GET_MONITOR_STATUS_SUCCESS'); -export const getMonitorStatusActionFail = createAction('GET_MONITOR_STATUS_FAIL'); diff --git a/x-pack/plugins/synthetics/public/state/actions/network_events.ts b/x-pack/plugins/synthetics/public/state/actions/network_events.ts deleted file mode 100644 index f078888d6eae8..0000000000000 --- a/x-pack/plugins/synthetics/public/state/actions/network_events.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { createAction } from 'redux-actions'; -import { SyntheticsNetworkEventsApiResponse } from '../../../common/runtime_types'; - -export interface FetchNetworkEventsParams { - checkGroup: string; - stepIndex: number; -} - -export interface FetchNetworkEventsFailPayload { - checkGroup: string; - stepIndex: number; - error: Error; -} - -export const getNetworkEvents = createAction('GET_NETWORK_EVENTS'); -export const getNetworkEventsSuccess = createAction< - Pick & SyntheticsNetworkEventsApiResponse ->('GET_NETWORK_EVENTS_SUCCESS'); -export const getNetworkEventsFail = - createAction('GET_NETWORK_EVENTS_FAIL'); diff --git a/x-pack/plugins/synthetics/public/state/actions/ping.ts b/x-pack/plugins/synthetics/public/state/actions/ping.ts deleted file mode 100644 index 6b997ba184b0b..0000000000000 --- a/x-pack/plugins/synthetics/public/state/actions/ping.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { createAction } from 'redux-actions'; -import { - GetPingHistogramParams, - HistogramResult, - PingsResponse, - GetPingsParams, -} from '../../../common/runtime_types'; -import { createAsyncAction } from './utils'; - -export const clearPings = createAction('CLEAR PINGS'); - -export const getPingHistogram = createAsyncAction( - 'GET_PING_HISTOGRAM' -); - -export const getPings = createAction('GET PINGS'); -export const getPingsSuccess = createAction('GET PINGS SUCCESS'); -export const getPingsFail = createAction('GET PINGS FAIL'); diff --git a/x-pack/plugins/synthetics/public/state/actions/snapshot.ts b/x-pack/plugins/synthetics/public/state/actions/snapshot.ts deleted file mode 100644 index b1ff299600943..0000000000000 --- a/x-pack/plugins/synthetics/public/state/actions/snapshot.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { Snapshot } from '../../../common/runtime_types'; -import { createAsyncAction } from './utils'; -import { SnapShotQueryParams } from '../api'; - -export const getSnapshotCountAction = createAsyncAction( - 'GET_SNAPSHOT_COUNT' -); diff --git a/x-pack/plugins/synthetics/public/state/alerts/alerts.ts b/x-pack/plugins/synthetics/public/state/alerts/alerts.ts deleted file mode 100644 index db969394c2f24..0000000000000 --- a/x-pack/plugins/synthetics/public/state/alerts/alerts.ts +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; -import { handleActions, Action } from 'redux-actions'; -import { call, put, select, takeLatest } from 'redux-saga/effects'; -import type { - ActionConnector as RawActionConnector, - Rule, -} from '@kbn/triggers-actions-ui-plugin/public'; -import { createAsyncAction } from '../actions/utils'; -import { asyncInitState, handleAsyncAction } from '../reducers/utils'; -import type { AppState } from '..'; -import { AsyncInitState } from '../reducers/types'; -import { fetchEffectFactory } from '../effects/fetch_effect'; -import { - createAlert, - disableAlertById, - fetchAlertRecords, - fetchConnectors, - fetchMonitorAlertRecords, - NewAlertParams, -} from '../api/alerts'; -import { kibanaService } from '../kibana_service'; -import { monitorIdSelector } from '../selectors'; -import { AlertsResult, MonitorIdParam } from '../actions/types'; -import { simpleAlertEnabled } from '../../lib/alert_types/alert_messages'; - -export type ActionConnector = Omit; - -/** - * TODO: Use actual AlertType Params type that's specific to Uptime instead of `any` - */ -export type UptimeAlertTypeParams = Record; - -export const createAlertAction = createAsyncAction< - NewAlertParams, - Rule | null ->('CREATE ALERT'); -export const getConnectorsAction = createAsyncAction<{}, ActionConnector[]>('GET CONNECTORS'); -export const getMonitorAlertsAction = createAsyncAction<{}, AlertsResult | null>('GET ALERTS'); - -export const getAnomalyAlertAction = createAsyncAction>( - 'GET EXISTING ALERTS' -); -export const deleteAlertAction = createAsyncAction<{ alertId: string }, string | null>( - 'DELETE ALERTS' -); -export const deleteAnomalyAlertAction = createAsyncAction<{ alertId: string }, any>( - 'DELETE ANOMALY ALERT' -); - -export interface AlertState { - connectors: AsyncInitState; - newAlert: AsyncInitState>; - alerts: AsyncInitState; - anomalyAlert: AsyncInitState>; - alertDeletion: AsyncInitState; - anomalyAlertDeletion: AsyncInitState; -} - -const initialState = { - connectors: asyncInitState(), - newAlert: asyncInitState(), - alerts: asyncInitState(), - anomalyAlert: asyncInitState(), - alertDeletion: asyncInitState(), - anomalyAlertDeletion: asyncInitState(), -}; - -export const alertsReducer = handleActions( - { - ...handleAsyncAction('connectors', getConnectorsAction), - ...handleAsyncAction('newAlert', createAlertAction), - ...handleAsyncAction('alerts', getMonitorAlertsAction), - ...handleAsyncAction('anomalyAlert', getAnomalyAlertAction), - ...handleAsyncAction('alertDeletion', deleteAlertAction), - ...handleAsyncAction('anomalyAlertDeletion', deleteAnomalyAlertAction), - }, - initialState -); - -const showAlertDisabledSuccess = () => { - kibanaService.core.notifications.toasts.addSuccess( - i18n.translate('xpack.uptime.overview.alerts.disabled.success', { - defaultMessage: 'Rule successfully disabled!', - }) - ); -}; - -const showAlertDisabledFailed = (err: Error) => { - kibanaService.core.notifications.toasts.addError(err, { - title: i18n.translate('xpack.uptime.overview.alerts.disabled.failed', { - defaultMessage: 'Rule cannot be disabled!', - }), - }); -}; - -export function* fetchAlertsEffect() { - yield takeLatest( - getAnomalyAlertAction.get, - fetchEffectFactory(fetchAlertRecords, getAnomalyAlertAction.success, getAnomalyAlertAction.fail) - ); - - yield takeLatest(deleteAnomalyAlertAction.get, function* (action: Action<{ alertId: string }>) { - try { - yield call(disableAlertById, action.payload); - yield put(deleteAnomalyAlertAction.success(action.payload.alertId)); - showAlertDisabledSuccess(); - const monitorId = (yield select(monitorIdSelector)) as AppState['ui']['monitorId']; - yield put(getAnomalyAlertAction.get({ monitorId })); - } catch (err) { - showAlertDisabledFailed(err); - yield put(deleteAnomalyAlertAction.fail(err)); - } - }); - - yield takeLatest(deleteAlertAction.get, function* (action: Action<{ alertId: string }>) { - try { - yield call(disableAlertById, action.payload); - // clear previous state - yield put(createAlertAction.success(null)); - yield put(deleteAlertAction.success(action.payload.alertId)); - - showAlertDisabledSuccess(); - yield put(getMonitorAlertsAction.get()); - } catch (err) { - showAlertDisabledFailed(err); - yield put(deleteAlertAction.fail(err)); - } - }); - - yield takeLatest( - getConnectorsAction.get, - fetchEffectFactory(fetchConnectors, getConnectorsAction.success, getConnectorsAction.fail) - ); - yield takeLatest( - getMonitorAlertsAction.get, - fetchEffectFactory( - fetchMonitorAlertRecords, - getMonitorAlertsAction.success, - getMonitorAlertsAction.fail - ) - ); - yield takeLatest(createAlertAction.get, function* (action: Action): Generator { - try { - const response = (yield call(createAlert, action.payload)) as Rule; - yield put(createAlertAction.success(response)); - - kibanaService.core.notifications.toasts.addSuccess( - simpleAlertEnabled(action.payload.defaultActions, kibanaService.theme, response) - ); - yield put(getMonitorAlertsAction.get()); - } catch (err) { - kibanaService.core.notifications.toasts.addError(err, { - title: i18n.translate('xpack.uptime.overview.alerts.enabled.failed', { - defaultMessage: 'Rule cannot be enabled!', - }), - }); - yield put(createAlertAction.fail(err)); - } - }); -} - -export const connectorsSelector = ({ alerts }: AppState) => alerts.connectors; -export const newAlertSelector = ({ alerts }: AppState) => alerts.newAlert; -export const alertsSelector = ({ alerts }: AppState) => alerts.alerts; -export const isAlertDeletedSelector = ({ alerts }: AppState) => alerts.alertDeletion; - -export const anomalyAlertSelector = ({ alerts }: AppState) => alerts.anomalyAlert; -export const isAnomalyAlertDeleting = ({ alerts }: AppState) => alerts.anomalyAlertDeletion.loading; diff --git a/x-pack/plugins/synthetics/public/state/api/alerts.ts b/x-pack/plugins/synthetics/public/state/api/alerts.ts deleted file mode 100644 index 2e02c36289ab8..0000000000000 --- a/x-pack/plugins/synthetics/public/state/api/alerts.ts +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { ActionType, AsApiContract, Rule } from '@kbn/triggers-actions-ui-plugin/public'; -import { RuleTypeParams } from '@kbn/alerting-plugin/common'; -import { CLIENT_ALERT_TYPES } from '../../../common/constants/alerts'; -import { apiService } from './utils'; -import { ActionConnector } from '../alerts/alerts'; - -import { AlertsResult, MonitorIdParam } from '../actions/types'; -import { API_URLS } from '../../../common/constants'; -import { AtomicStatusCheckParams } from '../../../common/runtime_types/alerts'; - -import { populateAlertActions, RuleAction } from './alert_actions'; -import { Ping } from '../../../common/runtime_types/ping'; -import { DefaultEmail } from '../../../common/runtime_types'; - -const UPTIME_AUTO_ALERT = 'UPTIME_AUTO'; - -export const fetchConnectors = async (): Promise => { - const response = (await apiService.get(API_URLS.RULE_CONNECTORS)) as Array< - AsApiContract - >; - return response.map( - ({ - connector_type_id: actionTypeId, - referenced_by_count: referencedByCount, - is_preconfigured: isPreconfigured, - is_missing_secrets: isMissingSecrets, - ...res - }) => ({ - ...res, - actionTypeId, - referencedByCount, - isPreconfigured, - isMissingSecrets, - }) - ); -}; - -export interface NewAlertParams extends RuleTypeParams { - selectedMonitor: Ping; - defaultActions: ActionConnector[]; - defaultEmail?: DefaultEmail; -} - -type NewMonitorStatusAlert = Omit< - Rule, - | 'id' - | 'createdBy' - | 'updatedBy' - | 'createdAt' - | 'updatedAt' - | 'apiKey' - | 'apiKeyOwner' - | 'muteAll' - | 'mutedInstanceIds' - | 'executionStatus' - | 'ruleTypeId' - | 'notifyWhen' - | 'actions' -> & { - rule_type_id: Rule['ruleTypeId']; - notify_when: Rule['notifyWhen']; - actions: RuleAction[]; -}; - -export const createAlert = async ({ - defaultActions, - monitorId, - selectedMonitor, - defaultEmail, -}: NewAlertParams): Promise => { - const actions: RuleAction[] = populateAlertActions({ - defaultActions, - selectedMonitor, - defaultEmail, - }); - - const data: NewMonitorStatusAlert = { - actions, - params: { - numTimes: 1, - timerangeUnit: 'm', - timerangeCount: 1, - shouldCheckStatus: true, - shouldCheckAvailability: false, - isAutoGenerated: true, - search: `monitor.id : ${monitorId} `, - filters: { 'url.port': [], 'observer.geo.name': [], 'monitor.type': [], tags: [] }, - }, - consumer: 'uptime', - rule_type_id: CLIENT_ALERT_TYPES.MONITOR_STATUS, - schedule: { interval: '1m' }, - notify_when: 'onActionGroupChange', - tags: [UPTIME_AUTO_ALERT], - name: `${selectedMonitor?.monitor.name || selectedMonitor?.url?.full}(Simple status alert)`, - enabled: true, - throttle: null, - }; - - return await apiService.post(API_URLS.CREATE_RULE, data); -}; - -export const fetchMonitorAlertRecords = async (): Promise => { - const data = { - page: 1, - per_page: 500, - filter: 'alert.attributes.alertTypeId:(xpack.uptime.alerts.monitorStatus)', - default_search_operator: 'AND', - sort_field: 'name.keyword', - sort_order: 'asc', - search_fields: ['name', 'tags'], - search: 'UPTIME_AUTO', - }; - return await apiService.get(API_URLS.RULES_FIND, data); -}; - -export const fetchAlertRecords = async ({ - monitorId, -}: MonitorIdParam): Promise> => { - const data = { - page: 1, - per_page: 500, - filter: 'alert.attributes.alertTypeId:(xpack.uptime.alerts.durationAnomaly)', - default_search_operator: 'AND', - sort_field: 'name.keyword', - sort_order: 'asc', - }; - const rawRules = await apiService.get<{ - data: Array & { rule_type_id: string }>; - }>(API_URLS.RULES_FIND, data); - const monitorRule = rawRules.data.find( - (rule) => rule.params.monitorId === monitorId - ) as Rule & { rule_type_id: string }; - return { - ...monitorRule, - ruleTypeId: monitorRule.rule_type_id, - }; -}; - -export const disableAlertById = async ({ alertId }: { alertId: string }) => { - return await apiService.delete(API_URLS.DELETE_RULE + alertId); -}; - -export const fetchActionTypes = async (): Promise => { - const response = (await apiService.get(API_URLS.CONNECTOR_TYPES)) as Array< - AsApiContract - >; - return response.map( - ({ - enabled_in_config: enabledInConfig, - enabled_in_license: enabledInLicense, - minimum_license_required: minimumLicenseRequired, - ...res - }: AsApiContract) => ({ - ...res, - enabledInConfig, - enabledInLicense, - minimumLicenseRequired, - }) - ); -}; diff --git a/x-pack/plugins/synthetics/public/state/api/dynamic_settings.ts b/x-pack/plugins/synthetics/public/state/api/dynamic_settings.ts deleted file mode 100644 index a7bacfbba3462..0000000000000 --- a/x-pack/plugins/synthetics/public/state/api/dynamic_settings.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - DynamicSettingsType, - DynamicSettings, - DynamicSettingsSaveResponse, - DynamicSettingsSaveType, -} from '../../../common/runtime_types'; -import { apiService } from './utils'; -import { API_URLS } from '../../../common/constants'; - -const apiPath = API_URLS.DYNAMIC_SETTINGS; - -interface SaveApiRequest { - settings: DynamicSettings; -} - -export const getDynamicSettings = async (): Promise => { - return await apiService.get(apiPath, undefined, DynamicSettingsType); -}; - -export const setDynamicSettings = async ({ - settings, -}: SaveApiRequest): Promise => { - return await apiService.post(apiPath, settings, DynamicSettingsSaveType); -}; diff --git a/x-pack/plugins/synthetics/public/state/api/index_status.ts b/x-pack/plugins/synthetics/public/state/api/index_status.ts deleted file mode 100644 index c6d8f96403eeb..0000000000000 --- a/x-pack/plugins/synthetics/public/state/api/index_status.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { API_URLS } from '../../../common/constants'; -import { StatesIndexStatus, StatesIndexStatusType } from '../../../common/runtime_types'; -import { apiService } from './utils'; - -export const fetchIndexStatus = async (): Promise => { - return await apiService.get(API_URLS.INDEX_STATUS, undefined, StatesIndexStatusType); -}; diff --git a/x-pack/plugins/synthetics/public/state/api/journey.ts b/x-pack/plugins/synthetics/public/state/api/journey.ts deleted file mode 100644 index 958ef5e474fee..0000000000000 --- a/x-pack/plugins/synthetics/public/state/api/journey.ts +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { apiService } from './utils'; -import { FetchJourneyStepsParams } from '../actions/journey'; -import { Ping, PingType } from '../../../common/runtime_types/ping/ping'; -import { - FailedStepsApiResponse, - FailedStepsApiResponseType, - ScreenshotBlockDoc, - ScreenshotImageBlob, - ScreenshotRefImageData, - SyntheticsJourneyApiResponse, - SyntheticsJourneyApiResponseType, -} from '../../../common/runtime_types/ping/synthetics'; -import { API_URLS } from '../../../common/constants'; - -export async function fetchScreenshotBlockSet(params: string[]): Promise { - return apiService.post(API_URLS.JOURNEY_SCREENSHOT_BLOCKS, { - hashes: params, - }); -} - -export async function fetchJourneySteps( - params: FetchJourneyStepsParams -): Promise { - return apiService.get( - `/internal/uptime/journey/${params.checkGroup}`, - { syntheticEventTypes: params.syntheticEventTypes }, - SyntheticsJourneyApiResponseType - ); -} - -export async function fetchJourneysFailedSteps({ - checkGroups, -}: { - checkGroups: string[]; -}): Promise { - return apiService.get(API_URLS.JOURNEY_FAILED_STEPS, { checkGroups }, FailedStepsApiResponseType); -} - -export async function fetchLastSuccessfulCheck({ - monitorId, - timestamp, - stepIndex, - location, -}: { - monitorId: string; - timestamp: string; - stepIndex: number; - location?: string; -}): Promise { - return await apiService.get( - API_URLS.SYNTHETICS_SUCCESSFUL_CHECK, - { - monitorId, - timestamp, - stepIndex, - location, - }, - PingType - ); -} - -export async function getJourneyScreenshot( - imgSrc: string -): Promise { - try { - const imgRequest = new Request(imgSrc); - - const response = await fetch(imgRequest); - - if (response.status !== 200) { - return null; - } - - const contentType = response.headers.get('content-type'); - const stepName = response.headers.get('caption-name'); - const maxSteps = Number(response.headers.get('max-steps') ?? 0); - if (contentType?.indexOf('application/json') !== -1) { - return { - stepName, - maxSteps, - ref: await response.json(), - }; - } else { - return { - stepName, - maxSteps, - src: URL.createObjectURL(await response.blob()), - }; - } - } catch (e) { - return null; - } -} diff --git a/x-pack/plugins/synthetics/public/state/api/monitor.ts b/x-pack/plugins/synthetics/public/state/api/monitor.ts deleted file mode 100644 index ef04b38f37469..0000000000000 --- a/x-pack/plugins/synthetics/public/state/api/monitor.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { BaseParams } from './types'; -import { MonitorDetailsType, MonitorLocationsType } from '../../../common/runtime_types'; -import { QueryParams } from '../actions/types'; -import { apiService } from './utils'; -import { API_URLS } from '../../../common/constants'; - -interface ApiRequest { - monitorId: string; -} - -export type MonitorQueryParams = BaseParams & ApiRequest; - -export const fetchMonitorDetails = async ({ - monitorId, - dateStart, - dateEnd, -}: MonitorQueryParams) => { - const params = { - monitorId, - dateStart, - dateEnd, - }; - return await apiService.get(API_URLS.MONITOR_DETAILS, params, MonitorDetailsType); -}; - -type ApiParams = QueryParams & ApiRequest; - -export const fetchMonitorLocations = async ({ monitorId, dateStart, dateEnd }: ApiParams) => { - const params = { - dateStart, - dateEnd, - monitorId, - }; - return await apiService.get(API_URLS.MONITOR_LOCATIONS, params, MonitorLocationsType); -}; diff --git a/x-pack/plugins/synthetics/public/state/api/monitor_duration.ts b/x-pack/plugins/synthetics/public/state/api/monitor_duration.ts deleted file mode 100644 index c8010e18d0868..0000000000000 --- a/x-pack/plugins/synthetics/public/state/api/monitor_duration.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { BaseParams } from './types'; -import { apiService } from './utils'; -import { API_URLS } from '../../../common/constants'; - -export const fetchMonitorDuration = async ({ monitorId, dateStart, dateEnd }: BaseParams) => { - const queryParams = { - monitorId, - dateStart, - dateEnd, - }; - - return await apiService.get(API_URLS.MONITOR_DURATION, queryParams); -}; diff --git a/x-pack/plugins/synthetics/public/state/api/monitor_list.ts b/x-pack/plugins/synthetics/public/state/api/monitor_list.ts deleted file mode 100644 index 860a46d3e3abc..0000000000000 --- a/x-pack/plugins/synthetics/public/state/api/monitor_list.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { API_URLS } from '../../../common/constants'; -import { apiService } from './utils'; -import { - FetchMonitorStatesQueryArgs, - MonitorSummariesResult, - MonitorSummariesResultType, -} from '../../../common/runtime_types'; - -export const fetchMonitorList = async ( - params: FetchMonitorStatesQueryArgs -): Promise => { - return await apiService.get(API_URLS.MONITOR_LIST, params, MonitorSummariesResultType); -}; diff --git a/x-pack/plugins/synthetics/public/state/api/monitor_management.ts b/x-pack/plugins/synthetics/public/state/api/monitor_management.ts deleted file mode 100644 index a776d33b8147b..0000000000000 --- a/x-pack/plugins/synthetics/public/state/api/monitor_management.ts +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { API_URLS } from '../../../common/constants'; -import { - FetchMonitorManagementListQueryArgs, - MonitorManagementListResultCodec, - MonitorManagementListResult, - MonitorManagementEnablementResultCodec, - MonitorManagementEnablementResult, - ServiceLocations, - SyntheticsMonitor, - EncryptedSyntheticsMonitor, - ServiceLocationsApiResponseCodec, - ServiceLocationErrors, - ThrottlingOptions, - Locations, - SyntheticsMonitorSchedule, -} from '../../../common/runtime_types'; -import { - DecryptedSyntheticsMonitorSavedObject, - SyntheticsServiceAllowed, -} from '../../../common/types'; -import { apiService } from './utils'; - -export const setMonitor = async ({ - monitor, - id, -}: { - monitor: SyntheticsMonitor | EncryptedSyntheticsMonitor; - id?: string; -}): Promise<{ attributes: { errors: ServiceLocationErrors } } | SyntheticsMonitor> => { - if (id) { - return await apiService.put(`${API_URLS.SYNTHETICS_MONITORS}/${id}`, monitor); - } else { - return await apiService.post(API_URLS.SYNTHETICS_MONITORS, monitor); - } -}; - -export const getMonitor = async ({ - id, -}: { - id: string; -}): Promise => { - return await apiService.get(`${API_URLS.SYNTHETICS_MONITORS}/${id}`); -}; - -export const deleteMonitor = async ({ id }: { id: string }): Promise => { - return await apiService.delete(`${API_URLS.SYNTHETICS_MONITORS}/${id}`); -}; - -export const fetchMonitorManagementList = async ( - params: FetchMonitorManagementListQueryArgs -): Promise => { - return await apiService.get( - API_URLS.SYNTHETICS_MONITORS, - params, - MonitorManagementListResultCodec - ); -}; - -export const fetchServiceLocations = async (): Promise<{ - throttling: ThrottlingOptions | undefined; - locations: ServiceLocations; -}> => { - const { throttling, locations } = await apiService.get( - API_URLS.SERVICE_LOCATIONS, - undefined, - ServiceLocationsApiResponseCodec - ); - return { throttling, locations }; -}; - -export const runOnceMonitor = async ({ - monitor, - id, -}: { - monitor: SyntheticsMonitor; - id: string; -}): Promise<{ errors: Array<{ error: Error }> }> => { - return await apiService.post(API_URLS.RUN_ONCE_MONITOR + `/${id}`, monitor); -}; - -export interface TestNowResponse { - schedule: SyntheticsMonitorSchedule; - locations: Locations; - errors?: ServiceLocationErrors; - testRunId: string; - monitorId: string; -} - -export const triggerTestNowMonitor = async ( - configId: string -): Promise => { - return await apiService.get(API_URLS.TRIGGER_MONITOR + `/${configId}`); -}; - -export const fetchGetSyntheticsEnablement = - async (): Promise => { - return await apiService.get( - API_URLS.SYNTHETICS_ENABLEMENT, - undefined, - MonitorManagementEnablementResultCodec - ); - }; - -export const fetchDisableSynthetics = async (): Promise => { - return await apiService.delete(API_URLS.SYNTHETICS_ENABLEMENT); -}; - -export const fetchEnableSynthetics = async (): Promise => { - return await apiService.post(API_URLS.SYNTHETICS_ENABLEMENT); -}; - -export const fetchServiceAllowed = async (): Promise => { - return await apiService.get(API_URLS.SERVICE_ALLOWED); -}; diff --git a/x-pack/plugins/synthetics/public/state/api/monitor_status.ts b/x-pack/plugins/synthetics/public/state/api/monitor_status.ts deleted file mode 100644 index 9c4e7e3eaf5d3..0000000000000 --- a/x-pack/plugins/synthetics/public/state/api/monitor_status.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { QueryParams } from '../actions/types'; -import { Ping } from '../../../common/runtime_types'; -import { API_URLS } from '../../../common/constants'; -import { apiService } from './utils'; - -export const fetchMonitorStatus = async ({ - monitorId, - dateStart, - dateEnd, -}: QueryParams): Promise => { - const queryParams = { - monitorId, - dateStart, - dateEnd, - }; - - return await apiService.get(API_URLS.MONITOR_STATUS, queryParams); -}; diff --git a/x-pack/plugins/synthetics/public/state/api/network_events.ts b/x-pack/plugins/synthetics/public/state/api/network_events.ts deleted file mode 100644 index d9b3d518444a3..0000000000000 --- a/x-pack/plugins/synthetics/public/state/api/network_events.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { apiService } from './utils'; -import { FetchNetworkEventsParams } from '../actions/network_events'; -import { - SyntheticsNetworkEventsApiResponse, - SyntheticsNetworkEventsApiResponseType, -} from '../../../common/runtime_types'; -import { API_URLS } from '../../../common/constants'; - -export async function fetchNetworkEvents( - params: FetchNetworkEventsParams -): Promise { - return (await apiService.get( - API_URLS.NETWORK_EVENTS, - { - checkGroup: params.checkGroup, - stepIndex: params.stepIndex, - }, - SyntheticsNetworkEventsApiResponseType - )) as SyntheticsNetworkEventsApiResponse; -} diff --git a/x-pack/plugins/synthetics/public/state/api/ping.ts b/x-pack/plugins/synthetics/public/state/api/ping.ts deleted file mode 100644 index e4fc5cc620b55..0000000000000 --- a/x-pack/plugins/synthetics/public/state/api/ping.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { APIFn } from './types'; -import { - PingsResponseType, - PingsResponse, - GetPingsParams, - GetPingHistogramParams, - HistogramResult, -} from '../../../common/runtime_types'; -import { apiService } from './utils'; -import { API_URLS } from '../../../common/constants'; - -export const fetchPings: APIFn = async ({ - dateRange: { from, to }, - ...optional -}) => await apiService.get(API_URLS.PINGS, { from, to, ...optional }, PingsResponseType); - -export const fetchPingHistogram: APIFn = async ({ - monitorId, - dateStart, - dateEnd, - filters, - bucketSize, - query, -}) => { - const queryParams = { - dateStart, - dateEnd, - monitorId, - filters, - bucketSize, - query, - }; - - return await apiService.get(API_URLS.PING_HISTOGRAM, queryParams); -}; diff --git a/x-pack/plugins/synthetics/public/state/api/snapshot.ts b/x-pack/plugins/synthetics/public/state/api/snapshot.ts deleted file mode 100644 index d8f38128e3202..0000000000000 --- a/x-pack/plugins/synthetics/public/state/api/snapshot.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { SnapshotType, Snapshot } from '../../../common/runtime_types'; -import { apiService } from './utils'; -import { API_URLS } from '../../../common/constants'; - -export interface SnapShotQueryParams { - dateRangeStart: string; - dateRangeEnd: string; - filters?: string; - query?: string; -} - -export const fetchSnapshotCount = async ({ - dateRangeStart, - dateRangeEnd, - filters, - query, -}: SnapShotQueryParams): Promise => { - const queryParams = { - dateRangeStart, - dateRangeEnd, - ...(filters && { filters }), - ...(query && { query }), - }; - - return await apiService.get(API_URLS.SNAPSHOT_COUNT, queryParams, SnapshotType); -}; diff --git a/x-pack/plugins/synthetics/public/state/effects/dynamic_settings.ts b/x-pack/plugins/synthetics/public/state/effects/dynamic_settings.ts deleted file mode 100644 index ffe7c61c7a4e3..0000000000000 --- a/x-pack/plugins/synthetics/public/state/effects/dynamic_settings.ts +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { takeLeading, put, call, takeLatest } from 'redux-saga/effects'; -import { Action } from 'redux-actions'; -import { i18n } from '@kbn/i18n'; -import { fetchEffectFactory } from './fetch_effect'; -import { - getDynamicSettings, - getDynamicSettingsSuccess, - getDynamicSettingsFail, - setDynamicSettingsSuccess, - setDynamicSettingsFail, - setDynamicSettings, -} from '../actions/dynamic_settings'; -import { - getDynamicSettings as getDynamicSettingsAPI, - setDynamicSettings as setDynamicSettingsAPI, -} from '../api'; -import { DynamicSettings } from '../../../common/runtime_types'; -import { kibanaService } from '../kibana_service'; - -export function* fetchDynamicSettingsEffect() { - yield takeLeading( - String(getDynamicSettings), - fetchEffectFactory(getDynamicSettingsAPI, getDynamicSettingsSuccess, getDynamicSettingsFail) - ); -} - -export function* setDynamicSettingsEffect() { - const couldNotSaveSettingsText = i18n.translate('xpack.uptime.settings.error.couldNotSave', { - defaultMessage: 'Could not save settings!', - }); - yield takeLatest(String(setDynamicSettings), function* (action: Action) { - try { - if (!action.payload) { - const err = new Error('Cannot fetch effect without a payload'); - yield put(setDynamicSettingsFail(err)); - - kibanaService.core.notifications.toasts.addError(err, { - title: couldNotSaveSettingsText, - }); - return; - } - yield call(setDynamicSettingsAPI, { settings: action.payload }); - yield put(setDynamicSettingsSuccess(action.payload)); - kibanaService.core.notifications.toasts.addSuccess( - i18n.translate('xpack.uptime.settings.saveSuccess', { - defaultMessage: 'Settings saved!', - }) - ); - } catch (err) { - kibanaService.core.notifications.toasts.addError(err, { - title: couldNotSaveSettingsText, - }); - yield put(setDynamicSettingsFail(err)); - } - }); -} diff --git a/x-pack/plugins/synthetics/public/state/effects/journey.ts b/x-pack/plugins/synthetics/public/state/effects/journey.ts deleted file mode 100644 index f7c1e23742e69..0000000000000 --- a/x-pack/plugins/synthetics/public/state/effects/journey.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { Action } from 'redux-actions'; -import { call, put, takeEvery } from 'redux-saga/effects'; -import { - getJourneySteps, - getJourneyStepsSuccess, - getJourneyStepsFail, - FetchJourneyStepsParams, -} from '../actions/journey'; -import { fetchJourneySteps } from '../api/journey'; -import type { SyntheticsJourneyApiResponse } from '../../../common/runtime_types'; - -const inFlightStepRequests: Record = {}; - -export function* fetchJourneyStepsEffect(): Generator { - yield takeEvery(getJourneySteps, function* (action: Action) { - if (inFlightStepRequests[action.payload.checkGroup]) return; - - try { - inFlightStepRequests[action.payload.checkGroup] = true; - const response = (yield call( - fetchJourneySteps, - action.payload - )) as SyntheticsJourneyApiResponse; - yield put(getJourneyStepsSuccess(response)); - } catch (e) { - yield put(getJourneyStepsFail({ checkGroup: action.payload.checkGroup, error: e })); - } finally { - delete inFlightStepRequests[action.payload.checkGroup]; - } - }); -} diff --git a/x-pack/plugins/synthetics/public/state/effects/monitor_management.ts b/x-pack/plugins/synthetics/public/state/effects/monitor_management.ts deleted file mode 100644 index 60a6676721784..0000000000000 --- a/x-pack/plugins/synthetics/public/state/effects/monitor_management.ts +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { takeLatest, takeLeading } from 'redux-saga/effects'; -import { - getMonitors, - getMonitorsSuccess, - getMonitorsFailure, - getServiceLocations, - getServiceLocationsSuccess, - getServiceLocationsFailure, - getSyntheticsEnablement, - getSyntheticsEnablementSuccess, - getSyntheticsEnablementFailure, - disableSynthetics, - disableSyntheticsSuccess, - disableSyntheticsFailure, - enableSynthetics, - enableSyntheticsSuccess, - enableSyntheticsFailure, - getSyntheticsServiceAllowed, -} from '../actions'; -import { - fetchMonitorManagementList, - fetchServiceLocations, - fetchServiceAllowed, - fetchGetSyntheticsEnablement, - fetchDisableSynthetics, - fetchEnableSynthetics, -} from '../api'; -import { fetchEffectFactory } from './fetch_effect'; - -export function* fetchMonitorManagementEffect() { - yield takeLatest( - getMonitors, - fetchEffectFactory(fetchMonitorManagementList, getMonitorsSuccess, getMonitorsFailure) - ); - yield takeLeading( - getServiceLocations, - fetchEffectFactory( - fetchServiceLocations, - getServiceLocationsSuccess, - getServiceLocationsFailure - ) - ); - yield takeLatest( - getSyntheticsEnablement, - fetchEffectFactory( - fetchGetSyntheticsEnablement, - getSyntheticsEnablementSuccess, - getSyntheticsEnablementFailure - ) - ); - yield takeLatest( - disableSynthetics, - fetchEffectFactory(fetchDisableSynthetics, disableSyntheticsSuccess, disableSyntheticsFailure) - ); - yield takeLatest( - enableSynthetics, - fetchEffectFactory(fetchEnableSynthetics, enableSyntheticsSuccess, enableSyntheticsFailure) - ); -} - -export function* fetchSyntheticsServiceAllowedEffect() { - yield takeLeading( - getSyntheticsServiceAllowed.get, - fetchEffectFactory( - fetchServiceAllowed, - getSyntheticsServiceAllowed.success, - getSyntheticsServiceAllowed.fail - ) - ); -} diff --git a/x-pack/plugins/synthetics/public/state/effects/network_events.ts b/x-pack/plugins/synthetics/public/state/effects/network_events.ts deleted file mode 100644 index 75ea3d4467eb4..0000000000000 --- a/x-pack/plugins/synthetics/public/state/effects/network_events.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { Action } from 'redux-actions'; -import { call, put, takeLatest } from 'redux-saga/effects'; -import { - getNetworkEvents, - getNetworkEventsSuccess, - getNetworkEventsFail, - FetchNetworkEventsParams, -} from '../actions/network_events'; -import { fetchNetworkEvents } from '../api/network_events'; -import type { SyntheticsNetworkEventsApiResponse } from '../../../common/runtime_types'; - -export function* fetchNetworkEventsEffect() { - yield takeLatest( - getNetworkEvents, - function* (action: Action): Generator { - try { - const response = (yield call( - fetchNetworkEvents, - action.payload - )) as SyntheticsNetworkEventsApiResponse; - - yield put( - getNetworkEventsSuccess({ - checkGroup: action.payload.checkGroup, - stepIndex: action.payload.stepIndex, - ...response, - }) - ); - } catch (e) { - yield put( - getNetworkEventsFail({ - checkGroup: action.payload.checkGroup, - stepIndex: action.payload.stepIndex, - error: e, - }) - ); - } - } - ); -} diff --git a/x-pack/plugins/synthetics/public/state/reducers/dynamic_settings.ts b/x-pack/plugins/synthetics/public/state/reducers/dynamic_settings.ts deleted file mode 100644 index 93f30c77f5536..0000000000000 --- a/x-pack/plugins/synthetics/public/state/reducers/dynamic_settings.ts +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { handleActions, Action } from 'redux-actions'; -import { - getDynamicSettings, - getDynamicSettingsSuccess, - getDynamicSettingsFail, - setDynamicSettings, - setDynamicSettingsSuccess, - setDynamicSettingsFail, -} from '../actions/dynamic_settings'; -import { DynamicSettings } from '../../../common/runtime_types'; - -export interface DynamicSettingsState { - settings?: DynamicSettings; - loadError?: Error; - saveError?: Error; - loading: boolean; -} - -const initialState: DynamicSettingsState = { - loading: true, -}; - -export const dynamicSettingsReducer = handleActions( - { - [String(getDynamicSettings)]: (state) => ({ - ...state, - loading: true, - }), - [String(getDynamicSettingsSuccess)]: (_state, action: Action) => ({ - loading: false, - settings: action.payload, - }), - [String(getDynamicSettingsFail)]: (_state, action: Action) => ({ - loading: false, - loadError: action.payload, - }), - [String(setDynamicSettings)]: (state) => ({ - ...state, - loading: true, - }), - [String(setDynamicSettingsSuccess)]: (_state, action: Action) => ({ - settings: action.payload, - saveSucceded: true, - loading: false, - }), - [String(setDynamicSettingsFail)]: (state, action: Action) => ({ - ...state, - loading: false, - saveSucceeded: false, - saveError: action.payload, - }), - }, - initialState -); diff --git a/x-pack/plugins/synthetics/public/state/reducers/index_status.ts b/x-pack/plugins/synthetics/public/state/reducers/index_status.ts deleted file mode 100644 index 7c3aecd98f706..0000000000000 --- a/x-pack/plugins/synthetics/public/state/reducers/index_status.ts +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { handleActions } from 'redux-actions'; -import { indexStatusAction } from '../actions'; -import { asyncInitState, handleAsyncAction } from './utils'; -import { AsyncInitState } from './types'; -import { StatesIndexStatus } from '../../../common/runtime_types'; - -export interface IndexStatusState { - indexStatus: AsyncInitState; -} - -const initialState: IndexStatusState = { - indexStatus: asyncInitState(), -}; - -type PayLoad = StatesIndexStatus & Error; - -export const indexStatusReducer = handleActions( - { - ...handleAsyncAction('indexStatus', indexStatusAction), - }, - initialState -); diff --git a/x-pack/plugins/synthetics/public/state/reducers/journey.ts b/x-pack/plugins/synthetics/public/state/reducers/journey.ts deleted file mode 100644 index 98bbd93a24e0c..0000000000000 --- a/x-pack/plugins/synthetics/public/state/reducers/journey.ts +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { handleActions, Action } from 'redux-actions'; -import { JourneyStep, SyntheticsJourneyApiResponse } from '../../../common/runtime_types'; -import { pruneJourneyState } from '../actions/journey'; -import { - FetchJourneyStepsParams, - GetJourneyFailPayload, - getJourneySteps, - getJourneyStepsFail, - getJourneyStepsSuccess, -} from '../actions/journey'; - -export interface JourneyState { - checkGroup: string; - steps: JourneyStep[]; - details?: SyntheticsJourneyApiResponse['details']; - loading: boolean; - error?: Error; -} - -export interface JourneyKVP { - [checkGroup: string]: JourneyState; -} - -const initialState: JourneyKVP = {}; - -type Payload = FetchJourneyStepsParams & - SyntheticsJourneyApiResponse & - GetJourneyFailPayload & - string[]; - -export const journeyReducer = handleActions( - { - [String(getJourneySteps)]: ( - state: JourneyKVP, - { payload: { checkGroup } }: Action - ) => ({ - ...state, - // add an empty entry while fetching the check group, - // or update the previously-loaded entry to a new loading state - [checkGroup]: state[checkGroup] - ? { - ...state[checkGroup], - loading: true, - } - : { - checkGroup, - steps: [], - loading: true, - }, - }), - - [String(getJourneyStepsSuccess)]: ( - state: JourneyKVP, - { payload: { checkGroup, steps, details } }: Action - ) => ({ - ...state, - [checkGroup]: { - loading: false, - checkGroup, - steps, - details, - }, - }), - - [String(getJourneyStepsFail)]: ( - state: JourneyKVP, - { payload: { checkGroup, error } }: Action - ) => ({ - ...state, - [checkGroup]: state[checkGroup] - ? { - ...state[checkGroup], - loading: false, - error, - } - : { - checkGroup, - loading: false, - steps: [], - error, - }, - }), - - [String(pruneJourneyState)]: (state: JourneyKVP, action: Action) => - action.payload.reduce( - (prev, cur) => ({ - ...prev, - [cur]: state[cur], - }), - {} - ), - }, - initialState -); diff --git a/x-pack/plugins/synthetics/public/state/reducers/monitor.ts b/x-pack/plugins/synthetics/public/state/reducers/monitor.ts deleted file mode 100644 index 3c5be59ea9dda..0000000000000 --- a/x-pack/plugins/synthetics/public/state/reducers/monitor.ts +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { Action } from 'redux-actions'; -import { - MonitorDetailsState, - getMonitorDetailsAction, - getMonitorLocationsAction, - getMonitorLocationsActionSuccess, - getMonitorLocationsActionFail, -} from '../actions/monitor'; -import { MonitorLocations } from '../../../common/runtime_types'; - -type MonitorLocationsList = Map; - -export interface MonitorState { - loading: boolean; - errors: any[]; - monitorDetailsList: MonitorDetailsState[]; - monitorLocationsList: MonitorLocationsList; -} - -const initialState: MonitorState = { - monitorDetailsList: [], - monitorLocationsList: new Map(), - loading: false, - errors: [], -}; - -export function monitorReducer(state = initialState, action: Action): MonitorState { - switch (action.type) { - case String(getMonitorDetailsAction.get): - return { - ...state, - loading: true, - }; - case String(getMonitorDetailsAction.success): - const { monitorId } = action.payload; - return { - ...state, - monitorDetailsList: { - ...state.monitorDetailsList, - [monitorId]: action.payload, - }, - loading: false, - }; - case String(getMonitorDetailsAction.fail): - return { - ...state, - errors: [...state.errors, action.payload], - loading: false, - }; - case String(getMonitorLocationsAction): - return { - ...state, - loading: true, - }; - case String(getMonitorLocationsActionSuccess): - const monLocations = state.monitorLocationsList; - monLocations.set(action.payload.monitorId, action.payload); - return { - ...state, - monitorLocationsList: monLocations, - loading: false, - }; - case String(getMonitorLocationsActionFail): - return { - ...state, - errors: [...state.errors, action.payload], - }; - default: - return state; - } -} diff --git a/x-pack/plugins/synthetics/public/state/reducers/monitor_duration.ts b/x-pack/plugins/synthetics/public/state/reducers/monitor_duration.ts deleted file mode 100644 index 51eae6049b309..0000000000000 --- a/x-pack/plugins/synthetics/public/state/reducers/monitor_duration.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { handleActions, Action } from 'redux-actions'; -import { - getMonitorDurationAction, - getMonitorDurationActionSuccess, - getMonitorDurationActionFail, -} from '../actions'; -import { MonitorDurationResult } from '../../../common/types'; - -export interface MonitorDuration { - durationLines: MonitorDurationResult | null; - errors: any[]; - loading: boolean; -} - -const initialState: MonitorDuration = { - durationLines: null, - loading: false, - errors: [], -}; - -type Payload = MonitorDurationResult & Error; - -export const monitorDurationReducer = handleActions( - { - [String(getMonitorDurationAction)]: (state: MonitorDuration) => ({ - ...state, - loading: true, - }), - - [String(getMonitorDurationActionSuccess)]: ( - state: MonitorDuration, - action: Action - ) => ({ - ...state, - loading: false, - durationLines: { ...action.payload }, - }), - - [String(getMonitorDurationActionFail)]: (state: MonitorDuration, action: Action) => ({ - ...state, - errors: [...state.errors, action.payload], - loading: false, - }), - }, - initialState -); diff --git a/x-pack/plugins/synthetics/public/state/reducers/monitor_list.ts b/x-pack/plugins/synthetics/public/state/reducers/monitor_list.ts deleted file mode 100644 index 3630842cb9f8f..0000000000000 --- a/x-pack/plugins/synthetics/public/state/reducers/monitor_list.ts +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { handleActions, Action } from 'redux-actions'; -import { IHttpFetchError, ResponseErrorBody } from '@kbn/core/public'; -import { - getMonitorList, - getMonitorListSuccess, - getMonitorListFailure, - getUpdatedMonitor, - clearRefreshedMonitorId, - setUpdatingMonitorId, -} from '../actions'; -import { MonitorSummariesResult } from '../../../common/runtime_types'; -import { AppState } from '..'; -import { TestNowResponse } from '../api'; - -export interface MonitorList { - loading: boolean; - refreshedMonitorIds?: string[]; - isUpdating?: string[]; - list: MonitorSummariesResult; - error?: IHttpFetchError; -} - -export const initialState: MonitorList = { - list: { - nextPagePagination: null, - prevPagePagination: null, - summaries: [], - }, - loading: false, - refreshedMonitorIds: [], -}; - -type Payload = MonitorSummariesResult & - IHttpFetchError & - string & - TestNowResponse; - -export const monitorListReducer = handleActions( - { - [String(getMonitorList)]: (state: MonitorList) => ({ - ...state, - loading: true, - }), - [String(getMonitorListSuccess)]: ( - state: MonitorList, - action: Action - ) => ({ - ...state, - loading: false, - error: undefined, - list: { ...action.payload }, - }), - [String(getMonitorListFailure)]: ( - state: MonitorList, - action: Action> - ) => ({ - ...state, - error: action.payload, - loading: false, - }), - [String(setUpdatingMonitorId)]: (state: MonitorList, action: Action) => ({ - ...state, - isUpdating: [...(state.isUpdating ?? []), action.payload], - }), - [String(getUpdatedMonitor.get)]: (state: MonitorList) => ({ - ...state, - }), - [String(getUpdatedMonitor.success)]: ( - state: MonitorList, - action: Action - ) => { - const summaries = state.list.summaries; - - const newSummary = action.payload.summaries?.[0]; - - if (!newSummary) { - return { ...state, isUpdating: [] }; - } - - return { - ...state, - loading: false, - error: undefined, - isUpdating: state.isUpdating?.filter((item) => item !== newSummary.monitor_id), - refreshedMonitorIds: [...(state.refreshedMonitorIds ?? []), newSummary.monitor_id], - list: { - ...state.list, - summaries: summaries.map((summary) => { - if (summary.monitor_id === newSummary.monitor_id) { - return newSummary; - } - return summary; - }), - }, - }; - }, - [String(getUpdatedMonitor.fail)]: ( - state: MonitorList, - action: Action> - ) => ({ - ...state, - error: action.payload, - loading: false, - isUpdating: [], - }), - [String(clearRefreshedMonitorId)]: (state: MonitorList, action: Action) => ({ - ...state, - refreshedMonitorIds: (state.refreshedMonitorIds ?? []).filter( - (item) => item !== action.payload - ), - }), - }, - initialState -); - -export const refreshedMonitorSelector = ({ monitorList }: AppState) => { - return monitorList.refreshedMonitorIds ?? []; -}; - -export const isUpdatingMonitorSelector = ({ monitorList }: AppState) => - monitorList.isUpdating ?? []; diff --git a/x-pack/plugins/synthetics/public/state/reducers/monitor_management.ts b/x-pack/plugins/synthetics/public/state/reducers/monitor_management.ts deleted file mode 100644 index d60de74c1f54c..0000000000000 --- a/x-pack/plugins/synthetics/public/state/reducers/monitor_management.ts +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { createReducer, PayloadAction } from '@reduxjs/toolkit'; -import { WritableDraft } from 'immer/dist/types/types-external'; -import { - getMonitors, - getMonitorsSuccess, - getMonitorsFailure, - getServiceLocations, - getServiceLocationsSuccess, - getServiceLocationsFailure, - getSyntheticsEnablement, - getSyntheticsEnablementSuccess, - getSyntheticsEnablementFailure, - disableSynthetics, - disableSyntheticsSuccess, - disableSyntheticsFailure, - enableSynthetics, - enableSyntheticsSuccess, - enableSyntheticsFailure, - getSyntheticsServiceAllowed, -} from '../actions'; -import { - MonitorManagementEnablementResult, - MonitorManagementListResult, - ServiceLocations, - ThrottlingOptions, - DEFAULT_THROTTLING, -} from '../../../common/runtime_types'; -import { SyntheticsServiceAllowed } from '../../../common/types'; - -export interface MonitorManagementList { - error: Record<'monitorList' | 'serviceLocations' | 'enablement', Error | null>; - loading: Record<'monitorList' | 'serviceLocations' | 'enablement', boolean>; - list: MonitorManagementListResult; - locations: ServiceLocations; - enablement: MonitorManagementEnablementResult | null; - syntheticsService: { isAllowed?: boolean; signupUrl: string | null; loading: boolean }; - throttling: ThrottlingOptions; -} - -export const initialState: MonitorManagementList = { - list: { - page: 1, - perPage: 10, - total: null, - monitors: [], - syncErrors: [], - }, - locations: [], - enablement: null, - loading: { - monitorList: false, - serviceLocations: false, - enablement: false, - }, - error: { - monitorList: null, - serviceLocations: null, - enablement: null, - }, - syntheticsService: { - signupUrl: null, - loading: false, - }, - throttling: DEFAULT_THROTTLING, -}; - -export const monitorManagementListReducer = createReducer(initialState, (builder) => { - builder - .addCase(getMonitors, (state: WritableDraft) => ({ - ...state, - loading: { - ...state.loading, - monitorList: true, - }, - })) - .addCase( - getMonitorsSuccess, - ( - state: WritableDraft, - action: PayloadAction - ) => ({ - ...state, - loading: { - ...state.loading, - monitorList: false, - }, - error: { - ...state.error, - monitorList: null, - }, - list: { ...action.payload }, - }) - ) - .addCase( - getMonitorsFailure, - (state: WritableDraft, action: PayloadAction) => ({ - ...state, - loading: { - ...state.loading, - monitorList: false, - }, - error: { - ...state.error, - monitorList: action.payload, - }, - }) - ) - .addCase(getServiceLocations, (state: WritableDraft) => ({ - ...state, - loading: { - ...state.loading, - serviceLocations: true, - }, - })) - .addCase( - getServiceLocationsSuccess, - ( - state: WritableDraft, - action: PayloadAction<{ - throttling: ThrottlingOptions | undefined; - locations: ServiceLocations; - }> - ) => ({ - ...state, - loading: { - ...state.loading, - serviceLocations: false, - }, - error: { - ...state.error, - serviceLocations: null, - }, - locations: action.payload.locations, - throttling: action.payload.throttling || DEFAULT_THROTTLING, - }) - ) - .addCase( - getServiceLocationsFailure, - (state: WritableDraft, action: PayloadAction) => ({ - ...state, - loading: { - ...state.loading, - serviceLocations: false, - }, - error: { - ...state.error, - serviceLocations: action.payload, - }, - }) - ) - .addCase(getSyntheticsEnablement, (state: WritableDraft) => ({ - ...state, - loading: { - ...state.loading, - enablement: true, - }, - })) - .addCase( - getSyntheticsEnablementSuccess, - (state: WritableDraft, action: PayloadAction) => ({ - ...state, - loading: { - ...state.loading, - enablement: false, - }, - error: { - ...state.error, - enablement: null, - }, - enablement: action.payload, - }) - ) - .addCase( - getSyntheticsEnablementFailure, - (state: WritableDraft, action: PayloadAction) => ({ - ...state, - loading: { - ...state.loading, - enablement: false, - }, - error: { - ...state.error, - enablement: action.payload, - }, - }) - ) - .addCase(disableSynthetics, (state: WritableDraft) => ({ - ...state, - loading: { - ...state.loading, - enablement: true, - }, - })) - .addCase(disableSyntheticsSuccess, (state: WritableDraft) => ({ - ...state, - loading: { - ...state.loading, - enablement: false, - }, - error: { - ...state.error, - enablement: null, - }, - enablement: { - canEnable: state.enablement?.canEnable || false, - areApiKeysEnabled: state.enablement?.areApiKeysEnabled || false, - isEnabled: false, - }, - })) - .addCase( - disableSyntheticsFailure, - (state: WritableDraft, action: PayloadAction) => ({ - ...state, - loading: { - ...state.loading, - enablement: false, - }, - error: { - ...state.error, - enablement: action.payload, - }, - }) - ) - .addCase(enableSynthetics, (state: WritableDraft) => ({ - ...state, - loading: { - ...state.loading, - enablement: true, - }, - })) - .addCase(enableSyntheticsSuccess, (state: WritableDraft) => ({ - ...state, - loading: { - ...state.loading, - enablement: false, - }, - error: { - ...state.error, - enablement: null, - }, - enablement: { - canEnable: state.enablement?.canEnable || false, - areApiKeysEnabled: state.enablement?.areApiKeysEnabled || false, - isEnabled: true, - }, - })) - .addCase( - enableSyntheticsFailure, - (state: WritableDraft, action: PayloadAction) => ({ - ...state, - loading: { - ...state.loading, - enablement: false, - }, - error: { - ...state.error, - enablement: action.payload, - }, - }) - ) - .addCase( - String(getSyntheticsServiceAllowed.get), - (state: WritableDraft) => ({ - ...state, - syntheticsService: { - isAllowed: state.syntheticsService?.isAllowed, - signupUrl: state.syntheticsService?.signupUrl, - loading: true, - }, - }) - ) - .addCase( - String(getSyntheticsServiceAllowed.success), - ( - state: WritableDraft, - action: PayloadAction - ) => ({ - ...state, - syntheticsService: { - isAllowed: action.payload.serviceAllowed, - signupUrl: action.payload.signupUrl, - loading: false, - }, - }) - ) - .addCase( - String(getSyntheticsServiceAllowed.fail), - (state: WritableDraft, action: PayloadAction) => ({ - ...state, - syntheticsService: { - isAllowed: false, - signupUrl: null, - loading: false, - }, - }) - ); -}); diff --git a/x-pack/plugins/synthetics/public/state/reducers/monitor_status.ts b/x-pack/plugins/synthetics/public/state/reducers/monitor_status.ts deleted file mode 100644 index b27de0d944a8e..0000000000000 --- a/x-pack/plugins/synthetics/public/state/reducers/monitor_status.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { handleActions, Action } from 'redux-actions'; -import { - getMonitorStatusAction, - getMonitorStatusActionSuccess, - getMonitorStatusActionFail, -} from '../actions'; -import { Ping } from '../../../common/runtime_types'; -import { QueryParams } from '../actions/types'; - -export interface MonitorStatusState { - status: Ping | null; - loading: boolean; -} - -export const initialState: MonitorStatusState = { - status: null, - loading: false, -}; - -export type MonitorStatusPayload = QueryParams & Ping; - -export const monitorStatusReducer = handleActions( - { - [String(getMonitorStatusAction)]: (state, action) => ({ - ...state, - // reset state if monitorId changes - status: action.payload.monitorId === state?.status?.monitor?.id ? state.status : null, - loading: true, - }), - - [String(getMonitorStatusActionSuccess)]: (state, action: Action) => { - return { - ...state, - loading: false, - // Keeping url from prev request to display, if there is no latest status - status: { - url: action.payload?.url || state.status?.url, - ...action.payload, - } as Ping, - }; - }, - - [String(getMonitorStatusActionFail)]: (state) => ({ - ...state, - loading: false, - }), - }, - initialState -); diff --git a/x-pack/plugins/synthetics/public/state/reducers/network_events.ts b/x-pack/plugins/synthetics/public/state/reducers/network_events.ts deleted file mode 100644 index e58a8f75c7fa3..0000000000000 --- a/x-pack/plugins/synthetics/public/state/reducers/network_events.ts +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { handleActions, Action } from 'redux-actions'; -import { NetworkEvent, SyntheticsNetworkEventsApiResponse } from '../../../common/runtime_types'; -import { - FetchNetworkEventsParams, - FetchNetworkEventsFailPayload, - getNetworkEvents, - getNetworkEventsFail, - getNetworkEventsSuccess, -} from '../actions/network_events'; - -export interface NetworkEventsState { - [checkGroup: string]: { - [stepIndex: number]: { - events: NetworkEvent[]; - total: number; - loading: boolean; - error?: Error; - isWaterfallSupported: boolean; - hasNavigationRequest?: boolean; - }; - }; -} - -const initialState: NetworkEventsState = {}; - -type Payload = FetchNetworkEventsParams & - SyntheticsNetworkEventsApiResponse & - FetchNetworkEventsFailPayload & - string[]; - -export const networkEventsReducer = handleActions( - { - [String(getNetworkEvents)]: ( - state: NetworkEventsState, - { payload: { checkGroup, stepIndex } }: Action - ) => ({ - ...state, - [checkGroup]: state[checkGroup] - ? { - [stepIndex]: state[checkGroup][stepIndex] - ? { - ...state[checkGroup][stepIndex], - loading: true, - events: [], - total: 0, - isWaterfallSupported: true, - } - : { - loading: true, - events: [], - total: 0, - isWaterfallSupported: true, - }, - } - : { - [stepIndex]: { - loading: true, - events: [], - total: 0, - isWaterfallSupported: true, - }, - }, - }), - - [String(getNetworkEventsSuccess)]: ( - state: NetworkEventsState, - { - payload: { - events, - total, - checkGroup, - stepIndex, - isWaterfallSupported, - hasNavigationRequest, - }, - }: Action - ) => { - return { - ...state, - [checkGroup]: state[checkGroup] - ? { - [stepIndex]: state[checkGroup][stepIndex] - ? { - ...state[checkGroup][stepIndex], - loading: false, - events, - total, - isWaterfallSupported, - hasNavigationRequest, - } - : { - loading: false, - events, - total, - isWaterfallSupported, - hasNavigationRequest, - }, - } - : { - [stepIndex]: { - loading: false, - events, - total, - isWaterfallSupported, - hasNavigationRequest, - }, - }, - }; - }, - - [String(getNetworkEventsFail)]: ( - state: NetworkEventsState, - { payload: { checkGroup, stepIndex, error } }: Action - ) => ({ - ...state, - [checkGroup]: state[checkGroup] - ? { - [stepIndex]: state[checkGroup][stepIndex] - ? { - ...state[checkGroup][stepIndex], - loading: false, - events: [], - total: 0, - error, - isWaterfallSupported: true, - } - : { - loading: false, - events: [], - total: 0, - error, - isWaterfallSupported: true, - }, - } - : { - [stepIndex]: { - loading: false, - events: [], - total: 0, - error, - isWaterfallSupported: true, - }, - }, - }), - }, - initialState -); diff --git a/x-pack/plugins/synthetics/public/state/reducers/ping.ts b/x-pack/plugins/synthetics/public/state/reducers/ping.ts deleted file mode 100644 index a91734d77b4ab..0000000000000 --- a/x-pack/plugins/synthetics/public/state/reducers/ping.ts +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { handleActions, Action } from 'redux-actions'; -import { getPingHistogram } from '../actions'; -import { HistogramResult } from '../../../common/runtime_types'; - -export interface PingState { - pingHistogram: HistogramResult | null; - errors: any[]; - loading: boolean; -} - -const initialState: PingState = { - pingHistogram: null, - loading: false, - errors: [], -}; - -type MonitorStatusPayload = HistogramResult & Error; - -export const pingReducer = handleActions( - { - [String(getPingHistogram.get)]: (state) => ({ - ...state, - loading: true, - }), - - [String(getPingHistogram.success)]: (state: PingState, action: Action) => ({ - ...state, - loading: false, - pingHistogram: { ...action.payload }, - }), - - [String(getPingHistogram.fail)]: (state, action: Action) => ({ - ...state, - errors: [...state.errors, action.payload], - loading: false, - }), - }, - initialState -); diff --git a/x-pack/plugins/synthetics/server/kibana.index.ts b/x-pack/plugins/synthetics/server/kibana.index.ts index 34cec1a2af37a..14ac9edd5ff2f 100644 --- a/x-pack/plugins/synthetics/server/kibana.index.ts +++ b/x-pack/plugins/synthetics/server/kibana.index.ts @@ -8,6 +8,7 @@ import { Request, Server } from '@hapi/hapi'; import { Logger } from '@kbn/core/server'; import { DEFAULT_APP_CATEGORIES } from '@kbn/core/server'; +import { UPTIME_RULE_TYPES } from '../common/constants/alerts'; import { PLUGIN } from '../common/constants/plugin'; import { compose } from './lib/compose/kibana'; import { initUptimeServer } from './uptime_server'; @@ -43,20 +44,15 @@ export const initServerWithKibana = ( name: PLUGIN.NAME, order: 1000, category: DEFAULT_APP_CATEGORIES.observability, - app: ['uptime', 'kibana'], + app: ['uptime', 'kibana', 'synthetics'], catalogue: ['uptime'], management: { insightsAndAlerting: ['triggersActions'], }, - alerting: [ - 'xpack.uptime.alerts.tls', - 'xpack.uptime.alerts.tlsCertificate', - 'xpack.uptime.alerts.monitorStatus', - 'xpack.uptime.alerts.durationAnomaly', - ], + alerting: UPTIME_RULE_TYPES, privileges: { all: { - app: ['uptime', 'kibana'], + app: ['uptime', 'kibana', 'synthetics'], catalogue: ['uptime'], api: ['uptime-read', 'uptime-write', 'lists-all'], savedObject: { @@ -65,20 +61,10 @@ export const initServerWithKibana = ( }, alerting: { rule: { - all: [ - 'xpack.uptime.alerts.tls', - 'xpack.uptime.alerts.tlsCertificate', - 'xpack.uptime.alerts.monitorStatus', - 'xpack.uptime.alerts.durationAnomaly', - ], + all: UPTIME_RULE_TYPES, }, alert: { - all: [ - 'xpack.uptime.alerts.tls', - 'xpack.uptime.alerts.tlsCertificate', - 'xpack.uptime.alerts.monitorStatus', - 'xpack.uptime.alerts.durationAnomaly', - ], + all: UPTIME_RULE_TYPES, }, }, management: { @@ -87,7 +73,7 @@ export const initServerWithKibana = ( ui: ['save', 'configureSettings', 'show', 'alerting:save'], }, read: { - app: ['uptime', 'kibana'], + app: ['uptime', 'kibana', 'synthetics'], catalogue: ['uptime'], api: ['uptime-read', 'lists-read'], savedObject: { @@ -96,20 +82,10 @@ export const initServerWithKibana = ( }, alerting: { rule: { - read: [ - 'xpack.uptime.alerts.tls', - 'xpack.uptime.alerts.tlsCertificate', - 'xpack.uptime.alerts.monitorStatus', - 'xpack.uptime.alerts.durationAnomaly', - ], + read: UPTIME_RULE_TYPES, }, alert: { - read: [ - 'xpack.uptime.alerts.tls', - 'xpack.uptime.alerts.tlsCertificate', - 'xpack.uptime.alerts.monitorStatus', - 'xpack.uptime.alerts.durationAnomaly', - ], + read: UPTIME_RULE_TYPES, }, }, management: { diff --git a/x-pack/plugins/synthetics/server/lib/alerts/action_variables.ts b/x-pack/plugins/synthetics/server/lib/alerts/action_variables.ts index 763cccb404e51..9a3ac2ab632c8 100644 --- a/x-pack/plugins/synthetics/server/lib/alerts/action_variables.ts +++ b/x-pack/plugins/synthetics/server/lib/alerts/action_variables.ts @@ -16,7 +16,7 @@ export const ACTION_VARIABLES = { [MESSAGE]: { name: MESSAGE, description: i18n.translate( - 'xpack.uptime.alerts.monitorStatus.actionVariables.context.message.description', + 'xpack.synthetics.alerts.monitorStatus.actionVariables.context.message.description', { defaultMessage: 'A generated message summarizing the currently down monitors', } @@ -25,7 +25,7 @@ export const ACTION_VARIABLES = { [MONITOR_WITH_GEO]: { name: MONITOR_WITH_GEO, description: i18n.translate( - 'xpack.uptime.alerts.monitorStatus.actionVariables.context.downMonitorsWithGeo.description', + 'xpack.synthetics.alerts.monitorStatus.actionVariables.context.downMonitorsWithGeo.description', { defaultMessage: 'A generated summary that shows some or all of the monitors detected as "down" by the alert', @@ -35,7 +35,7 @@ export const ACTION_VARIABLES = { [ALERT_REASON_MSG]: { name: ALERT_REASON_MSG, description: i18n.translate( - 'xpack.uptime.alerts.monitorStatus.actionVariables.context.alertReasonMessage.description', + 'xpack.synthetics.alerts.monitorStatus.actionVariables.context.alertReasonMessage.description', { defaultMessage: 'A concise description of the reason for the alert', } @@ -44,7 +44,7 @@ export const ACTION_VARIABLES = { [VIEW_IN_APP_URL]: { name: VIEW_IN_APP_URL, description: i18n.translate( - 'xpack.uptime.alerts.monitorStatus.actionVariables.context.viewInAppUrl.description', + 'xpack.synthetics.alerts.monitorStatus.actionVariables.context.viewInAppUrl.description', { defaultMessage: 'Link to the view or feature within Elastic that can be used to investigate the alert and its context further', diff --git a/x-pack/plugins/synthetics/server/lib/alerts/duration_anomaly.ts b/x-pack/plugins/synthetics/server/lib/alerts/duration_anomaly.ts index db50b5cf4bdbc..f2ec05b11f5ea 100644 --- a/x-pack/plugins/synthetics/server/lib/alerts/duration_anomaly.ts +++ b/x-pack/plugins/synthetics/server/lib/alerts/duration_anomaly.ts @@ -16,7 +16,7 @@ import { ActionGroupIdsOf } from '@kbn/alerting-plugin/common'; import { AnomaliesTableRecord } from '@kbn/ml-plugin/common/types/anomalies'; import { getSeverityType } from '@kbn/ml-plugin/common/util/anomaly_utils'; import { updateState, generateAlertMessage, getViewInAppUrl } from './common'; -import { DURATION_ANOMALY } from '../../../common/constants/alerts'; +import { CLIENT_ALERT_TYPES, DURATION_ANOMALY } from '../../../common/constants/alerts'; import { commonStateTranslations, durationAnomalyTranslations } from './translations'; import { UptimeCorePluginsSetup } from '../adapters/framework'; import { UptimeAlertTypeFactory } from './types'; @@ -77,7 +77,7 @@ export const durationAnomalyAlertFactory: UptimeAlertTypeFactory libs, plugins ) => ({ - id: 'xpack.uptime.alerts.durationAnomaly', + id: CLIENT_ALERT_TYPES.DURATION_ANOMALY, producer: 'uptime', name: durationAnomalyTranslations.alertFactoryName, validate: { diff --git a/x-pack/plugins/synthetics/server/lib/alerts/status_check.ts b/x-pack/plugins/synthetics/server/lib/alerts/status_check.ts index f1f00a8f7491f..d305dedea3e10 100644 --- a/x-pack/plugins/synthetics/server/lib/alerts/status_check.ts +++ b/x-pack/plugins/synthetics/server/lib/alerts/status_check.ts @@ -20,7 +20,7 @@ import { Ping, GetMonitorAvailabilityParams, } from '../../../common/runtime_types'; -import { MONITOR_STATUS } from '../../../common/constants/alerts'; +import { CLIENT_ALERT_TYPES, MONITOR_STATUS } from '../../../common/constants/alerts'; import { updateState, getViewInAppUrl } from './common'; import { commonMonitorStateI18, @@ -223,9 +223,9 @@ export const getInstanceId = (monitorInfo: Ping, monIdByLoc: string) => { }; export const statusCheckAlertFactory: UptimeAlertTypeFactory = (server, libs) => ({ - id: 'xpack.uptime.alerts.monitorStatus', + id: CLIENT_ALERT_TYPES.MONITOR_STATUS, producer: 'uptime', - name: i18n.translate('xpack.uptime.alerts.monitorStatus', { + name: i18n.translate('xpack.synthetics.alerts.monitorStatus', { defaultMessage: 'Uptime monitor status', }), validate: { diff --git a/x-pack/plugins/synthetics/server/lib/alerts/tls.ts b/x-pack/plugins/synthetics/server/lib/alerts/tls.ts index 55f7d3f972861..0a6fb24c88156 100644 --- a/x-pack/plugins/synthetics/server/lib/alerts/tls.ts +++ b/x-pack/plugins/synthetics/server/lib/alerts/tls.ts @@ -10,7 +10,7 @@ import { ALERT_REASON } from '@kbn/rule-data-utils'; import { ActionGroupIdsOf } from '@kbn/alerting-plugin/common'; import { UptimeAlertTypeFactory } from './types'; import { updateState, generateAlertMessage } from './common'; -import { TLS } from '../../../common/constants/alerts'; +import { CLIENT_ALERT_TYPES, TLS } from '../../../common/constants/alerts'; import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../common/constants'; import { Cert, CertResult } from '../../../common/runtime_types'; import { commonStateTranslations, tlsTranslations } from './translations'; @@ -94,7 +94,7 @@ export const getCertSummary = ( }; export const tlsAlertFactory: UptimeAlertTypeFactory = (_server, libs) => ({ - id: 'xpack.uptime.alerts.tlsCertificate', + id: CLIENT_ALERT_TYPES.TLS, producer: 'uptime', name: tlsTranslations.alertFactoryName, validate: { diff --git a/x-pack/plugins/synthetics/server/lib/alerts/tls_legacy.ts b/x-pack/plugins/synthetics/server/lib/alerts/tls_legacy.ts index 0490477cb24d1..1ae24138d9853 100644 --- a/x-pack/plugins/synthetics/server/lib/alerts/tls_legacy.ts +++ b/x-pack/plugins/synthetics/server/lib/alerts/tls_legacy.ts @@ -12,7 +12,7 @@ import { AlertInstanceContext } from '@kbn/alerting-plugin/common'; import { Alert } from '@kbn/alerting-plugin/server'; import { UptimeAlertTypeFactory } from './types'; import { updateState } from './common'; -import { TLS_LEGACY } from '../../../common/constants/alerts'; +import { CLIENT_ALERT_TYPES, TLS_LEGACY } from '../../../common/constants/alerts'; import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../common/constants'; import { Cert, CertResult } from '../../../common/runtime_types'; import { commonStateTranslations, tlsTranslations } from './translations'; @@ -93,7 +93,7 @@ export const getCertSummary = ( }; export const tlsLegacyAlertFactory: UptimeAlertTypeFactory = (_server, libs) => ({ - id: 'xpack.uptime.alerts.tls', + id: CLIENT_ALERT_TYPES.TLS_LEGACY, producer: 'uptime', name: tlsTranslations.legacyAlertFactoryName, validate: { diff --git a/x-pack/plugins/synthetics/server/lib/alerts/translations.ts b/x-pack/plugins/synthetics/server/lib/alerts/translations.ts index f80fb7e69e2d3..4a18d93db71e9 100644 --- a/x-pack/plugins/synthetics/server/lib/alerts/translations.ts +++ b/x-pack/plugins/synthetics/server/lib/alerts/translations.ts @@ -10,14 +10,18 @@ import { i18n } from '@kbn/i18n'; export const commonMonitorStateI18 = [ { name: 'monitorName', - description: i18n.translate('xpack.uptime.alerts.monitorStatus.actionVariables.state.monitor', { - defaultMessage: 'A human friendly rendering of name or ID, preferring name (e.g. My Monitor)', - }), + description: i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.actionVariables.state.monitor', + { + defaultMessage: + 'A human friendly rendering of name or ID, preferring name (e.g. My Monitor)', + } + ), }, { name: 'monitorId', description: i18n.translate( - 'xpack.uptime.alerts.monitorStatus.actionVariables.state.monitorId', + 'xpack.synthetics.alerts.monitorStatus.actionVariables.state.monitorId', { defaultMessage: 'ID of the monitor.', } @@ -26,7 +30,7 @@ export const commonMonitorStateI18 = [ { name: 'monitorUrl', description: i18n.translate( - 'xpack.uptime.alerts.monitorStatus.actionVariables.state.monitorUrl', + 'xpack.synthetics.alerts.monitorStatus.actionVariables.state.monitorUrl', { defaultMessage: 'URL of the monitor.', } @@ -35,7 +39,7 @@ export const commonMonitorStateI18 = [ { name: 'monitorType', description: i18n.translate( - 'xpack.uptime.alerts.monitorStatus.actionVariables.state.monitorType', + 'xpack.synthetics.alerts.monitorStatus.actionVariables.state.monitorType', { defaultMessage: 'Type (e.g. HTTP/TCP) of the monitor.', } @@ -44,7 +48,7 @@ export const commonMonitorStateI18 = [ { name: 'statusMessage', description: i18n.translate( - 'xpack.uptime.alerts.monitorStatus.actionVariables.state.statusMessage', + 'xpack.synthetics.alerts.monitorStatus.actionVariables.state.statusMessage', { defaultMessage: 'Status message e.g down or is below availability threshold in case of availability check or both.', @@ -54,7 +58,7 @@ export const commonMonitorStateI18 = [ { name: 'latestErrorMessage', description: i18n.translate( - 'xpack.uptime.alerts.monitorStatus.actionVariables.state.lastErrorMessage', + 'xpack.synthetics.alerts.monitorStatus.actionVariables.state.lastErrorMessage', { defaultMessage: 'Monitor latest error message', } @@ -63,7 +67,7 @@ export const commonMonitorStateI18 = [ { name: 'observerLocation', description: i18n.translate( - 'xpack.uptime.alerts.monitorStatus.actionVariables.state.observerLocation', + 'xpack.synthetics.alerts.monitorStatus.actionVariables.state.observerLocation', { defaultMessage: 'Observer location from which heartbeat check is performed.', } @@ -72,7 +76,7 @@ export const commonMonitorStateI18 = [ { name: 'observerHostname', description: i18n.translate( - 'xpack.uptime.alerts.monitorStatus.actionVariables.state.observerHostname', + 'xpack.synthetics.alerts.monitorStatus.actionVariables.state.observerHostname', { defaultMessage: 'Observer hostname from which heartbeat check is performed.', } @@ -84,7 +88,7 @@ export const commonStateTranslations = [ { name: 'firstCheckedAt', description: i18n.translate( - 'xpack.uptime.alerts.monitorStatus.actionVariables.state.firstCheckedAt', + 'xpack.synthetics.alerts.monitorStatus.actionVariables.state.firstCheckedAt', { defaultMessage: 'Timestamp indicating when this alert first checked', } @@ -93,7 +97,7 @@ export const commonStateTranslations = [ { name: 'firstTriggeredAt', description: i18n.translate( - 'xpack.uptime.alerts.monitorStatus.actionVariables.state.firstTriggeredAt', + 'xpack.synthetics.alerts.monitorStatus.actionVariables.state.firstTriggeredAt', { defaultMessage: 'Timestamp indicating when the alert first triggered', } @@ -102,7 +106,7 @@ export const commonStateTranslations = [ { name: 'currentTriggerStarted', description: i18n.translate( - 'xpack.uptime.alerts.monitorStatus.actionVariables.state.currentTriggerStarted', + 'xpack.synthetics.alerts.monitorStatus.actionVariables.state.currentTriggerStarted', { defaultMessage: 'Timestamp indicating when the current trigger state began, if alert is triggered', @@ -112,7 +116,7 @@ export const commonStateTranslations = [ { name: 'isTriggered', description: i18n.translate( - 'xpack.uptime.alerts.monitorStatus.actionVariables.state.isTriggered', + 'xpack.synthetics.alerts.monitorStatus.actionVariables.state.isTriggered', { defaultMessage: `Flag indicating if the alert is currently triggering`, } @@ -121,7 +125,7 @@ export const commonStateTranslations = [ { name: 'lastCheckedAt', description: i18n.translate( - 'xpack.uptime.alerts.monitorStatus.actionVariables.state.lastCheckedAt', + 'xpack.synthetics.alerts.monitorStatus.actionVariables.state.lastCheckedAt', { defaultMessage: `Timestamp indicating the alert's most recent check time`, } @@ -130,7 +134,7 @@ export const commonStateTranslations = [ { name: 'lastResolvedAt', description: i18n.translate( - 'xpack.uptime.alerts.monitorStatus.actionVariables.state.lastResolvedAt', + 'xpack.synthetics.alerts.monitorStatus.actionVariables.state.lastResolvedAt', { defaultMessage: `Timestamp indicating the most recent resolution time for this alert`, } @@ -139,7 +143,7 @@ export const commonStateTranslations = [ { name: 'lastTriggeredAt', description: i18n.translate( - 'xpack.uptime.alerts.monitorStatus.actionVariables.state.lastTriggeredAt', + 'xpack.synthetics.alerts.monitorStatus.actionVariables.state.lastTriggeredAt', { defaultMessage: `Timestamp indicating the alert's most recent trigger time`, } @@ -148,29 +152,32 @@ export const commonStateTranslations = [ ]; export const tlsTranslations = { - alertFactoryName: i18n.translate('xpack.uptime.alerts.tls', { + alertFactoryName: i18n.translate('xpack.synthetics.alerts.tls', { defaultMessage: 'Uptime TLS', }), - legacyAlertFactoryName: i18n.translate('xpack.uptime.alerts.tlsLegacy', { + legacyAlertFactoryName: i18n.translate('xpack.synthetics.alerts.tlsLegacy', { defaultMessage: 'Uptime TLS (Legacy)', }), actionVariables: [ { name: 'count', - description: i18n.translate('xpack.uptime.alerts.tls.actionVariables.state.count', { + description: i18n.translate('xpack.synthetics.alerts.tls.actionVariables.state.count', { defaultMessage: 'The number of certs detected by the alert executor', }), }, { name: 'expiringCount', - description: i18n.translate('xpack.uptime.alerts.tls.actionVariables.state.expiringCount', { - defaultMessage: 'The number of expiring certs detected by the alert.', - }), + description: i18n.translate( + 'xpack.synthetics.alerts.tls.actionVariables.state.expiringCount', + { + defaultMessage: 'The number of expiring certs detected by the alert.', + } + ), }, { name: 'expiringCommonNameAndDate', description: i18n.translate( - 'xpack.uptime.alerts.tls.actionVariables.state.expiringCommonNameAndDate', + 'xpack.synthetics.alerts.tls.actionVariables.state.expiringCommonNameAndDate', { defaultMessage: 'The common names and expiration date/time of the detected certs', } @@ -178,14 +185,14 @@ export const tlsTranslations = { }, { name: 'agingCount', - description: i18n.translate('xpack.uptime.alerts.tls.actionVariables.state.agingCount', { + description: i18n.translate('xpack.synthetics.alerts.tls.actionVariables.state.agingCount', { defaultMessage: 'The number of detected certs that are becoming too old.', }), }, { name: 'agingCommonNameAndDate', description: i18n.translate( - 'xpack.uptime.alerts.tls.actionVariables.state.agingCommonNameAndDate', + 'xpack.synthetics.alerts.tls.actionVariables.state.agingCommonNameAndDate', { defaultMessage: 'The common names and expiration date/time of the detected certs.', } @@ -193,7 +200,7 @@ export const tlsTranslations = { }, ], validAfterExpiredString: (date: string, relativeDate: number) => - i18n.translate('xpack.uptime.alerts.tls.validAfterExpiredString', { + i18n.translate('xpack.synthetics.alerts.tls.validAfterExpiredString', { defaultMessage: `expired on {date}, {relativeDate} days ago.`, values: { date, @@ -201,7 +208,7 @@ export const tlsTranslations = { }, }), validAfterExpiringString: (date: string, relativeDate: number) => - i18n.translate('xpack.uptime.alerts.tls.validAfterExpiringString', { + i18n.translate('xpack.synthetics.alerts.tls.validAfterExpiringString', { defaultMessage: `expires on {date} in {relativeDate} days.`, values: { date, @@ -209,7 +216,7 @@ export const tlsTranslations = { }, }), validBeforeExpiredString: (date: string, relativeDate: number) => - i18n.translate('xpack.uptime.alerts.tls.validBeforeExpiredString', { + i18n.translate('xpack.synthetics.alerts.tls.validBeforeExpiredString', { defaultMessage: 'valid since {date}, {relativeDate} days ago.', values: { date, @@ -217,36 +224,36 @@ export const tlsTranslations = { }, }), validBeforeExpiringString: (date: string, relativeDate: number) => - i18n.translate('xpack.uptime.alerts.tls.validBeforeExpiringString', { + i18n.translate('xpack.synthetics.alerts.tls.validBeforeExpiringString', { defaultMessage: 'invalid until {date}, {relativeDate} days from now.', values: { date, relativeDate, }, }), - expiredLabel: i18n.translate('xpack.uptime.alerts.tls.expiredLabel', { + expiredLabel: i18n.translate('xpack.synthetics.alerts.tls.expiredLabel', { defaultMessage: 'expired', }), - expiringLabel: i18n.translate('xpack.uptime.alerts.tls.expiringLabel', { + expiringLabel: i18n.translate('xpack.synthetics.alerts.tls.expiringLabel', { defaultMessage: 'expiring', }), - agingLabel: i18n.translate('xpack.uptime.alerts.tls.agingLabel', { + agingLabel: i18n.translate('xpack.synthetics.alerts.tls.agingLabel', { defaultMessage: 'becoming too old', }), - invalidLabel: i18n.translate('xpack.uptime.alerts.tls.invalidLabel', { + invalidLabel: i18n.translate('xpack.synthetics.alerts.tls.invalidLabel', { defaultMessage: 'invalid', }), }; export const durationAnomalyTranslations = { - alertFactoryName: i18n.translate('xpack.uptime.alerts.durationAnomaly', { + alertFactoryName: i18n.translate('xpack.synthetics.alerts.durationAnomaly', { defaultMessage: 'Uptime Duration Anomaly', }), actionVariables: [ { name: 'severity', description: i18n.translate( - 'xpack.uptime.alerts.durationAnomaly.actionVariables.state.severity', + 'xpack.synthetics.alerts.durationAnomaly.actionVariables.state.severity', { defaultMessage: 'The severity of the anomaly.', } @@ -255,7 +262,7 @@ export const durationAnomalyTranslations = { { name: 'anomalyStartTimestamp', description: i18n.translate( - 'xpack.uptime.alerts.durationAnomaly.actionVariables.state.anomalyStartTimestamp', + 'xpack.synthetics.alerts.durationAnomaly.actionVariables.state.anomalyStartTimestamp', { defaultMessage: 'ISO8601 timestamp of the start of the anomaly.', } @@ -264,7 +271,7 @@ export const durationAnomalyTranslations = { { name: 'monitor', description: i18n.translate( - 'xpack.uptime.alerts.durationAnomaly.actionVariables.state.monitor', + 'xpack.synthetics.alerts.durationAnomaly.actionVariables.state.monitor', { defaultMessage: 'A human friendly rendering of name or ID, preferring name (e.g. My Monitor)', @@ -274,7 +281,7 @@ export const durationAnomalyTranslations = { { name: 'monitorId', description: i18n.translate( - 'xpack.uptime.alerts.durationAnomaly.actionVariables.state.monitorId', + 'xpack.synthetics.alerts.durationAnomaly.actionVariables.state.monitorId', { defaultMessage: 'ID of the monitor.', } @@ -283,7 +290,7 @@ export const durationAnomalyTranslations = { { name: 'monitorUrl', description: i18n.translate( - 'xpack.uptime.alerts.durationAnomaly.actionVariables.state.monitorUrl', + 'xpack.synthetics.alerts.durationAnomaly.actionVariables.state.monitorUrl', { defaultMessage: 'URL of the monitor.', } @@ -292,7 +299,7 @@ export const durationAnomalyTranslations = { { name: 'slowestAnomalyResponse', description: i18n.translate( - 'xpack.uptime.alerts.durationAnomaly.actionVariables.state.slowestAnomalyResponse', + 'xpack.synthetics.alerts.durationAnomaly.actionVariables.state.slowestAnomalyResponse', { defaultMessage: 'Slowest response time during anomaly bucket with unit (ms, s) attached.', } @@ -301,7 +308,7 @@ export const durationAnomalyTranslations = { { name: 'expectedResponseTime', description: i18n.translate( - 'xpack.uptime.alerts.durationAnomaly.actionVariables.state.expectedResponseTime', + 'xpack.synthetics.alerts.durationAnomaly.actionVariables.state.expectedResponseTime', { defaultMessage: 'Expected response time', } @@ -310,7 +317,7 @@ export const durationAnomalyTranslations = { { name: 'severityScore', description: i18n.translate( - 'xpack.uptime.alerts.durationAnomaly.actionVariables.state.severityScore', + 'xpack.synthetics.alerts.durationAnomaly.actionVariables.state.severityScore', { defaultMessage: 'Anomaly severity score', } @@ -319,7 +326,7 @@ export const durationAnomalyTranslations = { { name: 'observerLocation', description: i18n.translate( - 'xpack.uptime.alerts.durationAnomaly.actionVariables.state.observerLocation', + 'xpack.synthetics.alerts.durationAnomaly.actionVariables.state.observerLocation', { defaultMessage: 'Observer location from which heartbeat check is performed.', } @@ -330,7 +337,7 @@ export const durationAnomalyTranslations = { export const statusCheckTranslations = { downMonitorsLabel: (count: number, interval: string, numTimes: number) => - i18n.translate('xpack.uptime.alerts.monitorStatus.actionVariables.down', { + i18n.translate('xpack.synthetics.alerts.monitorStatus.actionVariables.down', { defaultMessage: `failed {count} times in the last {interval}. Alert when > {numTimes}.`, values: { count, @@ -343,7 +350,7 @@ export const statusCheckTranslations = { expectedAvailability: string, interval: string ) => - i18n.translate('xpack.uptime.alerts.monitorStatus.actionVariables.availabilityMessage', { + i18n.translate('xpack.synthetics.alerts.monitorStatus.actionVariables.availabilityMessage', { defaultMessage: '{interval} availability is {availabilityRatio}%. Alert when < {expectedAvailability}%.', values: { @@ -356,11 +363,14 @@ export const statusCheckTranslations = { downMonitorsMessage: string, availabilityBreachMessage: string ) => - i18n.translate('xpack.uptime.alerts.monitorStatus.actionVariables.downAndAvailabilityMessage', { - defaultMessage: '{downMonitorsMessage} The {availabilityBreachMessage}', - values: { - downMonitorsMessage, - availabilityBreachMessage, - }, - }), + i18n.translate( + 'xpack.synthetics.alerts.monitorStatus.actionVariables.downAndAvailabilityMessage', + { + defaultMessage: '{downMonitorsMessage} The {availabilityBreachMessage}', + values: { + downMonitorsMessage, + availabilityBreachMessage, + }, + } + ), }; diff --git a/x-pack/plugins/synthetics/server/lib/requests/get_monitor_details.test.ts b/x-pack/plugins/synthetics/server/lib/requests/get_monitor_details.test.ts index 68560faf4f7fe..bfdee6291a04e 100644 --- a/x-pack/plugins/synthetics/server/lib/requests/get_monitor_details.test.ts +++ b/x-pack/plugins/synthetics/server/lib/requests/get_monitor_details.test.ts @@ -8,6 +8,7 @@ import { mockSearchResult } from './helper'; import { getMonitorAlerts, getMonitorDetails } from './get_monitor_details'; import * as statusCheck from '../alerts/status_check'; +import { CLIENT_ALERT_TYPES } from '../../../common/constants/alerts'; describe('getMonitorDetails', () => { it('getMonitorDetails will provide expected calls', async () => { @@ -128,7 +129,7 @@ const dummyAlertRules = { availability: { range: 30, rangeUnit: 'd', threshold: '99' }, filters: { tags: [], 'url.port': [], 'observer.geo.name': [], 'monitor.type': ['browser'] }, }, - rule_type_id: 'xpack.uptime.alerts.monitorStatus', + rule_type_id: CLIENT_ALERT_TYPES.MONITOR_STATUS, created_by: null, updated_by: null, created_at: '2021-10-20T20:52:20.050Z', @@ -163,7 +164,7 @@ const dummyAlertRules = { availability: { range: 30, rangeUnit: 'd', threshold: '99' }, filters: { tags: [], 'url.port': [], 'observer.geo.name': [], 'monitor.type': ['http'] }, }, - rule_type_id: 'xpack.uptime.alerts.monitorStatus', + rule_type_id: CLIENT_ALERT_TYPES.MONITOR_STATUS, created_by: null, updated_by: null, created_at: '2021-10-20T20:54:08.529Z', @@ -198,7 +199,7 @@ const dummyAlertRules = { availability: { range: 30, rangeUnit: 'd', threshold: '99' }, filters: { tags: [], 'url.port': [], 'observer.geo.name': [], 'monitor.type': ['http'] }, }, - rule_type_id: 'xpack.uptime.alerts.monitorStatus', + rule_type_id: CLIENT_ALERT_TYPES.MONITOR_STATUS, created_by: null, updated_by: null, created_at: '2021-10-20T20:57:38.451Z', diff --git a/x-pack/plugins/synthetics/server/lib/requests/get_monitor_details.ts b/x-pack/plugins/synthetics/server/lib/requests/get_monitor_details.ts index 6a4042a8f5fe6..e018902d32f7f 100644 --- a/x-pack/plugins/synthetics/server/lib/requests/get_monitor_details.ts +++ b/x-pack/plugins/synthetics/server/lib/requests/get_monitor_details.ts @@ -6,6 +6,7 @@ */ import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { CLIENT_ALERT_TYPES } from '../../../common/constants/alerts'; import { UMElasticsearchQueryFn } from '../adapters'; import { MonitorDetails, Ping } from '../../../common/runtime_types'; import { formatFilterString } from '../alerts/status_check'; @@ -31,7 +32,7 @@ export const getMonitorAlerts = async ({ const options: any = { page: 1, perPage: 500, - filter: 'alert.attributes.alertTypeId:(xpack.uptime.alerts.monitorStatus)', + filter: `alert.attributes.alertTypeId:(${CLIENT_ALERT_TYPES.MONITOR_STATUS})`, defaultSearchOperator: 'AND', sortField: 'name.keyword', }; diff --git a/x-pack/plugins/synthetics/server/lib/saved_objects/service_api_key.ts b/x-pack/plugins/synthetics/server/lib/saved_objects/service_api_key.ts index 1486c65f07b1a..db0c14be7089b 100644 --- a/x-pack/plugins/synthetics/server/lib/saved_objects/service_api_key.ts +++ b/x-pack/plugins/synthetics/server/lib/saved_objects/service_api_key.ts @@ -43,7 +43,7 @@ export const syntheticsServiceApiKey: SavedObjectsType = { importableAndExportable: false, icon: 'uptimeApp', getTitle: () => - i18n.translate('xpack.uptime.synthetics.service.apiKey', { + i18n.translate('xpack.synthetics.synthetics.service.apiKey', { defaultMessage: 'Synthetics service api key', }), }, diff --git a/x-pack/plugins/synthetics/server/lib/saved_objects/synthetics_monitor.ts b/x-pack/plugins/synthetics/server/lib/saved_objects/synthetics_monitor.ts index 306f6ee689a38..19a975607a59a 100644 --- a/x-pack/plugins/synthetics/server/lib/saved_objects/synthetics_monitor.ts +++ b/x-pack/plugins/synthetics/server/lib/saved_objects/synthetics_monitor.ts @@ -52,7 +52,7 @@ export const syntheticsMonitor: SavedObjectsType = { getTitle: (savedObject) => savedObject.attributes.name + ' - ' + - i18n.translate('xpack.uptime.syntheticsMonitors', { + i18n.translate('xpack.synthetics.syntheticsMonitors', { defaultMessage: 'Uptime - Monitor', }), }, diff --git a/x-pack/plugins/synthetics/server/lib/saved_objects/uptime_settings.ts b/x-pack/plugins/synthetics/server/lib/saved_objects/uptime_settings.ts index e8307256ddb2c..6791ad18db10f 100644 --- a/x-pack/plugins/synthetics/server/lib/saved_objects/uptime_settings.ts +++ b/x-pack/plugins/synthetics/server/lib/saved_objects/uptime_settings.ts @@ -41,7 +41,7 @@ export const umDynamicSettings: SavedObjectsType = { importableAndExportable: true, icon: 'uptimeApp', getTitle: () => - i18n.translate('xpack.uptime.uptimeSettings.index', { + i18n.translate('xpack.synthetics.uptimeSettings.index', { defaultMessage: 'Uptime Settings - Index', }), }, diff --git a/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/browser.ts b/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/browser.ts index 616d764c50abb..876827e453adf 100644 --- a/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/browser.ts +++ b/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/browser.ts @@ -10,6 +10,21 @@ import { BrowserFields, ConfigKey } from '../../../../common/runtime_types/monit export type BrowserFormatMap = Record; +const throttlingFormatter: Formatter = (fields) => { + if (!fields[ConfigKey.IS_THROTTLING_ENABLED]) return false; + + const getThrottlingValue = (v: string | undefined, suffix: 'd' | 'u' | 'l') => + v !== '' && v !== undefined ? `${v}${suffix}` : null; + + return [ + getThrottlingValue(fields[ConfigKey.DOWNLOAD_SPEED], 'd'), + getThrottlingValue(fields[ConfigKey.UPLOAD_SPEED], 'u'), + getThrottlingValue(fields[ConfigKey.LATENCY], 'l'), + ] + .filter((v) => v !== null) + .join('/'); +}; + export const browserFormatters: BrowserFormatMap = { [ConfigKey.METADATA]: (fields) => objectFormatter(fields[ConfigKey.METADATA]), [ConfigKey.URLS]: null, @@ -31,12 +46,7 @@ export const browserFormatters: BrowserFormatMap = { [ConfigKey.ZIP_URL_TLS_KEY_PASSPHRASE]: null, [ConfigKey.ZIP_URL_TLS_VERIFICATION_MODE]: null, [ConfigKey.IS_THROTTLING_ENABLED]: null, - [ConfigKey.THROTTLING_CONFIG]: (fields) => { - if (fields[ConfigKey.IS_THROTTLING_ENABLED] === false) { - return false; - } - return fields[ConfigKey.THROTTLING_CONFIG] ?? false; - }, + [ConfigKey.THROTTLING_CONFIG]: (fields) => throttlingFormatter(fields), [ConfigKey.DOWNLOAD_SPEED]: null, [ConfigKey.UPLOAD_SPEED]: null, [ConfigKey.LATENCY]: null, diff --git a/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/convert_to_data_stream.ts b/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/convert_to_data_stream.ts index 7d518b189afef..52ae921c78643 100644 --- a/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/convert_to_data_stream.ts +++ b/x-pack/plugins/synthetics/server/lib/synthetics_service/formatters/convert_to_data_stream.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { DEFAULT_NAMESPACE_STRING } from '../../../../common/constants'; +import { DEFAULT_NAMESPACE_STRING } from '../../../../common/constants/monitor_defaults'; import { DataStream, MonitorFields } from '../../../../common/runtime_types'; interface DataStreamConfig { diff --git a/x-pack/plugins/synthetics/server/rest_api/create_route_with_auth.ts b/x-pack/plugins/synthetics/server/rest_api/create_route_with_auth.ts index c3d7c693ef00a..20bb6043e624f 100644 --- a/x-pack/plugins/synthetics/server/rest_api/create_route_with_auth.ts +++ b/x-pack/plugins/synthetics/server/rest_api/create_route_with_auth.ts @@ -22,7 +22,7 @@ export const createRouteWithAuth = ( savedObjectsClient, server, }) => { - const { statusCode, message } = libs.license(context.licensing.license); + const { statusCode, message } = libs.license((await context.licensing).license); if (statusCode === 200) { return handler({ uptimeEsClient, diff --git a/x-pack/plugins/synthetics/server/rest_api/monitors/monitors_details.ts b/x-pack/plugins/synthetics/server/rest_api/monitors/monitors_details.ts index 64e9ed504e7cd..bed10c5cda9a7 100644 --- a/x-pack/plugins/synthetics/server/rest_api/monitors/monitors_details.ts +++ b/x-pack/plugins/synthetics/server/rest_api/monitors/monitors_details.ts @@ -23,7 +23,7 @@ export const createGetMonitorDetailsRoute: UMRestApiRouteFactory = (libs: UMServ handler: async ({ uptimeEsClient, context, request }): Promise => { const { monitorId, dateStart, dateEnd } = request.query; - const rulesClient = context.alerting?.getRulesClient(); + const rulesClient = (await context.alerting)?.getRulesClient(); return await libs.requests.getMonitorDetails({ uptimeEsClient, diff --git a/x-pack/plugins/synthetics/server/rest_api/uptime_route_wrapper.ts b/x-pack/plugins/synthetics/server/rest_api/uptime_route_wrapper.ts index 6ad4e868a7fcb..03948589774ab 100644 --- a/x-pack/plugins/synthetics/server/rest_api/uptime_route_wrapper.ts +++ b/x-pack/plugins/synthetics/server/rest_api/uptime_route_wrapper.ts @@ -21,20 +21,21 @@ export const uptimeRouteWrapper: UMKibanaRouteWrapper = (uptimeRoute, server) => tags: ['access:uptime-read', ...(uptimeRoute?.writeAccess ? ['access:uptime-write'] : [])], }, handler: async (context, request, response) => { - const { client: esClient } = context.core.elasticsearch; + const coreContext = await context.core; + const { client: esClient } = coreContext.elasticsearch; let savedObjectsClient: SavedObjectsClientContract; if (server.config?.service) { - savedObjectsClient = context.core.savedObjects.getClient({ + savedObjectsClient = coreContext.savedObjects.getClient({ includedHiddenTypes: [syntheticsServiceApiKey.name], }); } else { - savedObjectsClient = context.core.savedObjects.client; + savedObjectsClient = coreContext.savedObjects.client; } // specifically needed for the synthetics service api key generation server.authSavedObjectsClient = savedObjectsClient; - const isInspectorEnabled = await context.core.uiSettings.client.get( + const isInspectorEnabled = await coreContext.uiSettings.client.get( enableInspectEsQueries ); diff --git a/x-pack/plugins/synthetics/server/types.ts b/x-pack/plugins/synthetics/server/types.ts index b05ac2ee38a79..e66400ce55a07 100644 --- a/x-pack/plugins/synthetics/server/types.ts +++ b/x-pack/plugins/synthetics/server/types.ts @@ -5,16 +5,17 @@ * 2.0. */ -import type { IRouter, RequestHandlerContext } from '@kbn/core/server'; +import type { IRouter, CustomRequestHandlerContext } from '@kbn/core/server'; import type { AlertingApiRequestHandlerContext } from '@kbn/alerting-plugin/server'; import type { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server'; + /** * @internal */ -export interface UptimeRequestHandlerContext extends RequestHandlerContext { +export type UptimeRequestHandlerContext = CustomRequestHandlerContext<{ licensing: LicensingApiRequestHandlerContext; alerting: AlertingApiRequestHandlerContext; -} +}>; /** * @internal diff --git a/x-pack/plugins/synthetics/tsconfig.json b/x-pack/plugins/synthetics/tsconfig.json index 17088fe6f1fd9..023c98c66a4a5 100644 --- a/x-pack/plugins/synthetics/tsconfig.json +++ b/x-pack/plugins/synthetics/tsconfig.json @@ -10,7 +10,7 @@ "common/**/*", "scripts/**/*", "public/**/*", - "public/components/monitor/status_details/location_map/embeddables/low_poly_layer.json", + "public/legacy_uptime/components/monitor/status_details/location_map/embeddables/low_poly_layer.json", "server/**/*", "server/lib/requests/__fixtures__/monitor_charts_mock.json", "../../../typings/**/*" diff --git a/x-pack/plugins/task_manager/server/task_events.test.ts b/x-pack/plugins/task_manager/server/task_events.test.ts index 607453b7ea92f..9c6b9f9cdede8 100644 --- a/x-pack/plugins/task_manager/server/task_events.test.ts +++ b/x-pack/plugins/task_manager/server/task_events.test.ts @@ -11,17 +11,28 @@ const DelayIterations = 4; const DelayMillis = 250; const DelayTotal = DelayIterations * DelayMillis; -async function nonBlockingDelay(millis: number) { +async function basicNonBlockingDelay(millis: number) { await new Promise((resolve) => setTimeout(resolve, millis)); } +async function nonBlockingDelay(millis: number) { + // can't just use basicNonBlockingDelay because: + // https://github.com/nodejs/node/issues/26578 + const end = Date.now() + millis; + + while (Date.now() <= end) { + await basicNonBlockingDelay(millis); + } +} + async function blockingDelay(millis: number) { // get task in async queue await nonBlockingDelay(0); const end = Date.now() + millis; + // eslint-disable-next-line no-empty - while (Date.now() < end) {} + while (Date.now() <= end) {} } async function nonBlockingTask() { @@ -45,8 +56,7 @@ describe('task_events', () => { expect(result.eventLoopBlockMs).toBe(undefined); }); - // FLAKY: https://github.com/elastic/kibana/issues/128441 - describe.skip('startTaskTimerWithEventLoopMonitoring', () => { + describe('startTaskTimerWithEventLoopMonitoring', () => { test('non-blocking', async () => { const stopTaskTimer = startTaskTimerWithEventLoopMonitoring({ monitor: true, diff --git a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json index c8cd2b27210ff..aac8d2e40f650 100644 --- a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json +++ b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @@ -2269,6 +2269,332 @@ } } } + }, + "percentile_num_alerts_per_day": { + "properties": { + "p50": { + "type": "long" + }, + "p90": { + "type": "long" + }, + "p99": { + "type": "long" + } + } + }, + "percentile_num_alerts_by_type_per_day": { + "properties": { + "p50": { + "properties": { + "DYNAMIC_KEY": { + "type": "long" + }, + "__index-threshold": { + "type": "long" + }, + "__es-query": { + "type": "long" + }, + "transform_health": { + "type": "long" + }, + "apm__error_rate": { + "type": "long" + }, + "apm__transaction_error_rate": { + "type": "long" + }, + "apm__transaction_duration": { + "type": "long" + }, + "apm__transaction_duration_anomaly": { + "type": "long" + }, + "metrics__alert__threshold": { + "type": "long" + }, + "metrics__alert__inventory__threshold": { + "type": "long" + }, + "logs__alert__document__count": { + "type": "long" + }, + "monitoring_alert_cluster_health": { + "type": "long" + }, + "monitoring_alert_cpu_usage": { + "type": "long" + }, + "monitoring_alert_disk_usage": { + "type": "long" + }, + "monitoring_alert_elasticsearch_version_mismatch": { + "type": "long" + }, + "monitoring_alert_kibana_version_mismatch": { + "type": "long" + }, + "monitoring_alert_license_expiration": { + "type": "long" + }, + "monitoring_alert_logstash_version_mismatch": { + "type": "long" + }, + "monitoring_alert_nodes_changed": { + "type": "long" + }, + "siem__signals": { + "type": "long" + }, + "siem__notifications": { + "type": "long" + }, + "siem__eqlRule": { + "type": "long" + }, + "siem__indicatorRule": { + "type": "long" + }, + "siem__mlRule": { + "type": "long" + }, + "siem__queryRule": { + "type": "long" + }, + "siem__savedQueryRule": { + "type": "long" + }, + "siem__thresholdRule": { + "type": "long" + }, + "xpack__uptime__alerts__monitorStatus": { + "type": "long" + }, + "xpack__uptime__alerts__tls": { + "type": "long" + }, + "xpack__uptime__alerts__durationAnomaly": { + "type": "long" + }, + "__geo-containment": { + "type": "long" + }, + "xpack__ml__anomaly_detection_alert": { + "type": "long" + }, + "xpack__ml__anomaly_detection_jobs_health": { + "type": "long" + } + } + }, + "p90": { + "properties": { + "DYNAMIC_KEY": { + "type": "long" + }, + "__index-threshold": { + "type": "long" + }, + "__es-query": { + "type": "long" + }, + "transform_health": { + "type": "long" + }, + "apm__error_rate": { + "type": "long" + }, + "apm__transaction_error_rate": { + "type": "long" + }, + "apm__transaction_duration": { + "type": "long" + }, + "apm__transaction_duration_anomaly": { + "type": "long" + }, + "metrics__alert__threshold": { + "type": "long" + }, + "metrics__alert__inventory__threshold": { + "type": "long" + }, + "logs__alert__document__count": { + "type": "long" + }, + "monitoring_alert_cluster_health": { + "type": "long" + }, + "monitoring_alert_cpu_usage": { + "type": "long" + }, + "monitoring_alert_disk_usage": { + "type": "long" + }, + "monitoring_alert_elasticsearch_version_mismatch": { + "type": "long" + }, + "monitoring_alert_kibana_version_mismatch": { + "type": "long" + }, + "monitoring_alert_license_expiration": { + "type": "long" + }, + "monitoring_alert_logstash_version_mismatch": { + "type": "long" + }, + "monitoring_alert_nodes_changed": { + "type": "long" + }, + "siem__signals": { + "type": "long" + }, + "siem__notifications": { + "type": "long" + }, + "siem__eqlRule": { + "type": "long" + }, + "siem__indicatorRule": { + "type": "long" + }, + "siem__mlRule": { + "type": "long" + }, + "siem__queryRule": { + "type": "long" + }, + "siem__savedQueryRule": { + "type": "long" + }, + "siem__thresholdRule": { + "type": "long" + }, + "xpack__uptime__alerts__monitorStatus": { + "type": "long" + }, + "xpack__uptime__alerts__tls": { + "type": "long" + }, + "xpack__uptime__alerts__durationAnomaly": { + "type": "long" + }, + "__geo-containment": { + "type": "long" + }, + "xpack__ml__anomaly_detection_alert": { + "type": "long" + }, + "xpack__ml__anomaly_detection_jobs_health": { + "type": "long" + } + } + }, + "p99": { + "properties": { + "DYNAMIC_KEY": { + "type": "long" + }, + "__index-threshold": { + "type": "long" + }, + "__es-query": { + "type": "long" + }, + "transform_health": { + "type": "long" + }, + "apm__error_rate": { + "type": "long" + }, + "apm__transaction_error_rate": { + "type": "long" + }, + "apm__transaction_duration": { + "type": "long" + }, + "apm__transaction_duration_anomaly": { + "type": "long" + }, + "metrics__alert__threshold": { + "type": "long" + }, + "metrics__alert__inventory__threshold": { + "type": "long" + }, + "logs__alert__document__count": { + "type": "long" + }, + "monitoring_alert_cluster_health": { + "type": "long" + }, + "monitoring_alert_cpu_usage": { + "type": "long" + }, + "monitoring_alert_disk_usage": { + "type": "long" + }, + "monitoring_alert_elasticsearch_version_mismatch": { + "type": "long" + }, + "monitoring_alert_kibana_version_mismatch": { + "type": "long" + }, + "monitoring_alert_license_expiration": { + "type": "long" + }, + "monitoring_alert_logstash_version_mismatch": { + "type": "long" + }, + "monitoring_alert_nodes_changed": { + "type": "long" + }, + "siem__signals": { + "type": "long" + }, + "siem__notifications": { + "type": "long" + }, + "siem__eqlRule": { + "type": "long" + }, + "siem__indicatorRule": { + "type": "long" + }, + "siem__mlRule": { + "type": "long" + }, + "siem__queryRule": { + "type": "long" + }, + "siem__savedQueryRule": { + "type": "long" + }, + "siem__thresholdRule": { + "type": "long" + }, + "xpack__uptime__alerts__monitorStatus": { + "type": "long" + }, + "xpack__uptime__alerts__tls": { + "type": "long" + }, + "xpack__uptime__alerts__durationAnomaly": { + "type": "long" + }, + "__geo-containment": { + "type": "long" + }, + "xpack__ml__anomaly_detection_alert": { + "type": "long" + }, + "xpack__ml__anomaly_detection_jobs_health": { + "type": "long" + } + } + } + } } } }, @@ -4231,19 +4557,6 @@ } } }, - "search-session": { - "properties": { - "transientCount": { - "type": "long" - }, - "persistedCount": { - "type": "long" - }, - "totalCount": { - "type": "long" - } - } - }, "discoverEnhanced": { "properties": { "exploreDataInChartActionEnabled": { @@ -6663,6 +6976,9 @@ }, "browser_screenshot_error": { "type": "long" + }, + "visual_reporting_soft_disabled_error": { + "type": "long" } } } @@ -6778,6 +7094,9 @@ }, "browser_screenshot_error": { "type": "long" + }, + "visual_reporting_soft_disabled_error": { + "type": "long" } } } @@ -6925,6 +7244,9 @@ }, "browser_screenshot_error": { "type": "long" + }, + "visual_reporting_soft_disabled_error": { + "type": "long" } } } @@ -7072,6 +7394,9 @@ }, "browser_screenshot_error": { "type": "long" + }, + "visual_reporting_soft_disabled_error": { + "type": "long" } } } @@ -7926,6 +8251,9 @@ }, "browser_screenshot_error": { "type": "long" + }, + "visual_reporting_soft_disabled_error": { + "type": "long" } } } @@ -8041,6 +8369,9 @@ }, "browser_screenshot_error": { "type": "long" + }, + "visual_reporting_soft_disabled_error": { + "type": "long" } } } @@ -8188,6 +8519,9 @@ }, "browser_screenshot_error": { "type": "long" + }, + "visual_reporting_soft_disabled_error": { + "type": "long" } } } @@ -8335,6 +8669,9 @@ }, "browser_screenshot_error": { "type": "long" + }, + "visual_reporting_soft_disabled_error": { + "type": "long" } } } @@ -12475,98 +12812,6 @@ } } }, - "task_manager": { - "properties": { - "ephemeral_tasks_enabled": { - "type": "boolean" - }, - "ephemeral_request_capacity": { - "type": "short" - }, - "ephemeral_stats": { - "properties": { - "status": { - "type": "keyword" - }, - "queued_tasks": { - "properties": { - "p50": { - "type": "long" - }, - "p90": { - "type": "long" - }, - "p95": { - "type": "long" - }, - "p99": { - "type": "long" - } - } - }, - "load": { - "properties": { - "p50": { - "type": "long" - }, - "p90": { - "type": "long" - }, - "p95": { - "type": "long" - }, - "p99": { - "type": "long" - } - } - }, - "executions_per_cycle": { - "properties": { - "p50": { - "type": "long" - }, - "p90": { - "type": "long" - }, - "p95": { - "type": "long" - }, - "p99": { - "type": "long" - } - } - } - } - }, - "task_type_exclusion": { - "type": "array", - "items": { - "type": "keyword" - } - }, - "failed_tasks": { - "type": "long" - } - } - }, - "upgrade-assistant-telemetry": { - "properties": { - "features": { - "properties": { - "deprecation_logging": { - "properties": { - "enabled": { - "type": "boolean", - "_meta": { - "description": "Whether user has enabled Elasticsearch deprecation logging" - } - } - } - } - } - } - } - }, "uptime": { "properties": { "last_24_hours": { @@ -12707,6 +12952,98 @@ } } } + }, + "task_manager": { + "properties": { + "ephemeral_tasks_enabled": { + "type": "boolean" + }, + "ephemeral_request_capacity": { + "type": "short" + }, + "ephemeral_stats": { + "properties": { + "status": { + "type": "keyword" + }, + "queued_tasks": { + "properties": { + "p50": { + "type": "long" + }, + "p90": { + "type": "long" + }, + "p95": { + "type": "long" + }, + "p99": { + "type": "long" + } + } + }, + "load": { + "properties": { + "p50": { + "type": "long" + }, + "p90": { + "type": "long" + }, + "p95": { + "type": "long" + }, + "p99": { + "type": "long" + } + } + }, + "executions_per_cycle": { + "properties": { + "p50": { + "type": "long" + }, + "p90": { + "type": "long" + }, + "p95": { + "type": "long" + }, + "p99": { + "type": "long" + } + } + } + } + }, + "task_type_exclusion": { + "type": "array", + "items": { + "type": "keyword" + } + }, + "failed_tasks": { + "type": "long" + } + } + }, + "upgrade-assistant-telemetry": { + "properties": { + "features": { + "properties": { + "deprecation_logging": { + "properties": { + "enabled": { + "type": "boolean", + "_meta": { + "description": "Whether user has enabled Elasticsearch deprecation logging" + } + } + } + } + } + } + } } } } diff --git a/x-pack/plugins/timelines/common/search_strategy/timeline/events/common/index.ts b/x-pack/plugins/timelines/common/search_strategy/timeline/events/common/index.ts deleted file mode 100644 index 4a5bd2c99a0eb..0000000000000 --- a/x-pack/plugins/timelines/common/search_strategy/timeline/events/common/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { Ecs } from '../../../../ecs'; -import { CursorType, Maybe } from '../../../common'; - -export interface TimelineEdges { - node: TimelineItem; - cursor: CursorType; -} - -export interface TimelineItem { - _id: string; - _index?: Maybe; - data: TimelineNonEcsData[]; - ecs: Ecs; -} - -export interface TimelineNonEcsData { - field: string; - value?: Maybe; -} diff --git a/x-pack/plugins/timelines/common/utility_types.ts b/x-pack/plugins/timelines/common/utility_types.ts index ccdbc254033fd..13be4c00102b9 100644 --- a/x-pack/plugins/timelines/common/utility_types.ts +++ b/x-pack/plugins/timelines/common/utility_types.ts @@ -6,13 +6,6 @@ */ import * as runtimeTypes from 'io-ts'; -import { ReactNode } from 'react'; - -// This type is for typing EuiDescriptionList -export interface DescriptionList { - title: NonNullable; - description: NonNullable; -} export const unionWithNullType = (type: T) => runtimeTypes.union([type, runtimeTypes.null]); diff --git a/x-pack/plugins/timelines/kibana.json b/x-pack/plugins/timelines/kibana.json index 11adf42b3a6b4..77a5dcc699bdc 100644 --- a/x-pack/plugins/timelines/kibana.json +++ b/x-pack/plugins/timelines/kibana.json @@ -10,6 +10,6 @@ "extraPublicDirs": ["common"], "server": true, "ui": true, - "requiredPlugins": ["alerting", "cases", "data", "dataEnhanced", "kibanaReact", "kibanaUtils"], + "requiredPlugins": ["alerting", "cases", "data", "kibanaReact", "kibanaUtils"], "optionalPlugins": ["security"] } diff --git a/x-pack/plugins/timelines/public/components/actions/action_icon_item.tsx b/x-pack/plugins/timelines/public/components/actions/action_icon_item.tsx deleted file mode 100644 index d979354e5548b..0000000000000 --- a/x-pack/plugins/timelines/public/components/actions/action_icon_item.tsx +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { MouseEvent } from 'react'; -import { EuiButtonIcon, EuiToolTip } from '@elastic/eui'; - -import { EventsTdContent } from '../t_grid/styles'; -import { DEFAULT_ACTION_BUTTON_WIDTH } from '../t_grid/body/constants'; - -interface ActionIconItemProps { - ariaLabel?: string; - width?: number; - dataTestSubj?: string; - content?: string; - iconType?: string; - isDisabled?: boolean; - onClick?: (event: MouseEvent) => void; - children?: React.ReactNode; -} - -const ActionIconItemComponent: React.FC = ({ - width = DEFAULT_ACTION_BUTTON_WIDTH, - dataTestSubj, - content, - ariaLabel, - iconType = '', - isDisabled = false, - onClick, - children, -}) => ( -
- - {children ?? ( - - - - )} - -
-); - -ActionIconItemComponent.displayName = 'ActionIconItemComponent'; - -export const ActionIconItem = React.memo(ActionIconItemComponent); diff --git a/x-pack/plugins/timelines/public/components/draggables/field_badge/index.tsx b/x-pack/plugins/timelines/public/components/draggables/field_badge/index.tsx deleted file mode 100644 index 62f7e091fae9c..0000000000000 --- a/x-pack/plugins/timelines/public/components/draggables/field_badge/index.tsx +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { rgba } from 'polished'; -import React from 'react'; -import styled from 'styled-components'; - -interface WidthProp { - width?: number; -} - -const Field = styled.div.attrs(({ width }) => { - if (width) { - return { - style: { - width: `${width}px`, - }, - }; - } -})` - background-color: ${({ theme }) => theme.eui.euiColorEmptyShade}; - border: ${({ theme }) => theme.eui.euiBorderThin}; - box-shadow: 0 2px 2px -1px ${({ theme }) => rgba(theme.eui.euiColorMediumShade, 0.3)}, - 0 1px 5px -2px ${({ theme }) => rgba(theme.eui.euiColorMediumShade, 0.3)}; - font-size: ${({ theme }) => theme.eui.euiFontSizeXS}; - font-weight: ${({ theme }) => theme.eui.euiFontWeightSemiBold}; - line-height: ${({ theme }) => theme.eui.euiLineHeight}; - padding: ${({ theme }) => theme.eui.paddingSizes.xs}; -`; -Field.displayName = 'Field'; - -/** - * Renders a field (e.g. `event.action`) as a draggable badge - */ - -export const DraggableFieldBadge = React.memo<{ fieldId: string; fieldWidth?: number }>( - ({ fieldId, fieldWidth }) => ( - - {fieldId} - - ) -); - -DraggableFieldBadge.displayName = 'DraggableFieldBadge'; diff --git a/x-pack/plugins/timelines/public/components/draggables/field_badge/translations.ts b/x-pack/plugins/timelines/public/components/draggables/field_badge/translations.ts deleted file mode 100644 index 6c8143c228e14..0000000000000 --- a/x-pack/plugins/timelines/public/components/draggables/field_badge/translations.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const CATEGORY = i18n.translate('xpack.timelines.draggables.field.categoryLabel', { - defaultMessage: 'Category', -}); - -export const COPY_TO_CLIPBOARD = i18n.translate( - 'xpack.timelines.eventDetails.copyToClipboardTooltip', - { - defaultMessage: 'Copy to Clipboard', - } -); - -export const FIELD = i18n.translate('xpack.timelines.draggables.field.fieldLabel', { - defaultMessage: 'Field', -}); - -export const TYPE = i18n.translate('xpack.timelines.draggables.field.typeLabel', { - defaultMessage: 'Type', -}); - -export const VIEW_CATEGORY = i18n.translate( - 'xpack.timelines.draggables.field.viewCategoryTooltip', - { - defaultMessage: 'View Category', - } -); diff --git a/x-pack/plugins/timelines/public/components/draggables/index.tsx b/x-pack/plugins/timelines/public/components/draggables/index.tsx deleted file mode 100644 index a87d97b7ea74a..0000000000000 --- a/x-pack/plugins/timelines/public/components/draggables/index.tsx +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export * from './field_badge'; diff --git a/x-pack/plugins/timelines/public/components/empty_value/__snapshots__/empty_value.test.tsx.snap b/x-pack/plugins/timelines/public/components/empty_value/__snapshots__/empty_value.test.tsx.snap deleted file mode 100644 index 142ed7a0d7175..0000000000000 --- a/x-pack/plugins/timelines/public/components/empty_value/__snapshots__/empty_value.test.tsx.snap +++ /dev/null @@ -1,7 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`EmptyValue it renders against snapshot 1`] = ` -

- (Empty String) -

-`; diff --git a/x-pack/plugins/timelines/public/components/empty_value/empty_value.test.tsx b/x-pack/plugins/timelines/public/components/empty_value/empty_value.test.tsx index 0e5ee638d29e8..78f0ec9f42712 100644 --- a/x-pack/plugins/timelines/public/components/empty_value/empty_value.test.tsx +++ b/x-pack/plugins/timelines/public/components/empty_value/empty_value.test.tsx @@ -5,162 +5,10 @@ * 2.0. */ -import { mount, shallow } from 'enzyme'; -import React from 'react'; -import { ThemeProvider } from 'styled-components'; -import { mountWithIntl } from '@kbn/test-jest-helpers'; - -import { - defaultToEmptyTag, - getEmptyString, - getEmptyStringTag, - getEmptyTagValue, - getEmptyValue, - getOrEmptyTag, -} from '.'; -import { getMockTheme } from '../../mock/kibana_react.mock'; +import { getEmptyValue } from '.'; describe('EmptyValue', () => { - const mockTheme = getMockTheme({ eui: { euiColorMediumShade: '#ece' } }); - - test('it renders against snapshot', () => { - const wrapper = shallow(

{getEmptyString()}

); - expect(wrapper).toMatchSnapshot(); - }); - describe('#getEmptyValue', () => { test('should return an empty value', () => expect(getEmptyValue()).toBe('—')); }); - - describe('#getEmptyString', () => { - test('should turn into an empty string place holder', () => { - const wrapper = mountWithIntl( - -

{getEmptyString()}

-
- ); - expect(wrapper.text()).toBe('(Empty String)'); - }); - }); - - describe('#getEmptyTagValue', () => { - const wrapper = mount( - -

{getEmptyTagValue()}

-
- ); - test('should return an empty tag value', () => expect(wrapper.text()).toBe('—')); - }); - - describe('#getEmptyStringTag', () => { - test('should turn into an span that has length of 1', () => { - const wrapper = mountWithIntl( - -

{getEmptyStringTag()}

-
- ); - expect(wrapper.find('span')).toHaveLength(1); - }); - - test('should turn into an empty string tag place holder', () => { - const wrapper = mountWithIntl( - -

{getEmptyStringTag()}

-
- ); - expect(wrapper.text()).toBe(getEmptyString()); - }); - }); - - describe('#defaultToEmptyTag', () => { - test('should default to an empty value when a value is null', () => { - const wrapper = mount( - -

{defaultToEmptyTag(null)}

-
- ); - expect(wrapper.text()).toBe(getEmptyValue()); - }); - - test('should default to an empty value when a value is undefined', () => { - const wrapper = mount( - -

{defaultToEmptyTag(undefined)}

-
- ); - expect(wrapper.text()).toBe(getEmptyValue()); - }); - - test('should return a deep path value', () => { - const test = { - a: { - b: { - c: 1, - }, - }, - }; - const wrapper = mount(

{defaultToEmptyTag(test.a.b.c)}

); - expect(wrapper.text()).toBe('1'); - }); - }); - - describe('#getOrEmptyTag', () => { - test('should default empty value when a deep rooted value is null', () => { - const test = { - a: { - b: { - c: null, - }, - }, - }; - const wrapper = mount( - -

{getOrEmptyTag('a.b.c', test)}

-
- ); - expect(wrapper.text()).toBe(getEmptyValue()); - }); - - test('should default empty value when a deep rooted value is undefined', () => { - const test = { - a: { - b: { - c: undefined, - }, - }, - }; - const wrapper = mount( - -

{getOrEmptyTag('a.b.c', test)}

-
- ); - expect(wrapper.text()).toBe(getEmptyValue()); - }); - - test('should default empty value when a deep rooted value is missing', () => { - const test = { - a: { - b: {}, - }, - }; - const wrapper = mount( - -

{getOrEmptyTag('a.b.c', test)}

-
- ); - expect(wrapper.text()).toBe(getEmptyValue()); - }); - - test('should return a deep path value', () => { - const test = { - a: { - b: { - c: 1, - }, - }, - }; - const wrapper = mount(

{getOrEmptyTag('a.b.c', test)}

); - expect(wrapper.text()).toBe('1'); - }); - }); }); diff --git a/x-pack/plugins/timelines/public/components/empty_value/index.tsx b/x-pack/plugins/timelines/public/components/empty_value/index.tsx index 86efb4a78277a..9de9e22eb5b89 100644 --- a/x-pack/plugins/timelines/public/components/empty_value/index.tsx +++ b/x-pack/plugins/timelines/public/components/empty_value/index.tsx @@ -5,45 +5,4 @@ * 2.0. */ -import { get, isString } from 'lodash/fp'; -import React from 'react'; -import styled from 'styled-components'; - -import * as i18n from './translations'; - -const EmptyWrapper = styled.span` - color: ${(props) => props.theme.eui.euiColorMediumShade}; -`; - -EmptyWrapper.displayName = 'EmptyWrapper'; - export const getEmptyValue = () => '—'; -export const getEmptyString = () => `(${i18n.EMPTY_STRING})`; - -export const getEmptyTagValue = () => {getEmptyValue()}; -export const getEmptyStringTag = () => {getEmptyString()}; - -export const defaultToEmptyTag = (item: T): JSX.Element => { - if (item == null) { - return getEmptyTagValue(); - } else if (isString(item) && item === '') { - return getEmptyStringTag(); - } else { - return <>{item}; - } -}; - -export const getOrEmptyTag = (path: string, item: unknown): JSX.Element => { - const text = get(path, item); - return getOrEmptyTagFromValue(text); -}; - -export const getOrEmptyTagFromValue = (value: string | number | null | undefined): JSX.Element => { - if (value == null) { - return getEmptyTagValue(); - } else if (value === '') { - return getEmptyStringTag(); - } else { - return <>{value}; - } -}; diff --git a/x-pack/plugins/timelines/public/components/empty_value/translations.ts b/x-pack/plugins/timelines/public/components/empty_value/translations.ts deleted file mode 100644 index 20c822c67dfb3..0000000000000 --- a/x-pack/plugins/timelines/public/components/empty_value/translations.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const EMPTY_STRING = i18n.translate('xpack.timelines.emptyString.emptyStringDescription', { - defaultMessage: 'Empty String', -}); diff --git a/x-pack/plugins/timelines/public/components/exit_full_screen/index.test.tsx b/x-pack/plugins/timelines/public/components/exit_full_screen/index.test.tsx deleted file mode 100644 index b60bdafd0835f..0000000000000 --- a/x-pack/plugins/timelines/public/components/exit_full_screen/index.test.tsx +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { mount } from 'enzyme'; -import React from 'react'; - -import { TestProviders } from '../../mock/test_providers'; -import * as i18n from './translations'; -import { ExitFullScreen, EXIT_FULL_SCREEN_CLASS_NAME } from '.'; - -describe('ExitFullScreen', () => { - test('it returns null when fullScreen is false', () => { - const exitFullScreen = mount( - - - - ); - - expect(exitFullScreen.find('[data-test-subj="exit-full-screen"]').exists()).toBe(false); - }); - - test('it renders a button with the exported EXIT_FULL_SCREEN_CLASS_NAME class when fullScreen is true', () => { - const exitFullScreen = mount( - - - - ); - - expect(exitFullScreen.find(`button.${EXIT_FULL_SCREEN_CLASS_NAME}`).exists()).toBe(true); - }); - - test('it renders the expected button text when fullScreen is true', () => { - const exitFullScreen = mount( - - - - ); - - expect(exitFullScreen.find('[data-test-subj="exit-full-screen"]').first().text()).toBe( - i18n.EXIT_FULL_SCREEN - ); - }); - - test('it invokes setFullScreen with a value of false when the button is clicked', () => { - const setFullScreen = jest.fn(); - - const exitFullScreen = mount( - - - - ); - - exitFullScreen.find('[data-test-subj="exit-full-screen"]').first().simulate('click'); - expect(setFullScreen).toBeCalledWith(false); - }); -}); diff --git a/x-pack/plugins/timelines/public/components/exit_full_screen/index.tsx b/x-pack/plugins/timelines/public/components/exit_full_screen/index.tsx deleted file mode 100644 index 5ae537128bee6..0000000000000 --- a/x-pack/plugins/timelines/public/components/exit_full_screen/index.tsx +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiButton, EuiWindowEvent } from '@elastic/eui'; -import React, { useCallback } from 'react'; -import styled from 'styled-components'; - -import * as i18n from './translations'; - -export const EXIT_FULL_SCREEN_CLASS_NAME = 'exit-full-screen'; - -const StyledEuiButton = styled(EuiButton)` - margin: ${({ theme }) => theme.eui.paddingSizes.s}; -`; - -interface Props { - fullScreen: boolean; - setFullScreen: (fullScreen: boolean) => void; -} - -const ExitFullScreenComponent: React.FC = ({ fullScreen, setFullScreen }) => { - const exitFullScreen = useCallback(() => { - setFullScreen(false); - }, [setFullScreen]); - - const onKeyDown = useCallback( - (event: KeyboardEvent) => { - if (event.key === 'Escape') { - event.preventDefault(); - - exitFullScreen(); - } - }, - [exitFullScreen] - ); - - if (!fullScreen) { - return null; - } - - return ( - <> - - - {i18n.EXIT_FULL_SCREEN} - - - ); -}; - -ExitFullScreenComponent.displayName = 'ExitFullScreenComponent'; - -export const ExitFullScreen = React.memo(ExitFullScreenComponent); diff --git a/x-pack/plugins/timelines/public/components/exit_full_screen/translations.ts b/x-pack/plugins/timelines/public/components/exit_full_screen/translations.ts deleted file mode 100644 index 22aecebf12a07..0000000000000 --- a/x-pack/plugins/timelines/public/components/exit_full_screen/translations.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const EXIT_FULL_SCREEN = i18n.translate('xpack.timelines.exitFullScreenButton', { - defaultMessage: 'Exit full screen', -}); diff --git a/x-pack/plugins/timelines/public/components/index.tsx b/x-pack/plugins/timelines/public/components/index.tsx index ea1e6fdcf3b6d..c2ba5202aa76b 100644 --- a/x-pack/plugins/timelines/public/components/index.tsx +++ b/x-pack/plugins/timelines/public/components/index.tsx @@ -56,7 +56,6 @@ export const TGrid = (props: TGridComponent) => { export { TGrid as default }; export * from './drag_and_drop'; -export * from './draggables'; export * from './last_updated'; export * from './loading'; export * from './fields_browser'; diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/__snapshots__/index.test.tsx.snap b/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/__snapshots__/index.test.tsx.snap deleted file mode 100644 index 233e1c921cd50..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/__snapshots__/index.test.tsx.snap +++ /dev/null @@ -1,658 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`ColumnHeaders rendering renders correctly against snapshot 1`] = ` - -`; diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/actions/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/actions/index.tsx deleted file mode 100644 index 322059576d2b7..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/actions/index.tsx +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiButtonIcon } from '@elastic/eui'; -import React, { useCallback } from 'react'; -import type { ColumnHeaderOptions } from '../../../../../../common/types/timeline'; -import { EventsHeadingExtra, EventsLoading } from '../../../styles'; -import type { OnColumnRemoved } from '../../../types'; -import type { Sort } from '../../sort'; - -import * as i18n from '../translations'; - -interface Props { - header: ColumnHeaderOptions; - isLoading: boolean; - onColumnRemoved: OnColumnRemoved; - sort: Sort[]; -} - -/** Given a `header`, returns the `SortDirection` applicable to it */ - -export const CloseButton = React.memo<{ - columnId: string; - onColumnRemoved: OnColumnRemoved; -}>(({ columnId, onColumnRemoved }) => { - const handleClick = useCallback( - (event: React.MouseEvent) => { - // To avoid a re-sorting when you delete a column - event.preventDefault(); - event.stopPropagation(); - onColumnRemoved(columnId); - }, - [columnId, onColumnRemoved] - ); - - return ( - - ); -}); - -CloseButton.displayName = 'CloseButton'; - -export const Actions = React.memo(({ header, onColumnRemoved, sort, isLoading }) => { - return ( - <> - {sort.some((i) => i.columnId === header.id) && isLoading ? ( - - - - ) : ( - - - - )} - - ); -}); - -Actions.displayName = 'Actions'; diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/column_header.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/column_header.tsx deleted file mode 100644 index 4e6db10cc8bce..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/column_header.tsx +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiContextMenu, EuiContextMenuPanelDescriptor, EuiIcon, EuiPopover } from '@elastic/eui'; -import { - DRAGGABLE_KEYBOARD_WRAPPER_CLASS_NAME, - getDraggableFieldId, -} from '@kbn/securitysolution-t-grid'; -import React, { useCallback, useMemo, useRef, useState } from 'react'; -import { Draggable } from 'react-beautiful-dnd'; -import { Resizable, ResizeCallback } from 're-resizable'; -import deepEqual from 'fast-deep-equal'; -import { useDispatch } from 'react-redux'; -import styled from 'styled-components'; - -import { DEFAULT_COLUMN_MIN_WIDTH } from '../constants'; - -import { ARIA_COLUMN_INDEX_OFFSET } from '../../helpers'; -import { EventsTh, EventsThContent, EventsHeadingHandle } from '../../styles'; -import { Sort } from '../sort'; - -import { Header } from './header'; - -import * as i18n from './translations'; -import { tGridActions } from '../../../../store/t_grid'; -import { TimelineTabs } from '../../../../../common/types/timeline'; -import type { ColumnHeaderOptions } from '../../../../../common/types/timeline'; - -import { Direction } from '../../../../../common/search_strategy'; -import { useDraggableKeyboardWrapper } from '../../../drag_and_drop'; - -const ContextMenu = styled(EuiContextMenu)` - width: 115px; - - & .euiContextMenuItem { - font-size: 12px; - padding: 4px 8px; - width: 115px; - } -`; - -const PopoverContainer = styled.div<{ $width: number }>` - & .euiPopover__anchor { - padding-right: 8px; - width: ${({ $width }) => $width}px; - } -`; - -const RESIZABLE_ENABLE = { right: true }; - -interface ColumneHeaderProps { - draggableIndex: number; - header: ColumnHeaderOptions; - isDragging: boolean; - sort: Sort[]; - tabType: TimelineTabs; - timelineId: string; -} - -const ColumnHeaderComponent: React.FC = ({ - draggableIndex, - header, - timelineId, - isDragging, - sort, - tabType, -}) => { - const keyboardHandlerRef = useRef(null); - const [hoverActionsOwnFocus, setHoverActionsOwnFocus] = useState(false); - const restoreFocus = useCallback(() => keyboardHandlerRef.current?.focus(), []); - - const dispatch = useDispatch(); - const resizableSize = useMemo( - () => ({ - width: header.initialWidth ?? DEFAULT_COLUMN_MIN_WIDTH, - height: 'auto', - }), - [header.initialWidth] - ); - const resizableStyle: { - position: 'absolute' | 'relative'; - } = useMemo( - () => ({ - position: isDragging ? 'absolute' : 'relative', - }), - [isDragging] - ); - const resizableHandleComponent = useMemo( - () => ({ - right: , - }), - [] - ); - const handleResizeStop: ResizeCallback = useCallback( - (e, direction, ref, delta) => { - dispatch( - tGridActions.applyDeltaToColumnWidth({ - columnId: header.id, - delta: delta.width, - id: timelineId, - }) - ); - }, - [dispatch, header.id, timelineId] - ); - const draggableId = useMemo( - () => - getDraggableFieldId({ - contextId: `timeline-column-headers-${tabType}-${timelineId}`, - fieldId: header.id, - }), - [tabType, timelineId, header.id] - ); - - const onColumnSort = useCallback( - (sortDirection: Direction) => { - const columnId = header.id; - const headerIndex = sort.findIndex((col) => col.columnId === columnId); - const newSort = - headerIndex === -1 - ? [ - ...sort, - { - columnId, - columnType: `${header.type}`, - sortDirection, - }, - ] - : [ - ...sort.slice(0, headerIndex), - { - columnId, - columnType: `${header.type}`, - sortDirection, - }, - ...sort.slice(headerIndex + 1), - ]; - - dispatch( - tGridActions.updateSort({ - id: timelineId, - sort: newSort, - }) - ); - }, - [dispatch, header, sort, timelineId] - ); - - const handleClosePopOverTrigger = useCallback(() => { - setHoverActionsOwnFocus(false); - restoreFocus(); - }, [restoreFocus]); - - const panels: EuiContextMenuPanelDescriptor[] = useMemo( - () => [ - { - id: 0, - items: [ - { - icon: , - name: i18n.REMOVE_COLUMN, - onClick: () => { - dispatch(tGridActions.removeColumn({ id: timelineId, columnId: header.id })); - handleClosePopOverTrigger(); - }, - }, - ...(tabType !== TimelineTabs.eql - ? [ - { - disabled: !header.aggregatable, - icon: , - name: i18n.SORT_AZ, - onClick: () => { - onColumnSort(Direction.asc); - handleClosePopOverTrigger(); - }, - }, - { - disabled: !header.aggregatable, - icon: , - name: i18n.SORT_ZA, - onClick: () => { - onColumnSort(Direction.desc); - handleClosePopOverTrigger(); - }, - }, - ] - : []), - ], - }, - ], - [ - dispatch, - handleClosePopOverTrigger, - header.aggregatable, - header.id, - onColumnSort, - tabType, - timelineId, - ] - ); - - const headerButton = useMemo( - () =>
, - [header, sort, timelineId] - ); - - const DraggableContent = useCallback( - (dragProvided) => ( - - - - - - - - - - ), - [handleClosePopOverTrigger, headerButton, header.initialWidth, hoverActionsOwnFocus, panels] - ); - - const onFocus = useCallback(() => { - keyboardHandlerRef.current?.focus(); - }, []); - - const openPopover = useCallback(() => { - setHoverActionsOwnFocus(true); - }, []); - - const { onBlur, onKeyDown } = useDraggableKeyboardWrapper({ - closePopover: handleClosePopOverTrigger, - draggableId, - fieldName: header.id, - keyboardHandlerRef, - openPopover, - }); - - const keyDownHandler = useCallback( - (keyboardEvent: React.KeyboardEvent) => { - if (!hoverActionsOwnFocus) { - onKeyDown(keyboardEvent); - } - }, - [hoverActionsOwnFocus, onKeyDown] - ); - - return ( - -
- - {DraggableContent} - -
-
- ); -}; - -export const ColumnHeader = React.memo( - ColumnHeaderComponent, - (prevProps, nextProps) => - prevProps.draggableIndex === nextProps.draggableIndex && - prevProps.tabType === nextProps.tabType && - prevProps.timelineId === nextProps.timelineId && - prevProps.isDragging === nextProps.isDragging && - deepEqual(prevProps.sort, nextProps.sort) && - deepEqual(prevProps.header, nextProps.header) -); diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/common/dragging_container.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/common/dragging_container.tsx deleted file mode 100644 index 0d7ed0a91121e..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/common/dragging_container.tsx +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { FC, memo, useEffect } from 'react'; - -interface DraggingContainerProps { - children: JSX.Element; - onDragging: Function; -} - -const DraggingContainerComponent: FC = ({ children, onDragging }) => { - useEffect(() => { - onDragging(true); - - return () => onDragging(false); - }); - - return children; -}; - -export const DraggingContainer = memo(DraggingContainerComponent); diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/common/styles.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/common/styles.tsx deleted file mode 100644 index 254c7076fcf5a..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/common/styles.tsx +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import styled from 'styled-components'; - -export const FullHeightFlexGroup = styled(EuiFlexGroup)` - height: 100%; -`; -FullHeightFlexGroup.displayName = 'FullHeightFlexGroup'; - -export const FullHeightFlexItem = styled(EuiFlexItem)` - height: 100%; -`; -FullHeightFlexItem.displayName = 'FullHeightFlexItem'; diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header/__snapshots__/index.test.tsx.snap b/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header/__snapshots__/index.test.tsx.snap deleted file mode 100644 index ff2bdf2f643a0..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header/__snapshots__/index.test.tsx.snap +++ /dev/null @@ -1,51 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Header renders correctly against snapshot 1`] = ` - - - - - -`; diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header/header_content.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header/header_content.tsx deleted file mode 100644 index 04004b3e90314..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header/header_content.tsx +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiToolTip } from '@elastic/eui'; -import { noop } from 'lodash/fp'; -import React from 'react'; - -import type { ColumnHeaderOptions } from '../../../../../../common/types/timeline'; -import { TruncatableText } from '../../../../truncatable_text'; - -import { EventsHeading, EventsHeadingTitleButton, EventsHeadingTitleSpan } from '../../../styles'; -import { Sort } from '../../sort'; -import { SortIndicator } from '../../sort/sort_indicator'; -import { HeaderToolTipContent } from '../header_tooltip_content'; -import { getSortDirection, getSortIndex } from './helpers'; -interface HeaderContentProps { - children: React.ReactNode; - header: ColumnHeaderOptions; - isLoading: boolean; - isResizing: boolean; - onClick: () => void; - showSortingCapability: boolean; - sort: Sort[]; -} - -const HeaderContentComponent: React.FC = ({ - children, - header, - isLoading, - isResizing, - onClick, - showSortingCapability, - sort, -}) => ( - - {header.aggregatable && showSortingCapability ? ( - - - } - > - <> - {React.isValidElement(header.display) - ? header.display - : header.displayAsText ?? header.id} - - - - - - - ) : ( - - - } - > - <> - {React.isValidElement(header.display) - ? header.display - : header.displayAsText ?? header.id} - - - - - )} - - {children} - -); - -export const HeaderContent = React.memo(HeaderContentComponent); diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header/helpers.ts b/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header/helpers.ts deleted file mode 100644 index 7a3cad47bdcba..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header/helpers.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { Direction } from '../../../../../../common/search_strategy'; -import type { ColumnHeaderOptions } from '../../../../../../common/types'; -import { assertUnreachable } from '../../../../../../common/utility_types'; -import { Sort, SortDirection } from '../../sort'; - -interface GetNewSortDirectionOnClickParams { - clickedHeader: ColumnHeaderOptions; - currentSort: Sort[]; -} - -/** Given a `header`, returns the `SortDirection` applicable to it */ -export const getNewSortDirectionOnClick = ({ - clickedHeader, - currentSort, -}: GetNewSortDirectionOnClickParams): Direction => - currentSort.reduce( - (acc, item) => (clickedHeader.id === item.columnId ? getNextSortDirection(item) : acc), - Direction.desc - ); - -/** Given a current sort direction, it returns the next sort direction */ -export const getNextSortDirection = (currentSort: Sort): Direction => { - switch (currentSort.sortDirection) { - case Direction.desc: - return Direction.asc; - case Direction.asc: - return Direction.desc; - case 'none': - return Direction.desc; - default: - return assertUnreachable(currentSort.sortDirection as never, 'Unhandled sort direction'); - } -}; - -interface GetSortDirectionParams { - header: ColumnHeaderOptions; - sort: Sort[]; -} - -export const getSortDirection = ({ header, sort }: GetSortDirectionParams): SortDirection => - sort.reduce( - (acc, item) => (header.id === item.columnId ? item.sortDirection : acc), - 'none' - ); - -export const getSortIndex = ({ header, sort }: GetSortDirectionParams): number => - sort.findIndex((s) => s.columnId === header.id); diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header/index.test.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header/index.test.tsx deleted file mode 100644 index 4685af483c21e..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header/index.test.tsx +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { mount, shallow } from 'enzyme'; -import React from 'react'; - -import { Sort } from '../../sort'; -import { CloseButton } from '../actions'; -import { defaultHeaders } from '../default_headers'; - -import { HeaderComponent } from '.'; -import { getNewSortDirectionOnClick, getNextSortDirection, getSortDirection } from './helpers'; -import { Direction } from '../../../../../../common/search_strategy'; -import { TestProviders } from '../../../../../mock'; -import { tGridActions } from '../../../../../store/t_grid'; -import { mockGlobalState } from '../../../../../mock/global_state'; - -const mockDispatch = jest.fn(); -jest.mock('../../../../../hooks/use_selector', () => ({ - useShallowEqualSelector: () => mockGlobalState.timelineById.test, - useDeepEqualSelector: () => mockGlobalState.timelineById.test, -})); - -jest.mock('react-redux', () => { - const original = jest.requireActual('react-redux'); - - return { - ...original, - useSelector: jest.fn(), - useDispatch: () => mockDispatch, - }; -}); - -describe('Header', () => { - const columnHeader = defaultHeaders[0]; - const sort: Sort[] = [ - { - columnId: columnHeader.id, - columnType: columnHeader.type ?? 'number', - sortDirection: Direction.desc, - }, - ]; - const timelineId = 'test'; - - test('renders correctly against snapshot', () => { - const wrapper = shallow( - - - - ); - expect(wrapper.find('HeaderComponent').dive()).toMatchSnapshot(); - }); - - describe('rendering', () => { - test('it renders the header text', () => { - const wrapper = mount( - - - - ); - - expect( - wrapper.find(`[data-test-subj="header-text-${columnHeader.id}"]`).first().text() - ).toEqual(columnHeader.id); - }); - - test('it renders the header text alias when displayAsText is provided', () => { - const displayAsText = 'Timestamp'; - const headerWithLabel = { ...columnHeader, displayAsText }; - const wrapper = mount( - - - - ); - - expect( - wrapper.find(`[data-test-subj="header-text-${columnHeader.id}"]`).first().text() - ).toEqual(displayAsText); - }); - - test('it renders the header as a `ReactNode` when `display` is provided', () => { - const display: React.ReactNode = ( -
- {'The display property renders the column heading as a ReactNode'} -
- ); - const headerWithLabel = { ...columnHeader, display }; - const wrapper = mount( - - - - ); - - expect(wrapper.find(`[data-test-subj="rendered-via-display"]`).exists()).toBe(true); - }); - - test('it prefers to render `display` instead of `displayAsText` when both are provided', () => { - const displayAsText = 'this text should NOT be rendered'; - const display: React.ReactNode = ( -
{'this text is rendered via display'}
- ); - const headerWithLabel = { ...columnHeader, display, displayAsText }; - const wrapper = mount( - - - - ); - - expect(wrapper.text()).toBe('this text is rendered via display'); - }); - - test('it falls back to rendering header.id when `display` is not a valid React node', () => { - const display = {}; // a plain object is NOT a `ReactNode` - const headerWithLabel = { ...columnHeader, display }; - const wrapper = mount( - - - - ); - - expect( - wrapper.find(`[data-test-subj="header-text-${columnHeader.id}"]`).first().text() - ).toEqual(columnHeader.id); - }); - - test('it renders a sort indicator', () => { - const headerSortable = { ...columnHeader, aggregatable: true }; - const wrapper = mount( - - - - ); - - expect(wrapper.find('[data-test-subj="header-sort-indicator"]').first().exists()).toEqual( - true - ); - }); - }); - - describe('onColumnSorted', () => { - test('it invokes the onColumnSorted callback when the header sort button is clicked', () => { - const headerSortable = { ...columnHeader, aggregatable: true }; - const wrapper = mount( - - - - ); - - wrapper.find('[data-test-subj="header-sort-button"]').first().simulate('click'); - - expect(mockDispatch).toBeCalledWith( - tGridActions.updateSort({ - id: timelineId, - sort: [ - { - columnId: columnHeader.id, - columnType: columnHeader.type ?? 'number', - sortDirection: Direction.asc, // (because the previous state was Direction.desc) - }, - ], - }) - ); - }); - - test('it does NOT render the header sort button when aggregatable is false', () => { - const headerSortable = { ...columnHeader, aggregatable: false }; - const wrapper = mount( - - - - ); - - expect(wrapper.find('[data-test-subj="header-sort-button"]').length).toEqual(0); - }); - - test('it does NOT render the header sort button when aggregatable is missing', () => { - const headerSortable = { ...columnHeader }; - const wrapper = mount( - - - - ); - - expect(wrapper.find('[data-test-subj="header-sort-button"]').length).toEqual(0); - }); - - test('it does NOT invoke the onColumnSorted callback when the header is clicked and aggregatable is undefined', () => { - const mockOnColumnSorted = jest.fn(); - const headerSortable = { ...columnHeader, aggregatable: undefined }; - const wrapper = mount( - - - - ); - - wrapper.find(`[data-test-subj="header-${columnHeader.id}"]`).first().simulate('click'); - - expect(mockOnColumnSorted).not.toHaveBeenCalled(); - }); - }); - - describe('CloseButton', () => { - test('it invokes the onColumnRemoved callback with the column ID when the close button is clicked', () => { - const mockOnColumnRemoved = jest.fn(); - - const wrapper = mount( - - ); - - wrapper.find('[data-test-subj="remove-column"]').first().simulate('click'); - - expect(mockOnColumnRemoved).toBeCalledWith(columnHeader.id); - }); - }); - - describe('getSortDirection', () => { - test('it returns the sort direction when the header id matches the sort column id', () => { - expect(getSortDirection({ header: columnHeader, sort })).toEqual(sort[0].sortDirection); - }); - - test('it returns "none" when sort direction when the header id does NOT match the sort column id', () => { - const nonMatching: Sort[] = [ - { - columnId: 'differentSocks', - columnType: columnHeader.type ?? 'number', - sortDirection: Direction.desc, - }, - ]; - - expect(getSortDirection({ header: columnHeader, sort: nonMatching })).toEqual('none'); - }); - }); - - describe('getNextSortDirection', () => { - test('it returns "asc" when the current direction is "desc"', () => { - const sortDescending: Sort = { - columnId: columnHeader.id, - columnType: columnHeader.type ?? 'number', - sortDirection: Direction.desc, - }; - - expect(getNextSortDirection(sortDescending)).toEqual('asc'); - }); - - test('it returns "desc" when the current direction is "asc"', () => { - const sortAscending: Sort = { - columnId: columnHeader.id, - columnType: columnHeader.type ?? 'number', - sortDirection: Direction.asc, - }; - - expect(getNextSortDirection(sortAscending)).toEqual(Direction.desc); - }); - - test('it returns "desc" by default', () => { - const sortNone: Sort = { - columnId: columnHeader.id, - columnType: columnHeader.type ?? 'number', - sortDirection: 'none', - }; - - expect(getNextSortDirection(sortNone)).toEqual(Direction.desc); - }); - }); - - describe('getNewSortDirectionOnClick', () => { - test('it returns the expected new sort direction when the header id matches the sort column id', () => { - const sortMatches: Sort[] = [ - { - columnId: columnHeader.id, - columnType: columnHeader.type ?? 'number', - sortDirection: Direction.desc, - }, - ]; - - expect( - getNewSortDirectionOnClick({ - clickedHeader: columnHeader, - currentSort: sortMatches, - }) - ).toEqual(Direction.asc); - }); - - test('it returns the expected new sort direction when the header id does NOT match the sort column id', () => { - const sortDoesNotMatch: Sort[] = [ - { - columnId: 'someOtherColumn', - columnType: columnHeader.type ?? 'number', - sortDirection: 'none', - }, - ]; - - expect( - getNewSortDirectionOnClick({ - clickedHeader: columnHeader, - currentSort: sortDoesNotMatch, - }) - ).toEqual(Direction.desc); - }); - }); - - describe('text truncation styling', () => { - test('truncates the header text with an ellipsis', () => { - const wrapper = mount( - - - - ); - - expect( - wrapper.find(`[data-test-subj="header-text-${columnHeader.id}"]`).at(1) - ).toHaveStyleRule('text-overflow', 'ellipsis'); - }); - }); - - describe('header tooltip', () => { - test('it has a tooltip to display the properties of the field', () => { - const wrapper = mount( - - - - ); - - expect(wrapper.find('[data-test-subj="header-tooltip"]').exists()).toEqual(true); - }); - }); -}); diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header/index.tsx deleted file mode 100644 index 1ddade2b58968..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header/index.tsx +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useCallback, useMemo } from 'react'; -import { useDispatch } from 'react-redux'; -import { isDataViewFieldSubtypeNested } from '@kbn/es-query'; - -import type { ColumnHeaderOptions } from '../../../../../../common/types/timeline'; -import type { Sort } from '../../sort'; -import { Actions } from '../actions'; -import { getNewSortDirectionOnClick } from './helpers'; -import { HeaderContent } from './header_content'; -import { tGridActions, tGridSelectors } from '../../../../../store/t_grid'; -import { useDeepEqualSelector } from '../../../../../hooks/use_selector'; -interface Props { - header: ColumnHeaderOptions; - sort: Sort[]; - timelineId: string; -} - -export const HeaderComponent: React.FC = ({ header, sort, timelineId }) => { - const dispatch = useDispatch(); - - const onColumnSort = useCallback(() => { - const columnId = header.id; - const columnType = header.type ?? 'text'; - const sortDirection = getNewSortDirectionOnClick({ - clickedHeader: header, - currentSort: sort, - }); - const headerIndex = sort.findIndex((col) => col.columnId === columnId); - let newSort = []; - if (headerIndex === -1) { - newSort = [ - ...sort, - { - columnId, - columnType, - sortDirection, - }, - ]; - } else { - newSort = [ - ...sort.slice(0, headerIndex), - { - columnId, - columnType, - sortDirection, - }, - ...sort.slice(headerIndex + 1), - ]; - } - dispatch( - tGridActions.updateSort({ - id: timelineId, - sort: newSort, - }) - ); - }, [dispatch, header, sort, timelineId]); - - const onColumnRemoved = useCallback( - (columnId) => dispatch(tGridActions.removeColumn({ id: timelineId, columnId })), - [dispatch, timelineId] - ); - - const getManageTimeline = useMemo(() => tGridSelectors.getManageTimelineById(), []); - const { isLoading } = useDeepEqualSelector((state) => getManageTimeline(state, timelineId ?? '')); - const showSortingCapability = !isDataViewFieldSubtypeNested(header); - - return ( - <> - - - - - ); -}; - -export const Header = React.memo(HeaderComponent); diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header_tooltip_content/__snapshots__/index.test.tsx.snap b/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header_tooltip_content/__snapshots__/index.test.tsx.snap deleted file mode 100644 index 945a9a7aee698..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header_tooltip_content/__snapshots__/index.test.tsx.snap +++ /dev/null @@ -1,66 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`HeaderToolTipContent it renders the expected table content 1`] = ` - -

- - Category - : - - - base - -

-

- - Field - : - - - @timestamp - -

-

- - Type - : - - - - - date - - -

-

- - Description - : - - - Date/time when the event originated. -For log events this is the date/time when the event was generated, and not when it was read. -Required field for all events. - -

-
-`; diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header_tooltip_content/index.test.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header_tooltip_content/index.test.tsx deleted file mode 100644 index a38261994267c..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header_tooltip_content/index.test.tsx +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { mount, shallow } from 'enzyme'; -import { cloneDeep } from 'lodash/fp'; -import React from 'react'; - -import { ColumnHeaderOptions } from '../../../../../../common/types/timeline'; -import { HeaderToolTipContent } from '.'; -import { defaultHeaders } from '../../../../../mock/header'; - -describe('HeaderToolTipContent', () => { - let header: ColumnHeaderOptions; - beforeEach(() => { - header = cloneDeep(defaultHeaders[0]); - }); - - test('it renders the category', () => { - const wrapper = mount(); - - expect(wrapper.find('[data-test-subj="category-value"]').first().text()).toEqual( - header.category - ); - }); - - test('it renders the name of the field', () => { - const wrapper = mount(); - - expect(wrapper.find('[data-test-subj="field-value"]').first().text()).toEqual(header.id); - }); - - test('it renders the expected icon for the header type', () => { - const wrapper = mount(); - - expect(wrapper.find('[data-test-subj="type-icon"]').first().props().type).toEqual('clock'); - }); - - test('it renders the type of the field', () => { - const wrapper = mount(); - - expect(wrapper.find('[data-test-subj="type-value"]').first().text()).toEqual(header.type); - }); - - test('it renders the description of the field', () => { - const wrapper = mount(); - - expect(wrapper.find('[data-test-subj="description-value"]').first().text()).toEqual( - header.description - ); - }); - - test('it does NOT render the description column when the field does NOT contain a description', () => { - const noDescription = { - ...header, - description: '', - }; - - const wrapper = mount(); - - expect(wrapper.find('[data-test-subj="description"]').exists()).toEqual(false); - }); - - test('it renders the expected table content', () => { - const wrapper = shallow(); - - expect(wrapper).toMatchSnapshot(); - }); -}); diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header_tooltip_content/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header_tooltip_content/index.tsx deleted file mode 100644 index 91dd64d8fed3a..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header_tooltip_content/index.tsx +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiIcon } from '@elastic/eui'; -import { isEmpty } from 'lodash/fp'; -import React from 'react'; -import styled from 'styled-components'; - -import type { ColumnHeaderOptions } from '../../../../../../common/types/timeline'; -import { getIconFromType } from '../../../../utils/helpers'; -import * as i18n from '../translations'; - -const IconType = styled(EuiIcon)` - margin-right: 3px; - position: relative; - top: -2px; -`; -IconType.displayName = 'IconType'; - -const P = styled.span` - margin-bottom: 5px; -`; -P.displayName = 'P'; - -const ToolTipTableMetadata = styled.span` - margin-right: 5px; - display: block; -`; -ToolTipTableMetadata.displayName = 'ToolTipTableMetadata'; - -const ToolTipTableValue = styled.span` - word-wrap: break-word; -`; -ToolTipTableValue.displayName = 'ToolTipTableValue'; - -export const HeaderToolTipContent = React.memo<{ header: ColumnHeaderOptions }>(({ header }) => ( - <> - {!isEmpty(header.category) && ( -

- - {i18n.CATEGORY} - {':'} - - {header.category} -

- )} -

- - {i18n.FIELD} - {':'} - - {header.id} -

-

- - {i18n.TYPE} - {':'} - - - - {header.type} - -

- {!isEmpty(header.description) && ( -

- - {i18n.DESCRIPTION} - {':'} - - - {header.description} - -

- )} - -)); -HeaderToolTipContent.displayName = 'HeaderToolTipContent'; diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/index.test.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/index.test.tsx deleted file mode 100644 index 084cd31d76e61..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/index.test.tsx +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { shallow } from 'enzyme'; -import React from 'react'; - -import { getActionsColumnWidth } from './helpers'; - -import { defaultHeaders } from './default_headers'; -import { Sort } from '../sort'; - -import { ColumnHeadersComponent } from '.'; -import { cloneDeep } from 'lodash/fp'; -import { useMountAppended } from '../../../utils/use_mount_appended'; -import { mockBrowserFields } from '../../../../mock/browser_fields'; -import { Direction } from '../../../../../common/search_strategy'; -import { TimelineTabs } from '../../../../../common/types/timeline'; -import { tGridActions } from '../../../../store/t_grid'; -import { testTrailingControlColumns } from '../../../../mock/mock_timeline_control_columns'; -import { TestProviders } from '../../../../mock'; -import { mockGlobalState } from '../../../../mock/global_state'; - -const mockDispatch = jest.fn(); -jest.mock('../../../../hooks/use_selector', () => ({ - useShallowEqualSelector: () => mockGlobalState.timelineById.test, - useDeepEqualSelector: () => mockGlobalState.timelineById.test, -})); - -window.matchMedia = jest.fn().mockImplementation((query) => { - return { - matches: false, - media: query, - onchange: null, - addListener: jest.fn(), - removeListener: jest.fn(), - }; -}); - -jest.mock('react-redux', () => { - const original = jest.requireActual('react-redux'); - - return { - ...original, - useDispatch: () => mockDispatch, - }; -}); -const timelineId = 'test'; - -describe('ColumnHeaders', () => { - const mount = useMountAppended(); - const ACTION_BUTTON_COUNT = 4; - const actionsColumnWidth = getActionsColumnWidth(ACTION_BUTTON_COUNT); - - describe('rendering', () => { - const sort: Sort[] = [ - { - columnId: '@timestamp', - columnType: 'number', - sortDirection: Direction.desc, - }, - ]; - - test('renders correctly against snapshot', () => { - const wrapper = shallow( - - - - ); - expect(wrapper.find('ColumnHeadersComponent')).toMatchSnapshot(); - }); - - // TODO BrowserField When we bring back browser fields unskip - test.skip('it renders the field browser', () => { - const wrapper = mount( - - - - ); - - expect(wrapper.find('[data-test-subj="field-browser"]').first().exists()).toEqual(true); - }); - - test('it renders every column header', () => { - const wrapper = mount( - - - - ); - - defaultHeaders.forEach((h) => { - expect(wrapper.find('[data-test-subj="headers-group"]').first().text()).toContain(h.id); - }); - }); - }); - - describe('#onColumnsSorted', () => { - let mockSort: Sort[] = [ - { - columnId: '@timestamp', - columnType: 'number', - sortDirection: Direction.desc, - }, - { - columnId: 'host.name', - columnType: 'text', - sortDirection: Direction.asc, - }, - ]; - let mockDefaultHeaders = cloneDeep( - defaultHeaders.map((h) => (h.id === 'message' ? h : { ...h, aggregatable: true })) - ); - - beforeEach(() => { - mockDefaultHeaders = cloneDeep( - defaultHeaders.map((h) => (h.id === 'message' ? h : { ...h, aggregatable: true })) - ); - mockSort = [ - { - columnId: '@timestamp', - columnType: 'number', - sortDirection: Direction.desc, - }, - { - columnId: 'host.name', - columnType: 'text', - sortDirection: Direction.asc, - }, - ]; - }); - - test('Add column `event.category` as desc sorting', () => { - const wrapper = mount( - - - - ); - - wrapper - .find('[data-test-subj="header-event.category"] [data-test-subj="header-sort-button"]') - .first() - .simulate('click'); - expect(mockDispatch).toHaveBeenCalledWith( - tGridActions.updateSort({ - id: timelineId, - sort: [ - { - columnId: '@timestamp', - columnType: 'number', - sortDirection: Direction.desc, - }, - { - columnId: 'host.name', - columnType: 'text', - sortDirection: Direction.asc, - }, - { columnId: 'event.category', columnType: 'text', sortDirection: Direction.desc }, - ], - }) - ); - }); - - test('Change order of column `@timestamp` from desc to asc without changing index position', () => { - const wrapper = mount( - - - - ); - - wrapper - .find('[data-test-subj="header-@timestamp"] [data-test-subj="header-sort-button"]') - .first() - .simulate('click'); - expect(mockDispatch).toHaveBeenCalledWith( - tGridActions.updateSort({ - id: timelineId, - sort: [ - { - columnId: '@timestamp', - columnType: 'number', - sortDirection: Direction.asc, - }, - { columnId: 'host.name', columnType: 'text', sortDirection: Direction.asc }, - ], - }) - ); - }); - - test('Change order of column `host.name` from asc to desc without changing index position', () => { - const wrapper = mount( - - - - ); - - wrapper - .find('[data-test-subj="header-host.name"] [data-test-subj="header-sort-button"]') - .first() - .simulate('click'); - expect(mockDispatch).toHaveBeenCalledWith( - tGridActions.updateSort({ - id: timelineId, - sort: [ - { - columnId: '@timestamp', - columnType: 'number', - sortDirection: Direction.desc, - }, - { columnId: 'host.name', columnType: 'text', sortDirection: Direction.desc }, - ], - }) - ); - }); - test('Does not render the default leading action column header and renders a custom trailing header', () => { - const wrapper = mount( - - - - ); - - expect(wrapper.exists('[data-test-subj="field-browser"]')).toBeFalsy(); - expect(wrapper.exists('[data-test-subj="test-header-action-cell"]')).toBeTruthy(); - }); - }); -}); diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/index.tsx deleted file mode 100644 index 6a8568dcc6179..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/index.tsx +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { DRAG_TYPE_FIELD, droppableTimelineColumnsPrefix } from '@kbn/securitysolution-t-grid'; -import deepEqual from 'fast-deep-equal'; -import React, { useState, useEffect, useCallback, useMemo } from 'react'; -import { Droppable, DraggableChildrenFn } from 'react-beautiful-dnd'; - -import { TimelineId, TimelineTabs } from '../../../../../common/types/timeline'; -import type { - ControlColumnProps, - ColumnHeaderOptions, - HeaderActionProps, -} from '../../../../../common/types/timeline'; - -import type { BrowserFields } from '../../../../../common/search_strategy/index_fields'; - -import type { OnSelectAll } from '../../types'; -import { - EventsTh, - EventsThead, - EventsThGroupData, - EventsTrHeader, - EventsThGroupActions, -} from '../../styles'; -import { Sort } from '../sort'; -import { ColumnHeader } from './column_header'; -import { DraggableFieldBadge } from '../../../draggables'; - -interface Props { - actionsColumnWidth: number; - browserFields: BrowserFields; - columnHeaders: ColumnHeaderOptions[]; - isEventViewer?: boolean; - isSelectAllChecked: boolean; - onSelectAll: OnSelectAll; - showEventsSelect: boolean; - showSelectAllCheckbox: boolean; - sort: Sort[]; - tabType: TimelineTabs; - timelineId: string; - leadingControlColumns: ControlColumnProps[]; - trailingControlColumns: ControlColumnProps[]; -} - -interface DraggableContainerProps { - children: React.ReactNode; - onMount: () => void; - onUnmount: () => void; -} - -export const DraggableContainer = React.memo( - ({ children, onMount, onUnmount }) => { - useEffect(() => { - onMount(); - - return () => onUnmount(); - }, [onMount, onUnmount]); - - return <>{children}; - } -); - -DraggableContainer.displayName = 'DraggableContainer'; - -export const isFullScreen = ({ - globalFullScreen, - timelineId, - timelineFullScreen, -}: { - globalFullScreen: boolean; - timelineId: string; - timelineFullScreen: boolean; -}) => - (timelineId === TimelineId.active && timelineFullScreen) || - (timelineId !== TimelineId.active && globalFullScreen); - -/** Renders the timeline header columns */ -export const ColumnHeadersComponent = ({ - actionsColumnWidth, - browserFields, - columnHeaders, - isEventViewer = false, - isSelectAllChecked, - onSelectAll, - showEventsSelect, - showSelectAllCheckbox, - sort, - tabType, - timelineId, - leadingControlColumns, - trailingControlColumns, -}: Props) => { - const [draggingIndex, setDraggingIndex] = useState(null); - - const renderClone: DraggableChildrenFn = useCallback( - (dragProvided, _dragSnapshot, rubric) => { - const index = rubric.source.index; - const header = columnHeaders[index]; - - const onMount = () => setDraggingIndex(index); - const onUnmount = () => setDraggingIndex(null); - - return ( - - - - - - ); - }, - [columnHeaders, setDraggingIndex] - ); - - const ColumnHeaderList = useMemo( - () => - columnHeaders.map((header, draggableIndex) => ( - - )), - [columnHeaders, timelineId, draggingIndex, sort, tabType] - ); - - const DroppableContent = useCallback( - (dropProvided, snapshot) => ( - <> - - {ColumnHeaderList} - - - ), - [ColumnHeaderList] - ); - - const leadingHeaderCells = useMemo( - () => - leadingControlColumns ? leadingControlColumns.map((column) => column.headerCellRender) : [], - [leadingControlColumns] - ); - - const trailingHeaderCells = useMemo( - () => - trailingControlColumns ? trailingControlColumns.map((column) => column.headerCellRender) : [], - [trailingControlColumns] - ); - - const LeadingHeaderActions = useMemo(() => { - return leadingHeaderCells.map( - (Header: React.ComponentType | React.ComponentType | undefined, index) => { - const passedWidth = leadingControlColumns[index] && leadingControlColumns[index].width; - const width = passedWidth ? passedWidth : actionsColumnWidth; - return ( - - {Header && ( -
- )} - - ); - } - ); - }, [ - leadingHeaderCells, - leadingControlColumns, - actionsColumnWidth, - browserFields, - columnHeaders, - isEventViewer, - isSelectAllChecked, - onSelectAll, - showEventsSelect, - showSelectAllCheckbox, - sort, - tabType, - timelineId, - ]); - - const TrailingHeaderActions = useMemo(() => { - return trailingHeaderCells.map( - (Header: React.ComponentType | React.ComponentType | undefined, index) => { - const passedWidth = trailingControlColumns[index] && trailingControlColumns[index].width; - const width = passedWidth ? passedWidth : actionsColumnWidth; - return ( - - {Header && ( -
- )} - - ); - } - ); - }, [ - trailingHeaderCells, - trailingControlColumns, - actionsColumnWidth, - browserFields, - columnHeaders, - isEventViewer, - isSelectAllChecked, - onSelectAll, - showEventsSelect, - showSelectAllCheckbox, - sort, - tabType, - timelineId, - ]); - return ( - - - {LeadingHeaderActions} - - {DroppableContent} - - {TrailingHeaderActions} - - - ); -}; - -export const ColumnHeaders = React.memo( - ColumnHeadersComponent, - (prevProps, nextProps) => - prevProps.actionsColumnWidth === nextProps.actionsColumnWidth && - prevProps.isEventViewer === nextProps.isEventViewer && - prevProps.isSelectAllChecked === nextProps.isSelectAllChecked && - prevProps.onSelectAll === nextProps.onSelectAll && - prevProps.showEventsSelect === nextProps.showEventsSelect && - prevProps.showSelectAllCheckbox === nextProps.showSelectAllCheckbox && - deepEqual(prevProps.sort, nextProps.sort) && - prevProps.timelineId === nextProps.timelineId && - deepEqual(prevProps.columnHeaders, nextProps.columnHeaders) && - prevProps.tabType === nextProps.tabType && - deepEqual(prevProps.browserFields, nextProps.browserFields) -); diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/constants.ts b/x-pack/plugins/timelines/public/components/t_grid/body/constants.ts index 3f1889732483d..0af2efb593f55 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/body/constants.ts +++ b/x-pack/plugins/timelines/public/components/t_grid/body/constants.ts @@ -24,14 +24,8 @@ import { euiThemeVars } from '@kbn/ui-theme'; export const DEFAULT_ACTION_BUTTON_WIDTH = parseInt(euiThemeVars.euiSizeXL, 10) - parseInt(euiThemeVars.euiSizeXS, 10); // px -/** Additional column width to include when checkboxes are shown **/ -export const SHOW_CHECK_BOXES_COLUMN_WIDTH = 24; // px; - /** The default minimum width of a column (when a width for the column type is not specified) */ export const DEFAULT_COLUMN_MIN_WIDTH = 180; // px -/** The minimum width of a resized column */ -export const RESIZED_COLUMN_MIN_WITH = 70; // px - /** The default minimum width of a column of type `date` */ export const DEFAULT_DATE_COLUMN_MIN_WIDTH = 190; // px diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/data_driven_columns/__snapshots__/index.test.tsx.snap b/x-pack/plugins/timelines/public/components/t_grid/body/data_driven_columns/__snapshots__/index.test.tsx.snap deleted file mode 100644 index cbec3a3baa695..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/data_driven_columns/__snapshots__/index.test.tsx.snap +++ /dev/null @@ -1,967 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Columns it renders the expected columns 1`] = ` - - - - - - - - - -`; diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/data_driven_columns/index.test.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/data_driven_columns/index.test.tsx deleted file mode 100644 index be7114be67b04..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/data_driven_columns/index.test.tsx +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { shallow } from 'enzyme'; - -import React from 'react'; - -import { defaultHeaders } from '../column_headers/default_headers'; - -import { DataDrivenColumns } from '.'; -import { mockTimelineData } from '../../../../mock/mock_timeline_data'; -import { TestCellRenderer } from '../../../../mock/cell_renderer'; - -window.matchMedia = jest.fn().mockImplementation((query) => { - return { - matches: false, - media: query, - onchange: null, - addListener: jest.fn(), - removeListener: jest.fn(), - }; -}); - -describe('Columns', () => { - const headersSansTimestamp = defaultHeaders.filter((h) => h.id !== '@timestamp'); - - test('it renders the expected columns', () => { - const wrapper = shallow( - - ); - - expect(wrapper).toMatchSnapshot(); - }); -}); diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/data_driven_columns/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/data_driven_columns/index.tsx index 935b1c2e1d469..570581bcb640e 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/body/data_driven_columns/index.tsx +++ b/x-pack/plugins/timelines/public/components/t_grid/body/data_driven_columns/index.tsx @@ -5,396 +5,7 @@ * 2.0. */ -import { EuiScreenReaderOnly } from '@elastic/eui'; -import React, { useMemo } from 'react'; -import { getOr } from 'lodash/fp'; - -import { DRAGGABLE_KEYBOARD_WRAPPER_CLASS_NAME } from '@kbn/securitysolution-t-grid'; -import { OnRowSelected } from '../../types'; - -import { - EventsTd, - EVENTS_TD_CLASS_NAME, - EventsTdContent, - EventsTdGroupData, - EventsTdGroupActions, -} from '../../styles'; - -import { StatefulCell } from './stateful_cell'; -import * as i18n from './translations'; -import { - SetEventsDeleted, - SetEventsLoading, - TimelineTabs, -} from '../../../../../common/types/timeline'; -import type { - ActionProps, - CellValueElementProps, - ColumnHeaderOptions, - ControlColumnProps, - RowCellRender, -} from '../../../../../common/types/timeline'; import type { TimelineNonEcsData } from '../../../../../common/search_strategy'; -import { ARIA_COLUMN_INDEX_OFFSET } from '../../helpers'; -import type { Ecs } from '../../../../../common/ecs'; - -interface CellProps { - _id: string; - ariaRowindex: number; - index: number; - header: ColumnHeaderOptions; - data: TimelineNonEcsData[]; - ecsData: Ecs; - hasRowRenderers: boolean; - renderCellValue: (props: CellValueElementProps) => React.ReactNode; - tabType?: TimelineTabs; - timelineId: string; -} - -interface DataDrivenColumnProps { - id: string; - actionsColumnWidth: number; - ariaRowindex: number; - checked: boolean; - columnHeaders: ColumnHeaderOptions[]; - columnValues: string; - data: TimelineNonEcsData[]; - ecsData: Ecs; - isEventViewer?: boolean; - loadingEventIds: Readonly; - onEventDetailsPanelOpened: () => void; - onRowSelected: OnRowSelected; - onRuleChange?: () => void; - hasRowRenderers: boolean; - selectedEventIds: Readonly>; - showCheckboxes: boolean; - renderCellValue: (props: CellValueElementProps) => React.ReactNode; - tabType?: TimelineTabs; - timelineId: string; - trailingControlColumns: ControlColumnProps[]; - leadingControlColumns: ControlColumnProps[]; - setEventsLoading: SetEventsLoading; - setEventsDeleted: SetEventsDeleted; -} - -const SPACE = ' '; - -export const shouldForwardKeyDownEvent = (key: string): boolean => { - switch (key) { - case SPACE: // fall through - case 'Enter': - return true; - default: - return false; - } -}; - -export const onKeyDown = (keyboardEvent: React.KeyboardEvent) => { - const { altKey, ctrlKey, key, metaKey, shiftKey, target, type } = keyboardEvent; - - const targetElement = target as Element; - - // we *only* forward the event to the (child) draggable keyboard wrapper - // if the keyboard event originated from the container (TD) element - if (shouldForwardKeyDownEvent(key) && targetElement.className?.includes(EVENTS_TD_CLASS_NAME)) { - const draggableKeyboardWrapper = targetElement.querySelector( - `.${DRAGGABLE_KEYBOARD_WRAPPER_CLASS_NAME}` - ); - - const newEvent = new KeyboardEvent(type, { - altKey, - bubbles: true, - cancelable: true, - ctrlKey, - key, - metaKey, - shiftKey, - }); - - if (key === ' ') { - // prevent the default behavior of scrolling the table when space is pressed - keyboardEvent.preventDefault(); - } - - draggableKeyboardWrapper?.dispatchEvent(newEvent); - } -}; - -const TgridActionTdCell = ({ - action: Action, - width, - actionsColumnWidth, - ariaRowindex, - columnId, - columnValues, - data, - ecsData, - eventIdToNoteIds, - index, - isEventPinned, - isEventViewer, - eventId, - loadingEventIds, - onEventDetailsPanelOpened, - onRowSelected, - rowIndex, - hasRowRenderers, - onRuleChange, - selectedEventIds = {}, - showCheckboxes, - showNotes = false, - tabType, - timelineId, - toggleShowNotes, - setEventsLoading, - setEventsDeleted, -}: ActionProps & { - columnId: string; - hasRowRenderers: boolean; - actionsColumnWidth: number; - selectedEventIds: Readonly>; -}) => { - const displayWidth = width ? width : actionsColumnWidth; - return ( - - - - <> - -

{i18n.YOU_ARE_IN_A_TABLE_CELL({ row: ariaRowindex, column: index + 2 })}

-
- {Action && ( - - )} - -
- {hasRowRenderers ? ( - -

{i18n.EVENT_HAS_AN_EVENT_RENDERER(ariaRowindex)}

-
- ) : null} -
-
- ); -}; - -const TgridTdCell = ({ - _id, - ariaRowindex, - index, - header, - data, - ecsData, - hasRowRenderers, - renderCellValue, - tabType, - timelineId, -}: CellProps) => { - const ariaColIndex = index + ARIA_COLUMN_INDEX_OFFSET; - return ( - - - <> - -

{i18n.YOU_ARE_IN_A_TABLE_CELL({ row: ariaRowindex, column: ariaColIndex })}

-
- - -
- {hasRowRenderers ? ( - -

{i18n.EVENT_HAS_AN_EVENT_RENDERER(ariaRowindex)}

-
- ) : null} -
- ); -}; - -export const DataDrivenColumns = React.memo( - ({ - ariaRowindex, - actionsColumnWidth, - columnHeaders, - columnValues, - data, - ecsData, - isEventViewer, - id: _id, - loadingEventIds, - onEventDetailsPanelOpened, - onRowSelected, - hasRowRenderers, - onRuleChange, - renderCellValue, - selectedEventIds = {}, - showCheckboxes, - tabType, - timelineId, - trailingControlColumns, - leadingControlColumns, - setEventsLoading, - setEventsDeleted, - }) => { - const trailingActionCells = useMemo( - () => - trailingControlColumns ? trailingControlColumns.map((column) => column.rowCellRender) : [], - [trailingControlColumns] - ); - const leadingAndDataColumnCount = useMemo( - () => leadingControlColumns.length + columnHeaders.length, - [leadingControlColumns, columnHeaders] - ); - const TrailingActions = useMemo( - () => - trailingActionCells.map((Action: RowCellRender | undefined, index) => { - return ( - Action && ( - - ) - ); - }), - [ - trailingControlColumns, - _id, - data, - ecsData, - onRowSelected, - isEventViewer, - actionsColumnWidth, - ariaRowindex, - columnValues, - hasRowRenderers, - leadingAndDataColumnCount, - loadingEventIds, - onEventDetailsPanelOpened, - onRuleChange, - selectedEventIds, - showCheckboxes, - tabType, - timelineId, - trailingActionCells, - setEventsLoading, - setEventsDeleted, - ] - ); - const ColumnHeaders = useMemo( - () => - columnHeaders.map((header, index) => ( - - )), - [ - _id, - ariaRowindex, - columnHeaders, - data, - ecsData, - hasRowRenderers, - renderCellValue, - tabType, - timelineId, - ] - ); - return ( - - {ColumnHeaders} - {TrailingActions} - - ); - } -); - -DataDrivenColumns.displayName = 'DataDrivenColumns'; export const getMappedNonEcsValue = ({ data, diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/data_driven_columns/stateful_cell.test.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/data_driven_columns/stateful_cell.test.tsx deleted file mode 100644 index d79a59422ff43..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/data_driven_columns/stateful_cell.test.tsx +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { mount } from 'enzyme'; -import { cloneDeep } from 'lodash/fp'; -import React, { useEffect } from 'react'; - -import { StatefulCell } from './stateful_cell'; -import { getMappedNonEcsValue } from '.'; -import { defaultHeaders } from '../../../../mock/header'; -import { - CellValueElementProps, - ColumnHeaderOptions, - TimelineTabs, -} from '../../../../../common/types/timeline'; -import { TimelineNonEcsData } from '../../../../../common/search_strategy'; -import { mockTimelineData } from '../../../../mock/mock_timeline_data'; - -/** - * This (test) component implement's `EuiDataGrid`'s `renderCellValue` interface, - * as documented here: https://elastic.github.io/eui/#/tabular-content/data-grid - * - * Its `CellValueElementProps` props are a superset of `EuiDataGridCellValueElementProps`. - * The `setCellProps` function, defined by the `EuiDataGridCellValueElementProps` interface, - * is typically called in a `useEffect`, as illustrated by `EuiDataGrid`'s code sandbox example: - * https://codesandbox.io/s/zhxmo - */ -const RenderCellValue: React.FC = ({ columnId, data, setCellProps }) => { - useEffect(() => { - // branching logic that conditionally renders a specific cell green: - if (columnId === defaultHeaders[0].id) { - const value = getMappedNonEcsValue({ - data, - fieldName: columnId, - }); - - if (value?.length) { - setCellProps({ - style: { - backgroundColor: 'green', - }, - }); - } - } - }, [columnId, data, setCellProps]); - - return ( -
- {getMappedNonEcsValue({ - data, - fieldName: columnId, - })} -
- ); -}; - -describe('StatefulCell', () => { - const rowIndex = 123; - const colIndex = 0; - const eventId = '_id-123'; - const linkValues = ['foo', 'bar', '@baz']; - const tabType = TimelineTabs.query; - const timelineId = 'test'; - - let header: ColumnHeaderOptions; - let data: TimelineNonEcsData[]; - beforeEach(() => { - data = cloneDeep(mockTimelineData[0].data); - header = cloneDeep(defaultHeaders[0]); - }); - - test('it invokes renderCellValue with the expected arguments when tabType is specified', () => { - const renderCellValue = jest.fn(); - - mount( - - ); - - expect(renderCellValue).toBeCalledWith( - expect.objectContaining({ - columnId: header.id, - eventId, - data, - header, - isExpandable: true, - isExpanded: false, - isDetails: false, - linkValues, - rowIndex, - colIndex, - timelineId: `${timelineId}-${tabType}`, - }) - ); - }); - - test('it invokes renderCellValue with the expected arguments when tabType is NOT specified', () => { - const renderCellValue = jest.fn(); - - mount( - - ); - - expect(renderCellValue).toBeCalledWith( - expect.objectContaining({ - columnId: header.id, - eventId, - data, - header, - isExpandable: true, - isExpanded: false, - isDetails: false, - linkValues, - rowIndex, - colIndex, - timelineId, - }) - ); - }); - - test('it renders the React.Node returned by renderCellValue', () => { - const renderCellValue = () =>
; - - const wrapper = mount( - - ); - - expect(wrapper.find('[data-test-subj="renderCellValue"]').exists()).toBe(true); - }); - - test("it renders a div with the styles set by `renderCellValue`'s `setCellProps` argument", () => { - const wrapper = mount( - - ); - - expect( - wrapper.find('[data-test-subj="statefulCell"]').getDOMNode().getAttribute('style') - ).toEqual('background-color: green;'); - }); -}); diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/data_driven_columns/stateful_cell.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/data_driven_columns/stateful_cell.tsx deleted file mode 100644 index f66b4d88ba876..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/data_driven_columns/stateful_cell.tsx +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { HTMLAttributes, useState } from 'react'; -import type { TimelineNonEcsData } from '../../../../../common/search_strategy'; - -import { TimelineTabs } from '../../../../../common/types/timeline'; -import type { - CellValueElementProps, - ColumnHeaderOptions, -} from '../../../../../common/types/timeline'; - -export interface CommonProps { - className?: string; - 'aria-label'?: string; - 'data-test-subj'?: string; -} - -const StatefulCellComponent = ({ - rowIndex, - colIndex, - data, - header, - eventId, - linkValues, - renderCellValue, - tabType, - timelineId, -}: { - rowIndex: number; - colIndex: number; - data: TimelineNonEcsData[]; - header: ColumnHeaderOptions; - eventId: string; - linkValues: string[] | undefined; - renderCellValue: (props: CellValueElementProps) => React.ReactNode; - tabType?: TimelineTabs; - timelineId: string; -}) => { - const [cellProps, setCellProps] = useState>({}); - return ( -
- {renderCellValue({ - columnId: header.id, - eventId, - data, - header, - isDraggable: true, - isExpandable: true, - isExpanded: false, - isDetails: false, - linkValues, - rowIndex, - colIndex, - setCellProps, - timelineId: tabType != null ? `${timelineId}-${tabType}` : timelineId, - })} -
- ); -}; - -StatefulCellComponent.displayName = 'StatefulCellComponent'; - -export const StatefulCell = React.memo(StatefulCellComponent); diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/data_driven_columns/translations.ts b/x-pack/plugins/timelines/public/components/t_grid/body/data_driven_columns/translations.ts deleted file mode 100644 index 1e5b10bb7cbc2..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/data_driven_columns/translations.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const YOU_ARE_IN_A_TABLE_CELL = ({ column, row }: { column: number; row: number }) => - i18n.translate('xpack.timelines.timeline.youAreInATableCellScreenReaderOnly', { - values: { column, row }, - defaultMessage: 'You are in a table cell. row: {row}, column: {column}', - }); - -export const EVENT_HAS_AN_EVENT_RENDERER = (row: number) => - i18n.translate('xpack.timelines.timeline.eventHasEventRendererScreenReaderOnly', { - values: { row }, - defaultMessage: - 'The event in row {row} has an event renderer. Press shift + down arrow to focus it.', - }); - -export const EVENT_HAS_NOTES = ({ notesCount, row }: { notesCount: number; row: number }) => - i18n.translate('xpack.timelines.timeline.eventHasNotesScreenReaderOnly', { - values: { notesCount, row }, - defaultMessage: - 'The event in row {row} has {notesCount, plural, =1 {a note} other {{notesCount} notes}}. Press shift + right arrow to focus notes.', - }); diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/events/event_column_view.test.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/events/event_column_view.test.tsx deleted file mode 100644 index 366108a19b873..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/events/event_column_view.test.tsx +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { mount } from 'enzyme'; -import React from 'react'; - -import { getActionsColumnWidth } from '../column_headers/helpers'; - -import { EventColumnView } from './event_column_view'; -import { TestCellRenderer } from '../../../../mock/cell_renderer'; -import { TimelineId, TimelineTabs } from '../../../../../common/types/timeline'; -import { TestProviders } from '../../../../mock/test_providers'; -import { testLeadingControlColumn } from '../../../../mock/mock_timeline_control_columns'; -import { mockGlobalState } from '../../../../mock/global_state'; - -jest.mock('../../../../hooks/use_selector', () => ({ - useShallowEqualSelector: () => mockGlobalState.timelineById.test, - useDeepEqualSelector: () => mockGlobalState.timelineById.test, -})); - -describe('EventColumnView', () => { - const ACTION_BUTTON_COUNT = 4; - const props = { - ariaRowindex: 2, - id: 'event-id', - actionsColumnWidth: getActionsColumnWidth(ACTION_BUTTON_COUNT), - associateNote: jest.fn(), - columnHeaders: [], - columnRenderers: [], - data: [ - { - field: 'host.name', - }, - ], - ecsData: { - _id: 'id', - }, - eventIdToNoteIds: {}, - expanded: false, - hasRowRenderers: false, - loading: false, - loadingEventIds: [], - notesCount: 0, - onEventDetailsPanelOpened: jest.fn(), - onPinEvent: jest.fn(), - onRowSelected: jest.fn(), - onUnPinEvent: jest.fn(), - refetch: jest.fn(), - renderCellValue: TestCellRenderer, - selectedEventIds: {}, - showCheckboxes: false, - showNotes: false, - tabType: TimelineTabs.query, - timelineId: TimelineId.active, - toggleShowNotes: jest.fn(), - updateNote: jest.fn(), - isEventPinned: false, - leadingControlColumns: [], - trailingControlColumns: [], - setEventsLoading: jest.fn(), - setEventsDeleted: jest.fn(), - }; - - // TODO: next 3 tests will be re-enabled in the future. - test.skip('it render AddToCaseAction if timelineId === TimelineId.detectionsPage', () => { - const wrapper = mount(, { - wrappingComponent: TestProviders, - }); - - expect(wrapper.find('[data-test-subj="add-to-case-action"]').exists()).toBeTruthy(); - }); - - test.skip('it render AddToCaseAction if timelineId === TimelineId.detectionsRulesDetailsPage', () => { - const wrapper = mount( - , - { - wrappingComponent: TestProviders, - } - ); - - expect(wrapper.find('[data-test-subj="add-to-case-action"]').exists()).toBeTruthy(); - }); - - test.skip('it render AddToCaseAction if timelineId === TimelineId.active', () => { - const wrapper = mount(, { - wrappingComponent: TestProviders, - }); - - expect(wrapper.find('[data-test-subj="add-to-case-action"]').exists()).toBeTruthy(); - }); - - test.skip('it does NOT render AddToCaseAction when timelineId is not in the allowed list', () => { - const wrapper = mount(, { - wrappingComponent: TestProviders, - }); - - expect(wrapper.find('[data-test-subj="add-to-case-action"]').exists()).toBeFalsy(); - }); - - test('it renders a custom control column in addition to the default control column', () => { - const wrapper = mount( - , - { - wrappingComponent: TestProviders, - } - ); - - expect(wrapper.find('[data-test-subj="test-body-control-column-cell"]').exists()).toBeTruthy(); - }); -}); diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/events/event_column_view.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/events/event_column_view.tsx deleted file mode 100644 index 31123476a9a38..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/events/event_column_view.tsx +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useMemo } from 'react'; - -import type { OnRowSelected } from '../../types'; -import { EventsTrData, EventsTdGroupActions } from '../../styles'; -import { DataDrivenColumns, getMappedNonEcsValue } from '../data_driven_columns'; -import { TimelineTabs } from '../../../../../common/types/timeline'; -import type { - CellValueElementProps, - ColumnHeaderOptions, - ControlColumnProps, - RowCellRender, - SetEventsDeleted, - SetEventsLoading, -} from '../../../../../common/types/timeline'; -import type { TimelineNonEcsData } from '../../../../../common/search_strategy'; -import type { Ecs } from '../../../../../common/ecs'; - -interface Props { - id: string; - actionsColumnWidth: number; - ariaRowindex: number; - columnHeaders: ColumnHeaderOptions[]; - data: TimelineNonEcsData[]; - ecsData: Ecs; - isEventViewer?: boolean; - loadingEventIds: Readonly; - onEventDetailsPanelOpened: () => void; - onRowSelected: OnRowSelected; - renderCellValue: (props: CellValueElementProps) => React.ReactNode; - onRuleChange?: () => void; - hasRowRenderers: boolean; - selectedEventIds: Readonly>; - showCheckboxes: boolean; - tabType?: TimelineTabs; - timelineId: string; - leadingControlColumns: ControlColumnProps[]; - trailingControlColumns: ControlColumnProps[]; - setEventsLoading: SetEventsLoading; - setEventsDeleted: SetEventsDeleted; -} - -export const EventColumnView = React.memo( - ({ - id, - actionsColumnWidth, - ariaRowindex, - columnHeaders, - data, - ecsData, - isEventViewer = false, - loadingEventIds, - onEventDetailsPanelOpened, - onRowSelected, - hasRowRenderers, - onRuleChange, - renderCellValue, - selectedEventIds = {}, - showCheckboxes, - tabType, - timelineId, - leadingControlColumns, - trailingControlColumns, - setEventsLoading, - setEventsDeleted, - }) => { - // Each action button shall announce itself to screen readers via an `aria-label` - // in the following format: - // "button description, for the event in row {ariaRowindex}, with columns {columnValues}", - // so we combine the column values here: - const columnValues = useMemo( - () => - columnHeaders - .map( - (header) => - getMappedNonEcsValue({ - data, - fieldName: header.id, - }) ?? [] - ) - .join(' '), - [columnHeaders, data] - ); - const leadingActionCells = useMemo( - () => - leadingControlColumns ? leadingControlColumns.map((column) => column.rowCellRender) : [], - [leadingControlColumns] - ); - const LeadingActions = useMemo( - () => - leadingActionCells.map((Action: RowCellRender | undefined, index) => { - const width = leadingControlColumns[index].width - ? leadingControlColumns[index].width - : actionsColumnWidth; - return ( - - {Action && ( - - )} - - ); - }), - [ - actionsColumnWidth, - ariaRowindex, - columnValues, - data, - ecsData, - id, - isEventViewer, - leadingActionCells, - leadingControlColumns, - loadingEventIds, - onEventDetailsPanelOpened, - onRowSelected, - onRuleChange, - selectedEventIds, - showCheckboxes, - tabType, - timelineId, - setEventsLoading, - setEventsDeleted, - ] - ); - return ( - - {LeadingActions} - - - ); - } -); - -EventColumnView.displayName = 'EventColumnView'; diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/events/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/events/index.tsx deleted file mode 100644 index 708cf9fae0361..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/events/index.tsx +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { isEmpty } from 'lodash'; - -import { EventsTbody } from '../../styles'; -import { StatefulEvent } from './stateful_event'; -import type { BrowserFields } from '../../../../../common/search_strategy/index_fields'; -import { TimelineTabs } from '../../../../../common/types/timeline'; -import type { - CellValueElementProps, - ColumnHeaderOptions, - ControlColumnProps, - OnRowSelected, - RowRenderer, -} from '../../../../../common/types/timeline'; - -import { TimelineItem, TimelineNonEcsData } from '../../../../../common/search_strategy'; - -/** This offset begins at two, because the header row counts as "row 1", and aria-rowindex starts at "1" */ -const ARIA_ROW_INDEX_OFFSET = 2; - -interface Props { - actionsColumnWidth: number; - browserFields: BrowserFields; - columnHeaders: ColumnHeaderOptions[]; - containerRef: React.MutableRefObject; - data: TimelineItem[]; - id: string; - isEventViewer?: boolean; - lastFocusedAriaColindex: number; - loadingEventIds: Readonly; - onRowSelected: OnRowSelected; - renderCellValue: (props: CellValueElementProps) => React.ReactNode; - onRuleChange?: () => void; - rowRenderers: RowRenderer[]; - selectedEventIds: Readonly>; - showCheckboxes: boolean; - tabType?: TimelineTabs; - leadingControlColumns: ControlColumnProps[]; - trailingControlColumns: ControlColumnProps[]; -} - -const EventsComponent: React.FC = ({ - actionsColumnWidth, - browserFields, - columnHeaders, - containerRef, - data, - id, - isEventViewer = false, - lastFocusedAriaColindex, - loadingEventIds, - onRowSelected, - onRuleChange, - renderCellValue, - rowRenderers, - selectedEventIds, - showCheckboxes, - tabType, - leadingControlColumns, - trailingControlColumns, -}) => ( - - {data.map((event, i) => ( - - ))} - -); - -export const Events = React.memo(EventsComponent); diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/events/stateful_event.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/events/stateful_event.tsx deleted file mode 100644 index 8ad15580d7bfe..0000000000000 --- a/x-pack/plugins/timelines/public/components/t_grid/body/events/stateful_event.tsx +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useCallback, useMemo, useRef, useState } from 'react'; -import { useDispatch } from 'react-redux'; - -import { STATEFUL_EVENT_CSS_CLASS_NAME } from '../../helpers'; -import { EventsTrGroup, EventsTrSupplement } from '../../styles'; -import type { OnRowSelected } from '../../types'; -import { isEventBuildingBlockType, getEventType, isEvenEqlSequence } from '../helpers'; -import { EventColumnView } from './event_column_view'; -import { getRowRenderer } from '../renderers/get_row_renderer'; -import { StatefulRowRenderer } from './stateful_row_renderer'; -import { getMappedNonEcsValue } from '../data_driven_columns'; -import { StatefulEventContext } from './stateful_event_context'; -import type { BrowserFields } from '../../../../../common/search_strategy/index_fields'; -import { - SetEventsDeleted, - SetEventsLoading, - TimelineTabs, -} from '../../../../../common/types/timeline'; -import type { - CellValueElementProps, - ColumnHeaderOptions, - ControlColumnProps, - RowRenderer, - TimelineExpandedDetailType, -} from '../../../../../common/types/timeline'; - -import type { TimelineItem, TimelineNonEcsData } from '../../../../../common/search_strategy'; -import { tGridActions, tGridSelectors } from '../../../../store/t_grid'; -import { useDeepEqualSelector } from '../../../../hooks/use_selector'; - -interface Props { - actionsColumnWidth: number; - containerRef: React.MutableRefObject; - browserFields: BrowserFields; - columnHeaders: ColumnHeaderOptions[]; - event: TimelineItem; - isEventViewer?: boolean; - lastFocusedAriaColindex: number; - loadingEventIds: Readonly; - onRowSelected: OnRowSelected; - ariaRowindex: number; - onRuleChange?: () => void; - renderCellValue: (props: CellValueElementProps) => React.ReactNode; - rowRenderers: RowRenderer[]; - selectedEventIds: Readonly>; - showCheckboxes: boolean; - tabType?: TimelineTabs; - timelineId: string; - leadingControlColumns: ControlColumnProps[]; - trailingControlColumns: ControlColumnProps[]; -} - -const StatefulEventComponent: React.FC = ({ - actionsColumnWidth, - browserFields, - containerRef, - columnHeaders, - event, - isEventViewer = false, - lastFocusedAriaColindex, - loadingEventIds, - onRowSelected, - renderCellValue, - rowRenderers, - onRuleChange, - ariaRowindex, - selectedEventIds, - showCheckboxes, - tabType, - timelineId, - leadingControlColumns, - trailingControlColumns, -}) => { - const trGroupRef = useRef(null); - const dispatch = useDispatch(); - // Store context in state rather than creating object in provider value={} to prevent re-renders caused by a new object being created - const [activeStatefulEventContext] = useState({ timelineID: timelineId, tabType }); - const getTGrid = useMemo(() => tGridSelectors.getTGridByIdSelector(), []); - const expandedDetail = useDeepEqualSelector( - (state) => getTGrid(state, timelineId).expandedDetail ?? {} - ); - const hostName = useMemo(() => { - const hostNameArr = getMappedNonEcsValue({ data: event?.data, fieldName: 'host.name' }); - return hostNameArr && hostNameArr.length > 0 ? hostNameArr[0] : null; - }, [event?.data]); - - const hostIPAddresses = useMemo(() => { - const hostIpList = getMappedNonEcsValue({ data: event?.data, fieldName: 'host.ip' }) ?? []; - const sourceIpList = getMappedNonEcsValue({ data: event?.data, fieldName: 'source.ip' }) ?? []; - const destinationIpList = - getMappedNonEcsValue({ - data: event?.data, - fieldName: 'destination.ip', - }) ?? []; - return new Set([...hostIpList, ...sourceIpList, ...destinationIpList]); - }, [event?.data]); - - const activeTab = tabType ?? TimelineTabs.query; - const activeExpandedDetail = expandedDetail[activeTab]; - - const isDetailPanelExpanded: boolean = - (activeExpandedDetail?.panelView === 'eventDetail' && - activeExpandedDetail?.params?.eventId === event._id) || - (activeExpandedDetail?.panelView === 'hostDetail' && - activeExpandedDetail?.params?.hostName === hostName) || - (activeExpandedDetail?.panelView === 'networkDetail' && - activeExpandedDetail?.params?.ip && - hostIPAddresses?.has(activeExpandedDetail?.params?.ip)) || - false; - - const hasRowRenderers: boolean = useMemo( - () => getRowRenderer(event.ecs, rowRenderers) != null, - [event.ecs, rowRenderers] - ); - - const handleOnEventDetailPanelOpened = useCallback(() => { - const eventId = event._id; - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const indexName = event._index!; - - const updatedExpandedDetail: TimelineExpandedDetailType = { - panelView: 'eventDetail', - params: { - eventId, - indexName, - }, - }; - - dispatch( - tGridActions.toggleDetailPanel({ - ...updatedExpandedDetail, - tabType, - timelineId, - }) - ); - }, [dispatch, event._id, event._index, tabType, timelineId]); - - const setEventsLoading = useCallback( - ({ eventIds, isLoading }) => { - dispatch(tGridActions.setEventsLoading({ id: timelineId, eventIds, isLoading })); - }, - [dispatch, timelineId] - ); - - const setEventsDeleted = useCallback( - ({ eventIds, isDeleted }) => { - dispatch(tGridActions.setEventsDeleted({ id: timelineId, eventIds, isDeleted })); - }, - [dispatch, timelineId] - ); - - const RowRendererContent = useMemo( - () => ( - - - - ), - [ariaRowindex, containerRef, event, lastFocusedAriaColindex, rowRenderers, timelineId] - ); - - return ( - - - - -
{RowRendererContent}
-
-
- ); -}; - -export const StatefulEvent = React.memo(StatefulEventComponent); diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/helpers.test.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/helpers.test.tsx index e655037732650..2e2cf23a87df8 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/body/helpers.test.tsx +++ b/x-pack/plugins/timelines/public/components/t_grid/body/helpers.test.tsx @@ -8,13 +8,11 @@ import { omit } from 'lodash/fp'; import { ColumnHeaderOptions } from '../../../../common/types'; -import { Ecs } from '../../../../common/ecs'; import { allowSorting, hasCellActions, mapSortDirectionToDirection, mapSortingColumns, - stringifyEvent, addBuildingBlockStyle, } from './helpers'; @@ -22,173 +20,6 @@ import { euiThemeVars } from '@kbn/ui-theme'; import { mockDnsEvent } from '../../../mock'; describe('helpers', () => { - describe('stringifyEvent', () => { - test('it omits __typename when it appears at arbitrary levels', () => { - const toStringify: Ecs = { - __typename: 'level 0', - _id: '4', - timestamp: '2018-11-08T19:03:25.937Z', - host: { - __typename: 'level 1', - name: ['suricata'], - ip: ['192.168.0.1'], - }, - event: { - id: ['4'], - category: ['Attempted Administrator Privilege Gain'], - type: ['Alert'], - module: ['suricata'], - severity: [1], - }, - source: { - ip: ['192.168.0.3'], - port: [53], - }, - destination: { - ip: ['192.168.0.3'], - port: [6343], - }, - suricata: { - eve: { - flow_id: [4], - proto: [''], - alert: { - signature: ['ET PHONE HOME Stack Overflow (CVE-2019-90210)'], - signature_id: [4], - __typename: 'level 2', - }, - }, - }, - user: { - id: ['4'], - name: ['jack.black'], - }, - geo: { - region_name: ['neither'], - country_iso_code: ['sasquatch'], - }, - } as Ecs; // as cast so that `__typename` can be added for the tests even though it is not part of ECS - const expected: Ecs = { - _id: '4', - timestamp: '2018-11-08T19:03:25.937Z', - host: { - name: ['suricata'], - ip: ['192.168.0.1'], - }, - event: { - id: ['4'], - category: ['Attempted Administrator Privilege Gain'], - type: ['Alert'], - module: ['suricata'], - severity: [1], - }, - source: { - ip: ['192.168.0.3'], - port: [53], - }, - destination: { - ip: ['192.168.0.3'], - port: [6343], - }, - suricata: { - eve: { - flow_id: [4], - proto: [''], - alert: { - signature: ['ET PHONE HOME Stack Overflow (CVE-2019-90210)'], - signature_id: [4], - }, - }, - }, - user: { - id: ['4'], - name: ['jack.black'], - }, - geo: { - region_name: ['neither'], - country_iso_code: ['sasquatch'], - }, - }; - expect(JSON.parse(stringifyEvent(toStringify))).toEqual(expected); - }); - - test('it omits null and undefined values at arbitrary levels, for arbitrary data types', () => { - const expected: Ecs = { - _id: '4', - host: {}, - event: { - id: ['4'], - category: ['theory'], - type: ['Alert'], - module: ['me'], - severity: [1], - }, - source: { - port: [53], - }, - destination: { - ip: ['192.168.0.3'], - port: [6343], - }, - suricata: { - eve: { - flow_id: [4], - proto: [''], - alert: { - signature: ['dance moves'], - }, - }, - }, - user: { - id: ['4'], - name: ['no use for a'], - }, - geo: { - region_name: ['bizzaro'], - country_iso_code: ['world'], - }, - }; - const toStringify: Ecs = { - _id: '4', - host: {}, - event: { - id: ['4'], - category: ['theory'], - type: ['Alert'], - module: ['me'], - severity: [1], - }, - source: { - ip: undefined, - port: [53], - }, - destination: { - ip: ['192.168.0.3'], - port: [6343], - }, - suricata: { - eve: { - flow_id: [4], - proto: [''], - alert: { - signature: ['dance moves'], - signature_id: undefined, - }, - }, - }, - user: { - id: ['4'], - name: ['no use for a'], - }, - geo: { - region_name: ['bizzaro'], - country_iso_code: ['world'], - }, - }; - expect(JSON.parse(stringifyEvent(toStringify))).toEqual(expected); - }); - }); - describe('mapSortDirectionToDirection', () => { test('it returns the expected direction when sortDirection is `asc`', () => { expect(mapSortDirectionToDirection('asc')).toBe('asc'); diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/helpers.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/helpers.tsx index e17bb341b1408..dabaecfdeea2b 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/body/helpers.tsx +++ b/x-pack/plugins/timelines/public/components/t_grid/body/helpers.tsx @@ -20,15 +20,8 @@ import type { ColumnHeaderOptions, SortColumnTimeline, SortDirection, - TimelineEventsType, } from '../../../../common/types/timeline'; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export const omitTypenameAndEmpty = (k: string, v: any): any | undefined => - k !== '__typename' && v != null ? v : undefined; - -export const stringifyEvent = (ecs: Ecs): string => JSON.stringify(ecs, omitTypenameAndEmpty, 2); - /** * Creates mapping of eventID -> fieldData for given fieldsToKeep. Used to store additional field * data necessary for custom timeline actions in conjunction with selection state @@ -76,27 +69,6 @@ export const getEventIdToDataMapping = ( export const isEventBuildingBlockType = (event: Ecs): boolean => !isEmpty(event.kibana?.alert?.building_block_type); -export const isEvenEqlSequence = (event: Ecs): boolean => { - if (!isEmpty(event.eql?.sequenceNumber)) { - try { - const sequenceNumber = (event.eql?.sequenceNumber ?? '').split('-')[0]; - return parseInt(sequenceNumber, 10) % 2 === 0; - } catch { - return false; - } - } - return false; -}; -/** Return eventType raw or signal or eql */ -export const getEventType = (event: Ecs): Omit => { - if (!isEmpty(event.signal?.rule?.id)) { - return 'signal'; - } else if (!isEmpty(event.eql?.parentId)) { - return 'eql'; - } - return 'raw'; -}; - /** Maps (Redux) `SortDirection` to the `direction` values used by `EuiDataGrid` */ export const mapSortDirectionToDirection = (sortDirection: SortDirection): 'asc' | 'desc' => { switch (sortDirection) { diff --git a/x-pack/plugins/timelines/public/components/t_grid/types.ts b/x-pack/plugins/timelines/public/components/t_grid/types.ts index 494e06c9f2e0c..0d7d307b8b05f 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/types.ts +++ b/x-pack/plugins/timelines/public/components/t_grid/types.ts @@ -5,13 +5,4 @@ * 2.0. */ -export type { - OnColumnSorted, - OnColumnsSorted, - OnColumnRemoved, - OnColumnResized, - OnChangePage, - OnRowSelected, - OnSelectAll, - OnUpdateColumns, -} from '../../../common/types/timeline'; +export type { OnChangePage, OnRowSelected, OnSelectAll } from '../../../common/types/timeline'; diff --git a/x-pack/plugins/timelines/tsconfig.json b/x-pack/plugins/timelines/tsconfig.json index 9677c0e64dd88..3063c1acda545 100644 --- a/x-pack/plugins/timelines/tsconfig.json +++ b/x-pack/plugins/timelines/tsconfig.json @@ -20,7 +20,6 @@ { "path": "../../../src/core/tsconfig.json" }, { "path": "../../../src/plugins/data/tsconfig.json" }, { "path": "../../../src/plugins/home/tsconfig.json" }, - { "path": "../data_enhanced/tsconfig.json" }, { "path": "../features/tsconfig.json" }, { "path": "../cases/tsconfig.json" }, { "path": "../licensing/tsconfig.json" }, diff --git a/x-pack/plugins/transform/server/routes/api/field_histograms.ts b/x-pack/plugins/transform/server/routes/api/field_histograms.ts index 25991d7e865c3..c9623f262b5e0 100644 --- a/x-pack/plugins/transform/server/routes/api/field_histograms.ts +++ b/x-pack/plugins/transform/server/routes/api/field_histograms.ts @@ -32,8 +32,9 @@ export function registerFieldHistogramsRoutes({ router, license }: RouteDependen const { query, fields, runtimeMappings, samplerShardSize } = req.body; try { + const esClient = (await ctx.core).elasticsearch.client; const resp = await getHistogramsForFields( - ctx.core.elasticsearch.client, + esClient, dataViewTitle, query, fields, diff --git a/x-pack/plugins/transform/server/routes/api/privileges.ts b/x-pack/plugins/transform/server/routes/api/privileges.ts index d8bce73244c15..bad077100c83a 100644 --- a/x-pack/plugins/transform/server/routes/api/privileges.ts +++ b/x-pack/plugins/transform/server/routes/api/privileges.ts @@ -28,9 +28,10 @@ export function registerPrivilegesRoute({ router, license }: RouteDependencies) return res.ok({ body: privilegesResult }); } + const esClient = (await ctx.core).elasticsearch.client; // Get cluster privileges const { has_all_requested: hasAllPrivileges, cluster } = - await ctx.core.elasticsearch.client.asCurrentUser.security.hasPrivileges({ + await esClient.asCurrentUser.security.hasPrivileges({ body: { // @ts-expect-error SecurityClusterPrivilege doesn’t contain all the priviledges cluster: APP_CLUSTER_PRIVILEGES, @@ -42,8 +43,7 @@ export function registerPrivilegesRoute({ router, license }: RouteDependencies) privilegesResult.hasAllPrivileges = hasAllPrivileges; // Get all index privileges the user has - const { indices } = - await ctx.core.elasticsearch.client.asCurrentUser.security.getUserPrivileges(); + const { indices } = await esClient.asCurrentUser.security.getUserPrivileges(); // Check if they have all the required index privileges for at least one index const oneIndexWithAllPrivileges = indices.find(({ privileges }: { privileges: string[] }) => { diff --git a/x-pack/plugins/transform/server/routes/api/transforms.ts b/x-pack/plugins/transform/server/routes/api/transforms.ts index 252cc2eda5529..f1c5e74056a94 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms.ts @@ -90,15 +90,17 @@ export function registerTransformsRoutes(routeDependencies: RouteDependencies) { license.guardApiRoute( async (ctx, req, res) => { try { - const body = await ctx.core.elasticsearch.client.asCurrentUser.transform.getTransform({ + const esClient = (await ctx.core).elasticsearch.client; + const body = await esClient.asCurrentUser.transform.getTransform({ size: 1000, ...req.params, }); - if (ctx.alerting) { + const alerting = await ctx.alerting; + if (alerting) { const transformHealthService = transformHealthServiceProvider( - ctx.core.elasticsearch.client.asCurrentUser, - ctx.alerting.getRulesClient() + esClient.asCurrentUser, + alerting.getRulesClient() ); // @ts-ignore @@ -130,7 +132,8 @@ export function registerTransformsRoutes(routeDependencies: RouteDependencies) { license.guardApiRoute(async (ctx, req, res) => { const { transformId } = req.params; try { - const body = await ctx.core.elasticsearch.client.asCurrentUser.transform.getTransform({ + const esClient = (await ctx.core).elasticsearch.client; + const body = await esClient.asCurrentUser.transform.getTransform({ transform_id: transformId, }); return res.ok({ body }); @@ -152,11 +155,11 @@ export function registerTransformsRoutes(routeDependencies: RouteDependencies) { license.guardApiRoute( async (ctx, req, res) => { try { - const body = - await ctx.core.elasticsearch.client.asCurrentUser.transform.getTransformStats({ - size: 1000, - transform_id: '_all', - }); + const esClient = (await ctx.core).elasticsearch.client; + const body = await esClient.asCurrentUser.transform.getTransformStats({ + size: 1000, + transform_id: '_all', + }); return res.ok({ body }); } catch (e) { return res.customError(wrapError(wrapEsError(e))); @@ -182,7 +185,8 @@ export function registerTransformsRoutes(routeDependencies: RouteDependencies) { license.guardApiRoute(async (ctx, req, res) => { const { transformId } = req.params; try { - const body = await ctx.core.elasticsearch.client.asCurrentUser.transform.getTransformStats({ + const esClient = (await ctx.core).elasticsearch.client; + const body = await esClient.asCurrentUser.transform.getTransformStats({ transform_id: transformId, }); return res.ok({ body }); @@ -219,7 +223,8 @@ export function registerTransformsRoutes(routeDependencies: RouteDependencies) { errors: [], }; - await ctx.core.elasticsearch.client.asCurrentUser.transform + const esClient = (await ctx.core).elasticsearch.client; + await esClient.asCurrentUser.transform .putTransform({ // @ts-expect-error @elastic/elasticsearch group_by is expected to be optional in TransformPivot body: req.body, @@ -263,7 +268,8 @@ export function registerTransformsRoutes(routeDependencies: RouteDependencies) { const { transformId } = req.params; try { - const body = await ctx.core.elasticsearch.client.asCurrentUser.transform.updateTransform({ + const esClient = (await ctx.core).elasticsearch.client; + const body = await esClient.asCurrentUser.transform.updateTransform({ // @ts-expect-error query doesn't satisfy QueryDslQueryContainer from @elastic/elasticsearch body: req.body, transform_id: transformId, @@ -437,7 +443,8 @@ export function registerTransformsRoutes(routeDependencies: RouteDependencies) { }, license.guardApiRoute(async (ctx, req, res) => { try { - const body = await ctx.core.elasticsearch.client.asCurrentUser.search(req.body); + const esClient = (await ctx.core).elasticsearch.client; + const body = await esClient.asCurrentUser.search(req.body); return res.ok({ body }); } catch (e) { return res.customError(wrapError(wrapEsError(e))); @@ -482,6 +489,10 @@ async function deleteTransforms( const results: DeleteTransformsResponseSchema = {}; + const coreContext = await ctx.core; + const esClient = coreContext.elasticsearch.client; + const soClient = coreContext.savedObjects.client; + for (const transformInfo of transformsInfo) { let destinationIndex: string | undefined; @@ -501,7 +512,7 @@ async function deleteTransforms( if (!shouldForceDelete) { // Grab destination index info to delete try { - const body = await ctx.core.elasticsearch.client.asCurrentUser.transform.getTransform({ + const body = await esClient.asCurrentUser.transform.getTransform({ transform_id: transformId, }); const transformConfig = body.transforms[0]; @@ -525,7 +536,7 @@ async function deleteTransforms( try { // If user does have privilege to delete the index, then delete the index // if no permission then return 403 forbidden - await ctx.core.elasticsearch.client.asCurrentUser.indices.delete({ + await esClient.asCurrentUser.indices.delete({ index: destinationIndex, }); destIndexDeleted.success = true; @@ -537,9 +548,9 @@ async function deleteTransforms( // Delete the data view if there's a data view that matches the name of dest index if (destinationIndex && deleteDestDataView) { try { - const dataViewId = await getDataViewId(destinationIndex, ctx.core.savedObjects.client); + const dataViewId = await getDataViewId(destinationIndex, soClient); if (dataViewId) { - await deleteDestDataViewById(dataViewId, ctx.core.savedObjects.client); + await deleteDestDataViewById(dataViewId, soClient); destDataViewDeleted.success = true; } } catch (deleteDestDataViewError) { @@ -548,7 +559,7 @@ async function deleteTransforms( } try { - await ctx.core.elasticsearch.client.asCurrentUser.transform.deleteTransform({ + await esClient.asCurrentUser.transform.deleteTransform({ transform_id: transformId, force: shouldForceDelete && needToForceDelete, }); @@ -589,6 +600,7 @@ async function resetTransforms( const { transformsInfo } = reqBody; const results: ResetTransformsResponseSchema = {}; + const esClient = (await ctx.core).elasticsearch.client; for (const transformInfo of transformsInfo) { const transformReset: ResponseStatus = { success: false }; @@ -596,7 +608,7 @@ async function resetTransforms( try { try { - await ctx.core.elasticsearch.client.asCurrentUser.transform.resetTransform({ + await esClient.asCurrentUser.transform.resetTransform({ transform_id: transformId, }); transformReset.success = true; @@ -632,12 +644,13 @@ const previewTransformHandler: RequestHandler< > = async (ctx, req, res) => { try { const reqBody = req.body; - const body = await ctx.core.elasticsearch.client.asCurrentUser.transform.previewTransform({ + const esClient = (await ctx.core).elasticsearch.client; + const body = await esClient.asCurrentUser.transform.previewTransform({ body: reqBody, }); if (isLatestTransform(reqBody)) { // for the latest transform mappings properties have to be retrieved from the source - const fieldCapsResponse = await ctx.core.elasticsearch.client.asCurrentUser.fieldCaps({ + const fieldCapsResponse = await esClient.asCurrentUser.fieldCaps({ index: reqBody.source.index, fields: '*', include_unmapped: false, @@ -676,7 +689,8 @@ const startTransformsHandler: RequestHandler< const transformsInfo = req.body; try { - const body = await startTransforms(transformsInfo, ctx.core.elasticsearch.client.asCurrentUser); + const esClient = (await ctx.core).elasticsearch.client; + const body = await startTransforms(transformsInfo, esClient.asCurrentUser); return res.ok({ body, }); @@ -721,8 +735,9 @@ const stopTransformsHandler: RequestHandler< const transformsInfo = req.body; try { + const esClient = (await ctx.core).elasticsearch.client; return res.ok({ - body: await stopTransforms(transformsInfo, ctx.core.elasticsearch.client.asCurrentUser), + body: await stopTransforms(transformsInfo, esClient.asCurrentUser), }); } catch (e) { return res.customError(wrapError(wrapEsError(e))); diff --git a/x-pack/plugins/transform/server/routes/api/transforms_audit_messages.ts b/x-pack/plugins/transform/server/routes/api/transforms_audit_messages.ts index 3004a2bd42a71..bd3e7d101624e 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_audit_messages.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_audit_messages.ts @@ -78,7 +78,8 @@ export function registerTransformsAuditMessagesRoutes({ router, license }: Route } try { - const resp = await ctx.core.elasticsearch.client.asCurrentUser.search({ + const esClient = (await ctx.core).elasticsearch.client; + const resp = await esClient.asCurrentUser.search({ index: ML_DF_NOTIFICATION_INDEX_PATTERN, ignore_unavailable: true, size: SIZE, diff --git a/x-pack/plugins/transform/server/routes/api/transforms_nodes.ts b/x-pack/plugins/transform/server/routes/api/transforms_nodes.ts index 3950354f08d40..426dc3d4fa342 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_nodes.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_nodes.ts @@ -48,11 +48,12 @@ export function registerTransformNodesRoutes({ router, license }: RouteDependenc }, license.guardApiRoute(async (ctx, req, res) => { try { + const esClient = (await ctx.core).elasticsearch.client; // If security is enabled, check that the user has at least permission to // view transforms before calling the _nodes endpoint with the internal user. if (license.getStatus().isSecurityEnabled === true) { const { has_all_requested: hasAllPrivileges } = - await ctx.core.elasticsearch.client.asCurrentUser.security.hasPrivileges({ + await esClient.asCurrentUser.security.hasPrivileges({ body: { // @ts-expect-error SecurityClusterPrivilege doesn’t contain all the priviledges cluster: NODES_INFO_PRIVILEGES, @@ -64,7 +65,7 @@ export function registerTransformNodesRoutes({ router, license }: RouteDependenc } } - const { nodes } = await ctx.core.elasticsearch.client.asInternalUser.nodes.info({ + const { nodes } = await esClient.asInternalUser.nodes.info({ filter_path: `nodes.*.${NODE_ROLES}`, }); diff --git a/x-pack/plugins/transform/server/services/license.ts b/x-pack/plugins/transform/server/services/license.ts index cd98e28d973a0..7a54f45de707b 100644 --- a/x-pack/plugins/transform/server/services/license.ts +++ b/x-pack/plugins/transform/server/services/license.ts @@ -11,7 +11,7 @@ import { KibanaRequest, KibanaResponseFactory, RequestHandler, - RequestHandlerContext, + CustomRequestHandlerContext, } from '@kbn/core/server'; import { LicensingPluginSetup, LicenseType } from '@kbn/licensing-plugin/server'; @@ -29,9 +29,9 @@ interface SetupSettings { defaultErrorMessage: string; } -type TransformRequestHandlerContext = RequestHandlerContext & { +type TransformRequestHandlerContext = CustomRequestHandlerContext<{ alerting?: AlertingApiRequestHandlerContext; -}; +}>; export class License { private licenseStatus: LicenseStatus = { @@ -75,7 +75,7 @@ export class License { const license = this; return function licenseCheck( - ctx: RequestHandlerContext, + ctx: TransformRequestHandlerContext, request: KibanaRequest, response: KibanaResponseFactory ): IKibanaResponse | Promise> { diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 7be6ec5f7b464..a3f72e12dd15a 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -440,28 +440,18 @@ "xpack.lens.indexPattern.dateHistogram.autoAdvancedExplanation": "L'intervalle suit cette logique :", "xpack.lens.indexPattern.dateHistogram.autoBasicExplanation": "L'histogramme des dates automatique divise un champ de données en groupes par intervalle.", "xpack.lens.indexPattern.dateHistogram.autoBoundHeader": "Intervalle cible mesuré", - "xpack.lens.indexPattern.dateHistogram.autoHelpText": "Fonctionnement", - "xpack.lens.indexPattern.dateHistogram.autoInterval": "Personnaliser l'intervalle de temps", "xpack.lens.indexPattern.dateHistogram.autoIntervalHeader": "Intervalle utilisé", "xpack.lens.indexPattern.dateHistogram.autoLongerExplanation": "Pour choisir l'intervalle, Lens divise la plage temporelle spécifiée par le paramètre {targetBarSetting}. Lens calcule le meilleur intervalle pour vos données. Par exemple 30m, 1h et 12. Le nombre maximal de barres est défini par la valeur {maxBarSetting}.", "xpack.lens.indexPattern.dateHistogram.bindToGlobalTimePicker": "Lier au sélecteur d'heure globale", - "xpack.lens.indexPattern.dateHistogram.days": "jours", "xpack.lens.indexPattern.dateHistogram.dropPartialBuckets": "Abandonner les compartiments partiels", "xpack.lens.indexPattern.dateHistogram.dropPartialBucketsHelp": "L’abandon des compartiments partiels est désactivé, car ceux-ci ne peuvent être calculés que pour un champ temporel lié au sélecteur d’heure globale en haut à droite.", "xpack.lens.indexPattern.dateHistogram.globalTimePickerHelp": "Filtrez le champ sélectionné à l’aide du sélecteur d’heure globale en haut à droite. Ce paramètre ne peut pas être désactivé pour le champ temporel par défaut de la vue de données actuelle.", - "xpack.lens.indexPattern.dateHistogram.hours": "heures", "xpack.lens.indexPattern.dateHistogram.includeEmptyRows": "Inclure les lignes vides", - "xpack.lens.indexPattern.dateHistogram.milliseconds": "millisecondes", "xpack.lens.indexPattern.dateHistogram.minimumInterval": "Intervalle minimal", - "xpack.lens.indexPattern.dateHistogram.minutes": "minutes", - "xpack.lens.indexPattern.dateHistogram.month": "mois", "xpack.lens.indexPattern.dateHistogram.moreThanYear": "Plus d'un an", "xpack.lens.indexPattern.dateHistogram.restrictedInterval": "Intervalle fixé à {intervalValue} en raison de restrictions d'agrégation.", - "xpack.lens.indexPattern.dateHistogram.seconds": "secondes", "xpack.lens.indexPattern.dateHistogram.titleHelp": "Fonctionnement de l'histogramme des dates automatique", "xpack.lens.indexPattern.dateHistogram.upTo": "Jusqu'à", - "xpack.lens.indexPattern.dateHistogram.week": "semaine", - "xpack.lens.indexPattern.dateHistogram.year": "an", "xpack.lens.indexPattern.dateHistogramTimeShift": "Dans un calque unique, vous ne pouvez pas combiner un décalage de plage temporelle précédent avec des histogrammes de dates. Utilisez une durée de décalage temporel explicite dans \"{column}\" ou remplacez l’histogramme de dates.", "xpack.lens.indexPattern.decimalPlacesLabel": "Décimales", "xpack.lens.indexPattern.defaultFormatLabel": "Par défaut", @@ -538,7 +528,6 @@ "xpack.lens.indexPattern.incompleteOperation": "(incomplet)", "xpack.lens.indexPattern.intervals": "Intervalles", "xpack.lens.indexPattern.invalidFieldLabel": "Champ non valide. Vérifiez votre vue de données ou choisissez un autre champ.", - "xpack.lens.indexPattern.invalidInterval": "Valeur d'intervalle non valide", "xpack.lens.indexPattern.invalidOperationLabel": "Ce champ ne fonctionne pas avec la fonction sélectionnée.", "xpack.lens.indexPattern.invalidReferenceConfiguration": "La dimension \"{dimensionLabel}\" n'est pas configurée correctement", "xpack.lens.indexPattern.invalidTimeShift": "Décalage non valide. Entrez un entier positif suivi par l'une des unités suivantes : s, m, h, d, w, M, y. Par exemple, 3h pour 3 heures", @@ -573,7 +562,6 @@ "xpack.lens.indexPattern.moving_average.signature": "indicateur : nombre, [window] : nombre", "xpack.lens.indexPattern.movingAverage": "Moyenne mobile", "xpack.lens.indexPattern.movingAverage.basicExplanation": "La moyenne mobile fait glisser une fenêtre sur les données et affiche la valeur moyenne. La moyenne mobile est prise en charge uniquement par les histogrammes des dates.", - "xpack.lens.indexPattern.movingAverage.helpText": "Fonctionnement", "xpack.lens.indexPattern.movingAverage.limitations": "La première valeur de moyenne mobile commence au deuxième élément.", "xpack.lens.indexPattern.movingAverage.longerExplanation": "Pour calculer la moyenne mobile, Lens utilise la moyenne de la fenêtre et applique une politique d'omission pour les blancs. Pour les valeurs manquantes, le groupe est ignoré, et le calcul est effectué sur la valeur suivante.", "xpack.lens.indexPattern.movingAverage.tableExplanation": "Par exemple, avec les données [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], vous pouvez calculer une moyenne mobile simple avec une taille de fenêtre de 5 :", @@ -1974,22 +1962,6 @@ "data.inspector.table.tableLabel": "Tableau {index}", "data.inspector.table.tablesDescription": "Il y a {tablesCount, plural, one {# tableau} other {# tableaux} } au total.", "data.inspector.table.tableSelectorLabel": "Sélectionné :", - "data.kueryAutocomplete.andOperatorDescription": "Nécessite que {bothArguments} soient ''vrai''.", - "data.kueryAutocomplete.andOperatorDescription.bothArgumentsText": "les deux arguments", - "data.kueryAutocomplete.equalOperatorDescription": "{equals} une certaine valeur", - "data.kueryAutocomplete.equalOperatorDescription.equalsText": "égale", - "data.kueryAutocomplete.existOperatorDescription": "{exists} sous un certain format", - "data.kueryAutocomplete.existOperatorDescription.existsText": "existe", - "data.kueryAutocomplete.greaterThanOperatorDescription": "est {greaterThan} une certaine valeur", - "data.kueryAutocomplete.greaterThanOperatorDescription.greaterThanText": "supérieur à", - "data.kueryAutocomplete.greaterThanOrEqualOperatorDescription": "est {greaterThanOrEqualTo} une certaine valeur", - "data.kueryAutocomplete.greaterThanOrEqualOperatorDescription.greaterThanOrEqualToText": "supérieur ou égal à", - "data.kueryAutocomplete.lessThanOperatorDescription": "est {lessThan} une certaine valeur", - "data.kueryAutocomplete.lessThanOperatorDescription.lessThanText": "inférieur à", - "data.kueryAutocomplete.lessThanOrEqualOperatorDescription": "est {lessThanOrEqualTo} une certaine valeur", - "data.kueryAutocomplete.lessThanOrEqualOperatorDescription.lessThanOrEqualToText": "inférieur ou égal à", - "data.kueryAutocomplete.orOperatorDescription": "Nécessite qu’{oneOrMoreArguments} soit ''vrai''.", - "data.kueryAutocomplete.orOperatorDescription.oneOrMoreArgumentsText": "au moins un argument", "data.painlessError.buttonTxt": "Modifier le script", "data.painlessError.painlessScriptedFieldErrorMessage": "Erreur d'exécution du champ d'exécution ou du champ scripté sur le modèle d'indexation {indexPatternName}", "data.parseEsInterval.invalidEsCalendarIntervalErrorMessage": "Intervalle de calendrier non valide : {interval} ; la valeur doit être 1.", @@ -2636,6 +2608,107 @@ "data.searchSessions.sessionService.sessionObjectFetchError": "Échec de récupération des informations de la session de recherche", "data.triggers.applyFilterDescription": "Lorsque le filtre Kibana est appliqué. Peut être un filtre simple ou un filtre de plage.", "data.triggers.applyFilterTitle": "Appliquer le filtre", + "data.mgmt.searchSessions.actionDelete": "Supprimer", + "data.mgmt.searchSessions.actionExtend": "Étendre", + "data.mgmt.searchSessions.actionRename": "Modifier le nom", + "data.mgmt.searchSessions.actions.tooltip.moreActions": "Plus d'actions", + "data.mgmt.searchSessions.api.deleted": "La session de recherche a été supprimée.", + "data.mgmt.searchSessions.api.deletedError": "Impossible de supprimer la session de recherche !", + "data.mgmt.searchSessions.api.extended": "La session de recherche a été étendue.", + "data.mgmt.searchSessions.api.extendError": "Impossible d'étendre la session de recherche !", + "data.mgmt.searchSessions.api.fetchError": "Impossible d'actualiser la page !", + "data.mgmt.searchSessions.api.fetchTimeout": "La récupération des informations de la session de recherche a expiré après {timeout} secondes", + "data.mgmt.searchSessions.api.rename": "La session de recherche a été renommée", + "data.mgmt.searchSessions.api.renameError": "Impossible de renommer la session de recherche", + "data.mgmt.searchSessions.appTitle": "Sessions de recherche", + "data.mgmt.searchSessions.ariaLabel.moreActions": "Plus d'actions", + "data.mgmt.searchSessions.cancelModal.cancelButton": "Annuler", + "data.mgmt.searchSessions.cancelModal.deleteButton": "Supprimer", + "data.mgmt.searchSessions.cancelModal.message": "La suppression de la session de recherche \"{name}\" supprime tous les résultats mis en cache.", + "data.mgmt.searchSessions.cancelModal.title": "Supprimer la session de recherche", + "data.mgmt.searchSessions.extendModal.dontExtendButton": "Annuler", + "data.mgmt.searchSessions.extendModal.extendButton": "Étendre l'expiration", + "data.mgmt.searchSessions.extendModal.extendMessage": "L'expiration de la session de recherche \"{name}\" sera étendue jusqu'à {newExpires}.", + "data.mgmt.searchSessions.extendModal.title": "Étendre l'expiration de la session de recherche", + "data.mgmt.searchSessions.flyoutTitle": "Inspecter", + "data.mgmt.searchSessions.main.backgroundSessionsDocsLinkText": "Documentation", + "data.mgmt.searchSessions.main.sectionDescription": "Gérez vos sessions de recherche enregistrées.", + "data.mgmt.searchSessions.main.sectionTitle": "Sessions de recherche", + "data.mgmt.searchSessions.renameModal.cancelButton": "Annuler", + "data.mgmt.searchSessions.renameModal.renameButton": "Enregistrer", + "data.mgmt.searchSessions.renameModal.searchSessionNameInputLabel": "Nom de la session de recherche", + "data.mgmt.searchSessions.renameModal.title": "Modifier le nom de la session de recherche", + "data.mgmt.searchSessions.search.filterApp": "Application", + "data.mgmt.searchSessions.search.filterStatus": "Statut", + "data.mgmt.searchSessions.search.tools.refresh": "Actualiser", + "data.mgmt.searchSessions.status.expireDateUnknown": "inconnu", + "data.mgmt.searchSessions.status.expiresOn": "Expire le {expireDate}", + "data.mgmt.searchSessions.status.expiresSoonInDays": "Expire dans {numDays} jours", + "data.mgmt.searchSessions.status.expiresSoonInDaysTooltip": "{numDays} jours", + "data.mgmt.searchSessions.status.expiresSoonInHours": "Cette session expire dans {numHours} heures", + "data.mgmt.searchSessions.status.expiresSoonInHoursTooltip": "{numHours} heures", + "data.mgmt.searchSessions.status.label.cancelled": "Annulé", + "data.mgmt.searchSessions.status.label.complete": "Terminé", + "data.mgmt.searchSessions.status.label.error": "Erreur", + "data.mgmt.searchSessions.status.label.expired": "Expiré", + "data.mgmt.searchSessions.status.label.inProgress": "En cours", + "data.mgmt.searchSessions.status.message.cancelled": "Annulé par l'utilisateur", + "data.mgmt.searchSessions.status.message.createdOn": "Expire le {expireDate}", + "data.mgmt.searchSessions.status.message.error": "Erreur : {error}", + "data.mgmt.searchSessions.status.message.expiredOn": "Expiré le {expireDate}", + "data.mgmt.searchSessions.table.headerExpiration": "Expiration", + "data.mgmt.searchSessions.table.headerName": "Nom", + "data.mgmt.searchSessions.table.headerStarted": "Créé", + "data.mgmt.searchSessions.table.headerStatus": "Statut", + "data.mgmt.searchSessions.table.headerType": "Application", + "data.mgmt.searchSessions.table.notRestorableWarning": "La session de recherche va être de nouveau exécutée. Vous pouvez ensuite l'enregistrer pour une utilisation ultérieure.", + "data.mgmt.searchSessions.table.numSearches": "# recherches", + "data.mgmt.searchSessions.table.versionIncompatibleWarning": "Cette session de recherche a été créée dans une instance Kibana exécutant une version différente. Il se peut qu'elle ne soit pas correctement restaurée.", + "data.mgmt.searchSessions.table.mlAppName": "Machine Learning", + "data.search.statusError": "Recherche terminée avec un statut {errorCode}", + "data.search.statusThrow": "Le statut de la recherche a généré un statut d'erreur {message} ({errorCode})", + "data.searchSessionIndicator.cancelButtonText": "Arrêter la session", + "data.searchSessionIndicator.canceledDescriptionText": "Vous visualisez des données incomplètes", + "data.searchSessionIndicator.canceledIconAriaLabel": "La session de recherche s'est arrêtée", + "data.searchSessionIndicator.canceledTitleText": "La session de recherche s'est arrêtée", + "data.searchSessionIndicator.canceledTooltipText": "La session de recherche s'est arrêtée", + "data.searchSessionIndicator.canceledWhenText": "Arrêtée {when}", + "data.searchSessionIndicator.continueInBackgroundButtonText": "Enregistrer la session", + "data.searchSessionIndicator.disabledDueToDisabledGloballyMessage": "Vous ne disposez pas d'autorisations pour gérer les sessions de recherche", + "data.searchSessionIndicator.disabledDueToTimeoutMessage": "Les résultats de la session de recherche ont expiré.", + "data.searchSessionIndicator.loadingInTheBackgroundDescriptionText": "Vous pouvez retourner aux résultats terminés à partir de la page Gestion", + "data.searchSessionIndicator.loadingInTheBackgroundIconAriaLabel": "Session enregistrée en cours", + "data.searchSessionIndicator.loadingInTheBackgroundIconTooltipText": "Session enregistrée en cours", + "data.searchSessionIndicator.loadingInTheBackgroundTitleText": "Session enregistrée en cours", + "data.searchSessionIndicator.loadingInTheBackgroundWhenText": "Débuté {when}", + "data.searchSessionIndicator.loadingResultsDescription": "Enregistrer votre session, poursuivre votre travail et retourner aux résultats terminés", + "data.searchSessionIndicator.loadingResultsIconAriaLabel": "Chargement de la session de recherche", + "data.searchSessionIndicator.loadingResultsIconTooltipText": "Chargement de la session de recherche", + "data.searchSessionIndicator.loadingResultsTitle": "Votre recherche prend un certain temps…", + "data.searchSessionIndicator.loadingResultsWhenText": "Débuté {when}", + "data.searchSessionIndicator.restoredDescriptionText": "Vous affichez des données mises en cache d'une plage temporelle spécifique. La modification de la plage temporelle ou des filtres entraînera la réexécution de la session", + "data.searchSessionIndicator.restoredResultsIconAriaLabel": "Session enregistrée restaurée", + "data.searchSessionIndicator.restoredResultsTooltipText": "Session de recherche restaurée", + "data.searchSessionIndicator.restoredTitleText": "Session de recherche restaurée", + "data.searchSessionIndicator.restoredWhenText": "Terminé {when}", + "data.searchSessionIndicator.resultLoadedInTheBackgroundDescriptionText": "Vous pouvez retourner à ces résultats à partir de la page de gestion", + "data.searchSessionIndicator.resultLoadedInTheBackgroundIconAriaLabel": "Session enregistrée terminée", + "data.searchSessionIndicator.resultLoadedInTheBackgroundIconTooltipText": "Session enregistrée terminée", + "data.searchSessionIndicator.resultLoadedInTheBackgroundTitleText": "Session de recherche enregistrée", + "data.searchSessionIndicator.resultLoadedInTheBackgroundWhenText": "Terminé {when}", + "data.searchSessionIndicator.resultsLoadedDescriptionText": "Enregistrer votre session pour y revenir ultérieurement", + "data.searchSessionIndicator.resultsLoadedIconAriaLabel": "Session de recherche terminée", + "data.searchSessionIndicator.resultsLoadedIconTooltipText": "Session de recherche terminée", + "data.searchSessionIndicator.resultsLoadedText": "Session de recherche terminée", + "data.searchSessionIndicator.resultsLoadedWhenText": "Terminé {when}", + "data.searchSessionIndicator.saveButtonText": "Enregistrer la session", + "data.searchSessionIndicator.viewSearchSessionsLinkText": "Gérer les sessions", + "data.searchSessionName.ariaLabelText": "Nom de la session de recherche", + "data.searchSessionName.editAriaLabelText": "Modifier le nom de la session de recherche", + "data.searchSessionName.placeholderText": "Entrer un nom pour la session de recherche", + "data.searchSessionName.saveButtonText": "Enregistrer", + "data.sessions.management.flyoutText": "Configuration de cette session de recherche", + "data.sessions.management.flyoutTitle": "Inspecter la session de recherche", "dataViews.deprecations.scriptedFields.manualStepOneMessage": "Accédez à Gestion de la Suite > Kibana > Vues de données.", "dataViews.deprecations.scriptedFields.manualStepTwoMessage": "Mettez à jour les vues de données {numberOfIndexPatternsWithScriptedFields} qui ont des champs scriptés pour qu’elles utilisent des champs d’exécution. Dans la plupart des cas, pour migrer des scripts existants, vous devrez remplacer \"return ;\" par \"emit();\". Vues de données avec au moins un champ scripté : {allTitles}", "dataViews.deprecations.scriptedFieldsMessage": "Vous avez {numberOfIndexPatternsWithScriptedFields} vues de données ({titlesPreview}...) qui utilisent des champs scriptés. Les champs scriptés sont déclassés et seront supprimés à l’avenir. Utilisez plutôt des champs d’exécution.", @@ -2648,6 +2721,121 @@ "dataViews.unableWriteLabel": "Impossible d’écrire la vue de données ! Actualisez la page pour obtenir la dernière version de cette vue de données.", "devTools.badge.betaLabel": "Bêta", "devTools.badge.betaTooltipText": "Cette fonctionnalité pourra considérablement changer dans les futures versions", + "unifiedSearch.search.unableToGetSavedQueryToastTitle": "Impossible de charger la requête enregistrée {savedQueryId}", + "unifiedSearch.noDataPopover.content": "Cette plage temporelle ne contient pas de données. Étendez ou ajustez la plage temporelle pour obtenir plus de champs et pouvoir créer des graphiques.", + "unifiedSearch.noDataPopover.dismissAction": "Ne plus afficher", + "unifiedSearch.noDataPopover.subtitle": "Conseil", + "unifiedSearch.noDataPopover.title": "Ensemble de données vide", + "unifiedSearch.query.queryBar.clearInputLabel": "Effacer l'entrée", + "unifiedSearch.query.queryBar.comboboxAriaLabel": "Rechercher et filtrer la page {pageType}", + "unifiedSearch.query.queryBar.kqlFullLanguageName": "Langage de requête Kibana", + "unifiedSearch.query.queryBar.kqlLanguageName": "KQL", + "unifiedSearch.query.queryBar.KQLNestedQuerySyntaxInfoDocLinkText": "documents", + "unifiedSearch.query.queryBar.KQLNestedQuerySyntaxInfoOptOutText": "Ne plus afficher", + "unifiedSearch.query.queryBar.KQLNestedQuerySyntaxInfoText": "Il semblerait que votre requête porte sur un champ imbriqué. Selon le résultat visé, il existe plusieurs façons de construire une syntaxe KQL pour des requêtes imbriquées. Apprenez-en plus avec notre {link}.", + "unifiedSearch.query.queryBar.KQLNestedQuerySyntaxInfoTitle": "Syntaxe de requête imbriquée KQL", + "unifiedSearch.query.queryBar.kqlOffLabel": "Désactivé", + "unifiedSearch.query.queryBar.kqlOnLabel": "Activé", + "unifiedSearch.query.queryBar.languageSwitcher.toText": "Passer au langage de requête Kibana pour la recherche", + "unifiedSearch.query.queryBar.luceneLanguageName": "Lucene", + "unifiedSearch.query.queryBar.searchInputAriaLabel": "Commencer à taper pour rechercher et filtrer la page {pageType}", + "unifiedSearch.query.queryBar.searchInputPlaceholder": "Recherche", + "unifiedSearch.query.queryBar.syntaxOptionsDescription": "{docsLink} (KQL) offre une syntaxe de requête simplifiée et la prise en charge des champs scriptés. KQL offre également une fonctionnalité de saisie semi-automatique. Si vous désactivez KQL, {nonKqlModeHelpText}.", + "unifiedSearch.query.queryBar.syntaxOptionsDescription.nonKqlModeHelpText": "Kibana utilise Lucene.", + "unifiedSearch.search.searchBar.savedQueryDescriptionLabelText": "Description", + "unifiedSearch.search.searchBar.savedQueryDescriptionText": "Enregistrez le texte et les filtres de la requête que vous souhaitez réutiliser.", + "unifiedSearch.search.searchBar.savedQueryForm.titleConflictText": "Ce nom est en conflit avec une requête enregistrée existante.", + "unifiedSearch.search.searchBar.savedQueryFormCancelButtonText": "Annuler", + "unifiedSearch.search.searchBar.savedQueryFormSaveButtonText": "Enregistrer", + "unifiedSearch.search.searchBar.savedQueryFormTitle": "Enregistrer la requête", + "unifiedSearch.search.searchBar.savedQueryIncludeFiltersLabelText": "Inclure les filtres", + "unifiedSearch.search.searchBar.savedQueryIncludeTimeFilterLabelText": "Inclure le filtre temporel", + "unifiedSearch.search.searchBar.savedQueryNameHelpText": "Un nom est requis. Le nom ne peut pas contenir d'espace vide au début ou à la fin. Le nom doit être unique.", + "unifiedSearch.search.searchBar.savedQueryNameLabelText": "Nom", + "unifiedSearch.search.searchBar.savedQueryNoSavedQueriesText": "Aucune requête enregistrée.", + "unifiedSearch.search.searchBar.savedQueryPopoverButtonText": "Voir les requêtes enregistrées", + "unifiedSearch.search.searchBar.savedQueryPopoverClearButtonAriaLabel": "Effacer la requête enregistrée en cours", + "unifiedSearch.search.searchBar.savedQueryPopoverClearButtonText": "Effacer", + "unifiedSearch.search.searchBar.savedQueryPopoverConfirmDeletionCancelButtonText": "Annuler", + "unifiedSearch.search.searchBar.savedQueryPopoverConfirmDeletionConfirmButtonText": "Supprimer", + "unifiedSearch.search.searchBar.savedQueryPopoverConfirmDeletionTitle": "Supprimer \"{savedQueryName}\" ?", + "unifiedSearch.search.searchBar.savedQueryPopoverDeleteButtonAriaLabel": "Supprimer la requête enregistrée {savedQueryName}", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveAsNewButtonAriaLabel": "Enregistrer en tant que nouvelle requête enregistrée", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveAsNewButtonText": "Enregistrer en tant que nouvelle", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveButtonAriaLabel": "Enregistrer une nouvelle requête enregistrée", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveButtonText": "Enregistrer la requête en cours", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveChangesButtonAriaLabel": "Enregistrer les modifications apportées à {title}", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveChangesButtonText": "Enregistrer les modifications", + "unifiedSearch.search.searchBar.savedQueryPopoverSavedQueryListItemButtonAriaLabel": "Bouton de requête enregistrée {savedQueryName}", + "unifiedSearch.search.searchBar.savedQueryPopoverSavedQueryListItemDescriptionAriaLabel": "Description de {savedQueryName}", + "unifiedSearch.search.searchBar.savedQueryPopoverSavedQueryListItemSelectedButtonAriaLabel": "Bouton de requête enregistrée {savedQueryName} sélectionné. Appuyez pour effacer les modifications.", + "unifiedSearch.search.searchBar.savedQueryPopoverTitleText": "Requêtes enregistrées", + "unifiedSearch.query.queryBar.syntaxOptionsTitle": "Options de syntaxe", + "unifiedSearch.filter.applyFilterActionTitle": "Appliquer le filtre à la vue en cours", + "unifiedSearch.filter.applyFilters.popupHeader": "Sélectionner les filtres à appliquer", + "unifiedSearch.filter.applyFiltersPopup.cancelButtonLabel": "Annuler", + "unifiedSearch.filter.applyFiltersPopup.saveButtonLabel": "Appliquer", + "unifiedSearch.filter.filterBar.addFilterButtonLabel": "Ajouter un filtre", + "unifiedSearch.filter.filterBar.deleteFilterButtonLabel": "Supprimer", + "unifiedSearch.filter.filterBar.disabledFilterPrefix": "Désactivé", + "unifiedSearch.filter.filterBar.disableFilterButtonLabel": "Désactiver temporairement", + "unifiedSearch.filter.filterBar.editFilterButtonLabel": "Modifier le filtre", + "unifiedSearch.filter.filterBar.enableFilterButtonLabel": "Réactiver", + "unifiedSearch.filter.filterBar.excludeFilterButtonLabel": "Exclure les résultats", + "unifiedSearch.filter.filterBar.filterItemBadgeAriaLabel": "Actions de filtrage", + "unifiedSearch.filter.filterBar.filterItemBadgeIconAriaLabel": "Supprimer {filter}", + "unifiedSearch.filter.filterBar.includeFilterButtonLabel": "Inclure les résultats", + "unifiedSearch.filter.filterBar.indexPatternSelectPlaceholder": "Sélectionner un modèle d'indexation", + "unifiedSearch.filter.filterBar.labelErrorInfo": "Modèle d'indexation {indexPattern} introuvable", + "unifiedSearch.filter.filterBar.labelErrorText": "Erreur", + "unifiedSearch.filter.filterBar.labelWarningInfo": "Le champ {fieldName} n'existe pas dans la vue en cours.", + "unifiedSearch.filter.filterBar.labelWarningText": "Avertissement", + "unifiedSearch.filter.filterBar.moreFilterActionsMessage": "Filtre : {innerText}. Sélectionner pour plus d’actions de filtrage.", + "unifiedSearch.filter.filterBar.negatedFilterPrefix": "NON ", + "unifiedSearch.filter.filterBar.pinFilterButtonLabel": "Épingler dans toutes les applications", + "unifiedSearch.filter.filterBar.pinnedFilterPrefix": "Épinglé", + "unifiedSearch.filter.filterBar.unpinFilterButtonLabel": "Désépingler", + "unifiedSearch.filter.filterEditor.cancelButtonLabel": "Annuler", + "unifiedSearch.filter.filterEditor.createCustomLabelInputLabel": "Étiquette personnalisée", + "unifiedSearch.filter.filterEditor.createCustomLabelSwitchLabel": "Créer une étiquette personnalisée ?", + "unifiedSearch.filter.filterEditor.doesNotExistOperatorOptionLabel": "n'existe pas", + "unifiedSearch.filter.filterEditor.editFilterPopupTitle": "Modifier le filtre", + "unifiedSearch.filter.filterEditor.editFilterValuesButtonLabel": "Modifier les valeurs du filtre", + "unifiedSearch.filter.filterEditor.editQueryDslButtonLabel": "Modifier en tant que Query DSL", + "unifiedSearch.filter.filterEditor.existsOperatorOptionLabel": "existe", + "unifiedSearch.filter.filterEditor.falseOptionLabel": "false", + "unifiedSearch.filter.filterEditor.fieldSelectLabel": "Champ", + "unifiedSearch.filter.filterEditor.fieldSelectPlaceholder": "Sélectionner d'abord un champ", + "unifiedSearch.filter.filterEditor.indexPatternSelectLabel": "Modèle d'indexation", + "unifiedSearch.filter.filterEditor.isBetweenOperatorOptionLabel": "est entre", + "unifiedSearch.filter.filterEditor.isNotBetweenOperatorOptionLabel": "n'est pas entre", + "unifiedSearch.filter.filterEditor.isNotOneOfOperatorOptionLabel": "n'est pas l'une des options suivantes", + "unifiedSearch.filter.filterEditor.isNotOperatorOptionLabel": "n'est pas", + "unifiedSearch.filter.filterEditor.isOneOfOperatorOptionLabel": "est l'une des options suivantes", + "unifiedSearch.filter.filterEditor.isOperatorOptionLabel": "est", + "unifiedSearch.filter.filterEditor.operatorSelectLabel": "Opérateur", + "unifiedSearch.filter.filterEditor.operatorSelectPlaceholderSelect": "Sélectionner", + "unifiedSearch.filter.filterEditor.operatorSelectPlaceholderWaiting": "En attente", + "unifiedSearch.filter.filterEditor.queryDslLabel": "Query DSL d'Elasticsearch", + "unifiedSearch.filter.filterEditor.rangeEndInputPlaceholder": "Fin de la plage", + "unifiedSearch.filter.filterEditor.rangeInputLabel": "Plage", + "unifiedSearch.filter.filterEditor.rangeStartInputPlaceholder": "Début de la plage", + "unifiedSearch.filter.filterEditor.saveButtonLabel": "Enregistrer", + "unifiedSearch.filter.filterEditor.trueOptionLabel": "vrai", + "unifiedSearch.filter.filterEditor.valueInputLabel": "Valeur", + "unifiedSearch.filter.filterEditor.valueInputPlaceholder": "Saisir une valeur", + "unifiedSearch.filter.filterEditor.valueSelectPlaceholder": "Sélectionner une valeur", + "unifiedSearch.filter.filterEditor.valuesSelectLabel": "Valeurs", + "unifiedSearch.filter.filterEditor.valuesSelectPlaceholder": "Sélectionner des valeurs", + "unifiedSearch.filter.options.changeAllFiltersButtonLabel": "Changer tous les filtres", + "unifiedSearch.filter.options.deleteAllFiltersButtonLabel": "Tout supprimer", + "unifiedSearch.filter.options.disableAllFiltersButtonLabel": "Tout désactiver", + "unifiedSearch.filter.options.enableAllFiltersButtonLabel": "Tout activer", + "unifiedSearch.filter.options.invertDisabledFiltersButtonLabel": "Inverser l’activation/désactivation", + "unifiedSearch.filter.options.invertNegatedFiltersButtonLabel": "Inverser l'inclusion", + "unifiedSearch.filter.options.pinAllFiltersButtonLabel": "Tout épingler", + "unifiedSearch.filter.options.unpinAllFiltersButtonLabel": "Tout désépingler", + "unifiedSearch.filter.searchBar.changeAllFiltersTitle": "Changer tous les filtres", "devTools.badge.readOnly.text": "Lecture seule", "devTools.badge.readOnly.tooltip": "Enregistrement impossible", "devTools.breadcrumb.homeLabel": "Outils de développement", @@ -7292,7 +7480,6 @@ "xpack.apm.filter.environment.allLabel": "Tous", "xpack.apm.filter.environment.label": "Environnement", "xpack.apm.filter.environment.notDefinedLabel": "Non défini", - "xpack.apm.filter.environment.selectEnvironmentLabel": "Sélectionner l'environnement", "xpack.apm.fleet_integration.settings.advancedOptionsLavel": "Options avancées", "xpack.apm.fleet_integration.settings.agentAuthorization.anonymousAllowAgentHelpText": "Noms d'agents autorisés pour l'accès anonyme.", "xpack.apm.fleet_integration.settings.agentAuthorization.anonymousAllowAgentLabel": "Agents autorisés", @@ -7519,7 +7706,6 @@ "xpack.apm.propertiesTable.tabs.metadataLabel": "Métadonnées", "xpack.apm.propertiesTable.tabs.timelineLabel": "Chronologie", "xpack.apm.searchInput.filter": "Filtrer…", - "xpack.apm.selectCustomOptionText": "Ajouter \\{searchValue\\} en tant que nouvelle option", "xpack.apm.selectPlaceholder": "Sélectionner une option :", "xpack.apm.serviceDependencies.breakdownChartTitle": "Temps consacré par dépendance", "xpack.apm.serviceDetails.dependenciesTabLabel": "Dépendances", @@ -10055,7 +10241,6 @@ "xpack.csp.passed": "Approuvé", "xpack.csp.posture_score": "Score du niveau", "xpack.csp.posture_score_trend": "Tendance du score du niveau", - "xpack.csp.resource_type": "Type de ressource", "xpack.csp.rules.activateAllButtonLabel": "Activer {count, plural, one {# règle} other {# règles}}", "xpack.csp.rules.bulkActionsButtonLabel": "Actions groupées", "xpack.csp.rules.cancelButtonLabel": "Annuler", @@ -10091,107 +10276,6 @@ "xpack.dashboard.drilldown.goToDashboard": "Accéder au tableau de bord", "xpack.dashboard.FlyoutCreateDrilldownAction.displayName": "Créer une recherche", "xpack.dashboard.panel.openFlyoutEditDrilldown.displayName": "Gérer les recherches", - "xpack.data.mgmt.searchSessions.actionDelete": "Supprimer", - "xpack.data.mgmt.searchSessions.actionExtend": "Étendre", - "xpack.data.mgmt.searchSessions.actionRename": "Modifier le nom", - "xpack.data.mgmt.searchSessions.actions.tooltip.moreActions": "Plus d'actions", - "xpack.data.mgmt.searchSessions.api.deleted": "La session de recherche a été supprimée.", - "xpack.data.mgmt.searchSessions.api.deletedError": "Impossible de supprimer la session de recherche !", - "xpack.data.mgmt.searchSessions.api.extended": "La session de recherche a été étendue.", - "xpack.data.mgmt.searchSessions.api.extendError": "Impossible d'étendre la session de recherche !", - "xpack.data.mgmt.searchSessions.api.fetchError": "Impossible d'actualiser la page !", - "xpack.data.mgmt.searchSessions.api.fetchTimeout": "La récupération des informations de la session de recherche a expiré après {timeout} secondes", - "xpack.data.mgmt.searchSessions.api.rename": "La session de recherche a été renommée", - "xpack.data.mgmt.searchSessions.api.renameError": "Impossible de renommer la session de recherche", - "xpack.data.mgmt.searchSessions.appTitle": "Sessions de recherche", - "xpack.data.mgmt.searchSessions.ariaLabel.moreActions": "Plus d'actions", - "xpack.data.mgmt.searchSessions.cancelModal.cancelButton": "Annuler", - "xpack.data.mgmt.searchSessions.cancelModal.deleteButton": "Supprimer", - "xpack.data.mgmt.searchSessions.cancelModal.message": "La suppression de la session de recherche \"{name}\" supprime tous les résultats mis en cache.", - "xpack.data.mgmt.searchSessions.cancelModal.title": "Supprimer la session de recherche", - "xpack.data.mgmt.searchSessions.extendModal.dontExtendButton": "Annuler", - "xpack.data.mgmt.searchSessions.extendModal.extendButton": "Étendre l'expiration", - "xpack.data.mgmt.searchSessions.extendModal.extendMessage": "L'expiration de la session de recherche \"{name}\" sera étendue jusqu'à {newExpires}.", - "xpack.data.mgmt.searchSessions.extendModal.title": "Étendre l'expiration de la session de recherche", - "xpack.data.mgmt.searchSessions.flyoutTitle": "Inspecter", - "xpack.data.mgmt.searchSessions.main.backgroundSessionsDocsLinkText": "Documentation", - "xpack.data.mgmt.searchSessions.main.sectionDescription": "Gérez vos sessions de recherche enregistrées.", - "xpack.data.mgmt.searchSessions.main.sectionTitle": "Sessions de recherche", - "xpack.data.mgmt.searchSessions.renameModal.cancelButton": "Annuler", - "xpack.data.mgmt.searchSessions.renameModal.renameButton": "Enregistrer", - "xpack.data.mgmt.searchSessions.renameModal.searchSessionNameInputLabel": "Nom de la session de recherche", - "xpack.data.mgmt.searchSessions.renameModal.title": "Modifier le nom de la session de recherche", - "xpack.data.mgmt.searchSessions.search.filterApp": "Application", - "xpack.data.mgmt.searchSessions.search.filterStatus": "Statut", - "xpack.data.mgmt.searchSessions.search.tools.refresh": "Actualiser", - "xpack.data.mgmt.searchSessions.status.expireDateUnknown": "inconnu", - "xpack.data.mgmt.searchSessions.status.expiresOn": "Expire le {expireDate}", - "xpack.data.mgmt.searchSessions.status.expiresSoonInDays": "Expire dans {numDays} jours", - "xpack.data.mgmt.searchSessions.status.expiresSoonInDaysTooltip": "{numDays} jours", - "xpack.data.mgmt.searchSessions.status.expiresSoonInHours": "Cette session expire dans {numHours} heures", - "xpack.data.mgmt.searchSessions.status.expiresSoonInHoursTooltip": "{numHours} heures", - "xpack.data.mgmt.searchSessions.status.label.cancelled": "Annulé", - "xpack.data.mgmt.searchSessions.status.label.complete": "Terminé", - "xpack.data.mgmt.searchSessions.status.label.error": "Erreur", - "xpack.data.mgmt.searchSessions.status.label.expired": "Expiré", - "xpack.data.mgmt.searchSessions.status.label.inProgress": "En cours", - "xpack.data.mgmt.searchSessions.status.message.cancelled": "Annulé par l'utilisateur", - "xpack.data.mgmt.searchSessions.status.message.createdOn": "Expire le {expireDate}", - "xpack.data.mgmt.searchSessions.status.message.error": "Erreur : {error}", - "xpack.data.mgmt.searchSessions.status.message.expiredOn": "Expiré le {expireDate}", - "xpack.data.mgmt.searchSessions.table.headerExpiration": "Expiration", - "xpack.data.mgmt.searchSessions.table.headerName": "Nom", - "xpack.data.mgmt.searchSessions.table.headerStarted": "Créé", - "xpack.data.mgmt.searchSessions.table.headerStatus": "Statut", - "xpack.data.mgmt.searchSessions.table.headerType": "Application", - "xpack.data.mgmt.searchSessions.table.mlAppName": "Machine Learning", - "xpack.data.mgmt.searchSessions.table.notRestorableWarning": "La session de recherche va être de nouveau exécutée. Vous pouvez ensuite l'enregistrer pour une utilisation ultérieure.", - "xpack.data.mgmt.searchSessions.table.numSearches": "# recherches", - "xpack.data.mgmt.searchSessions.table.versionIncompatibleWarning": "Cette session de recherche a été créée dans une instance Kibana exécutant une version différente. Il se peut qu'elle ne soit pas correctement restaurée.", - "xpack.data.search.statusError": "Recherche terminée avec un statut {errorCode}", - "xpack.data.search.statusThrow": "Le statut de la recherche a généré un statut d'erreur {message} ({errorCode})", - "xpack.data.searchSessionIndicator.cancelButtonText": "Arrêter la session", - "xpack.data.searchSessionIndicator.canceledDescriptionText": "Vous visualisez des données incomplètes", - "xpack.data.searchSessionIndicator.canceledIconAriaLabel": "La session de recherche s'est arrêtée", - "xpack.data.searchSessionIndicator.canceledTitleText": "La session de recherche s'est arrêtée", - "xpack.data.searchSessionIndicator.canceledTooltipText": "La session de recherche s'est arrêtée", - "xpack.data.searchSessionIndicator.canceledWhenText": "Arrêtée {when}", - "xpack.data.searchSessionIndicator.continueInBackgroundButtonText": "Enregistrer la session", - "xpack.data.searchSessionIndicator.disabledDueToDisabledGloballyMessage": "Vous ne disposez pas d'autorisations pour gérer les sessions de recherche", - "xpack.data.searchSessionIndicator.disabledDueToTimeoutMessage": "Les résultats de la session de recherche ont expiré.", - "xpack.data.searchSessionIndicator.loadingInTheBackgroundDescriptionText": "Vous pouvez retourner aux résultats terminés à partir de la page Gestion", - "xpack.data.searchSessionIndicator.loadingInTheBackgroundIconAriaLabel": "Session enregistrée en cours", - "xpack.data.searchSessionIndicator.loadingInTheBackgroundIconTooltipText": "Session enregistrée en cours", - "xpack.data.searchSessionIndicator.loadingInTheBackgroundTitleText": "Session enregistrée en cours", - "xpack.data.searchSessionIndicator.loadingInTheBackgroundWhenText": "Débuté {when}", - "xpack.data.searchSessionIndicator.loadingResultsDescription": "Enregistrer votre session, poursuivre votre travail et retourner aux résultats terminés", - "xpack.data.searchSessionIndicator.loadingResultsIconAriaLabel": "Chargement de la session de recherche", - "xpack.data.searchSessionIndicator.loadingResultsIconTooltipText": "Chargement de la session de recherche", - "xpack.data.searchSessionIndicator.loadingResultsTitle": "Votre recherche prend un certain temps…", - "xpack.data.searchSessionIndicator.loadingResultsWhenText": "Débuté {when}", - "xpack.data.searchSessionIndicator.restoredDescriptionText": "Vous affichez des données mises en cache d'une plage temporelle spécifique. La modification de la plage temporelle ou des filtres entraînera la réexécution de la session", - "xpack.data.searchSessionIndicator.restoredResultsIconAriaLabel": "Session enregistrée restaurée", - "xpack.data.searchSessionIndicator.restoredResultsTooltipText": "Session de recherche restaurée", - "xpack.data.searchSessionIndicator.restoredTitleText": "Session de recherche restaurée", - "xpack.data.searchSessionIndicator.restoredWhenText": "Terminé {when}", - "xpack.data.searchSessionIndicator.resultLoadedInTheBackgroundDescriptionText": "Vous pouvez retourner à ces résultats à partir de la page de gestion", - "xpack.data.searchSessionIndicator.resultLoadedInTheBackgroundIconAriaLabel": "Session enregistrée terminée", - "xpack.data.searchSessionIndicator.resultLoadedInTheBackgroundIconTooltipText": "Session enregistrée terminée", - "xpack.data.searchSessionIndicator.resultLoadedInTheBackgroundTitleText": "Session de recherche enregistrée", - "xpack.data.searchSessionIndicator.resultLoadedInTheBackgroundWhenText": "Terminé {when}", - "xpack.data.searchSessionIndicator.resultsLoadedDescriptionText": "Enregistrer votre session pour y revenir ultérieurement", - "xpack.data.searchSessionIndicator.resultsLoadedIconAriaLabel": "Session de recherche terminée", - "xpack.data.searchSessionIndicator.resultsLoadedIconTooltipText": "Session de recherche terminée", - "xpack.data.searchSessionIndicator.resultsLoadedText": "Session de recherche terminée", - "xpack.data.searchSessionIndicator.resultsLoadedWhenText": "Terminé {when}", - "xpack.data.searchSessionIndicator.saveButtonText": "Enregistrer la session", - "xpack.data.searchSessionIndicator.viewSearchSessionsLinkText": "Gérer les sessions", - "xpack.data.searchSessionName.ariaLabelText": "Nom de la session de recherche", - "xpack.data.searchSessionName.editAriaLabelText": "Modifier le nom de la session de recherche", - "xpack.data.searchSessionName.placeholderText": "Entrer un nom pour la session de recherche", - "xpack.data.searchSessionName.saveButtonText": "Enregistrer", - "xpack.data.sessions.management.flyoutText": "Configuration de cette session de recherche", - "xpack.data.sessions.management.flyoutTitle": "Inspecter la session de recherche", "xpack.dataVisualizer.addCombinedFieldsLabel": "Ajouter un champ combiné", "xpack.dataVisualizer.choroplethMap.topValuesCount": "Compte des valeurs les plus élevées pour {fieldName}", "xpack.dataVisualizer.chrome.help.appName": "Data Visualizer (Visualiseur de données)", @@ -11416,8 +11500,6 @@ "xpack.enterpriseSearch.overview.productCard.setupButton": "Configurer {productName}", "xpack.enterpriseSearch.overview.productName": "Enterprise Search", "xpack.enterpriseSearch.overview.setupCta.description": "Ajoutez des fonctions de recherche à votre application ou à votre organisation interne avec Elastic App Search et Workplace Search. Regardez la vidéo pour savoir ce qu'il est possible de faire lorsque la recherche est facilitée.", - "xpack.enterpriseSearch.overview.setupHeading": "Choisissez un produit à configurer et lancez-vous.", - "xpack.enterpriseSearch.overview.subheading": "Ajoutez une fonction de recherche à votre application ou à votre organisation.", "xpack.enterpriseSearch.productSelectorCalloutTitle": "Des fonctionnalités de niveau entreprise pour les grandes et petites équipes", "xpack.enterpriseSearch.readOnlyMode.warning": "Enterprise Search est en mode de lecture seule. Vous ne pourrez pas effectuer de changements tels que création, modification ou suppression.", "xpack.enterpriseSearch.roleMapping.addRoleMappingButtonLabel": "Ajouter un mapping", @@ -11828,7 +11910,6 @@ "xpack.enterpriseSearch.workplaceSearch.groups.newGroup.action": "Gérer le groupe", "xpack.enterpriseSearch.workplaceSearch.groups.newGroupSavedSuccess": "{groupName} créé avec succès", "xpack.enterpriseSearch.workplaceSearch.groups.noSourcesMessage": "Aucune source de contenu organisationnelle", - "xpack.enterpriseSearch.workplaceSearch.groups.noUsersMessage": "Aucun utilisateur", "xpack.enterpriseSearch.workplaceSearch.groups.overview.confirmRemoveButtonText": "Supprimer {name}", "xpack.enterpriseSearch.workplaceSearch.groups.overview.confirmRemoveDescription": "Votre groupe sera supprimé de Workplace Search. Voulez-vous vraiment supprimer {name} ?", "xpack.enterpriseSearch.workplaceSearch.groups.overview.confirmTitleText": "Confirmer", @@ -12807,7 +12888,6 @@ "xpack.fleet.fleetServerSetup.cloudDeploymentLink": "Modifier le déploiement", "xpack.fleet.fleetServerSetup.cloudSetupText": "Un serveur Fleet est nécessaire pour enregistrer des agents avec Fleet. Le moyen le plus simple d’en obtenir un est d’ajouter un serveur d’intégration, qui prend en charge l’intégration du serveur Fleet. Vous pouvez l’ajouter à votre déploiement dans la console cloud. Pour en savoir plus, consultez {link}", "xpack.fleet.fleetServerSetup.cloudSetupTitle": "Activer un serveur Fleet", - "xpack.fleet.fleetServerSetup.continueButton": "Continuer", "xpack.fleet.fleetServerSetup.deploymentModeProductionOption": "{production} : fournissez vos propres certificats. Cette option demande aux agents de préciser une clé de certificat lors de leur enregistrement avec Fleet", "xpack.fleet.fleetServerSetup.deploymentModeQuickStartOption": "{quickStart} : le serveur Fleet génère un certificat autosigné. Les agents suivants doivent être enregistrés avec l'indicateur --insecure. Non recommandé pour les cas d'utilisation en production.", "xpack.fleet.fleetServerSetup.errorAddingFleetServerHostTitle": "Erreur lors de l'ajout de l'hôte du serveur Fleet", @@ -12816,23 +12896,16 @@ "xpack.fleet.fleetServerSetup.fleetSettingsLink": "Paramètres de Fleet", "xpack.fleet.fleetServerSetup.generateServiceTokenButton": "Générer un jeton de service", "xpack.fleet.fleetServerSetup.generateServiceTokenDescription": "Un jeton de service accorde au serveur Fleet les autorisations en écriture nécessaires dans Elasticsearch.", - "xpack.fleet.fleetServerSetup.installAgentDescription": "Depuis le répertoire de l'agent, copiez et exécutez la commande de démarrage rapide appropriée pour lancer un agent Elastic en tant que serveur Fleet à l'aide du jeton généré et d'un certificat autosigné. Reportez-vous au {userGuideLink} pour obtenir les instructions d'utilisation de vos propres certificats à des fins de déploiement de production. Toutes les commandes nécessitent des privilèges d'administrateur.", "xpack.fleet.fleetServerSetup.productionText": "Production", "xpack.fleet.fleetServerSetup.quickStartText": "Démarrage rapide", "xpack.fleet.fleetServerSetup.saveServiceTokenDescription": "Enregistrez les informations de votre jeton de service. Ce message s'affiche une seule fois.", "xpack.fleet.fleetServerSetup.serviceTokenLabel": "Jeton de service", "xpack.fleet.fleetServerSetup.setupGuideLink": "Guide de Fleet et d’Elastic Agent", - "xpack.fleet.fleetServerSetup.setupText": "Un serveur Fleet est nécessaire pour enregistrer des agents avec Fleet. Suivez les instructions ci-après pour configurer un serveur Fleet. Pour en savoir plus, consultez le {userGuideLink}.", - "xpack.fleet.fleetServerSetup.setupTitle": "Ajouter un serveur Fleet", "xpack.fleet.fleetServerSetup.stepCreateAgentPolicyTitle": "Créer une stratégie d’agent pour héberger le serveur Fleet", "xpack.fleet.fleetServerSetup.stepDeploymentModeDescriptionText": "Fleet utilise le protocole TLS (Transport Layer Security) pour chiffrer le trafic entre les agents Elastic et d'autres composants de la Suite Elastic. Sélectionnez un mode de déploiement pour définir comment vous souhaitez gérer les certificats. Votre sélection impactera la commande de configuration du serveur Fleet qui s'affichera à une étape ultérieure.", "xpack.fleet.fleetServerSetup.stepDeploymentModeTitle": "Sélectionner un mode de déploiement pour Security", - "xpack.fleet.fleetServerSetup.stepFleetServerCompleteDescription": "Vous pouvez désormais enregistrer des agents avec Fleet.", - "xpack.fleet.fleetServerSetup.stepFleetServerCompleteTitle": "Serveur Fleet connecté", "xpack.fleet.fleetServerSetup.stepGenerateServiceTokenTitle": "Générer un jeton de service", - "xpack.fleet.fleetServerSetup.stepInstallAgentTitle": "Lancer le serveur Fleet", "xpack.fleet.fleetServerSetup.stepSelectAgentPolicyTitle": "Sélectionner une stratégie d’agent pour héberger le serveur Fleet", - "xpack.fleet.fleetServerSetup.stepWaitingForFleetServerTitle": "En attente de connexion du serveur Fleet…", "xpack.fleet.fleetServerSetup.waitingText": "En attente de connexion d'un serveur Fleet…", "xpack.fleet.fleetServerSetupPermissionDeniedErrorMessage": "Le serveur Fleet doit être configuré. Pour cela, le privilège de cluster {roleName} est requis. Contactez votre administrateur.", "xpack.fleet.fleetServerSetupPermissionDeniedErrorTitle": "Autorisation refusée", @@ -18503,7 +18576,6 @@ "xpack.ml.jobsList.alertingRules.tooltipContent": "La tâche a {rulesCount} {rulesCount, plural, one { règle d'alerte associée} other { règles d'alerte associées}}", "xpack.ml.jobsList.analyticsSpacesLabel": "Espaces", "xpack.ml.jobsList.auditMessageColumn.screenReaderDescription": "Cette colonne affiche des icônes lorsque des erreurs ou des avertissements pour la tâche ont été signalé(e)s au cours des dernières 24 heures", - "xpack.ml.jobsList.breadcrumb": "Tâches", "xpack.ml.jobsList.cannotSelectRowForJobMessage": "Impossible de sélectionner l'ID de tâche {jobId}", "xpack.ml.jobsList.cloneJobErrorMessage": "Impossible de cloner {jobId}. La tâche est introuvable", "xpack.ml.jobsList.closeActionStatusText": "fermer", @@ -21683,12 +21755,6 @@ "xpack.observability.noDataConfig.beatsCard.title": "Ajouter des intégrations", "xpack.observability.noDataConfig.solutionName": "Observabilité", "xpack.observability.notAvailable": "S. O.", - "xpack.observability.overview.alert.allTypes": "Tous les types", - "xpack.observability.overview.alert.appLink": "Afficher toutes les alertes", - "xpack.observability.overview.alert.errorMessage": "Une erreur s’est produite lors du chargement des données d’alerte. Réessayez plus tard.", - "xpack.observability.overview.alert.errorTitle": "Impossible de charger les données d’alerte.", - "xpack.observability.overview.alerts.appLink": "Afficher les alertes", - "xpack.observability.overview.alerts.muted": "Muet", "xpack.observability.overview.alerts.title": "Alertes", "xpack.observability.overview.apm.appLink": "Afficher l’inventaire des services", "xpack.observability.overview.apm.services": "Services", @@ -21996,9 +22062,6 @@ "xpack.osquery.liveQueryDetails.viewLiveQueriesHistoryTitle": "Afficher l'historique des recherches en direct", "xpack.osquery.liveQueryForm.form.saveForLaterButtonLabel": "Enregistrer pour plus tard", "xpack.osquery.liveQueryForm.form.submitButtonLabel": "Envoyer", - "xpack.osquery.liveQueryForm.steps.agentsStepHeading": "Sélectionner les agents", - "xpack.osquery.liveQueryForm.steps.queryStepHeading": "Entrer la recherche", - "xpack.osquery.liveQueryForm.steps.resultsStepHeading": "Vérifier les résultats", "xpack.osquery.liveQueryResults.table.agentColumnTitle": "agent", "xpack.osquery.liveQueryResults.table.fieldMappedLabel": "Le champ est mappé à", "xpack.osquery.newLiveQuery.pageTitle": "Nouvelle recherche en direct", @@ -22480,7 +22543,6 @@ "xpack.reporting.publicNotifier.csvContainsFormulas.formulaReportMessage": "Le rapport \"{reportObjectTitle}\" contient des caractères que les applications de feuilles de calcul peuvent considérer comme des formules.", "xpack.reporting.publicNotifier.csvContainsFormulas.formulaReportTitle": "Les rapports du type {reportType} peuvent contenir des formules.", "xpack.reporting.publicNotifier.downloadReportButtonLabel": "Télécharger le rapport", - "xpack.reporting.publicNotifier.error.calloutTitle": "La tâche de reporting a échoué", "xpack.reporting.publicNotifier.error.checkManagement": "Accédez à {path} pour plus d’informations.", "xpack.reporting.publicNotifier.error.couldNotCreateReportTitle": "Impossible de créer un rapport {reportType} pour \"{reportObjectTitle}\".", "xpack.reporting.publicNotifier.error.reportingSectionUrlLinkLabel": "Gestion de la Suite > Kibana > Reporting", @@ -25480,17 +25542,11 @@ "xpack.securitySolution.endpoint.policyResponse.appliedOn": "Révision {rev} appliquée le {date}", "xpack.securitySolution.endpoint.policyResponse.backLinkTitle": "Détails de point de terminaison", "xpack.securitySolution.endpoint.policyResponse.title": "Réponse de politique", - "xpack.securitySolution.endpoint.resolver.compactBillions": "B", - "xpack.securitySolution.endpoint.resolver.compactMillions": "M", - "xpack.securitySolution.endpoint.resolver.compactOverflow": "+", - "xpack.securitySolution.endpoint.resolver.compactThousands": "k", - "xpack.securitySolution.endpoint.resolver.compactTrillions": "T", "xpack.securitySolution.endpoint.resolver.eitherLineageLimitExceeded": "Certains événements de processus dans la visualisation et la liste d'événements ci-dessous n'ont pas pu être affichés, car la limite de données a été atteinte.", "xpack.securitySolution.endpoint.resolver.elapsedTime": "{duration} {durationType}", "xpack.securitySolution.endpoint.resolver.errorProcess": "Processus d'erreur", "xpack.securitySolution.endpoint.resolver.loadingError": "Erreur lors du chargement des données.", "xpack.securitySolution.endpoint.resolver.loadingProcess": "Processus de chargement", - "xpack.securitySolution.endpoint.resolver.node.pillNumber": "{mantissa}{scale}{hasRemainder}", "xpack.securitySolution.endpoint.resolver.panel.error.error": "Erreur", "xpack.securitySolution.endpoint.resolver.panel.error.events": "Événements", "xpack.securitySolution.endpoint.resolver.panel.error.goBack": "Afficher tous les processus", @@ -26808,8 +26864,6 @@ "xpack.securitySolution.trustedApps.assignmentSectionDescription": "Affectez cette application de confiance globalement à toutes les politiques, ou de façon spécifique à certaines politiques.", "xpack.securitySolution.trustedapps.card.operator.is": "est", "xpack.securitySolution.trustedapps.card.operator.matches": "correspond à", - "xpack.securitySolution.trustedApps.conditionsSectionDescription": "Sélectionnez un système d'exploitation et ajoutez des conditions. La disponibilité des conditions peut dépendre de votre système d’exploitation.", - "xpack.securitySolution.trustedApps.conditionsSectionTitle": "Conditions", "xpack.securitySolution.trustedapps.create.conditionFieldDegradedPerformanceMsg": "[{row}] L'utilisation d'un caractère générique dans le nom de fichier affectera les performances du point de terminaison", "xpack.securitySolution.trustedapps.create.conditionFieldDuplicatedMsg": "{field} ne peut pas être ajouté plus d'une fois", "xpack.securitySolution.trustedapps.create.conditionFieldInvalidHashMsg": "[{row}] Valeur de hachage non valide", @@ -26817,41 +26871,10 @@ "xpack.securitySolution.trustedapps.create.conditionFieldValueRequiredMsg": "[{row}] L'entrée de champ doit inclure une valeur", "xpack.securitySolution.trustedapps.create.conditionRequiredMsg": "Au moins une définition de champ est requise", "xpack.securitySolution.trustedapps.create.description": "Description", - "xpack.securitySolution.trustedapps.create.name": "Nommer votre application de confiance", "xpack.securitySolution.trustedapps.create.nameRequiredMsg": "Le nom est requis", - "xpack.securitySolution.trustedapps.create.os": "Sélectionner un système d'exploitation", "xpack.securitySolution.trustedapps.create.osRequiredMsg": "Le système d'exploitation est requis", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.cancelButton": "Annuler", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.createSaveButton": "Ajouter une application de confiance", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.createTitle": "Ajouter une application de confiance", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.editSaveButton": "Enregistrer", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.editTitle": "Modifier une application de confiance", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.expiredLicenseMessage": "Votre licence Kibana est passée à une version inférieure. Les futures configurations de politiques seront désormais globalement affectées à toutes les politiques. Pour en savoir plus, consultez notre ", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.expiredLicenseTitle": "Licence expirée", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.notFoundToastMessage": "Impossible de modifier l'application de confiance ({apiMsg})", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.successToastTitle": "\"{name}\" a été ajouté à la liste d'applications de confiance.", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.updateSuccessToastTitle": "\"{name}\" a été mis à jour.", - "xpack.securitySolution.trustedapps.creationSuccess.title": "Cette action a réussi !", - "xpack.securitySolution.trustedapps.deletionDialog.calloutMessage": "La suppression de cette entrée entraînera son retrait dans {count} {count, plural, one {politique associée} other {politiques associées}}.", - "xpack.securitySolution.trustedapps.deletionDialog.calloutTitle": "Avertissement", - "xpack.securitySolution.trustedapps.deletionDialog.cancelButton": "Annuler", - "xpack.securitySolution.trustedapps.deletionDialog.confirmButton": "Supprimer", - "xpack.securitySolution.trustedapps.deletionDialog.subMessage": "Cette action ne peut pas être annulée. Voulez-vous vraiment continuer ?", - "xpack.securitySolution.trustedapps.deletionDialog.title": "Supprimer \"{name}\"", - "xpack.securitySolution.trustedapps.deletionError.text": "Impossible de retirer \"{name}\" de la liste d'applications de confiance. Raison : {message}", - "xpack.securitySolution.trustedapps.deletionError.title": "Échec du retrait", - "xpack.securitySolution.trustedapps.deletionSuccess.text": "\"{name}\" a été retiré de la liste d'applications de confiance.", - "xpack.securitySolution.trustedapps.deletionSuccess.title": "Retrait effectué avec succès", - "xpack.securitySolution.trustedApps.detailsSectionTitle": "Détails", - "xpack.securitySolution.trustedapps.docsLink": "Documentation relative aux applications de confiance.", - "xpack.securitySolution.trustedapps.grid.cardAction.delete": "Supprimer une application de confiance", - "xpack.securitySolution.trustedapps.grid.cardAction.edit": "Modifier une application de confiance", - "xpack.securitySolution.trustedapps.grid.policyDetailsLinkBackLabel": "Retour aux applications de confiance", "xpack.securitySolution.trustedapps.list.addButton": "Ajouter une application de confiance", - "xpack.securitySolution.trustedapps.list.pageTitle": "Applications de confiance", - "xpack.securitySolution.trustedapps.list.search.placeholder": "Rechercher sur les champs ci-dessous : nom, description, valeur", - "xpack.securitySolution.trustedapps.list.totalCount": "Affichage de {totalItemsCount, plural, one {# application de confiance} other {# applications de confiance}}", - "xpack.securitySolution.trustedapps.listEmptyState.message": "Ajoutez une application de confiance pour améliorer les performances ou réduire les conflits avec d'autres applications en cours d'exécution sur vos hôtes.", + "xpack.securitySolution.trustedapps.listEmptyState.message": "Aucune application de confiance ne figure actuellement dans votre point de terminaison.", "xpack.securitySolution.trustedapps.listEmptyState.title": "Ajouter votre première application de confiance", "xpack.securitySolution.trustedapps.logicalConditionBuilder.entry.field.description.hash": "md5, sha1 ou sha256", "xpack.securitySolution.trustedapps.logicalConditionBuilder.entry.field.description.path": "Chemin complet de l'application", @@ -26862,14 +26885,9 @@ "xpack.securitySolution.trustedapps.logicalConditionBuilder.entry.removeLabel": "Retirer l'entrée", "xpack.securitySolution.trustedapps.logicalConditionBuilder.group.andOperator": "AND", "xpack.securitySolution.trustedapps.logicalConditionBuilder.noEntries": "Aucune condition définie", - "xpack.securitySolution.trustedapps.middleware.editIdMissing": "Aucun ID fourni", "xpack.securitySolution.trustedapps.trustedapp.entry.field": "Champ", "xpack.securitySolution.trustedapps.trustedapp.entry.operator": "Opérateur", "xpack.securitySolution.trustedapps.trustedapp.entry.value": "Valeur", - "xpack.securitySolution.trustedapps.updateSuccess.title": "Cette action a réussi !", - "xpack.securitySolution.trustedapps.view.toggle.grid": "Vue Grille", - "xpack.securitySolution.trustedapps.view.toggle.list": "Vue Liste", - "xpack.securitySolution.trustedapps.viewTypeToggle.controlLegend": "Type de vue", "xpack.securitySolution.trustedAppsTab": "Applications de confiance", "xpack.securitySolution.uiSettings.defaultAnomalyScoreDescription": "

Valeur au-dessus de laquelle les anomalies de tâche de Machine Learning sont affichées dans l'application Security.

Valeurs valides : 0 à 100.

", "xpack.securitySolution.uiSettings.defaultAnomalyScoreLabel": "Seuil d'anomalie", @@ -28110,13 +28128,6 @@ "xpack.timelines.clipboard.copy.to.the.clipboard": "Copier dans le presse-papiers", "xpack.timelines.clipboard.to.the.clipboard": "dans le presse-papiers", "xpack.timelines.copyToClipboardTooltip": "Copier dans le presse-papiers", - "xpack.timelines.draggables.field.categoryLabel": "Catégorie", - "xpack.timelines.draggables.field.fieldLabel": "Champ", - "xpack.timelines.draggables.field.typeLabel": "Type", - "xpack.timelines.draggables.field.viewCategoryTooltip": "Afficher la catégorie", - "xpack.timelines.emptyString.emptyStringDescription": "Chaîne vide", - "xpack.timelines.eventDetails.copyToClipboardTooltip": "Copier dans le presse-papiers", - "xpack.timelines.exitFullScreenButton": "Quitter le plein écran", "xpack.timelines.fieldBrowser.categoriesCountTitle": "{totalCount} {totalCount, plural, =1 {catégorie} other {catégories}}", "xpack.timelines.fieldBrowser.categoriesTitle": "Catégories", "xpack.timelines.fieldBrowser.categoryLabel": "Catégorie", @@ -28207,8 +28218,6 @@ "xpack.timelines.timeline.closedAlertSuccessToastMessage": "Fermeture réussie de {totalAlerts} {totalAlerts, plural, =1 {alerte} other {alertes}}.", "xpack.timelines.timeline.closeSelectedTitle": "Marquer comme fermé", "xpack.timelines.timeline.descriptionTooltip": "Description", - "xpack.timelines.timeline.eventHasEventRendererScreenReaderOnly": "L'événement de la ligne {row} possède un outil de rendu d'événement. Appuyez sur Maj + flèche vers le bas pour faire la mise au point dessus.", - "xpack.timelines.timeline.eventHasNotesScreenReaderOnly": "L'événement de la ligne {row} possède {notesCount, plural, =1 {une note} other {{notesCount} des notes}}. Appuyez sur Maj + flèche vers la droite pour faire la mise au point sur les notes.", "xpack.timelines.timeline.eventsTableAriaLabel": "events; Page {activePage} sur {totalPages}", "xpack.timelines.timeline.fieldTooltip": "Champ", "xpack.timelines.timeline.flyout.pane.removeColumnButtonLabel": "Retirer une colonne", @@ -28225,7 +28234,6 @@ "xpack.timelines.timeline.updateAlertStatusFailedDetailed": "{ updated } {updated, plural, =1 {alerte a été mise à jour} other {alertes ont été mises à jour}} correctement, mais { conflicts } n'ont pas pu être mis à jour\n car { conflicts, plural, =1 {elle était} other {elles étaient}} déjà en cours de modification.", "xpack.timelines.timeline.updateAlertStatusFailedSingleAlert": "Impossible de mettre à jour l'alerte, car elle était déjà en cours de modification.", "xpack.timelines.timeline.youAreInAnEventRendererScreenReaderOnly": "Vous êtes dans un outil de rendu d'événement pour la ligne : {row}. Appuyez sur la touche fléchée vers le haut pour quitter et revenir à la ligne en cours, ou sur la touche fléchée vers le bas pour quitter et passer à la ligne suivante.", - "xpack.timelines.timeline.youAreInATableCellScreenReaderOnly": "Vous êtes dans une cellule de tableau. Ligne : {row}, colonne : {column}", "xpack.timelines.timelineEvents.errorSearchDescription": "Une erreur s'est produite lors de la recherche d'événements de la chronologie", "xpack.timelines.toolbar.bulkActions.clearSelectionTitle": "Effacer la sélection", "xpack.timelines.toolbar.bulkActions.selectAllAlertsTitle": "Sélectionner un total de {totalAlertsFormatted} {totalAlerts, plural, =1 {alerte} other {alertes}}", @@ -29346,7 +29354,6 @@ "xpack.triggersActionsUI.sections.rulesList.ruleStatusActive": "Actif", "xpack.triggersActionsUI.sections.rulesList.ruleStatusDropdownMenuLabel": "Modifier le statut de la règle ou répéter", "xpack.triggersActionsUI.sections.rulesList.ruleStatusError": "Erreur", - "xpack.triggersActionsUI.sections.rulesList.ruleStatusFilterLabel": "Dernière réponse", "xpack.triggersActionsUI.sections.rulesList.ruleStatusLicenseError": "Erreur de licence", "xpack.triggersActionsUI.sections.rulesList.ruleStatusOk": "Ok", "xpack.triggersActionsUI.sections.rulesList.ruleStatusPending": "En attente", @@ -29768,842 +29775,842 @@ "xpack.upgradeAssistant.upgradedTitle": "Votre cluster a été mis à niveau", "xpack.upgradeAssistant.upgradingDescription": "Un ou plusieurs nœuds Elasticsearch ont une version plus récente d'Elasticsearch que Kibana. Une fois que tous vos nœuds auront été mis à niveau, procédez à la mise à niveau de Kibana.", "xpack.upgradeAssistant.upgradingTitle": "Votre cluster est en cours de mise à niveau", - "xpack.uptime.addDataButtonLabel": "Ajouter des données", - "xpack.uptime.addMonitor.pageHeader.title": "Ajouter un moniteur", - "xpack.uptime.addMonitorRoute.title": "Ajouter un moniteur | {baseTitle}", - "xpack.uptime.alertDropdown.noWritePermissions": "Vous devez disposer d'un accès en lecture-écriture à Uptime pour créer des alertes dans cette application.", - "xpack.uptime.alerts.anomaly.criteriaExpression.ariaLabel": "Expression affichant les critères d'un moniteur sélectionné.", - "xpack.uptime.alerts.anomaly.criteriaExpression.description": "Quand le moniteur", - "xpack.uptime.alerts.anomaly.scoreExpression.ariaLabel": "Expression affichant les critères d'un seuil d'alerte d'anomalie.", - "xpack.uptime.alerts.anomaly.scoreExpression.description": "comporte une anomalie avec sévérité", - "xpack.uptime.alerts.createRulesPanel.title": "Créer des règles", - "xpack.uptime.alerts.durationAnomaly": "Anomalie de durée Uptime", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.anomalyStartTimestamp": "Horodatage ISO8601 du début de l'anomalie.", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.expectedResponseTime": "Temps de réponse attendu", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.monitor": "Rendu convivial du nom ou de l'ID, ou nom préféré (par ex. Mon moniteur)", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.monitorId": "ID du moniteur.", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.monitorUrl": "URL du moniteur.", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.observerLocation": "Emplacement de l'observateur à partir duquel la vérification des pulsations est effectuée.", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.severity": "Sévérité de l'anomalie.", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.severityScore": "Note de sévérité d'anomalie", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.slowestAnomalyResponse": "Temps de réponse le plus lent dans le compartiment d'anomalies avec des unités associées (ms, s).", - "xpack.uptime.alerts.durationAnomaly.clientName": "Anomalie de durée Uptime", - "xpack.uptime.alerts.durationAnomaly.defaultActionMessage": "Temps de réponse anormal (niveau {severity}) détecté dans le {monitor} possédant l'URL {monitorUrl} à {anomalyStartTimestamp}. La note de sévérité anormale est {severityScore}.\nDes temps de réponse aussi élevés que {slowestAnomalyResponse} ont été détectés à partir de l'emplacement {observerLocation}. Le temps de réponse attendu est {expectedResponseTime}.", - "xpack.uptime.alerts.durationAnomaly.description": "Alerte lorsque la durée du moniteur Uptime est anormale.", - "xpack.uptime.alerts.monitorExpression.label": "Retirer le filtre {title}", - "xpack.uptime.alerts.monitorStatus": "Statut du moniteur Uptime", - "xpack.uptime.alerts.monitorStatus.actionVariables.availabilityMessage": "La disponibilité {interval} est de {availabilityRatio} %. Alerte lorsque < {expectedAvailability} %.", - "xpack.uptime.alerts.monitorStatus.actionVariables.context.alertReasonMessage.description": "Une description concise de la raison du signalement", - "xpack.uptime.alerts.monitorStatus.actionVariables.context.downMonitorsWithGeo.description": "Résumé généré montrant certains ou tous les moniteurs détectés comme \"arrêtés\" par l'alerte", - "xpack.uptime.alerts.monitorStatus.actionVariables.context.message.description": "Message généré résumant les moniteurs actuellement arrêtés", - "xpack.uptime.alerts.monitorStatus.actionVariables.context.viewInAppUrl.description": "Lien vers la vue ou la fonctionnalité dans Elastic qui peut être utilisée pour examiner l'alerte et son contexte de manière plus approfondie", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.currentTriggerStarted": "Horodatage indiquant à quel moment l'état de déclenchement actuel a commencé, si l'alerte est déclenchée", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.firstCheckedAt": "Horodatage indiquant à quel moment cette alerte a effectué des vérifications pour la première fois", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.firstTriggeredAt": "Horodatage indiquant à quel moment cette alerte a été déclenchée pour la première fois", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.isTriggered": "Indicateur spécifiant si l'alerte est en cours de déclenchement", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.lastCheckedAt": "Horodatage indiquant l'heure de vérification la plus récente de l'alerte", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.lastErrorMessage": "Dernier message d'erreur du moniteur", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.lastResolvedAt": "Horodatage indiquant l'heure de résolution la plus récente pour cette alerte", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.lastTriggeredAt": "Horodatage indiquant l'heure de déclenchement la plus récente de l'alerte", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.monitor": "Rendu convivial du nom ou de l'ID, ou nom préféré (par ex. Mon moniteur)", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.monitorId": "ID du moniteur.", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.monitorType": "Type (par ex. HTTP/TCP) du moniteur.", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.monitorUrl": "URL du moniteur.", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.observerHostname": "Nom d'hôte de l'observateur à partir duquel la vérification des pulsations est effectuée.", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.observerLocation": "Emplacement de l'observateur à partir duquel la vérification des pulsations est effectuée.", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.statusMessage": "Message de statut, par ex. \"arrêté\" ou \"se trouve au-dessous du seuil de disponibilité\" en cas de vérification de disponibilité, ou les deux.", - "xpack.uptime.alerts.monitorStatus.addFilter": "Ajouter un filtre", - "xpack.uptime.alerts.monitorStatus.addFilter.location": "Emplacement", - "xpack.uptime.alerts.monitorStatus.addFilter.port": "Port", - "xpack.uptime.alerts.monitorStatus.addFilter.tag": "Balise", - "xpack.uptime.alerts.monitorStatus.addFilter.type": "Type", - "xpack.uptime.alerts.monitorStatus.availability.isEnabledCheckbox.label": "Disponibilité", - "xpack.uptime.alerts.monitorStatus.availability.threshold.anyMonitorDescription": "tout moniteur est opérationnel dans", - "xpack.uptime.alerts.monitorStatus.availability.threshold.ariaLabel": "Spécifier les seuils de disponibilité pour cette alerte", - "xpack.uptime.alerts.monitorStatus.availability.threshold.description": "les moniteurs correspondants sont opérationnels dans", - "xpack.uptime.alerts.monitorStatus.availability.threshold.input.ariaLabel": "Saisir un seuil de disponibilité à vérifier pour cette alerte", - "xpack.uptime.alerts.monitorStatus.availability.threshold.value": "< {value} % des vérifications", - "xpack.uptime.alerts.monitorStatus.availability.timerangeValueField.ariaLabel": "Entrez le nombre d'unités pour la vérification de disponibilité de l'alerte.", - "xpack.uptime.alerts.monitorStatus.availability.timerangeValueField.expression": "ces derniers/dernières", - "xpack.uptime.alerts.monitorStatus.availability.timerangeValueField.popover.ariaLabel": "Spécifier la plage temporelle de suivi de disponibilité", - "xpack.uptime.alerts.monitorStatus.availability.unit.headline": "Sélectionner l'unité de la plage temporelle", - "xpack.uptime.alerts.monitorStatus.availability.unit.selectable": "Utiliser cette sélection pour définir les unités de la plage temporelle pour cette alerte", - "xpack.uptime.alerts.monitorStatus.clientName": "Statut du moniteur Uptime", - "xpack.uptime.alerts.monitorStatus.defaultActionMessage": "Moniteur {monitorName} avec l'URL {monitorUrl} depuis {observerLocation} {statusMessage} Le dernier message d'erreur est {latestErrorMessage}", - "xpack.uptime.alerts.monitorStatus.description": "Alerte lorsqu'un monitoring est arrêté ou qu'un seuil de disponibilité est dépassé.", - "xpack.uptime.alerts.monitorStatus.filterBar.ariaLabel": "Entrée qui permet le filtrage de critères pour l'alerte de statut du moniteur", - "xpack.uptime.alerts.monitorStatus.filters.anyLocation": "tout emplacement", - "xpack.uptime.alerts.monitorStatus.filters.anyPort": "tout port", - "xpack.uptime.alerts.monitorStatus.filters.anyTag": "toute balise", - "xpack.uptime.alerts.monitorStatus.filters.anyType": "tout type", - "xpack.uptime.alerts.monitorStatus.filters.from": "De", - "xpack.uptime.alerts.monitorStatus.filters.fromLocation": "Depuis l'emplacement", - "xpack.uptime.alerts.monitorStatus.filters.location.label": "Sélectionnez les filtres d'emplacement à appliquer à la requête de l'alerte.", - "xpack.uptime.alerts.monitorStatus.filters.of": "sur", - "xpack.uptime.alerts.monitorStatus.filters.ofType": "De type", - "xpack.uptime.alerts.monitorStatus.filters.port.label": "Sélectionnez les filtres de port à appliquer à la requête de l'alerte.", - "xpack.uptime.alerts.monitorStatus.filters.scheme.label": "Sélectionnez les filtres de schéma de protocole à appliquer à la requête de l'alerte.", - "xpack.uptime.alerts.monitorStatus.filters.tag.label": "Sélectionnez les filtres de balise à appliquer à la requête de l'alerte.", - "xpack.uptime.alerts.monitorStatus.filters.using": "À l'aide de", - "xpack.uptime.alerts.monitorStatus.filters.usingPort": "En utilisant le port", - "xpack.uptime.alerts.monitorStatus.filters.with": "À l'aide de", - "xpack.uptime.alerts.monitorStatus.filters.withTag": "Avec la balise", - "xpack.uptime.alerts.monitorStatus.monitorCallOut.title": "Cette alerte s'appliquera à environ {snapshotCount} moniteurs.", - "xpack.uptime.alerts.monitorStatus.numTimesExpression.anyMonitors.description": "tout moniteur est arrêté >", - "xpack.uptime.alerts.monitorStatus.numTimesExpression.ariaLabel": "Ouvrir la fenêtre contextuelle pour saisir le compte de moniteurs arrêtés", - "xpack.uptime.alerts.monitorStatus.numTimesExpression.matchingMonitors.description": "les moniteurs correspondants sont arrêtés >", - "xpack.uptime.alerts.monitorStatus.numTimesField.ariaLabel": "Entrer le nombre de moniteurs arrêtés requis pour déclencher l'alerte", - "xpack.uptime.alerts.monitorStatus.oldAlertCallout.title": "Si vous modifiez une ancienne alerte, certains champs ne se rempliront peut-être pas automatiquement.", - "xpack.uptime.alerts.monitorStatus.recoveryMessage": "Le moniteur {monitor} possédant l'URL {url} a repris avec le statut Opérationnel", - "xpack.uptime.alerts.monitorStatus.statusEnabledCheck.label": "Vérification du statut", - "xpack.uptime.alerts.monitorStatus.timerangeOption.days": "jours", - "xpack.uptime.alerts.monitorStatus.timerangeOption.hours": "heures", - "xpack.uptime.alerts.monitorStatus.timerangeOption.minutes": "minutes", - "xpack.uptime.alerts.monitorStatus.timerangeOption.months": "mois", - "xpack.uptime.alerts.monitorStatus.timerangeOption.seconds": "secondes", - "xpack.uptime.alerts.monitorStatus.timerangeOption.weeks": "semaines", - "xpack.uptime.alerts.monitorStatus.timerangeOption.years": "ans", - "xpack.uptime.alerts.monitorStatus.timerangeSelectionHeader": "Sélectionner l'unité de la plage temporelle", - "xpack.uptime.alerts.monitorStatus.timerangeUnitExpression.ariaLabel": "Ouvrir la fenêtre contextuelle pour accéder au champ de sélection d'unité de la plage temporelle", - "xpack.uptime.alerts.monitorStatus.timerangeUnitSelectable": "Le champ sélectionnable pour les alertes d'unités de la plage temporelle doit utiliser", - "xpack.uptime.alerts.monitorStatus.timerangeValueExpression.ariaLabel": "Ouvrir la fenêtre contextuelle pour accéder au champ de valeur de la plage temporelle", - "xpack.uptime.alerts.monitorStatus.timerangeValueField.ariaLabel": "Entrer le nombre d'unités de temps pour la plage de l'alerte", - "xpack.uptime.alerts.monitorStatus.timerangeValueField.expression": "dans", - "xpack.uptime.alerts.monitorStatus.timerangeValueField.value": "dernier/dernière(s) {value}", - "xpack.uptime.alerts.searchPlaceholder.kql": "Filtrer à l'aide de la syntaxe KQL", - "xpack.uptime.alerts.settings.addConnector": "Ajouter un connecteur", - "xpack.uptime.alerts.timerangeUnitSelectable.daysOption.ariaLabel": "Élément de sélection de la plage temporelle \"Jours\"", - "xpack.uptime.alerts.timerangeUnitSelectable.hoursOption.ariaLabel": "Élément de sélection de la plage temporelle \"Heures\"", - "xpack.uptime.alerts.timerangeUnitSelectable.minutesOption.ariaLabel": "Élément de sélection de la plage temporelle \"Minutes\"", - "xpack.uptime.alerts.timerangeUnitSelectable.monthsOption.ariaLabel": "Élément de sélection de la plage temporelle \"Mois\"", - "xpack.uptime.alerts.timerangeUnitSelectable.secondsOption.ariaLabel": "Élément de sélection de la plage temporelle \"Secondes\"", - "xpack.uptime.alerts.timerangeUnitSelectable.weeksOption.ariaLabel": "Élément de sélection de la plage temporelle \"Semaines\"", - "xpack.uptime.alerts.timerangeUnitSelectable.yearsOption.ariaLabel": "Élément de sélection de la plage temporelle \"Années\"", - "xpack.uptime.alerts.tls": "Uptime TLS", - "xpack.uptime.alerts.tls.actionVariables.state.agingCommonNameAndDate": "Noms courants et date/heure d'expiration des certificats détectés.", - "xpack.uptime.alerts.tls.actionVariables.state.agingCount": "Nombre de certificats détectés qui deviennent trop anciens.", - "xpack.uptime.alerts.tls.actionVariables.state.count": "Nombre de certificats détectés par l'exécuteur d'alertes", - "xpack.uptime.alerts.tls.actionVariables.state.expiringCommonNameAndDate": "Noms courants et date/heure d'expiration des certificats détectés", - "xpack.uptime.alerts.tls.actionVariables.state.expiringCount": "Nombre de certificats sur le point d'expirer détectés par l'alerte.", - "xpack.uptime.alerts.tls.ageExpression.ariaLabel": "Expression affichant le seuil qui déclenchera l'alerte TLS pour les certificats anciens", - "xpack.uptime.alerts.tls.ageExpression.description": "ou plus anciens que", - "xpack.uptime.alerts.tls.ageExpression.value": "{value} jours", - "xpack.uptime.alerts.tls.agingLabel": "devient trop ancien", - "xpack.uptime.alerts.tls.clientName": "Uptime TLS", - "xpack.uptime.alerts.tls.criteriaExpression.ariaLabel": "Expression affichant les critères des moniteurs surveillés par cette alerte", - "xpack.uptime.alerts.tls.criteriaExpression.description": "quand", - "xpack.uptime.alerts.tls.criteriaExpression.value": "tout moniteur", - "xpack.uptime.alerts.tls.defaultActionMessage": "Le certificat TLS {commonName} détecté de l'émetteur {issuer} est {status}. Certificat {summary}\n", - "xpack.uptime.alerts.tls.description": "Alerte lorsque le certificat TLS d'un moniteur Uptime est sur le point d'expirer.", - "xpack.uptime.alerts.tls.expirationExpression.ariaLabel": "Expression affichant le seuil qui déclenchera l'alerte TLS pour l'expiration des certificats", - "xpack.uptime.alerts.tls.expirationExpression.description": "possède un certificat expirant dans", - "xpack.uptime.alerts.tls.expirationExpression.value": "{value} jours", - "xpack.uptime.alerts.tls.expiredLabel": "expiré", - "xpack.uptime.alerts.tls.expiringLabel": "sur le point d'expirer", - "xpack.uptime.alerts.tls.invalidLabel": "non valide", - "xpack.uptime.alerts.tls.legacy.clientName": "Uptime TLS (existant)", - "xpack.uptime.alerts.tls.legacy.defaultActionMessage": "Détection de {count} certificats TLS sur le point d'expirer ou devenant trop anciens.\n{expiringConditionalOpen}\nNombre de certificats sur le point d'expirer : {expiringCount}\nCertificats sur le point d'expirer : {expiringCommonNameAndDate}\n{expiringConditionalClose}\n{agingConditionalOpen}\nNombre de certificats vieillissants : {agingCount}\nCertificats vieillissants : {agingCommonNameAndDate}\n{agingConditionalClose}\n", - "xpack.uptime.alerts.tls.legacy.description": "Alerte lorsque le certificat TLS d'un moniteur Uptime est sur le point d'expirer. Cette alerte sera déclassée dans une future version.", - "xpack.uptime.alerts.tls.settingsPageNav.text": "Vous pouvez modifier ces seuils sur la {settingsPageLink}.", - "xpack.uptime.alerts.tls.validAfterExpiredString": "expiré le {date}, il y a {relativeDate} jours.", - "xpack.uptime.alerts.tls.validAfterExpiringString": "expire le {date}, dans {relativeDate} jours.", - "xpack.uptime.alerts.tls.validBeforeExpiredString": "valide depuis le {date}, il y a {relativeDate} jours.", - "xpack.uptime.alerts.tls.validBeforeExpiringString": "non valide jusqu'au {date}, dans {relativeDate} jours.", - "xpack.uptime.alerts.tlsLegacy": "Uptime TLS (existant)", - "xpack.uptime.alerts.toggleAlertFlyoutButtonText": "Alertes et règles", - "xpack.uptime.alertsPopover.toggleButton.ariaLabel": "Ouvrir le menu contextuel des alertes et règles", - "xpack.uptime.analyzeDataButtonLabel": "Explorer les données", - "xpack.uptime.analyzeDataButtonLabel.message": "La fonctionnalité Explorer les données vous permet de sélectionner et de filtrer les données de résultat dans toute dimension et de rechercher la cause ou l'impact des problèmes de performances.", - "xpack.uptime.apmIntegrationAction.description": "Rechercher ce monitoring dans APM", - "xpack.uptime.apmIntegrationAction.text": "Afficher les données APM", - "xpack.uptime.availabilityLabelText": "{value} %", - "xpack.uptime.badge.readOnly.text": "Lecture seule", - "xpack.uptime.badge.readOnly.tooltip": "Enregistrement impossible", - "xpack.uptime.breadcrumbs.observabilityText": "Observabilité", - "xpack.uptime.breadcrumbs.overviewBreadcrumbText": "Uptime", - "xpack.uptime.certificates.heading": "Certificats TLS ({total})", - "xpack.uptime.certificates.loading": "Chargement des certificats...", - "xpack.uptime.certificates.refresh": "Actualiser", - "xpack.uptime.certificatesPage.heading": "Certificats TLS", - "xpack.uptime.certificatesRoute.title": "Certificats | {baseTitle}", - "xpack.uptime.certs.expired": "Expiré", - "xpack.uptime.certs.expires": "Expire", - "xpack.uptime.certs.expireSoon": "Expire bientôt", - "xpack.uptime.certs.list.ageCol": "Âge", - "xpack.uptime.certs.list.commonName": "Nom courant", - "xpack.uptime.certs.list.copyFingerprint": "Cliquez pour copier la valeur d'empreinte", - "xpack.uptime.certs.list.days": "jours", - "xpack.uptime.certs.list.empty": "Aucun certificat n'a été trouvé. Remarque : les certificats sont visibles uniquement pour Heartbeat 7.8+", - "xpack.uptime.certs.list.expirationDate": "Empreintes", - "xpack.uptime.certs.list.issuedBy": "Émis par", - "xpack.uptime.certs.list.monitors": "Moniteurs", - "xpack.uptime.certs.list.status": "Statut", - "xpack.uptime.certs.list.status.old": "Trop ancien", - "xpack.uptime.certs.list.validUntil": "Valide jusque", - "xpack.uptime.certs.ok": "OK", - "xpack.uptime.certs.searchCerts": "Rechercher dans les certificats", - "xpack.uptime.certs.status.ok.label": " {okRelativeDate}", - "xpack.uptime.charts.mlAnnotation.header": "Note : {score}", - "xpack.uptime.charts.mlAnnotation.severity": "Sévérité : {severity}", - "xpack.uptime.controls.selectSeverity.criticalLabel": "critique", - "xpack.uptime.controls.selectSeverity.majorLabel": "majeur", - "xpack.uptime.controls.selectSeverity.minorLabel": "mineure", - "xpack.uptime.controls.selectSeverity.scoreDetailsDescription": "score {value} et supérieur", - "xpack.uptime.controls.selectSeverity.warningLabel": "avertissement", - "xpack.uptime.createPackagePolicy.stepConfigure.browser.scriptRecorder.experimentalLabel": "Préversion technique", - "xpack.uptime.createPackagePolicy.stepConfigure.browser.scriptRecorder.experimentalTooltip": "Prévisualisez la méthode la plus rapide permettant de créer des scripts de monitoring Elastic Synthetics avec notre enregistreur Elastic Synthetics", - "xpack.uptime.createPackagePolicy.stepConfigure.browser.scriptRecorder.label": "Enregistreur de scripts", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.description": "Fournissez une configuration précise pour l'agent synthétique.", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.filtering.description": "Utilisez ces options pour appliquer les paramètres de moniteur sélectionnés à un sous-ensemble des tests de votre suite. Seul le sous-ensemble configuré sera exécuté par ce moniteur.", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.filtering.title": "Tests sélectifs", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.ignoreHttpsErrors.helpText": "Définissez cette option sur \"true\" pour désactiver la validation TLS/SSL dans le navigateur synthétique. Cette opération est utile pour tester les sites qui utilisent des certificats autosignés.", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.ignoreHttpsErrors.label": "Ignorer les erreurs HTTPS", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersMatch.helpText": "Exécutez uniquement les parcours dont le nom correspond au glob fourni avec ce moniteur.", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersMatch.label": "Filtrer la correspondance", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersTags.helpText": "Exécutez uniquement les parcours en utilisant les balises données avec ce moniteur.", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersTags.label": "Filtrer les balises", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.screenshots.helpText": "Définissez cette option pour gérer les captures d'écran effectuées par l'agent synthétique.", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.screenshots.label": "Options de capture d'écran", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.syntheticsArgs.helpText": "Arguments supplémentaires à transmettre au package de l'agent synthétique. Accepte une liste de chaînes. Cela est utile dans des scénarios rares et ne devrait normalement pas avoir besoin d'être défini.", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.syntheticsArgs.label": "Arguments synthétiques", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.automatic_node_cap.message": "Lorsque vous désactivez la régulation, la bande passante de votre moniteur sera toujours limitée par les configurations des nœuds synthétiques dans lesquels votre moniteur est en cours d'exécution.", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.automatic_node_cap.title": "Limite automatique", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.description": "Contrôlez les vitesses de téléchargement et chargement du moniteur, ainsi que sa latence pour simuler le comportement de votre application sur des réseaux plus lents.", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.download.error": "La vitesse de téléchargement doit être supérieure à zéro.", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.download.label": "Vitesse de téléchargement", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.exceeded_throttling.message": "Lors de l'utilisation de valeurs de régulation plus élevées que la limite de la bande passante d'un nœud synthétique, la bande passante de votre moniteur sera toujours limitée.", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.exceeded_throttling.title": "Vous avez dépassé les limites de bande passante du nœud synthétique", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.latency.error": "La latence ne doit pas être négative.", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.latency.label": "Latence", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.switch.description": "Activer la régulation", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.title": "Options de régulation", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.upload.error": "La vitesse de chargement doit être supérieure à zéro.", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.upload.label": "Vitesse de chargement", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.title": "Options de l'agent synthétique", - "xpack.uptime.createPackagePolicy.stepConfigure.certificateSettings.enableSSLSettings.label": "Activer la configuration TLS", - "xpack.uptime.createPackagePolicy.stepConfigure.certificateSettings.enableZipUrlSSLSettings.label": "Activer la configuration TLS pour l'URL du zip", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificate.helpText": "Certificat formaté PEM pour l'authentification du client TLS.", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificate.label": "certificat", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificateAuthorities.helpText": "Autorités de certificats personnalisés formatés PEM.", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificateAuthorities.label": "Autorités de certificats", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificateKey.helpText": "Clé de certificat formaté PEM pour l'authentification du client TLS.", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificateKey.label": "clé", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificateKeyPassphrase.helpText": "Phrase secrète de la clé de certificat pour l'authentification du client TLS.", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificateKeyPassphrase.label": "phrase secrète de la clé", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.legend": "Paramètres de certificat", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.tlsRole.client": "Client", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.tlsRole.server": "Serveur", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.certificate.description": "Vérifie que le certificat fourni est signé par une autorité reconnue (CA), mais n'effectue aucune vérification du nom d'hôte.", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.certificate.label": "Certificat", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.full.description": "Vérifie que le certificat fourni est signé par une autorité reconnue (CA), mais également que le nom d'hôte du serveur (ou l'adresse IP) correspond aux noms identifiés dans le certificat.", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.full.label": "Entier", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.label": "Mode de vérification", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.none.description": "N'effectue aucune vérification du certificat du serveur. Il est principalement destiné à servir de mécanisme de diagnostic temporaire lors de tentatives de résolution des erreurs TLS ; son utilisation dans des environnements de production est fortement déconseillée.", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.none.label": "Aucun", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.strict.description": "Vérifie que le certificat fourni est signé par une autorité reconnue (CA), mais également que le nom d'hôte du serveur (ou l'adresse IP) correspond aux noms identifiés dans le certificat. Si le nom alternatif du sujet n'est pas renseigné, il renvoie une erreur.", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.strict.label": "Strict", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.warning.description": "Ce mode désactive de nombreux avantages de sécurité de SSL/TLS et ne doit être utilisé qu'après un examen approfondi.", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.warning.title": "Désactivation de TLS", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.version.label": "Protocoles TLS pris en charge", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.version.placeholder": "Sélectionnez un ou plusieurs protocoles TLS.", - "xpack.uptime.createPackagePolicy.stepConfigure.headerField.addHeader.label": "Ajouter un en-tête", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions": "Options HTTP avancées", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.indexResponseBody.helpText": "Contrôle l'indexation du contenu du corps de la réponse HTTP en fonction du ", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.indexResponseHeaders.helpText": "Contrôle l'indexation des en-têtes de la réponse HTTP en fonction du ", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestBody.helpText": "Contenu du corps de la requête.", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.description": "Configurez une requête facultative à envoyer à l'hôte distant, comprenant la méthode, le corps et les en-têtes.", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.requestBody": "Corps de la requête", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.requestHeaders": "En-têtes de la requête", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.requestMethod.label": "Méthode de la requête", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.title": "Configuration de la requête", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestHeadersField.error": "La clé d'en-tête doit être un token HTTP valide.", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestHeadersField.helpText": "Dictionnaire d'en-têtes HTTP supplémentaires à envoyer. Par défaut, le client définira l'en-tête User-Agent (utilisateur-agent) de façon à ce qu'il s'identifie lui-même.", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestMethod.helpText": "Méthode HTTP à utiliser.", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseBodyCheckNegative.helpText": "Liste d'expressions régulières pour une correspondance négative à la sortie du corps. Appuyez sur Entrée pour ajouter une nouvelle expression. Renvoie un échec de correspondance si l'expression unique correspond.", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseBodyCheckPositive.helpText": "Liste d'expressions régulières pour une correspondance au corps. Appuyez sur Entrée pour ajouter une nouvelle expression. Seule une expression unique a besoin de correspondre.", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseCheckNegative.label": "Le corps de la réponse de vérification ne contient pas", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseCheckPositive.label": "Le corps de la réponse de vérification contient", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.checkResponseHeadersContain": "Les en-têtes de la réponse de vérification contiennent", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.description": "Configurez la réponse HTTP attendue.", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.responseStatusCheck.error": "Le code de statut doit contenir uniquement des chiffres.", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.responseStatusCheck.helpText": "Liste de codes de statut attendus. Appuyez sur Entrée pour ajouter un nouveau code. Les codes 4xx et 5xx sont considérés comme \"Arrêté\" par défaut. Les autres codes sont considérés comme \"Opérationnel\"", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.responseStatusCheck.label": "Le statut de la réponse de vérification est égal à", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.title": "Vérifications des réponses", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfig.indexResponseBody": "Indexer le corps de réponse", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfig.indexResponseHeaders": "Indexer les en-têtes de réponse", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfig.responseBodyIndexPolicy": "Politique d'indexation du corps de réponse", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfiguration.description": "Contrôlez l'indexation des contenus de réponses HTTP.", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfiguration.title": "Configuration des réponses", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseHeadersField.error": "La clé d'en-tête doit être un token HTTP valide.", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseHeadersField.helpText": "Liste d'en-têtes de réponse attendus.", - "xpack.uptime.createPackagePolicy.stepConfigure.icmpAdvancedOptions": "Options ICMP avancées", - "xpack.uptime.createPackagePolicy.stepConfigure.inputVarFieldOptionalLabel": "Facultatif", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.helpText": "Nom de service APM pour ce monitoring. Correspond au champ ECS service.name. Définissez-le lors du monitoring d'une application qui utilise également APM pour activer les intégrations entre les données Uptime et APM dans Kibana.", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.label": "Nom de service APM", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.brower.proxyURL.label": "URL du zip du proxy", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.http.helpText": "Proxy HTTP pour l'URL du zip.", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.error": "Script obligatoire", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.helpText": "Exécute des scripts de tests synthétiques définis en ligne.", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.label": "Script en ligne", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.params.helpText": "Objet JSON qui définit toute variable dont vos tests ont besoin.", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.params.label": "Paramètres", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.scriptRecorder.closeButtonLabel": "Fermer le menu volant du script", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.scriptRecorder.mockFileName": "test_script.js", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.sourceType.label": "Type de source", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.fieldLabel": "Script de test", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.invalidFileError": "Type de fichier non valide. Veuillez charger un fichier .js généré par l'enregistreur Elastic Synthetics.", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.label": "Sélectionner un fichier .js généré par l'enregistreur", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.parsingError": "Erreur lors du chargement du fichier. Veuillez charger un fichier .js généré par l'enregistreur Elastic Synthetics au format de script en ligne.", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.error": "L'URL de zip est requise", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.helpText": "Emplacement du fichier zip du référentiel du projet synthétique.", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.label": "URL du zip", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.recorderLink": "Télécharger l'enregistreur Elastic Synthetics", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.removeScriptLabel": "Retirer le script", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.showScriptLabel": "Afficher le script", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlFolder.helpText": "Chemin de répertoire relatif d'emplacement des fichiers de parcours synthétiques dans le référentiel.", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlFolder.label": "Dossier", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlPassword.abel": "Mot de passe de l'URL du zip", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlPassword.helpText": "Mot de passe pour l'authentification avec le point de terminaison du zip.", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlUsername.helpText": "Nom d'utilisateur pour l'authentification avec le point de terminaison du zip.", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlUsername.label": "Nom d'utilisateur de l'URL du zip", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browserLabel": "Navigateur (version bêta)", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.enabled.helpText": "Désactivez cette configuration pour désactiver le moniteur.", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.enabled.label": "Activé", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.icmp.hosts": "Hôte", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.icmp.hosts.error": "L'hôte est requis", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.maxRedirects": "Nb maxi de redirections", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.maxRedirects.error": "Le nb maxi de redirections doit être supérieur ou égal à 0", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.maxRedirects.helpText": "Nombre total de redirections à suivre.", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorInterval": "Fréquence", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorInterval.error": "La fréquence du moniteur est requise", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType": "Type de moniteur", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.description": "Pour créer un moniteur \"Navigateur\", veuillez vous assurer que vous utilisez le conteneur Docker elastic-agent-complete, qui inclut les dépendances permettant d'exécuter ces moniteurs. Pour en savoir plus, visitez notre {link}.", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.link": "documentation Synthetics", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.error": "Le type de moniteur est requis", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.password.helpText": "Mot de passe pour l'authentification avec le serveur.", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.password.label": "Mot de passe", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyUrl.http.helpText": "URL du proxy HTTP.", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyURL.http.label": "URL du proxy", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyURL.label": "URL du proxy", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyUrl.tcp.helpText": "URL du proxy SOCKS5 à utiliser lors de la connexion au serveur. La valeur doit être une URL avec un schéma de socks5://.", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.resolveHostnamesLocally": "Résout les noms d'hôte localement", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tags.helpText": "Liste de balises qui seront envoyées avec l'événement de monitoring. Appuyez sur Entrée pour ajouter une nouvelle balise. Affiché dans Uptime et permet la recherche par balise.", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tags.label": "Balises", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tcp.hosts": "Host:Port", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tcp.hosts.error": "L'hôte et le port sont requis", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.helpText": "Temps total autorisé pour tester la connexion et l'échange de données.", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.label": "Délai d'expiration en secondes", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.lessThanIntervalError": "Le délai d'expiration doit être inférieur à la fréquence du moniteur", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.moreThanZeroError": "Le délai d'expiration doit être supérieur ou égal à 0", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.URL": "URL", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.URL.error": "L'URL est requise", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.username.helpText": "Nom d'utilisateur pour l'authentification avec le serveur.", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.username.label": "Nom d'utilisateur", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.wait.error": "L'attente doit être supérieure ou égale à 0", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.wait.helpText": "Durée d'attente avant l'émission d'une autre requête d'écho ICMP si aucune réponse n'est reçue.", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.wait.label": "Attente en secondes", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSectionDescription": "Configurez votre moniteur avec les options suivantes.", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSectionTitle": "Paramètres du moniteur", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBody.codeEditor.javascript.ariaLabel": "Éditeur de code JavaScript", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBody.codeEditor.json.ariaLabel": "Éditeur de code JSON", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBody.codeEditor.text.ariaLabel": "Éditeur de code texte", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBody.codeEditor.xml.ariaLabel": "Éditeur de code XML", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBody.formField.addFormField.label": "Ajouter un champ de formulaire", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBodyType.form": "Formulaire", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBodyType.JSON": "JSON", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBodyType.text": "Texte", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBodyType.XML": "XML", - "xpack.uptime.createPackagePolicy.stepConfigure.responseBodyIndex.always": "Toujours", - "xpack.uptime.createPackagePolicy.stepConfigure.responseBodyIndex.onError": "En cas d'erreur", - "xpack.uptime.createPackagePolicy.stepConfigure.scheduleField.minutes": "Minutes", - "xpack.uptime.createPackagePolicy.stepConfigure.scheduleField.number": "Nombre", - "xpack.uptime.createPackagePolicy.stepConfigure.scheduleField.seconds": "Secondes", - "xpack.uptime.createPackagePolicy.stepConfigure.scheduleField.unit": "Unité", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.description": "Configurez les données utiles envoyées à l'hôte distant.", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.requestPayload.helpText": "Chaîne de données utiles à envoyer à l'hôte distant.", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.requestPayload.label": "Charge utile de la requête", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.title": "Configuration de la requête", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.responseConfiguration.responseContains.helpText": "Réponse attendue de l'hôte distant.", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.responseConfiguration.responseContains.label": "La réponse de vérification contient", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvancedOptions.responseConfiguration.description": "Configurez la réponse attendue à partir de l'hôte distant.", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvancedOptions.responseConfiguration.title": "Vérifications des réponses", - "xpack.uptime.createPackagePolicy.stepConfigure.tlsSettings.description": "Configurez les options TLS, y compris le mode de vérification, les autorités de certification et les certificats clients.", - "xpack.uptime.createPackagePolicy.stepConfigure.tlsSettings.label": "Paramètres TLS", - "xpack.uptime.durationChart.emptyPrompt.description": "Ce monitoring n'a jamais été {emphasizedText} au cours de la plage temporelle sélectionnée.", - "xpack.uptime.durationChart.emptyPrompt.title": "Aucune donnée de durée n'est disponible", - "xpack.uptime.editMonitor.pageHeader.title": "Modifier le moniteur", - "xpack.uptime.editMonitorRoute.title": "Modifier le moniteur | {baseTitle}", - "xpack.uptime.emptyState.loadingMessage": "Chargement…", - "xpack.uptime.emptyStateError.notAuthorized": "Vous n'êtes pas autorisé à afficher les données Uptime, veuillez contacter votre administrateur système.", - "xpack.uptime.emptyStateError.notFoundPage": "Page introuvable", - "xpack.uptime.emptyStateError.title": "Erreur", - "xpack.uptime.enableAlert.editAlert": "Modifier l'alerte", - "xpack.uptime.filterBar.ariaLabel": "Saisissez des critères de filtre pour la page d'aperçu", - "xpack.uptime.filterBar.filterAllLabel": "Tous", - "xpack.uptime.filterBar.options.location.name": "Emplacement", - "xpack.uptime.filterBar.options.portLabel": "Port", - "xpack.uptime.filterBar.options.schemeLabel": "Schéma", - "xpack.uptime.filterBar.options.tagsLabel": "Balise", - "xpack.uptime.fleetIntegration.assets.description": "Afficher les moniteurs dans Uptime", - "xpack.uptime.fleetIntegration.assets.name": "Moniteurs", - "xpack.uptime.inspectButtonText": "Inspecter", - "xpack.uptime.integrationLink.missingDataMessage": "Les données requises pour cette intégration sont introuvables.", - "xpack.uptime.keyValuePairsField.deleteItem.label": "Supprimer le numéro d'élément {index}, {key}:{value}", - "xpack.uptime.keyValuePairsField.key.ariaLabel": "Clé", - "xpack.uptime.keyValuePairsField.key.label": "Clé", - "xpack.uptime.keyValuePairsField.value.ariaLabel": "Valeur", - "xpack.uptime.keyValuePairsField.value.label": "Valeur", - "xpack.uptime.kueryBar.searchPlaceholder.kql": "Rechercher à l'aide de la syntaxe KQL des ID, noms et types etc. de moniteurs (par ex. monitor.type: \"http\" AND tags: \"dev\")", - "xpack.uptime.kueryBar.searchPlaceholder.simple": "Rechercher par ID, nom ou URL de moniteur (par ex. http:// )", - "xpack.uptime.locationName.helpLinkAnnotation": "Ajouter un emplacement", - "xpack.uptime.mappingErrorRoute.breadcrumb": "Erreur de mapping", - "xpack.uptime.mappingErrorRoute.pageHeader.title": "Erreur de mapping", - "xpack.uptime.mappingErrorRoute.title": "Synthetics | erreur de mapping", - "xpack.uptime.millisecond.abbreviation.label": "ms", - "xpack.uptime.ml.durationChart.exploreInMlApp": "Explorer dans ML App", - "xpack.uptime.ml.enableAnomalyDetectionPanel.add_job_permissions_needed": "Autorisations requises", - "xpack.uptime.ml.enableAnomalyDetectionPanel.anomalyDetectionTitle": "Détection des anomalies", - "xpack.uptime.ml.enableAnomalyDetectionPanel.cancelLabel": "Annuler", - "xpack.uptime.ml.enableAnomalyDetectionPanel.createMLJobDescription": "Ici, vous pouvez créer une tâche de Machine Learning afin de calculer les scores d'anomalie pour\n les durées de réponse pour Uptime Monitor. Une fois activé, le graphique de durée de monitoring de la page des détails\n affichera les limites attendues et annotera le graphique avec les anomalies. Vous pouvez aussi éventuellement\n identifier les périodes de latence augmentées selon les zones géographiques.", - "xpack.uptime.ml.enableAnomalyDetectionPanel.createNewJobButtonLabel": "Créer une nouvelle tâche", - "xpack.uptime.ml.enableAnomalyDetectionPanel.disableAnomalyAlert": "Désactiver l'alerte d'anomalie", - "xpack.uptime.ml.enableAnomalyDetectionPanel.disableAnomalyDetectionTitle": "Désactiver la détection des anomalies", - "xpack.uptime.ml.enableAnomalyDetectionPanel.enable_or_manage_job": "Vous pouvez activer la tâche de détection des anomalies, ou, si elle est déjà présente, vous pouvez gérer la tâche ou l'alerte.", - "xpack.uptime.ml.enableAnomalyDetectionPanel.enableAnomalyAlert": "Activer l'alerte d'anomalie", - "xpack.uptime.ml.enableAnomalyDetectionPanel.enableAnomalyDetectionTitle": "Activer la détection des anomalies", - "xpack.uptime.ml.enableAnomalyDetectionPanel.insufficient_permissions_add_job": "Vous devez disposer des privilèges Kibana de Machine Learning pour utiliser cette fonctionnalité.", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreatedLazyNotificationText": "L'analyse attend qu'un nœud de ML devienne disponible. L'ajout des résultats au graphique peut prendre un certain temps.", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreatedNotificationText": "L'analyse est à présent en cours d'exécution pour le graphique de durée de réponse. L'ajout des résultats au graphique peut prendre un certain temps.", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreatedNotificationText.viewJobLinkText": "Afficher la tâche", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreatedNotificationTitle": "Tâche créée avec succès", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreationFailedNotificationText": "Il est possible que votre licence actuelle n'autorise pas la création de tâches de Machine Learning, ou cette tâche existe peut-être déjà.", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreationFailedNotificationTitle": "La création de la tâche a échoué", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobDeletionConfirmLabel": "Supprimer la tâche de détection des anomalies ?", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobDeletionNotificationTitle": "Tâche supprimée", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobDeletionSuccessNotificationText": "La tâche a été supprimée avec succès", - "xpack.uptime.ml.enableAnomalyDetectionPanel.manageAnomalyDetectionTitle": "Gérer la détection des anomalies", - "xpack.uptime.ml.enableAnomalyDetectionPanel.manageMLJobDescription": "Une fois qu'une tâche a été créée, vous pouvez la gérer et afficher davantage de détails sur la {mlJobsPageLink}.", - "xpack.uptime.ml.enableAnomalyDetectionPanel.manageMLJobDescription.mlJobsPageLinkText": "Page de gestion des tâches de Machine Learning", - "xpack.uptime.ml.enableAnomalyDetectionPanel.manageMLJobDescription.noteText": "Remarque : La tâche peut mettre un certain temps à démarrer le calcul des résultats.", - "xpack.uptime.ml.enableAnomalyDetectionPanel.noPermissionsTooltip": "Vous devez disposer d'un accès en lecture-écriture à Uptime pour créer des alertes d'anomalie.", - "xpack.uptime.ml.enableAnomalyDetectionPanel.startTrial": "Commencer un essai gratuit de 14 jours", - "xpack.uptime.ml.enableAnomalyDetectionPanel.startTrialDesc": "Pour pouvoir accéder à la détection des anomalies de durée, vous devez être abonné à une licence Elastic Platinum.", - "xpack.uptime.monitor.simpleStatusAlert.email.subject": "Le moniteur {monitor} possédant l'URL {url} est arrêté", - "xpack.uptime.monitorCharts.durationChart.leftAxis.title": "Durée en {unit}", - "xpack.uptime.monitorCharts.durationChart.wrapper.label": "Graphique affichant la durée de ping du moniteur, avec regroupement par emplacement.", - "xpack.uptime.monitorCharts.monitorDuration.titleLabel": "Durée du moniteur", - "xpack.uptime.monitorCharts.monitorDuration.titleLabelWithAnomaly": "Durée du moniteur (Anomalies : {noOfAnomalies})", - "xpack.uptime.monitorDetails.ml.confirmAlertDeleteMessage": "Voulez-vous vraiment supprimer l'alerte pour les anomalies ?", - "xpack.uptime.monitorDetails.ml.confirmDeleteMessage": "Voulez-vous vraiment supprimer cette tâche ?", - "xpack.uptime.monitorDetails.ml.deleteJobWarning": "La suppression d'une tâche peut prendre beaucoup de temps. Elle sera supprimée en arrière-plan, et les données ne disparaîtront peut-être pas instantanément.", - "xpack.uptime.monitorDetails.ml.deleteMessage": "Suppression des tâches...", - "xpack.uptime.monitorDetails.statusBar.pingType.browser": "Navigateur", - "xpack.uptime.monitorDetails.statusBar.pingType.http": "HTTP", - "xpack.uptime.monitorDetails.statusBar.pingType.icmp": "ICMP", - "xpack.uptime.monitorDetails.statusBar.pingType.tcp": "TCP", - "xpack.uptime.monitorDetails.title.disclaimer.description": "(BÊTA)", - "xpack.uptime.monitorDetails.title.disclaimer.link": "Afficher plus", - "xpack.uptime.monitorDetails.title.pingType.browser": "Navigateur", - "xpack.uptime.monitorDetails.title.pingType.http": "Ping HTTP", - "xpack.uptime.monitorDetails.title.pingType.icmp": "Ping ICMP", - "xpack.uptime.monitorDetails.title.pingType.tcp": "Ping TCP", - "xpack.uptime.monitorList.allMonitors": "Tous les moniteurs", - "xpack.uptime.monitorList.anomalyColumn.label": "Score d'anomalies de réponse", - "xpack.uptime.monitorList.defineConnector.description": "Définissez un connecteur par défaut dans {link} pour activer les alertes de statut du moniteur.", - "xpack.uptime.monitorList.defineConnector.popover.description": "pour recevoir les alertes de statut.", - "xpack.uptime.monitorList.disableDownAlert": "Désactiver les alertes de statut", - "xpack.uptime.monitorList.downLineSeries.downLabel": "Vérifications des arrêts", - "xpack.uptime.monitorList.drawer.missingLocation": "Certaines instances Heartbeat n'ont pas d'emplacement défini. {link} vers votre configuration Heartbeat.", - "xpack.uptime.monitorList.drawer.mostRecentRun": "Exécution de test la plus récente", - "xpack.uptime.monitorList.drawer.statusRowLocationList": "Liste d'emplacements ayant le statut \"{status}\" à la dernière vérification.", - "xpack.uptime.monitorList.drawer.url": "Url", - "xpack.uptime.monitorList.enabledAlerts.noAlert": "Aucune règle n'est activée pour ce moniteur.", - "xpack.uptime.monitorList.enabledAlerts.title": "Règles activées", - "xpack.uptime.monitorList.enableDownAlert": "Activer les alertes de statut", - "xpack.uptime.monitorList.errorSummary": "Résumé des erreurs", - "xpack.uptime.monitorList.expandDrawerButton.ariaLabel": "Développer la ligne du moniteur avec l'ID {id}", - "xpack.uptime.monitorList.geoName.helpLinkAnnotation": "Ajouter un emplacement", - "xpack.uptime.monitorList.infraIntegrationAction.container.message": "Afficher les indicateurs de conteneurs", - "xpack.uptime.monitorList.infraIntegrationAction.docker.description": "Vérifier l'interface utilisateur de l'infrastructure pour cet ID de conteneur du moniteur", - "xpack.uptime.monitorList.infraIntegrationAction.docker.tooltip": "Vérifier l'interface utilisateur de l'infrastructure pour l'ID de conteneur \"{containerId}\"", - "xpack.uptime.monitorList.infraIntegrationAction.ip.ariaLabel": "Vérifier l'interface utilisateur de l'infrastructure pour cette adresse IP du moniteur", - "xpack.uptime.monitorList.infraIntegrationAction.ip.message": "Afficher les indicateurs d'hôte", - "xpack.uptime.monitorList.infraIntegrationAction.ip.tooltip": "Vérifier l'interface utilisateur de l'infrastructure pour l'IP \"{ip}\"", - "xpack.uptime.monitorList.infraIntegrationAction.kubernetes.description": "Vérifier l'interface utilisateur de l'infrastructure pour cet UID de pod du monitoring", - "xpack.uptime.monitorList.infraIntegrationAction.kubernetes.message": "Afficher les indicateurs de pod", - "xpack.uptime.monitorList.infraIntegrationAction.kubernetes.tooltip": "Vérifier l'interface utilisateur de l'infrastructure pour l'UID de pod \"{podUid}\".", - "xpack.uptime.monitorList.integrationGroup.emptyMessage": "Aucune application intégrée n'est disponible", - "xpack.uptime.monitorList.invalidMonitors": "Moniteurs non valides", - "xpack.uptime.monitorList.loading": "Chargement...", - "xpack.uptime.monitorList.locations.expand": "Cliquer pour afficher les emplacements restants", - "xpack.uptime.monitorList.loggingIntegrationAction.container.id": "Afficher les logs du conteneur", - "xpack.uptime.monitorList.loggingIntegrationAction.container.message": "Afficher les logs du conteneur", - "xpack.uptime.monitorList.loggingIntegrationAction.container.tooltip": "Vérifier l'interface utilisateur de logging pour l'ID de conteneur \"{containerId}\"", - "xpack.uptime.monitorList.loggingIntegrationAction.ip.description": "Vérifier l'interface utilisateur de logging pour cette adresse IP de moniteur", - "xpack.uptime.monitorList.loggingIntegrationAction.ip.message": "Afficher les logs des hôtes", - "xpack.uptime.monitorList.loggingIntegrationAction.ip.tooltip": "Vérifier l'interface utilisateur de logging pour l'IP \"{ip}\"", - "xpack.uptime.monitorList.loggingIntegrationAction.kubernetes.ariaLabel": "Afficher les logs de pod", - "xpack.uptime.monitorList.loggingIntegrationAction.kubernetes.message": "Afficher les logs de pod", - "xpack.uptime.monitorList.loggingIntegrationAction.kubernetes.tooltip": "Rechercher les logs pour l'UID de pod \"{podUid}\"", - "xpack.uptime.monitorList.monitorHistoryColumnLabel": "Historique d'indisponibilité", - "xpack.uptime.monitorList.monitoringStatusTitle": "Moniteurs", - "xpack.uptime.monitorList.monitorType.filter": "Filtrer tous les moniteurs ayant le type {type}", - "xpack.uptime.monitorList.mostRecentError.title": "Erreurs les plus récentes ({timestamp})", - "xpack.uptime.monitorList.nameColumnLabel": "Nom", - "xpack.uptime.monitorList.noDownHistory": "Ce moniteur n'a jamais été {emphasizedText} au cours de la plage temporelle sélectionnée.", - "xpack.uptime.monitorList.noItemForSelectedFiltersMessage": "Aucun moniteur trouvé pour les critères de filtre sélectionnés", - "xpack.uptime.monitorList.noItemMessage": "Aucun moniteur Uptime trouvé", - "xpack.uptime.monitorList.observabilityIntegrationsColumn.apmIntegrationLink.tooltip": "Cliquez ici pour vérifier les APM pour le domaine \"{domain}\" ou le \"nom de service\" explicitement défini.", - "xpack.uptime.monitorList.observabilityIntegrationsColumn.popoverIconButton.ariaLabel": "Ouvre la fenêtre contextuelle des intégrations pour le moniteur avec l'URL {monitorUrl}", - "xpack.uptime.monitorList.observabilityInvestigateColumn.popoverIconButton.label": "Investiguer", - "xpack.uptime.monitorList.pageSizePopoverButtonText": "Lignes par page : {size}", - "xpack.uptime.monitorList.pageSizeSelect.numRowsItemMessage": "{numRows} lignes", - "xpack.uptime.monitorList.redirects.description": "Heartbeat a suivi {number} redirections lors de l'exécution du ping.", - "xpack.uptime.monitorList.redirects.openWindow": "Le lien s'ouvrira dans une nouvelle fenêtre.", - "xpack.uptime.monitorList.redirects.title": "Redirections", - "xpack.uptime.monitorList.redirects.title.number": "{number}", - "xpack.uptime.monitorList.refresh": "Actualiser", - "xpack.uptime.monitorList.statusAlert.label": "Alerte de statut", - "xpack.uptime.monitorList.statusColumn.checkedTimestamp": "Vérifié à {timestamp}", - "xpack.uptime.monitorList.statusColumn.completeLabel": "Terminé", - "xpack.uptime.monitorList.statusColumn.downLabel": "Arrêté", - "xpack.uptime.monitorList.statusColumn.error.logs": "Logs d'erreurs", - "xpack.uptime.monitorList.statusColumn.error.message": "{message}. Cliquez pour en savoir plus.", - "xpack.uptime.monitorList.statusColumn.error.messageLabel": "{message}. Cliquez pour en savoir plus.", - "xpack.uptime.monitorList.statusColumn.failedLabel": "Échoué", - "xpack.uptime.monitorList.statusColumn.locStatusMessage": "dans {noLoc} emplacement", - "xpack.uptime.monitorList.statusColumn.locStatusMessage.multiple": "dans {noLoc} emplacements", - "xpack.uptime.monitorList.statusColumn.locStatusMessage.tooltip.down": "Arrêté dans {locs}", - "xpack.uptime.monitorList.statusColumn.locStatusMessage.tooltip.up": "Opérationnel dans {locs}", - "xpack.uptime.monitorList.statusColumn.upLabel": "Opérationnel", - "xpack.uptime.monitorList.statusColumnLabel": "Statut", - "xpack.uptime.monitorList.table.description": "Tableau de statut de moniteur avec les colonnes Statut, Nom, URL, IP, Historique d'indisponibilité et Intégrations. Le tableau affiche actuellement {length} éléments.", - "xpack.uptime.monitorList.table.tags.name": "Balises", - "xpack.uptime.monitorList.table.url.name": "Url", - "xpack.uptime.monitorList.tags.expand": "Cliquer pour afficher les balises restantes", - "xpack.uptime.monitorList.tags.filter": "Filtrer tous les moniteurs avec la balise {tag}", - "xpack.uptime.monitorList.testNow.AriaLabel": "Cliquer pour exécuter le test maintenant", - "xpack.uptime.monitorList.testNow.available": "L'option Tester maintenant est uniquement disponible pour les moniteurs ajoutés via la liste Gestion des moniteurs.", - "xpack.uptime.monitorList.testNow.label": "Tester maintenant", - "xpack.uptime.monitorList.testNow.scheduled": "Le test est déjà programmé", - "xpack.uptime.monitorList.testRunLogs": "Logs d'exécution de test", - "xpack.uptime.monitorList.timestamp": "Horodatage", - "xpack.uptime.monitorList.tlsColumnLabel": "Certificat TLS", - "xpack.uptime.monitorList.viewInDiscover": "Afficher dans Discover", - "xpack.uptime.monitorManagement.addMonitorCrumb": "Ajouter un moniteur", - "xpack.uptime.monitorManagement.addMonitorError": "Impossible de charger les emplacements de services. Réessayez plus tard.", - "xpack.uptime.monitorManagement.addMonitorLabel": "Ajouter un moniteur", - "xpack.uptime.monitorManagement.addMonitorLoadingError": "Erreur lors du chargement de la liste Gestion des moniteurs", - "xpack.uptime.monitorManagement.addMonitorLoadingLabel": "Chargement de la liste Gestion des moniteurs", - "xpack.uptime.monitorManagement.addMonitorServiceLocationsLoadingError": "Impossible de charger les emplacements de services. Réessayez plus tard.", - "xpack.uptime.monitorManagement.closeButtonLabel": "Fermer", - "xpack.uptime.monitorManagement.completed": "TERMINÉ", - "xpack.uptime.monitorManagement.confirmDescriptionLabel": "Cette action supprimera le moniteur mais conservera toute donnée collectée. Cette action ne peut pas être annulée.", - "xpack.uptime.monitorManagement.deleteMonitorLabel": "Supprimer le moniteur", - "xpack.uptime.monitorManagement.disableMonitorLabel": "Désactiver le moniteur", - "xpack.uptime.monitorManagement.discardLabel": "Abandonner", - "xpack.uptime.monitorManagement.duplicateNameError": "Le nom du moniteur existe déjà.", - "xpack.uptime.monitorManagement.editMonitorCrumb": "Modifier le moniteur", - "xpack.uptime.monitorManagement.editMonitorError": "Erreur lors du chargement de la liste Gestion des moniteurs", - "xpack.uptime.monitorManagement.editMonitorErrorBody": "Impossible de charger la configuration du moniteur. Réessayez plus tard.", - "xpack.uptime.monitorManagement.editMonitorLabel": "Modifier le moniteur", - "xpack.uptime.monitorManagement.editMonitorLoadingLabel": "Chargement du moniteur", - "xpack.uptime.monitorManagement.enableMonitorLabel": "Activer le moniteur", - "xpack.uptime.monitorManagement.failed": "ÉCHOUÉ", - "xpack.uptime.monitorManagement.failedRun": "Impossible d'exécuter les étapes", - "xpack.uptime.monitorManagement.inProgress": "EN COURS", - "xpack.uptime.monitorManagement.label": "Gestion des moniteurs", - "xpack.uptime.monitorManagement.loading.label": "Chargement de la liste Gestion des moniteurs", - "xpack.uptime.monitorManagement.loadingSteps": "Chargement des étapes...", - "xpack.uptime.monitorManagement.monitorAddedSuccessMessage": "Moniteur ajouté avec succès.", - "xpack.uptime.monitorManagement.monitorAdvancedOptions.dataStreamConfiguration.description": "Configurez les options de flux de données supplémentaires.", - "xpack.uptime.monitorManagement.monitorAdvancedOptions.dataStreamConfiguration.title": "Paramètres de flux de données", - "xpack.uptime.monitorManagement.monitorAdvancedOptions.monitorNamespaceFieldLabel": "Espace de nom", - "xpack.uptime.monitorManagement.monitorAdvancedOptions.namespaceHelpLabel": "Modifiez l'espace de nom par défaut. Ce paramètre modifie le nom du flux de données du moniteur. {learnMore}.", - "xpack.uptime.monitorManagement.monitorAdvancedOptions.namespaceHelpLearnMoreLabel": "En savoir plus", - "xpack.uptime.monitorManagement.monitorDeleteFailureMessage": "Impossible de supprimer le moniteur. Réessayez plus tard.", - "xpack.uptime.monitorManagement.monitorDeleteLoadingMessage": "Suppression du moniteur...", - "xpack.uptime.monitorManagement.monitorDeleteSuccessMessage": "Moniteur supprimé avec succès.", - "xpack.uptime.monitorManagement.monitorDisabledSuccessMessage": "Moniteur {name} désactivé avec succès.", - "xpack.uptime.monitorManagement.monitorEditedSuccessMessage": "Moniteur mis à jour avec succès.", - "xpack.uptime.monitorManagement.monitorEnabledSuccessMessage": "Moniteur {name} activé avec succès.", - "xpack.uptime.monitorManagement.monitorEnabledUpdateFailureMessage": "Impossible de mettre à jour le moniteur {name}.", - "xpack.uptime.monitorManagement.monitorFailureMessage": "Impossible d'enregistrer le moniteur. Réessayez plus tard.", - "xpack.uptime.monitorManagement.monitorList.actions": "Actions", - "xpack.uptime.monitorManagement.monitorList.enabled": "Activé", - "xpack.uptime.monitorManagement.monitorList.locations": "Emplacements", - "xpack.uptime.monitorManagement.monitorList.monitorName": "Nom de moniteur", - "xpack.uptime.monitorManagement.monitorList.monitorType": "Type de moniteur", - "xpack.uptime.monitorManagement.monitorList.schedule": "Fréquence (min)", - "xpack.uptime.monitorManagement.monitorList.tags": "Balises", - "xpack.uptime.monitorManagement.monitorList.title": "Liste Gestion des moniteurs", - "xpack.uptime.monitorManagement.monitorList.URL": "URL", - "xpack.uptime.monitorManagement.monitorLocationsLabel": "Emplacements des moniteurs", - "xpack.uptime.monitorManagement.monitorManagementCrumb": "Gestion des moniteurs", - "xpack.uptime.monitorManagement.monitorNameFieldError": "Le nom de moniteur est requis", - "xpack.uptime.monitorManagement.monitorNameFieldLabel": "Nom de moniteur", - "xpack.uptime.monitorManagement.noLabel": "Annuler", - "xpack.uptime.monitorManagement.pageHeader.title": "Gérer les moniteurs", - "xpack.uptime.monitorManagement.pending": "EN ATTENTE", - "xpack.uptime.monitorManagement.publicBetaDescription": "La liste Gestion des moniteurs est disponible uniquement pour les utilisateurs de la version bêta publique sélectionnés. Avec un accès\nà la version bêta publique, vous pourrez ajouter des vérifications HTTP, TCP, ICMP et Navigateur qui seront\nexécutées sur les nœuds de service synthétiques gérés d'Elastic.", - "xpack.uptime.monitorManagement.requestAccess": "Demander un accès", - "xpack.uptime.monitorManagement.reRunTest": "Exécuter à nouveau le test", - "xpack.uptime.monitorManagement.runTest": "Exécuter le test", - "xpack.uptime.monitorManagement.saveMonitorLabel": "Enregistrer le moniteur", - "xpack.uptime.monitorManagement.service.error.message": "Votre moniteur a été enregistré, mais un problème est survenu lors de la synchronisation de la configuration pour {location}. Nous réessaierons plus tard de façon automatique. Si le problème persiste, vos moniteurs arrêteront de fonctionner dans {location}. Veuillez contacter le support technique pour obtenir de l'aide.", - "xpack.uptime.monitorManagement.service.error.reason": "Raison : {reason}.", - "xpack.uptime.monitorManagement.service.error.status": "Statut : {status}. ", - "xpack.uptime.monitorManagement.service.error.title": "Impossible de synchroniser la configuration du moniteur", - "xpack.uptime.monitorManagement.serviceLocationsValidationError": "Au moins un emplacement de service doit être spécifié", - "xpack.uptime.monitorManagement.stepCompleted": "{stepCount, number} {stepCount, plural, one {étape terminée} other {étapes terminées}}", - "xpack.uptime.monitorManagement.testResult": "Résultat du test", - "xpack.uptime.monitorManagement.timeTaken": "Durée de {timeTaken}", - "xpack.uptime.monitorManagement.updateMonitorLabel": "Mettre à jour le moniteur", - "xpack.uptime.monitorManagement.validationError": "Votre moniteur comporte des erreurs. Corrigez-les avant de l'enregistrer.", - "xpack.uptime.monitorManagement.viewTestRunDetails": "Afficher les détails du résultat du test", - "xpack.uptime.monitorManagement.yesLabel": "Supprimer", - "xpack.uptime.monitorManagementRoute.title": "Gérer les moniteurs | {baseTitle}", - "xpack.uptime.monitorRoute.title": "Moniteur | {baseTitle}", - "xpack.uptime.monitorStatusBar.durationTextAriaLabel": "Durée du monitoring en millisecondes", - "xpack.uptime.monitorStatusBar.healthStatusMessageAriaLabel": "Statut du moniteur", - "xpack.uptime.monitorStatusBar.loadingMessage": "Chargement…", - "xpack.uptime.monitorStatusBar.locations.oneLocStatus": "{status} dans {loc} emplacement", - "xpack.uptime.monitorStatusBar.locations.upStatus": "{status} dans {loc} emplacements", - "xpack.uptime.monitorStatusBar.monitor.availability": "Disponibilité générale", - "xpack.uptime.monitorStatusBar.monitor.availabilityReport.availability": "Disponibilité", - "xpack.uptime.monitorStatusBar.monitor.availabilityReport.lastCheck": "Dernière vérification", - "xpack.uptime.monitorStatusBar.monitor.availabilityReport.location": "Emplacement", - "xpack.uptime.monitorStatusBar.monitor.id": "ID de moniteur", - "xpack.uptime.monitorStatusBar.monitor.monitoringFrom": "Monitoring à partir de", - "xpack.uptime.monitorStatusBar.monitor.monitoringFrom.listToMap": "Passer à la vue de carte pour vérifier la disponibilité par emplacement.", - "xpack.uptime.monitorStatusBar.monitor.monitoringFrom.MapToList": "Passer à la vue de liste pour vérifier la disponibilité par emplacement.", - "xpack.uptime.monitorStatusBar.monitorUrlLinkAriaLabel": "Lien d'URL du moniteur", - "xpack.uptime.monitorStatusBar.sslCertificate.title": "Certificat TLS", - "xpack.uptime.monitorStatusBar.timestampFromNowTextAriaLabel": "Temps depuis la dernière vérification", - "xpack.uptime.monitorStatusBar.type.ariaLabel": "Type de moniteur", - "xpack.uptime.monitorStatusBar.type.label": "Type", - "xpack.uptime.navigateToAlertingButton.content": "Gérer les règles", - "xpack.uptime.navigateToAlertingUi": "Quitter Uptime et accéder à la page de gestion Alerting", - "xpack.uptime.noDataConfig.beatsCard.description": "Monitorez de façon proactive la disponibilité de vos sites et services. Recevez des alertes et corrigez les problèmes plus rapidement pour optimiser l'expérience de vos utilisateurs.", - "xpack.uptime.noDataConfig.beatsCard.title": "Ajouter des moniteurs avec Heartbeat", - "xpack.uptime.noDataConfig.solutionName": "Observabilité", - "xpack.uptime.notFountPage.homeLinkText": "Retour à l'accueil", - "xpack.uptime.openAlertContextPanel.ariaLabel": "Ouvrez le panneau de contexte des règles pour choisir un type de règle", - "xpack.uptime.openAlertContextPanel.label": "Créer une règle", - "xpack.uptime.overview.alerts.disabled.failed": "La règle ne peut pas être désactivée !", - "xpack.uptime.overview.alerts.disabled.success": "La règle a été correctement désactivée !", - "xpack.uptime.overview.alerts.enabled.failed": "La règle ne peut pas être activée !", - "xpack.uptime.overview.alerts.enabled.success": "La règle a été correctement activée ", - "xpack.uptime.overview.alerts.enabled.success.description": "Un message sera envoyé à {actionConnectors} lorsque ce monitoring sera arrêté.", - "xpack.uptime.overview.heading": "Moniteurs", - "xpack.uptime.overview.pageHeader.syntheticsCallout.announcementLink": "Lire l'annonce", - "xpack.uptime.overview.pageHeader.syntheticsCallout.content": "Uptime affiche maintenant l'aperçu du support pour les vérifications scriptées de disponibilité à plusieurs étapes. Cela signifie que vous pouvez interagir avec les éléments d'une page Web et vérifier la disponibilité d'un parcours complet (par exemple, effectuer un achat ou se connecter à un système) au lieu d'effectuer de simples petites vérifications. Veuillez cliquer ci-dessous pour en savoir plus et, si vous souhaitez être l'un des premiers à utiliser ces fonctionnalités, vous pouvez télécharger notre agent d'aperçu synthétique et visualiser vos vérifications synthétiques dans Uptime.", - "xpack.uptime.overview.pageHeader.syntheticsCallout.dismissButtonText": "Rejeter", - "xpack.uptime.overview.pageHeader.syntheticsCallout.title": "Elastic Synthetics", - "xpack.uptime.overviewPage.headerText": "Aperçu", - "xpack.uptime.overviewPageLink.disabled.ariaLabel": "Bouton de pagination désactivé indiquant qu'aucune autre navigation ne peut être effectuée dans la liste des moniteurs.", - "xpack.uptime.overviewPageLink.next.ariaLabel": "Page de résultats suivante", - "xpack.uptime.overviewPageLink.prev.ariaLabel": "Page de résultats précédente", - "xpack.uptime.page_header.addDataLink.label": "Accédez à un tutoriel sur l'ajout de données Uptime", - "xpack.uptime.page_header.analyzeData.label": "Accédez à la vue \"Explorer les données\" pour visualiser les données synthétiques/d'utilisateur", - "xpack.uptime.page_header.defineConnector.popover.defaultLink": "Définir un connecteur par défaut", - "xpack.uptime.page_header.defineConnector.settingsLink": "Paramètres", - "xpack.uptime.page_header.manageLink.label": "Accéder à la page de gestion des moniteurs Uptime", - "xpack.uptime.page_header.settingsLink": "Paramètres", - "xpack.uptime.page_header.settingsLink.label": "Accédez à la page de paramètres Uptime", - "xpack.uptime.pingHistogram.analyze": "Analyser", - "xpack.uptime.pingist.durationSecondsColumnFormatting": "{seconds} secondes", - "xpack.uptime.pingist.durationSecondsColumnFormatting.singular": "{seconds} seconde", - "xpack.uptime.pingList.checkHistoryTitle": "Historique", - "xpack.uptime.pingList.collapseRow": "Réduire", - "xpack.uptime.pingList.columns.failedStep": "Étape ayant échoué", - "xpack.uptime.pingList.drawer.body.docsLink": "documents", - "xpack.uptime.pingList.durationMsColumnFormatting": "{millis} ms", - "xpack.uptime.pingList.durationMsColumnLabel": "Durée", - "xpack.uptime.pingList.errorColumnLabel": "Erreur", - "xpack.uptime.pingList.errorTypeColumnLabel": "Type d'erreur", - "xpack.uptime.pingList.expandedRow.bodySize": "La taille du corps est de {bodyBytes}.", - "xpack.uptime.pingList.expandedRow.error": "Erreur", - "xpack.uptime.pingList.expandedRow.response_body": "Corps de réponse", - "xpack.uptime.pingList.expandedRow.response_body.notRecorded": "Corps non enregistré. Lisez notre {docsLink} pour en savoir plus sur l'enregistrement des corps de réponse.", - "xpack.uptime.pingList.expandedRow.truncated": "Affichage des {contentBytes} premiers octets.", - "xpack.uptime.pingList.expandRow": "Développer", - "xpack.uptime.pingList.headers.title": "En-têtes de réponse", - "xpack.uptime.pingList.ipAddressColumnLabel": "IP", - "xpack.uptime.pingList.locationNameColumnLabel": "Emplacement", - "xpack.uptime.pingList.pingsLoadingMesssage": "Chargement de l'historique...", - "xpack.uptime.pingList.pingsUnavailableMessage": "Aucun historique trouvé", - "xpack.uptime.pingList.recencyMessage": "Vérifié {fromNow}", - "xpack.uptime.pingList.responseCodeColumnLabel": "Code de réponse", - "xpack.uptime.pingList.statusColumnLabel": "Statut", - "xpack.uptime.pingList.stepDurationHeader": "Durée de l’étape", - "xpack.uptime.pingList.synthetics.performanceBreakDown": "Afficher la répartition des performances", - "xpack.uptime.pingList.synthetics.waterfall.filters.collapseRequestsLabel": "Réduire pour afficher uniquement les requêtes correspondantes", - "xpack.uptime.pingList.synthetics.waterfall.filters.popover": "Cliquer pour ouvrir les filtres de cascade", - "xpack.uptime.pingList.timestampColumnLabel": "Horodatage", - "xpack.uptime.pluginDescription": "Monitoring Uptime", - "xpack.uptime.public.pages.mappingError.bodyDocsLink": "Vous pouvez apprendre à corriger ce problème dans la {docsLink}.", - "xpack.uptime.public.pages.mappingError.bodyMessage": "Mappings incorrects détectés ! Vous avez peut-être oublié d'exécuter la commande {setup} Heartbeat ?", - "xpack.uptime.public.pages.mappingError.title": "Mappings Heartbeat manquants", - "xpack.uptime.routes.baseTitle": "Uptime - Kibana", - "xpack.uptime.seconds.label": "secondes", - "xpack.uptime.seconds.shortForm.label": "s", - "xpack.uptime.settings.blank.error": "Ne peut pas être vide.", - "xpack.uptime.settings.blankNumberField.error": "Doit être un nombre.", - "xpack.uptime.settings.cannotEditText": "Actuellement, votre utilisateur possède les autorisations \"Lecture\" pour l'application Uptime. Activez un niveau d'autorisation \"Tout\" pour pouvoir modifier ces paramètres.", - "xpack.uptime.settings.cannotEditTitle": "Vous ne disposez pas d'autorisation pour modifier les paramètres.", - "xpack.uptime.settings.error.couldNotSave": "Impossible d'enregistrer les paramètres !", - "xpack.uptime.settings.heading": "Paramètres Uptime", - "xpack.uptime.settings.invalid.error": "La valeur doit être supérieure à 0.", - "xpack.uptime.settings.invalid.nanError": "La valeur doit être un entier.", - "xpack.uptime.settings.noSpace.error": "Les noms d'index ne doivent pas contenir d'espace", - "xpack.uptime.settings.saveSuccess": "Paramètres enregistrés !", - "xpack.uptime.settingsBreadcrumbText": "Paramètres", - "xpack.uptime.settingsRoute.title": "Paramètres | {baseTitle}", - "xpack.uptime.snapshot.donutChart.ariaLabel": "Camembert affichant le statut actuel. {down} moniteurs sur {total} sont arrêtés.", - "xpack.uptime.snapshot.monitor": "Moniteur", - "xpack.uptime.snapshot.monitors": "Moniteurs", - "xpack.uptime.snapshot.noDataDescription": "Aucun ping dans la plage temporelle sélectionnée.", - "xpack.uptime.snapshot.noDataTitle": "Pas de données ping disponibles", - "xpack.uptime.snapshot.pingsOverTimeTitle": "Pings sur la durée", - "xpack.uptime.snapshotHistogram.description": "Graphique à barres affichant le statut Uptime au fil du temps de {startTime} à {endTime}.", - "xpack.uptime.snapshotHistogram.series.pings": "Monitorer les pings", - "xpack.uptime.snapshotHistogram.xAxisId": "Axe X des pings", - "xpack.uptime.snapshotHistogram.yAxis.title": "Pings", - "xpack.uptime.snapshotHistogram.yAxisId": "Axe Y des pings", - "xpack.uptime.sourceConfiguration.ageLimit.units.days": "Jours", - "xpack.uptime.sourceConfiguration.ageLimitThresholdInput.ariaLabel": "Entrée contrôlant le nombre maximal de jours pendant lesquels un certificat TLS peut être valide avant que Kibana n'affiche un avertissement.", - "xpack.uptime.sourceConfiguration.ageThresholdDefaultValue": "La valeur par défaut est {defaultValue}", - "xpack.uptime.sourceConfiguration.alertConnectors": "Connecteurs d'alerte", - "xpack.uptime.sourceConfiguration.alertConnectors.defaultEmail": "E-mail par défaut", - "xpack.uptime.sourceConfiguration.alertDefaultForm.emailConnectorPlaceHolder": "À : pour le connecteur d'e-mails", - "xpack.uptime.sourceConfiguration.alertDefaultForm.invalidEmail": "{val} n'est pas un e-mail valide.", - "xpack.uptime.sourceConfiguration.alertDefaultForm.requiredEmail": "L'e-mail du destinataire est requis pour le connecteur d'e-mails", - "xpack.uptime.sourceConfiguration.alertDefaultForm.selectConnector": "Veuillez sélectionner un ou plusieurs connecteurs", - "xpack.uptime.sourceConfiguration.alertDefaults": "Valeurs par défaut des alertes", - "xpack.uptime.sourceConfiguration.applySettingsButtonLabel": "Appliquer les modifications", - "xpack.uptime.sourceConfiguration.certificateExpirationThresholdInput.ariaLabel": "Entrée contrôlant le nombre minimal de jours restants pour l'expiration du certificat TLS avant que Kibana n'affiche un avertissement.", - "xpack.uptime.sourceConfiguration.certificateThresholdDescription": "Modifiez le seuil pour l'affichage et l'alerting lors d'erreurs de certificat. Remarque : cette action affectera toutes les alertes configurées.", - "xpack.uptime.sourceConfiguration.certificationSectionTitle": "Expiration du certificat", - "xpack.uptime.sourceConfiguration.defaultConnectors": "Connecteurs par défaut", - "xpack.uptime.sourceConfiguration.defaultConnectors.description": "Connecteurs par défaut à utiliser pour envoyer une alerte.", - "xpack.uptime.sourceConfiguration.defaultConnectors.description.defaultEmail": "Paramètres d'e-mails requis pour les connecteurs d'alertes d'e-mails sélectionnés.", - "xpack.uptime.sourceConfiguration.discardSettingsButtonLabel": "Annuler", - "xpack.uptime.sourceConfiguration.errorStateLabel": "Seuil d'expiration", - "xpack.uptime.sourceConfiguration.expirationThreshold": "Seuils expiration/âge", - "xpack.uptime.sourceConfiguration.expirationThresholdDefaultValue": "La valeur par défaut est {defaultValue}", - "xpack.uptime.sourceConfiguration.heartbeatIndicesDefaultValue": "La valeur par défaut est {defaultValue}", - "xpack.uptime.sourceConfiguration.heartbeatIndicesDescription": "Modèle d'indexation pour la correspondance d'index contenant des données Heartbeat", - "xpack.uptime.sourceConfiguration.heartbeatIndicesLabel": "Index Heartbeat", - "xpack.uptime.sourceConfiguration.heartbeatIndicesTitle": "Index Uptime", - "xpack.uptime.sourceConfiguration.indicesSectionTitle": "Index", - "xpack.uptime.sourceConfiguration.warningStateLabel": "Limite d'âge", - "xpack.uptime.stepDetailRoute.title": "Détail synthétique | {baseTitle}", - "xpack.uptime.stepList.collapseRow": "Réduire", - "xpack.uptime.stepList.expandRow": "Développer", - "xpack.uptime.stepList.stepName": "Nom de l'étape", - "xpack.uptime.synthetics.consoleStepList.message": "Ce parcours n'a pas réussi à s'exécuter ; la sortie de la console enregistrée est affichée ci-dessous :", - "xpack.uptime.synthetics.consoleStepList.title": "Aucune étape exécutée", - "xpack.uptime.synthetics.emptyJourney.message.checkGroupField": "Le groupe de vérification du parcours est {codeBlock}.", - "xpack.uptime.synthetics.emptyJourney.message.footer": "Aucune autre information à afficher.", - "xpack.uptime.synthetics.emptyJourney.message.heading": "Le parcours ne contenait aucune étape.", - "xpack.uptime.synthetics.emptyJourney.title": "Aucune étape pour ce parcours", - "xpack.uptime.synthetics.executedStep.consoleOutput.label": "Sortie de la console", - "xpack.uptime.synthetics.executedStep.errorHeading": "Message d'erreur", - "xpack.uptime.synthetics.executedStep.screenshot.not": "Capture d'écran", - "xpack.uptime.synthetics.executedStep.screenshot.notSucceeded": "Capture d'écran pour la vérification du statut {status}", - "xpack.uptime.synthetics.executedStep.screenshot.success": "dernière vérification réussie", - "xpack.uptime.synthetics.executedStep.screenshot.successfulLink": "Capture d'écran de {link}", - "xpack.uptime.synthetics.executedStep.scriptHeading.label": "Script exécuté à cette étape", - "xpack.uptime.synthetics.executedStep.stackTrace": "Trace de la Suite Elastic", - "xpack.uptime.synthetics.imageLoadingSpinner.ariaLabel": "Boucle de progression animée indiquant que l'image est en train de se charger", - "xpack.uptime.synthetics.journey.allFailedMessage": "{total} étapes - toutes échouées ou ignorées", - "xpack.uptime.synthetics.journey.allSucceededMessage": "{total} étapes - toutes réussies", - "xpack.uptime.synthetics.journey.loadingSteps": "Chargement des étapes...", - "xpack.uptime.synthetics.journey.partialSuccessMessage": "{total} étapes - {succeeded} réussies", - "xpack.uptime.synthetics.markers.explore": "Explorer", - "xpack.uptime.synthetics.markers.noFieldIcon.label": "Icône indiquant que ce marqueur ne possède aucun champ associé", - "xpack.uptime.synthetics.markers.openEmbeddableButton.label": "Utilisez ce bouton icône pour afficher les indicateurs pour ce marqueur d'annotation.", - "xpack.uptime.synthetics.nextStepButton.ariaLabel": "Étape suivante", - "xpack.uptime.synthetics.performanceBreakDown.label": "Répartition des performances", - "xpack.uptime.synthetics.pingTimestamp.captionContent": "Étape : {stepNumber} sur {totalSteps}", - "xpack.uptime.synthetics.prevStepButton.airaLabel": "Étape précédente", - "xpack.uptime.synthetics.screenshot.noImageMessage": "Aucune image disponible", - "xpack.uptime.synthetics.screenshotDisplay.altText": "Capture d'écran de l'étape portant le nom \"{stepName}\"", - "xpack.uptime.synthetics.screenshotDisplay.altTextWithoutName": "Capture d'écran", - "xpack.uptime.synthetics.service.apiKey": "Clé d'API du service Synthetics", - "xpack.uptime.synthetics.statusBadge.failedMessage": "Échoué", - "xpack.uptime.synthetics.statusBadge.skippedMessage": "Ignoré", - "xpack.uptime.synthetics.statusBadge.succeededMessage": "Réussi", - "xpack.uptime.synthetics.step.duration": "{value} secondes", - "xpack.uptime.synthetics.step.durationTrend": "Tendance de durée de l'étape", - "xpack.uptime.synthetics.stepDetail.nextCheckButtonText": "Vérification suivante", - "xpack.uptime.synthetics.stepDetail.noData": "Aucune donnée n'a été trouvée pour cette étape", - "xpack.uptime.synthetics.stepDetail.previousCheckButtonText": "Vérification précédente", - "xpack.uptime.synthetics.stepDetail.totalSteps": "Étape {stepIndex} sur {totalSteps}", - "xpack.uptime.synthetics.stepDetail.waterfall.loading": "Chargement du graphique en cascade", - "xpack.uptime.synthetics.stepDetail.waterfallNoData": "Aucune donnée de cascade n'a été trouvée pour cette étape", - "xpack.uptime.synthetics.stepDetail.waterfallUnsupported.description": "Le graphique en cascade ne peut pas être affiché. Vous utilisez peut-être une ancienne version de l'agent synthétique. Veuillez vérifier votre version et envisager d'effectuer une mise à niveau.", - "xpack.uptime.synthetics.stepDetail.waterfallUnsupported.title": "Graphique en cascade non disponible", - "xpack.uptime.synthetics.stepList.nextCheck": "Vérification suivante", - "xpack.uptime.synthetics.stepList.previousCheck": "Vérification précédente", - "xpack.uptime.synthetics.thumbnail.fullSize.alt": "Version plus grande de la capture d'écran de la miniature de l'étape du parcours.", - "xpack.uptime.synthetics.waterfall.domContentLabel": "Contenu DOM chargé", - "xpack.uptime.synthetics.waterfall.fcpLabel": "First Contentful Paint", - "xpack.uptime.synthetics.waterfall.filterGroup.filterScreenreaderLabel": "Filtrer par", - "xpack.uptime.synthetics.waterfall.filterGroup.removeFilterScreenReaderLabel": "Retirer le filtre Filtrer par", - "xpack.uptime.synthetics.waterfall.flyout.certificates": "En-têtes de certificat", - "xpack.uptime.synthetics.waterfall.flyout.details": "Détails", - "xpack.uptime.synthetics.waterfall.flyout.requestHeaders": "En-têtes de la requête", - "xpack.uptime.synthetics.waterfall.flyout.responseHeaders": "En-têtes de réponse", - "xpack.uptime.synthetics.waterfall.layoutShiftLabel": "Layout Shift", - "xpack.uptime.synthetics.waterfall.lcpLabel": "Largest Contentful Paint", - "xpack.uptime.synthetics.waterfall.loadEventLabel": "Charger l'événement", - "xpack.uptime.synthetics.waterfall.offsetUnit": "{offset} ms", - "xpack.uptime.synthetics.waterfall.requestsHighlightedMessage": "({numHighlightedRequests} correspondent au filtre)", - "xpack.uptime.synthetics.waterfall.requestsTotalMessage": "{numNetworkRequests} requêtes réseau", - "xpack.uptime.synthetics.waterfall.requestsTotalMessage.first": "Premier(s)/première(s) {count}", - "xpack.uptime.synthetics.waterfall.requestsTotalMessage.info": "La vue cascade ne peut pas afficher plus de 1 000 requêtes", - "xpack.uptime.synthetics.waterfall.resource.externalLink": "Ouvrir la ressource dans un nouvel onglet", - "xpack.uptime.synthetics.waterfall.searchBox.placeholder": "Filtrer les nouvelles requêtes réseau", - "xpack.uptime.synthetics.waterfall.sidebar.filterMatchesScreenReaderLabel": "La ressource correspond au filtre", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.certificateExpiryDate": "Valide jusque", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.certificateIssueDate": "Valide depuis", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.certificateIssuer": "Émetteur", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.certificateSubject": "Nom courant", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.contentType": "Type de contenu", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.ip": "IP", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.requestStart": "Début de la requête", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.resourceSize": "Taille de la ressource", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.status": "Statut", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.transferSize": "Taille du transfert", - "xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.font": "Police", - "xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.html": "HTML", - "xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.media": "Support", - "xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.other": "Autre", - "xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.script": "JS", - "xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.stylesheet": "CSS", - "xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.xhr": "XHR", - "xpack.uptime.synthetics.waterfallChart.labels.timings.blocked": "En file d'attente / Bloqué", - "xpack.uptime.synthetics.waterfallChart.labels.timings.connect": "Connexion", - "xpack.uptime.synthetics.waterfallChart.labels.timings.dns": "DNS", - "xpack.uptime.synthetics.waterfallChart.labels.timings.receive": "Téléchargement du contenu", - "xpack.uptime.synthetics.waterfallChart.labels.timings.send": "Envoi de la requête", - "xpack.uptime.synthetics.waterfallChart.labels.timings.ssl": "TLS", - "xpack.uptime.synthetics.waterfallChart.labels.timings.wait": "En attente (TTFB)", - "xpack.uptime.syntheticsMonitors": "Uptime - Moniteur", - "xpack.uptime.testRun.description": "Tester votre moniteur et vérifier les résultats avant d'enregistrer", - "xpack.uptime.testRun.pushError": "Impossible d'envoyer le moniteur vers le service.", - "xpack.uptime.testRun.pushErrorLabel": "Erreur d'envoi", - "xpack.uptime.testRun.pushing.description": "Envoi du moniteur vers le service...", - "xpack.uptime.title": "Uptime", - "xpack.uptime.toggleAlertButton.content": "Règle de statut du moniteur", - "xpack.uptime.toggleAlertFlyout.ariaLabel": "Ouvrir le menu volant d'ajout de règle", - "xpack.uptime.toggleTlsAlertButton.ariaLabel": "Ouvrir le menu volant de règle TLS", - "xpack.uptime.toggleTlsAlertButton.content": "Règle TLS", - "xpack.uptime.uptimeFeatureCatalogueTitle": "Uptime", - "xpack.uptime.uptimeSettings.index": "Paramètres Uptime - Index", - "xpack.uptime.waterfallChart.sidebar.url.https": "https", + "xpack.synthetics.addDataButtonLabel": "Ajouter des données", + "xpack.synthetics.addMonitor.pageHeader.title": "Ajouter un moniteur", + "xpack.synthetics.addMonitorRoute.title": "Ajouter un moniteur | {baseTitle}", + "xpack.synthetics.alertDropdown.noWritePermissions": "Vous devez disposer d'un accès en lecture-écriture à Uptime pour créer des alertes dans cette application.", + "xpack.synthetics.alerts.anomaly.criteriaExpression.ariaLabel": "Expression affichant les critères d'un moniteur sélectionné.", + "xpack.synthetics.alerts.anomaly.criteriaExpression.description": "Quand le moniteur", + "xpack.synthetics.alerts.anomaly.scoreExpression.ariaLabel": "Expression affichant les critères d'un seuil d'alerte d'anomalie.", + "xpack.synthetics.alerts.anomaly.scoreExpression.description": "comporte une anomalie avec sévérité", + "xpack.synthetics.alerts.createRulesPanel.title": "Créer des règles", + "xpack.synthetics.alerts.durationAnomaly": "Anomalie de durée Uptime", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.anomalyStartTimestamp": "Horodatage ISO8601 du début de l'anomalie.", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.expectedResponseTime": "Temps de réponse attendu", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.monitor": "Rendu convivial du nom ou de l'ID, ou nom préféré (par ex. Mon moniteur)", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.monitorId": "ID du moniteur.", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.monitorUrl": "URL du moniteur.", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.observerLocation": "Emplacement de l'observateur à partir duquel la vérification des pulsations est effectuée.", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.severity": "Sévérité de l'anomalie.", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.severityScore": "Note de sévérité d'anomalie", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.slowestAnomalyResponse": "Temps de réponse le plus lent dans le compartiment d'anomalies avec des unités associées (ms, s).", + "xpack.synthetics.alerts.durationAnomaly.clientName": "Anomalie de durée Uptime", + "xpack.synthetics.alerts.durationAnomaly.defaultActionMessage": "Temps de réponse anormal (niveau {severity}) détecté dans le {monitor} possédant l'URL {monitorUrl} à {anomalyStartTimestamp}. La note de sévérité anormale est {severityScore}.\nDes temps de réponse aussi élevés que {slowestAnomalyResponse} ont été détectés à partir de l'emplacement {observerLocation}. Le temps de réponse attendu est {expectedResponseTime}.", + "xpack.synthetics.alerts.durationAnomaly.description": "Alerte lorsque la durée du moniteur Uptime est anormale.", + "xpack.synthetics.alerts.monitorExpression.label": "Retirer le filtre {title}", + "xpack.synthetics.alerts.monitorStatus": "Statut du moniteur Uptime", + "xpack.synthetics.alerts.monitorStatus.actionVariables.availabilityMessage": "La disponibilité {interval} est de {availabilityRatio} %. Alerte lorsque < {expectedAvailability} %.", + "xpack.synthetics.alerts.monitorStatus.actionVariables.context.alertReasonMessage.description": "Une description concise de la raison du signalement", + "xpack.synthetics.alerts.monitorStatus.actionVariables.context.downMonitorsWithGeo.description": "Résumé généré montrant certains ou tous les moniteurs détectés comme \"arrêtés\" par l'alerte", + "xpack.synthetics.alerts.monitorStatus.actionVariables.context.message.description": "Message généré résumant les moniteurs actuellement arrêtés", + "xpack.synthetics.alerts.monitorStatus.actionVariables.context.viewInAppUrl.description": "Lien vers la vue ou la fonctionnalité dans Elastic qui peut être utilisée pour examiner l'alerte et son contexte de manière plus approfondie", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.currentTriggerStarted": "Horodatage indiquant à quel moment l'état de déclenchement actuel a commencé, si l'alerte est déclenchée", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.firstCheckedAt": "Horodatage indiquant à quel moment cette alerte a effectué des vérifications pour la première fois", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.firstTriggeredAt": "Horodatage indiquant à quel moment cette alerte a été déclenchée pour la première fois", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.isTriggered": "Indicateur spécifiant si l'alerte est en cours de déclenchement", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.lastCheckedAt": "Horodatage indiquant l'heure de vérification la plus récente de l'alerte", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.lastErrorMessage": "Dernier message d'erreur du moniteur", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.lastResolvedAt": "Horodatage indiquant l'heure de résolution la plus récente pour cette alerte", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.lastTriggeredAt": "Horodatage indiquant l'heure de déclenchement la plus récente de l'alerte", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.monitor": "Rendu convivial du nom ou de l'ID, ou nom préféré (par ex. Mon moniteur)", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.monitorId": "ID du moniteur.", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.monitorType": "Type (par ex. HTTP/TCP) du moniteur.", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.monitorUrl": "URL du moniteur.", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.observerHostname": "Nom d'hôte de l'observateur à partir duquel la vérification des pulsations est effectuée.", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.observerLocation": "Emplacement de l'observateur à partir duquel la vérification des pulsations est effectuée.", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.statusMessage": "Message de statut, par ex. \"arrêté\" ou \"se trouve au-dessous du seuil de disponibilité\" en cas de vérification de disponibilité, ou les deux.", + "xpack.synthetics.alerts.monitorStatus.addFilter": "Ajouter un filtre", + "xpack.synthetics.alerts.monitorStatus.addFilter.location": "Emplacement", + "xpack.synthetics.alerts.monitorStatus.addFilter.port": "Port", + "xpack.synthetics.alerts.monitorStatus.addFilter.tag": "Balise", + "xpack.synthetics.alerts.monitorStatus.addFilter.type": "Type", + "xpack.synthetics.alerts.monitorStatus.availability.isEnabledCheckbox.label": "Disponibilité", + "xpack.synthetics.alerts.monitorStatus.availability.threshold.anyMonitorDescription": "tout moniteur est opérationnel dans", + "xpack.synthetics.alerts.monitorStatus.availability.threshold.ariaLabel": "Spécifier les seuils de disponibilité pour cette alerte", + "xpack.synthetics.alerts.monitorStatus.availability.threshold.description": "les moniteurs correspondants sont opérationnels dans", + "xpack.synthetics.alerts.monitorStatus.availability.threshold.input.ariaLabel": "Saisir un seuil de disponibilité à vérifier pour cette alerte", + "xpack.synthetics.alerts.monitorStatus.availability.threshold.value": "< {value} % des vérifications", + "xpack.synthetics.alerts.monitorStatus.availability.timerangeValueField.ariaLabel": "Entrez le nombre d'unités pour la vérification de disponibilité de l'alerte.", + "xpack.synthetics.alerts.monitorStatus.availability.timerangeValueField.expression": "ces derniers/dernières", + "xpack.synthetics.alerts.monitorStatus.availability.timerangeValueField.popover.ariaLabel": "Spécifier la plage temporelle de suivi de disponibilité", + "xpack.synthetics.alerts.monitorStatus.availability.unit.headline": "Sélectionner l'unité de la plage temporelle", + "xpack.synthetics.alerts.monitorStatus.availability.unit.selectable": "Utiliser cette sélection pour définir les unités de la plage temporelle pour cette alerte", + "xpack.synthetics.alerts.monitorStatus.clientName": "Statut du moniteur Uptime", + "xpack.synthetics.alerts.monitorStatus.defaultActionMessage": "Moniteur {monitorName} avec l'URL {monitorUrl} depuis {observerLocation} {statusMessage} Le dernier message d'erreur est {latestErrorMessage}", + "xpack.synthetics.alerts.monitorStatus.description": "Alerte lorsqu'un monitoring est arrêté ou qu'un seuil de disponibilité est dépassé.", + "xpack.synthetics.alerts.monitorStatus.filterBar.ariaLabel": "Entrée qui permet le filtrage de critères pour l'alerte de statut du moniteur", + "xpack.synthetics.alerts.monitorStatus.filters.anyLocation": "tout emplacement", + "xpack.synthetics.alerts.monitorStatus.filters.anyPort": "tout port", + "xpack.synthetics.alerts.monitorStatus.filters.anyTag": "toute balise", + "xpack.synthetics.alerts.monitorStatus.filters.anyType": "tout type", + "xpack.synthetics.alerts.monitorStatus.filters.from": "De", + "xpack.synthetics.alerts.monitorStatus.filters.fromLocation": "Depuis l'emplacement", + "xpack.synthetics.alerts.monitorStatus.filters.location.label": "Sélectionnez les filtres d'emplacement à appliquer à la requête de l'alerte.", + "xpack.synthetics.alerts.monitorStatus.filters.of": "sur", + "xpack.synthetics.alerts.monitorStatus.filters.ofType": "De type", + "xpack.synthetics.alerts.monitorStatus.filters.port.label": "Sélectionnez les filtres de port à appliquer à la requête de l'alerte.", + "xpack.synthetics.alerts.monitorStatus.filters.scheme.label": "Sélectionnez les filtres de schéma de protocole à appliquer à la requête de l'alerte.", + "xpack.synthetics.alerts.monitorStatus.filters.tag.label": "Sélectionnez les filtres de balise à appliquer à la requête de l'alerte.", + "xpack.synthetics.alerts.monitorStatus.filters.using": "À l'aide de", + "xpack.synthetics.alerts.monitorStatus.filters.usingPort": "En utilisant le port", + "xpack.synthetics.alerts.monitorStatus.filters.with": "À l'aide de", + "xpack.synthetics.alerts.monitorStatus.filters.withTag": "Avec la balise", + "xpack.synthetics.alerts.monitorStatus.monitorCallOut.title": "Cette alerte s'appliquera à environ {snapshotCount} moniteurs.", + "xpack.synthetics.alerts.monitorStatus.numTimesExpression.anyMonitors.description": "tout moniteur est arrêté >", + "xpack.synthetics.alerts.monitorStatus.numTimesExpression.ariaLabel": "Ouvrir la fenêtre contextuelle pour saisir le compte de moniteurs arrêtés", + "xpack.synthetics.alerts.monitorStatus.numTimesExpression.matchingMonitors.description": "les moniteurs correspondants sont arrêtés >", + "xpack.synthetics.alerts.monitorStatus.numTimesField.ariaLabel": "Entrer le nombre de moniteurs arrêtés requis pour déclencher l'alerte", + "xpack.synthetics.alerts.monitorStatus.oldAlertCallout.title": "Si vous modifiez une ancienne alerte, certains champs ne se rempliront peut-être pas automatiquement.", + "xpack.synthetics.alerts.monitorStatus.recoveryMessage": "Le moniteur {monitor} possédant l'URL {url} a repris avec le statut Opérationnel", + "xpack.synthetics.alerts.monitorStatus.statusEnabledCheck.label": "Vérification du statut", + "xpack.synthetics.alerts.monitorStatus.timerangeOption.days": "jours", + "xpack.synthetics.alerts.monitorStatus.timerangeOption.hours": "heures", + "xpack.synthetics.alerts.monitorStatus.timerangeOption.minutes": "minutes", + "xpack.synthetics.alerts.monitorStatus.timerangeOption.months": "mois", + "xpack.synthetics.alerts.monitorStatus.timerangeOption.seconds": "secondes", + "xpack.synthetics.alerts.monitorStatus.timerangeOption.weeks": "semaines", + "xpack.synthetics.alerts.monitorStatus.timerangeOption.years": "ans", + "xpack.synthetics.alerts.monitorStatus.timerangeSelectionHeader": "Sélectionner l'unité de la plage temporelle", + "xpack.synthetics.alerts.monitorStatus.timerangeUnitExpression.ariaLabel": "Ouvrir la fenêtre contextuelle pour accéder au champ de sélection d'unité de la plage temporelle", + "xpack.synthetics.alerts.monitorStatus.timerangeUnitSelectable": "Le champ sélectionnable pour les alertes d'unités de la plage temporelle doit utiliser", + "xpack.synthetics.alerts.monitorStatus.timerangeValueExpression.ariaLabel": "Ouvrir la fenêtre contextuelle pour accéder au champ de valeur de la plage temporelle", + "xpack.synthetics.alerts.monitorStatus.timerangeValueField.ariaLabel": "Entrer le nombre d'unités de temps pour la plage de l'alerte", + "xpack.synthetics.alerts.monitorStatus.timerangeValueField.expression": "dans", + "xpack.synthetics.alerts.monitorStatus.timerangeValueField.value": "dernier/dernière(s) {value}", + "xpack.synthetics.alerts.searchPlaceholder.kql": "Filtrer à l'aide de la syntaxe KQL", + "xpack.synthetics.alerts.settings.addConnector": "Ajouter un connecteur", + "xpack.synthetics.alerts.timerangeUnitSelectable.daysOption.ariaLabel": "Élément de sélection de la plage temporelle \"Jours\"", + "xpack.synthetics.alerts.timerangeUnitSelectable.hoursOption.ariaLabel": "Élément de sélection de la plage temporelle \"Heures\"", + "xpack.synthetics.alerts.timerangeUnitSelectable.minutesOption.ariaLabel": "Élément de sélection de la plage temporelle \"Minutes\"", + "xpack.synthetics.alerts.timerangeUnitSelectable.monthsOption.ariaLabel": "Élément de sélection de la plage temporelle \"Mois\"", + "xpack.synthetics.alerts.timerangeUnitSelectable.secondsOption.ariaLabel": "Élément de sélection de la plage temporelle \"Secondes\"", + "xpack.synthetics.alerts.timerangeUnitSelectable.weeksOption.ariaLabel": "Élément de sélection de la plage temporelle \"Semaines\"", + "xpack.synthetics.alerts.timerangeUnitSelectable.yearsOption.ariaLabel": "Élément de sélection de la plage temporelle \"Années\"", + "xpack.synthetics.alerts.tls": "Uptime TLS", + "xpack.synthetics.alerts.tls.actionVariables.state.agingCommonNameAndDate": "Noms courants et date/heure d'expiration des certificats détectés.", + "xpack.synthetics.alerts.tls.actionVariables.state.agingCount": "Nombre de certificats détectés qui deviennent trop anciens.", + "xpack.synthetics.alerts.tls.actionVariables.state.count": "Nombre de certificats détectés par l'exécuteur d'alertes", + "xpack.synthetics.alerts.tls.actionVariables.state.expiringCommonNameAndDate": "Noms courants et date/heure d'expiration des certificats détectés", + "xpack.synthetics.alerts.tls.actionVariables.state.expiringCount": "Nombre de certificats sur le point d'expirer détectés par l'alerte.", + "xpack.synthetics.alerts.tls.ageExpression.ariaLabel": "Expression affichant le seuil qui déclenchera l'alerte TLS pour les certificats anciens", + "xpack.synthetics.alerts.tls.ageExpression.description": "ou plus anciens que", + "xpack.synthetics.alerts.tls.ageExpression.value": "{value} jours", + "xpack.synthetics.alerts.tls.agingLabel": "devient trop ancien", + "xpack.synthetics.alerts.tls.clientName": "Uptime TLS", + "xpack.synthetics.alerts.tls.criteriaExpression.ariaLabel": "Expression affichant les critères des moniteurs surveillés par cette alerte", + "xpack.synthetics.alerts.tls.criteriaExpression.description": "quand", + "xpack.synthetics.alerts.tls.criteriaExpression.value": "tout moniteur", + "xpack.synthetics.alerts.tls.defaultActionMessage": "Le certificat TLS {commonName} détecté de l'émetteur {issuer} est {status}. Certificat {summary}\n", + "xpack.synthetics.alerts.tls.description": "Alerte lorsque le certificat TLS d'un moniteur Uptime est sur le point d'expirer.", + "xpack.synthetics.alerts.tls.expirationExpression.ariaLabel": "Expression affichant le seuil qui déclenchera l'alerte TLS pour l'expiration des certificats", + "xpack.synthetics.alerts.tls.expirationExpression.description": "possède un certificat expirant dans", + "xpack.synthetics.alerts.tls.expirationExpression.value": "{value} jours", + "xpack.synthetics.alerts.tls.expiredLabel": "expiré", + "xpack.synthetics.alerts.tls.expiringLabel": "sur le point d'expirer", + "xpack.synthetics.alerts.tls.invalidLabel": "non valide", + "xpack.synthetics.alerts.tls.legacy.clientName": "Uptime TLS (existant)", + "xpack.synthetics.alerts.tls.legacy.defaultActionMessage": "Détection de {count} certificats TLS sur le point d'expirer ou devenant trop anciens.\n{expiringConditionalOpen}\nNombre de certificats sur le point d'expirer : {expiringCount}\nCertificats sur le point d'expirer : {expiringCommonNameAndDate}\n{expiringConditionalClose}\n{agingConditionalOpen}\nNombre de certificats vieillissants : {agingCount}\nCertificats vieillissants : {agingCommonNameAndDate}\n{agingConditionalClose}\n", + "xpack.synthetics.alerts.tls.legacy.description": "Alerte lorsque le certificat TLS d'un moniteur Uptime est sur le point d'expirer. Cette alerte sera déclassée dans une future version.", + "xpack.synthetics.alerts.tls.settingsPageNav.text": "Vous pouvez modifier ces seuils sur la {settingsPageLink}.", + "xpack.synthetics.alerts.tls.validAfterExpiredString": "expiré le {date}, il y a {relativeDate} jours.", + "xpack.synthetics.alerts.tls.validAfterExpiringString": "expire le {date}, dans {relativeDate} jours.", + "xpack.synthetics.alerts.tls.validBeforeExpiredString": "valide depuis le {date}, il y a {relativeDate} jours.", + "xpack.synthetics.alerts.tls.validBeforeExpiringString": "non valide jusqu'au {date}, dans {relativeDate} jours.", + "xpack.synthetics.alerts.tlsLegacy": "Uptime TLS (existant)", + "xpack.synthetics.alerts.toggleAlertFlyoutButtonText": "Alertes et règles", + "xpack.synthetics.alertsPopover.toggleButton.ariaLabel": "Ouvrir le menu contextuel des alertes et règles", + "xpack.synthetics.analyzeDataButtonLabel": "Explorer les données", + "xpack.synthetics.analyzeDataButtonLabel.message": "La fonctionnalité Explorer les données vous permet de sélectionner et de filtrer les données de résultat dans toute dimension et de rechercher la cause ou l'impact des problèmes de performances.", + "xpack.synthetics.apmIntegrationAction.description": "Rechercher ce monitoring dans APM", + "xpack.synthetics.apmIntegrationAction.text": "Afficher les données APM", + "xpack.synthetics.availabilityLabelText": "{value} %", + "xpack.synthetics.badge.readOnly.text": "Lecture seule", + "xpack.synthetics.badge.readOnly.tooltip": "Enregistrement impossible", + "xpack.synthetics.breadcrumbs.observabilityText": "Observabilité", + "xpack.synthetics.breadcrumbs.overviewBreadcrumbText": "Uptime", + "xpack.synthetics.certificates.heading": "Certificats TLS ({total})", + "xpack.synthetics.certificates.loading": "Chargement des certificats...", + "xpack.synthetics.certificates.refresh": "Actualiser", + "xpack.synthetics.certificatesPage.heading": "Certificats TLS", + "xpack.synthetics.certificatesRoute.title": "Certificats | {baseTitle}", + "xpack.synthetics.certs.expired": "Expiré", + "xpack.synthetics.certs.expires": "Expire", + "xpack.synthetics.certs.expireSoon": "Expire bientôt", + "xpack.synthetics.certs.list.ageCol": "Âge", + "xpack.synthetics.certs.list.commonName": "Nom courant", + "xpack.synthetics.certs.list.copyFingerprint": "Cliquez pour copier la valeur d'empreinte", + "xpack.synthetics.certs.list.days": "jours", + "xpack.synthetics.certs.list.empty": "Aucun certificat n'a été trouvé. Remarque : les certificats sont visibles uniquement pour Heartbeat 7.8+", + "xpack.synthetics.certs.list.expirationDate": "Empreintes", + "xpack.synthetics.certs.list.issuedBy": "Émis par", + "xpack.synthetics.certs.list.monitors": "Moniteurs", + "xpack.synthetics.certs.list.status": "Statut", + "xpack.synthetics.certs.list.status.old": "Trop ancien", + "xpack.synthetics.certs.list.validUntil": "Valide jusque", + "xpack.synthetics.certs.ok": "OK", + "xpack.synthetics.certs.searchCerts": "Rechercher dans les certificats", + "xpack.synthetics.certs.status.ok.label": " {okRelativeDate}", + "xpack.synthetics.charts.mlAnnotation.header": "Note : {score}", + "xpack.synthetics.charts.mlAnnotation.severity": "Sévérité : {severity}", + "xpack.synthetics.controls.selectSeverity.criticalLabel": "critique", + "xpack.synthetics.controls.selectSeverity.majorLabel": "majeur", + "xpack.synthetics.controls.selectSeverity.minorLabel": "mineure", + "xpack.synthetics.controls.selectSeverity.scoreDetailsDescription": "score {value} et supérieur", + "xpack.synthetics.controls.selectSeverity.warningLabel": "avertissement", + "xpack.synthetics.createPackagePolicy.stepConfigure.browser.scriptRecorder.experimentalLabel": "Préversion technique", + "xpack.synthetics.createPackagePolicy.stepConfigure.browser.scriptRecorder.experimentalTooltip": "Prévisualisez la méthode la plus rapide permettant de créer des scripts de monitoring Elastic Synthetics avec notre enregistreur Elastic Synthetics", + "xpack.synthetics.createPackagePolicy.stepConfigure.browser.scriptRecorder.label": "Enregistreur de scripts", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.description": "Fournissez une configuration précise pour l'agent synthétique.", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.filtering.description": "Utilisez ces options pour appliquer les paramètres de moniteur sélectionnés à un sous-ensemble des tests de votre suite. Seul le sous-ensemble configuré sera exécuté par ce moniteur.", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.filtering.title": "Tests sélectifs", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.ignoreHttpsErrors.helpText": "Définissez cette option sur \"true\" pour désactiver la validation TLS/SSL dans le navigateur synthétique. Cette opération est utile pour tester les sites qui utilisent des certificats autosignés.", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.ignoreHttpsErrors.label": "Ignorer les erreurs HTTPS", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersMatch.helpText": "Exécutez uniquement les parcours dont le nom correspond au glob fourni avec ce moniteur.", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersMatch.label": "Filtrer la correspondance", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersTags.helpText": "Exécutez uniquement les parcours en utilisant les balises données avec ce moniteur.", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersTags.label": "Filtrer les balises", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.screenshots.helpText": "Définissez cette option pour gérer les captures d'écran effectuées par l'agent synthétique.", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.screenshots.label": "Options de capture d'écran", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.syntheticsArgs.helpText": "Arguments supplémentaires à transmettre au package de l'agent synthétique. Accepte une liste de chaînes. Cela est utile dans des scénarios rares et ne devrait normalement pas avoir besoin d'être défini.", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.syntheticsArgs.label": "Arguments synthétiques", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.automatic_node_cap.message": "Lorsque vous désactivez la régulation, la bande passante de votre moniteur sera toujours limitée par les configurations des nœuds synthétiques dans lesquels votre moniteur est en cours d'exécution.", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.automatic_node_cap.title": "Limite automatique", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.description": "Contrôlez les vitesses de téléchargement et chargement du moniteur, ainsi que sa latence pour simuler le comportement de votre application sur des réseaux plus lents.", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.download.error": "La vitesse de téléchargement doit être supérieure à zéro.", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.download.label": "Vitesse de téléchargement", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.exceeded_throttling.message": "Lors de l'utilisation de valeurs de régulation plus élevées que la limite de la bande passante d'un nœud synthétique, la bande passante de votre moniteur sera toujours limitée.", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.exceeded_throttling.title": "Vous avez dépassé les limites de bande passante du nœud synthétique", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.latency.error": "La latence ne doit pas être négative.", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.latency.label": "Latence", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.switch.description": "Activer la régulation", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.title": "Options de régulation", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.upload.error": "La vitesse de chargement doit être supérieure à zéro.", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.upload.label": "Vitesse de chargement", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.title": "Options de l'agent synthétique", + "xpack.synthetics.createPackagePolicy.stepConfigure.certificateSettings.enableSSLSettings.label": "Activer la configuration TLS", + "xpack.synthetics.createPackagePolicy.stepConfigure.certificateSettings.enableZipUrlSSLSettings.label": "Activer la configuration TLS pour l'URL du zip", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificate.helpText": "Certificat formaté PEM pour l'authentification du client TLS.", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificate.label": "certificat", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificateAuthorities.helpText": "Autorités de certificats personnalisés formatés PEM.", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificateAuthorities.label": "Autorités de certificats", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificateKey.helpText": "Clé de certificat formaté PEM pour l'authentification du client TLS.", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificateKey.label": "clé", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificateKeyPassphrase.helpText": "Phrase secrète de la clé de certificat pour l'authentification du client TLS.", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificateKeyPassphrase.label": "phrase secrète de la clé", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.legend": "Paramètres de certificat", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.tlsRole.client": "Client", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.tlsRole.server": "Serveur", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.certificate.description": "Vérifie que le certificat fourni est signé par une autorité reconnue (CA), mais n'effectue aucune vérification du nom d'hôte.", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.certificate.label": "Certificat", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.full.description": "Vérifie que le certificat fourni est signé par une autorité reconnue (CA), mais également que le nom d'hôte du serveur (ou l'adresse IP) correspond aux noms identifiés dans le certificat.", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.full.label": "Entier", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.label": "Mode de vérification", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.none.description": "N'effectue aucune vérification du certificat du serveur. Il est principalement destiné à servir de mécanisme de diagnostic temporaire lors de tentatives de résolution des erreurs TLS ; son utilisation dans des environnements de production est fortement déconseillée.", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.none.label": "Aucun", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.strict.description": "Vérifie que le certificat fourni est signé par une autorité reconnue (CA), mais également que le nom d'hôte du serveur (ou l'adresse IP) correspond aux noms identifiés dans le certificat. Si le nom alternatif du sujet n'est pas renseigné, il renvoie une erreur.", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.strict.label": "Strict", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.warning.description": "Ce mode désactive de nombreux avantages de sécurité de SSL/TLS et ne doit être utilisé qu'après un examen approfondi.", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.warning.title": "Désactivation de TLS", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.version.label": "Protocoles TLS pris en charge", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.version.placeholder": "Sélectionnez un ou plusieurs protocoles TLS.", + "xpack.synthetics.createPackagePolicy.stepConfigure.headerField.addHeader.label": "Ajouter un en-tête", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions": "Options HTTP avancées", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.indexResponseBody.helpText": "Contrôle l'indexation du contenu du corps de la réponse HTTP en fonction du ", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.indexResponseHeaders.helpText": "Contrôle l'indexation des en-têtes de la réponse HTTP en fonction du ", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestBody.helpText": "Contenu du corps de la requête.", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.description": "Configurez une requête facultative à envoyer à l'hôte distant, comprenant la méthode, le corps et les en-têtes.", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.requestBody": "Corps de la requête", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.requestHeaders": "En-têtes de la requête", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.requestMethod.label": "Méthode de la requête", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.title": "Configuration de la requête", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestHeadersField.error": "La clé d'en-tête doit être un token HTTP valide.", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestHeadersField.helpText": "Dictionnaire d'en-têtes HTTP supplémentaires à envoyer. Par défaut, le client définira l'en-tête User-Agent (utilisateur-agent) de façon à ce qu'il s'identifie lui-même.", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestMethod.helpText": "Méthode HTTP à utiliser.", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseBodyCheckNegative.helpText": "Liste d'expressions régulières pour une correspondance négative à la sortie du corps. Appuyez sur Entrée pour ajouter une nouvelle expression. Renvoie un échec de correspondance si l'expression unique correspond.", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseBodyCheckPositive.helpText": "Liste d'expressions régulières pour une correspondance au corps. Appuyez sur Entrée pour ajouter une nouvelle expression. Seule une expression unique a besoin de correspondre.", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseCheckNegative.label": "Le corps de la réponse de vérification ne contient pas", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseCheckPositive.label": "Le corps de la réponse de vérification contient", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.checkResponseHeadersContain": "Les en-têtes de la réponse de vérification contiennent", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.description": "Configurez la réponse HTTP attendue.", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.responseStatusCheck.error": "Le code de statut doit contenir uniquement des chiffres.", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.responseStatusCheck.helpText": "Liste de codes de statut attendus. Appuyez sur Entrée pour ajouter un nouveau code. Les codes 4xx et 5xx sont considérés comme \"Arrêté\" par défaut. Les autres codes sont considérés comme \"Opérationnel\"", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.responseStatusCheck.label": "Le statut de la réponse de vérification est égal à", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.title": "Vérifications des réponses", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfig.indexResponseBody": "Indexer le corps de réponse", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfig.indexResponseHeaders": "Indexer les en-têtes de réponse", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfig.responseBodyIndexPolicy": "Politique d'indexation du corps de réponse", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfiguration.description": "Contrôlez l'indexation des contenus de réponses HTTP.", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfiguration.title": "Configuration des réponses", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseHeadersField.error": "La clé d'en-tête doit être un token HTTP valide.", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseHeadersField.helpText": "Liste d'en-têtes de réponse attendus.", + "xpack.synthetics.createPackagePolicy.stepConfigure.icmpAdvancedOptions": "Options ICMP avancées", + "xpack.synthetics.createPackagePolicy.stepConfigure.inputVarFieldOptionalLabel": "Facultatif", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.helpText": "Nom de service APM pour ce monitoring. Correspond au champ ECS service.name. Définissez-le lors du monitoring d'une application qui utilise également APM pour activer les intégrations entre les données Uptime et APM dans Kibana.", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.label": "Nom de service APM", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.brower.proxyURL.label": "URL du zip du proxy", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.http.helpText": "Proxy HTTP pour l'URL du zip.", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.error": "Script obligatoire", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.helpText": "Exécute des scripts de tests synthétiques définis en ligne.", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.label": "Script en ligne", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.params.helpText": "Objet JSON qui définit toute variable dont vos tests ont besoin.", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.params.label": "Paramètres", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.scriptRecorder.closeButtonLabel": "Fermer le menu volant du script", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.scriptRecorder.mockFileName": "test_script.js", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.sourceType.label": "Type de source", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.fieldLabel": "Script de test", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.invalidFileError": "Type de fichier non valide. Veuillez charger un fichier .js généré par l'enregistreur Elastic Synthetics.", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.label": "Sélectionner un fichier .js généré par l'enregistreur", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.parsingError": "Erreur lors du chargement du fichier. Veuillez charger un fichier .js généré par l'enregistreur Elastic Synthetics au format de script en ligne.", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.error": "L'URL de zip est requise", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.helpText": "Emplacement du fichier zip du référentiel du projet synthétique.", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.label": "URL du zip", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.recorderLink": "Télécharger l'enregistreur Elastic Synthetics", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.removeScriptLabel": "Retirer le script", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.showScriptLabel": "Afficher le script", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlFolder.helpText": "Chemin de répertoire relatif d'emplacement des fichiers de parcours synthétiques dans le référentiel.", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlFolder.label": "Dossier", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlPassword.abel": "Mot de passe de l'URL du zip", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlPassword.helpText": "Mot de passe pour l'authentification avec le point de terminaison du zip.", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlUsername.helpText": "Nom d'utilisateur pour l'authentification avec le point de terminaison du zip.", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlUsername.label": "Nom d'utilisateur de l'URL du zip", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browserLabel": "Navigateur (version bêta)", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.enabled.helpText": "Désactivez cette configuration pour désactiver le moniteur.", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.enabled.label": "Activé", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.icmp.hosts": "Hôte", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.icmp.hosts.error": "L'hôte est requis", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.maxRedirects": "Nb maxi de redirections", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.maxRedirects.error": "Le nb maxi de redirections doit être supérieur ou égal à 0", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.maxRedirects.helpText": "Nombre total de redirections à suivre.", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorInterval": "Fréquence", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorInterval.error": "La fréquence du moniteur est requise", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType": "Type de moniteur", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.description": "Pour créer un moniteur \"Navigateur\", veuillez vous assurer que vous utilisez le conteneur Docker elastic-agent-complete, qui inclut les dépendances permettant d'exécuter ces moniteurs. Pour en savoir plus, visitez notre {link}.", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.link": "documentation Synthetics", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.error": "Le type de moniteur est requis", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.password.helpText": "Mot de passe pour l'authentification avec le serveur.", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.password.label": "Mot de passe", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyUrl.http.helpText": "URL du proxy HTTP.", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyURL.http.label": "URL du proxy", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyURL.label": "URL du proxy", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyUrl.tcp.helpText": "URL du proxy SOCKS5 à utiliser lors de la connexion au serveur. La valeur doit être une URL avec un schéma de socks5://.", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.resolveHostnamesLocally": "Résout les noms d'hôte localement", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tags.helpText": "Liste de balises qui seront envoyées avec l'événement de monitoring. Appuyez sur Entrée pour ajouter une nouvelle balise. Affiché dans Uptime et permet la recherche par balise.", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tags.label": "Balises", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tcp.hosts": "Host:Port", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tcp.hosts.error": "L'hôte et le port sont requis", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.helpText": "Temps total autorisé pour tester la connexion et l'échange de données.", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.label": "Délai d'expiration en secondes", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.lessThanIntervalError": "Le délai d'expiration doit être inférieur à la fréquence du moniteur", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.moreThanZeroError": "Le délai d'expiration doit être supérieur ou égal à 0", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.URL": "URL", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.URL.error": "L'URL est requise", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.username.helpText": "Nom d'utilisateur pour l'authentification avec le serveur.", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.username.label": "Nom d'utilisateur", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.wait.error": "L'attente doit être supérieure ou égale à 0", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.wait.helpText": "Durée d'attente avant l'émission d'une autre requête d'écho ICMP si aucune réponse n'est reçue.", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.wait.label": "Attente en secondes", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSectionDescription": "Configurez votre moniteur avec les options suivantes.", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSectionTitle": "Paramètres du moniteur", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBody.codeEditor.javascript.ariaLabel": "Éditeur de code JavaScript", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBody.codeEditor.json.ariaLabel": "Éditeur de code JSON", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBody.codeEditor.text.ariaLabel": "Éditeur de code texte", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBody.codeEditor.xml.ariaLabel": "Éditeur de code XML", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBody.formField.addFormField.label": "Ajouter un champ de formulaire", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBodyType.form": "Formulaire", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBodyType.JSON": "JSON", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBodyType.text": "Texte", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBodyType.XML": "XML", + "xpack.synthetics.createPackagePolicy.stepConfigure.responseBodyIndex.always": "Toujours", + "xpack.synthetics.createPackagePolicy.stepConfigure.responseBodyIndex.onError": "En cas d'erreur", + "xpack.synthetics.createPackagePolicy.stepConfigure.scheduleField.minutes": "Minutes", + "xpack.synthetics.createPackagePolicy.stepConfigure.scheduleField.number": "Nombre", + "xpack.synthetics.createPackagePolicy.stepConfigure.scheduleField.seconds": "Secondes", + "xpack.synthetics.createPackagePolicy.stepConfigure.scheduleField.unit": "Unité", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.description": "Configurez les données utiles envoyées à l'hôte distant.", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.requestPayload.helpText": "Chaîne de données utiles à envoyer à l'hôte distant.", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.requestPayload.label": "Charge utile de la requête", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.title": "Configuration de la requête", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.responseConfiguration.responseContains.helpText": "Réponse attendue de l'hôte distant.", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.responseConfiguration.responseContains.label": "La réponse de vérification contient", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvancedOptions.responseConfiguration.description": "Configurez la réponse attendue à partir de l'hôte distant.", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvancedOptions.responseConfiguration.title": "Vérifications des réponses", + "xpack.synthetics.createPackagePolicy.stepConfigure.tlsSettings.description": "Configurez les options TLS, y compris le mode de vérification, les autorités de certification et les certificats clients.", + "xpack.synthetics.createPackagePolicy.stepConfigure.tlsSettings.label": "Paramètres TLS", + "xpack.synthetics.durationChart.emptyPrompt.description": "Ce monitoring n'a jamais été {emphasizedText} au cours de la plage temporelle sélectionnée.", + "xpack.synthetics.durationChart.emptyPrompt.title": "Aucune donnée de durée n'est disponible", + "xpack.synthetics.editMonitor.pageHeader.title": "Modifier le moniteur", + "xpack.synthetics.editMonitorRoute.title": "Modifier le moniteur | {baseTitle}", + "xpack.synthetics.emptyState.loadingMessage": "Chargement…", + "xpack.synthetics.emptyStateError.notAuthorized": "Vous n'êtes pas autorisé à afficher les données Uptime, veuillez contacter votre administrateur système.", + "xpack.synthetics.emptyStateError.notFoundPage": "Page introuvable", + "xpack.synthetics.emptyStateError.title": "Erreur", + "xpack.synthetics.enableAlert.editAlert": "Modifier l'alerte", + "xpack.synthetics.filterBar.ariaLabel": "Saisissez des critères de filtre pour la page d'aperçu", + "xpack.synthetics.filterBar.filterAllLabel": "Tous", + "xpack.synthetics.filterBar.options.location.name": "Emplacement", + "xpack.synthetics.filterBar.options.portLabel": "Port", + "xpack.synthetics.filterBar.options.schemeLabel": "Schéma", + "xpack.synthetics.filterBar.options.tagsLabel": "Balise", + "xpack.synthetics.fleetIntegration.assets.description": "Afficher les moniteurs dans Uptime", + "xpack.synthetics.fleetIntegration.assets.name": "Moniteurs", + "xpack.synthetics.inspectButtonText": "Inspecter", + "xpack.synthetics.integrationLink.missingDataMessage": "Les données requises pour cette intégration sont introuvables.", + "xpack.synthetics.keyValuePairsField.deleteItem.label": "Supprimer le numéro d'élément {index}, {key}:{value}", + "xpack.synthetics.keyValuePairsField.key.ariaLabel": "Clé", + "xpack.synthetics.keyValuePairsField.key.label": "Clé", + "xpack.synthetics.keyValuePairsField.value.ariaLabel": "Valeur", + "xpack.synthetics.keyValuePairsField.value.label": "Valeur", + "xpack.synthetics.kueryBar.searchPlaceholder.kql": "Rechercher à l'aide de la syntaxe KQL des ID, noms et types etc. de moniteurs (par ex. monitor.type: \"http\" AND tags: \"dev\")", + "xpack.synthetics.kueryBar.searchPlaceholder.simple": "Rechercher par ID, nom ou URL de moniteur (par ex. http:// )", + "xpack.synthetics.locationName.helpLinkAnnotation": "Ajouter un emplacement", + "xpack.synthetics.mappingErrorRoute.breadcrumb": "Erreur de mapping", + "xpack.synthetics.mappingErrorRoute.pageHeader.title": "Erreur de mapping", + "xpack.synthetics.mappingErrorRoute.title": "Synthetics | erreur de mapping", + "xpack.synthetics.millisecond.abbreviation.label": "ms", + "xpack.synthetics.ml.durationChart.exploreInMlApp": "Explorer dans ML App", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.add_job_permissions_needed": "Autorisations requises", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.anomalyDetectionTitle": "Détection des anomalies", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.cancelLabel": "Annuler", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.createMLJobDescription": "Ici, vous pouvez créer une tâche de Machine Learning afin de calculer les scores d'anomalie pour\n les durées de réponse pour Uptime Monitor. Une fois activé, le graphique de durée de monitoring de la page des détails\n affichera les limites attendues et annotera le graphique avec les anomalies. Vous pouvez aussi éventuellement\n identifier les périodes de latence augmentées selon les zones géographiques.", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.createNewJobButtonLabel": "Créer une nouvelle tâche", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.disableAnomalyAlert": "Désactiver l'alerte d'anomalie", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.disableAnomalyDetectionTitle": "Désactiver la détection des anomalies", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.enable_or_manage_job": "Vous pouvez activer la tâche de détection des anomalies, ou, si elle est déjà présente, vous pouvez gérer la tâche ou l'alerte.", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.enableAnomalyAlert": "Activer l'alerte d'anomalie", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.enableAnomalyDetectionTitle": "Activer la détection des anomalies", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.insufficient_permissions_add_job": "Vous devez disposer des privilèges Kibana de Machine Learning pour utiliser cette fonctionnalité.", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreatedLazyNotificationText": "L'analyse attend qu'un nœud de ML devienne disponible. L'ajout des résultats au graphique peut prendre un certain temps.", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreatedNotificationText": "L'analyse est à présent en cours d'exécution pour le graphique de durée de réponse. L'ajout des résultats au graphique peut prendre un certain temps.", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreatedNotificationText.viewJobLinkText": "Afficher la tâche", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreatedNotificationTitle": "Tâche créée avec succès", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreationFailedNotificationText": "Il est possible que votre licence actuelle n'autorise pas la création de tâches de Machine Learning, ou cette tâche existe peut-être déjà.", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreationFailedNotificationTitle": "La création de la tâche a échoué", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobDeletionConfirmLabel": "Supprimer la tâche de détection des anomalies ?", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobDeletionNotificationTitle": "Tâche supprimée", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobDeletionSuccessNotificationText": "La tâche a été supprimée avec succès", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.manageAnomalyDetectionTitle": "Gérer la détection des anomalies", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.manageMLJobDescription": "Une fois qu'une tâche a été créée, vous pouvez la gérer et afficher davantage de détails sur la {mlJobsPageLink}.", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.manageMLJobDescription.mlJobsPageLinkText": "Page de gestion des tâches de Machine Learning", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.manageMLJobDescription.noteText": "Remarque : La tâche peut mettre un certain temps à démarrer le calcul des résultats.", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.noPermissionsTooltip": "Vous devez disposer d'un accès en lecture-écriture à Uptime pour créer des alertes d'anomalie.", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.startTrial": "Commencer un essai gratuit de 14 jours", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.startTrialDesc": "Pour pouvoir accéder à la détection des anomalies de durée, vous devez être abonné à une licence Elastic Platinum.", + "xpack.synthetics.monitor.simpleStatusAlert.email.subject": "Le moniteur {monitor} possédant l'URL {url} est arrêté", + "xpack.synthetics.monitorCharts.durationChart.leftAxis.title": "Durée en {unit}", + "xpack.synthetics.monitorCharts.durationChart.wrapper.label": "Graphique affichant la durée de ping du moniteur, avec regroupement par emplacement.", + "xpack.synthetics.monitorCharts.monitorDuration.titleLabel": "Durée du moniteur", + "xpack.synthetics.monitorCharts.monitorDuration.titleLabelWithAnomaly": "Durée du moniteur (Anomalies : {noOfAnomalies})", + "xpack.synthetics.monitorDetails.ml.confirmAlertDeleteMessage": "Voulez-vous vraiment supprimer l'alerte pour les anomalies ?", + "xpack.synthetics.monitorDetails.ml.confirmDeleteMessage": "Voulez-vous vraiment supprimer cette tâche ?", + "xpack.synthetics.monitorDetails.ml.deleteJobWarning": "La suppression d'une tâche peut prendre beaucoup de temps. Elle sera supprimée en arrière-plan, et les données ne disparaîtront peut-être pas instantanément.", + "xpack.synthetics.monitorDetails.ml.deleteMessage": "Suppression des tâches...", + "xpack.synthetics.monitorDetails.statusBar.pingType.browser": "Navigateur", + "xpack.synthetics.monitorDetails.statusBar.pingType.http": "HTTP", + "xpack.synthetics.monitorDetails.statusBar.pingType.icmp": "ICMP", + "xpack.synthetics.monitorDetails.statusBar.pingType.tcp": "TCP", + "xpack.synthetics.monitorDetails.title.disclaimer.description": "(BÊTA)", + "xpack.synthetics.monitorDetails.title.disclaimer.link": "Afficher plus", + "xpack.synthetics.monitorDetails.title.pingType.browser": "Navigateur", + "xpack.synthetics.monitorDetails.title.pingType.http": "Ping HTTP", + "xpack.synthetics.monitorDetails.title.pingType.icmp": "Ping ICMP", + "xpack.synthetics.monitorDetails.title.pingType.tcp": "Ping TCP", + "xpack.synthetics.monitorList.allMonitors": "Tous les moniteurs", + "xpack.synthetics.monitorList.anomalyColumn.label": "Score d'anomalies de réponse", + "xpack.synthetics.monitorList.defineConnector.description": "Définissez un connecteur par défaut dans {link} pour activer les alertes de statut du moniteur.", + "xpack.synthetics.monitorList.defineConnector.popover.description": "pour recevoir les alertes de statut.", + "xpack.synthetics.monitorList.disableDownAlert": "Désactiver les alertes de statut", + "xpack.synthetics.monitorList.downLineSeries.downLabel": "Vérifications des arrêts", + "xpack.synthetics.monitorList.drawer.missingLocation": "Certaines instances Heartbeat n'ont pas d'emplacement défini. {link} vers votre configuration Heartbeat.", + "xpack.synthetics.monitorList.drawer.mostRecentRun": "Exécution de test la plus récente", + "xpack.synthetics.monitorList.drawer.statusRowLocationList": "Liste d'emplacements ayant le statut \"{status}\" à la dernière vérification.", + "xpack.synthetics.monitorList.drawer.url": "Url", + "xpack.synthetics.monitorList.enabledAlerts.noAlert": "Aucune règle n'est activée pour ce moniteur.", + "xpack.synthetics.monitorList.enabledAlerts.title": "Règles activées", + "xpack.synthetics.monitorList.enableDownAlert": "Activer les alertes de statut", + "xpack.synthetics.monitorList.errorSummary": "Résumé des erreurs", + "xpack.synthetics.monitorList.expandDrawerButton.ariaLabel": "Développer la ligne du moniteur avec l'ID {id}", + "xpack.synthetics.monitorList.geoName.helpLinkAnnotation": "Ajouter un emplacement", + "xpack.synthetics.monitorList.infraIntegrationAction.container.message": "Afficher les indicateurs de conteneurs", + "xpack.synthetics.monitorList.infraIntegrationAction.docker.description": "Vérifier l'interface utilisateur de l'infrastructure pour cet ID de conteneur du moniteur", + "xpack.synthetics.monitorList.infraIntegrationAction.docker.tooltip": "Vérifier l'interface utilisateur de l'infrastructure pour l'ID de conteneur \"{containerId}\"", + "xpack.synthetics.monitorList.infraIntegrationAction.ip.ariaLabel": "Vérifier l'interface utilisateur de l'infrastructure pour cette adresse IP du moniteur", + "xpack.synthetics.monitorList.infraIntegrationAction.ip.message": "Afficher les indicateurs d'hôte", + "xpack.synthetics.monitorList.infraIntegrationAction.ip.tooltip": "Vérifier l'interface utilisateur de l'infrastructure pour l'IP \"{ip}\"", + "xpack.synthetics.monitorList.infraIntegrationAction.kubernetes.description": "Vérifier l'interface utilisateur de l'infrastructure pour cet UID de pod du monitoring", + "xpack.synthetics.monitorList.infraIntegrationAction.kubernetes.message": "Afficher les indicateurs de pod", + "xpack.synthetics.monitorList.infraIntegrationAction.kubernetes.tooltip": "Vérifier l'interface utilisateur de l'infrastructure pour l'UID de pod \"{podUid}\".", + "xpack.synthetics.monitorList.integrationGroup.emptyMessage": "Aucune application intégrée n'est disponible", + "xpack.synthetics.monitorList.invalidMonitors": "Moniteurs non valides", + "xpack.synthetics.monitorList.loading": "Chargement...", + "xpack.synthetics.monitorList.locations.expand": "Cliquer pour afficher les emplacements restants", + "xpack.synthetics.monitorList.loggingIntegrationAction.container.id": "Afficher les logs du conteneur", + "xpack.synthetics.monitorList.loggingIntegrationAction.container.message": "Afficher les logs du conteneur", + "xpack.synthetics.monitorList.loggingIntegrationAction.container.tooltip": "Vérifier l'interface utilisateur de logging pour l'ID de conteneur \"{containerId}\"", + "xpack.synthetics.monitorList.loggingIntegrationAction.ip.description": "Vérifier l'interface utilisateur de logging pour cette adresse IP de moniteur", + "xpack.synthetics.monitorList.loggingIntegrationAction.ip.message": "Afficher les logs des hôtes", + "xpack.synthetics.monitorList.loggingIntegrationAction.ip.tooltip": "Vérifier l'interface utilisateur de logging pour l'IP \"{ip}\"", + "xpack.synthetics.monitorList.loggingIntegrationAction.kubernetes.ariaLabel": "Afficher les logs de pod", + "xpack.synthetics.monitorList.loggingIntegrationAction.kubernetes.message": "Afficher les logs de pod", + "xpack.synthetics.monitorList.loggingIntegrationAction.kubernetes.tooltip": "Rechercher les logs pour l'UID de pod \"{podUid}\"", + "xpack.synthetics.monitorList.monitorHistoryColumnLabel": "Historique d'indisponibilité", + "xpack.synthetics.monitorList.monitoringStatusTitle": "Moniteurs", + "xpack.synthetics.monitorList.monitorType.filter": "Filtrer tous les moniteurs ayant le type {type}", + "xpack.synthetics.monitorList.mostRecentError.title": "Erreurs les plus récentes ({timestamp})", + "xpack.synthetics.monitorList.nameColumnLabel": "Nom", + "xpack.synthetics.monitorList.noDownHistory": "Ce moniteur n'a jamais été {emphasizedText} au cours de la plage temporelle sélectionnée.", + "xpack.synthetics.monitorList.noItemForSelectedFiltersMessage": "Aucun moniteur trouvé pour les critères de filtre sélectionnés", + "xpack.synthetics.monitorList.noItemMessage": "Aucun moniteur Uptime trouvé", + "xpack.synthetics.monitorList.observabilityIntegrationsColumn.apmIntegrationLink.tooltip": "Cliquez ici pour vérifier les APM pour le domaine \"{domain}\" ou le \"nom de service\" explicitement défini.", + "xpack.synthetics.monitorList.observabilityIntegrationsColumn.popoverIconButton.ariaLabel": "Ouvre la fenêtre contextuelle des intégrations pour le moniteur avec l'URL {monitorUrl}", + "xpack.synthetics.monitorList.observabilityInvestigateColumn.popoverIconButton.label": "Investiguer", + "xpack.synthetics.monitorList.pageSizePopoverButtonText": "Lignes par page : {size}", + "xpack.synthetics.monitorList.pageSizeSelect.numRowsItemMessage": "{numRows} lignes", + "xpack.synthetics.monitorList.redirects.description": "Heartbeat a suivi {number} redirections lors de l'exécution du ping.", + "xpack.synthetics.monitorList.redirects.openWindow": "Le lien s'ouvrira dans une nouvelle fenêtre.", + "xpack.synthetics.monitorList.redirects.title": "Redirections", + "xpack.synthetics.monitorList.redirects.title.number": "{number}", + "xpack.synthetics.monitorList.refresh": "Actualiser", + "xpack.synthetics.monitorList.statusAlert.label": "Alerte de statut", + "xpack.synthetics.monitorList.statusColumn.checkedTimestamp": "Vérifié à {timestamp}", + "xpack.synthetics.monitorList.statusColumn.completeLabel": "Terminé", + "xpack.synthetics.monitorList.statusColumn.downLabel": "Arrêté", + "xpack.synthetics.monitorList.statusColumn.error.logs": "Logs d'erreurs", + "xpack.synthetics.monitorList.statusColumn.error.message": "{message}. Cliquez pour en savoir plus.", + "xpack.synthetics.monitorList.statusColumn.error.messageLabel": "{message}. Cliquez pour en savoir plus.", + "xpack.synthetics.monitorList.statusColumn.failedLabel": "Échoué", + "xpack.synthetics.monitorList.statusColumn.locStatusMessage": "dans {noLoc} emplacement", + "xpack.synthetics.monitorList.statusColumn.locStatusMessage.multiple": "dans {noLoc} emplacements", + "xpack.synthetics.monitorList.statusColumn.locStatusMessage.tooltip.down": "Arrêté dans {locs}", + "xpack.synthetics.monitorList.statusColumn.locStatusMessage.tooltip.up": "Opérationnel dans {locs}", + "xpack.synthetics.monitorList.statusColumn.upLabel": "Opérationnel", + "xpack.synthetics.monitorList.statusColumnLabel": "Statut", + "xpack.synthetics.monitorList.table.description": "Tableau de statut de moniteur avec les colonnes Statut, Nom, URL, IP, Historique d'indisponibilité et Intégrations. Le tableau affiche actuellement {length} éléments.", + "xpack.synthetics.monitorList.table.tags.name": "Balises", + "xpack.synthetics.monitorList.table.url.name": "Url", + "xpack.synthetics.monitorList.tags.expand": "Cliquer pour afficher les balises restantes", + "xpack.synthetics.monitorList.tags.filter": "Filtrer tous les moniteurs avec la balise {tag}", + "xpack.synthetics.monitorList.testNow.AriaLabel": "Cliquer pour exécuter le test maintenant", + "xpack.synthetics.monitorList.testNow.available": "L'option Tester maintenant est uniquement disponible pour les moniteurs ajoutés via la liste Gestion des moniteurs.", + "xpack.synthetics.monitorList.testNow.label": "Tester maintenant", + "xpack.synthetics.monitorList.testNow.scheduled": "Le test est déjà programmé", + "xpack.synthetics.monitorList.testRunLogs": "Logs d'exécution de test", + "xpack.synthetics.monitorList.timestamp": "Horodatage", + "xpack.synthetics.monitorList.tlsColumnLabel": "Certificat TLS", + "xpack.synthetics.monitorList.viewInDiscover": "Afficher dans Discover", + "xpack.synthetics.monitorManagement.addMonitorCrumb": "Ajouter un moniteur", + "xpack.synthetics.monitorManagement.addMonitorError": "Impossible de charger les emplacements de services. Réessayez plus tard.", + "xpack.synthetics.monitorManagement.addMonitorLabel": "Ajouter un moniteur", + "xpack.synthetics.monitorManagement.addMonitorLoadingError": "Erreur lors du chargement de la liste Gestion des moniteurs", + "xpack.synthetics.monitorManagement.addMonitorLoadingLabel": "Chargement de la liste Gestion des moniteurs", + "xpack.synthetics.monitorManagement.addMonitorServiceLocationsLoadingError": "Impossible de charger les emplacements de services. Réessayez plus tard.", + "xpack.synthetics.monitorManagement.closeButtonLabel": "Fermer", + "xpack.synthetics.monitorManagement.completed": "TERMINÉ", + "xpack.synthetics.monitorManagement.confirmDescriptionLabel": "Cette action supprimera le moniteur mais conservera toute donnée collectée. Cette action ne peut pas être annulée.", + "xpack.synthetics.monitorManagement.deleteMonitorLabel": "Supprimer le moniteur", + "xpack.synthetics.monitorManagement.disableMonitorLabel": "Désactiver le moniteur", + "xpack.synthetics.monitorManagement.discardLabel": "Abandonner", + "xpack.synthetics.monitorManagement.duplicateNameError": "Le nom du moniteur existe déjà.", + "xpack.synthetics.monitorManagement.editMonitorCrumb": "Modifier le moniteur", + "xpack.synthetics.monitorManagement.editMonitorError": "Erreur lors du chargement de la liste Gestion des moniteurs", + "xpack.synthetics.monitorManagement.editMonitorErrorBody": "Impossible de charger la configuration du moniteur. Réessayez plus tard.", + "xpack.synthetics.monitorManagement.editMonitorLabel": "Modifier le moniteur", + "xpack.synthetics.monitorManagement.editMonitorLoadingLabel": "Chargement du moniteur", + "xpack.synthetics.monitorManagement.enableMonitorLabel": "Activer le moniteur", + "xpack.synthetics.monitorManagement.failed": "ÉCHOUÉ", + "xpack.synthetics.monitorManagement.failedRun": "Impossible d'exécuter les étapes", + "xpack.synthetics.monitorManagement.inProgress": "EN COURS", + "xpack.synthetics.monitorManagement.label": "Gestion des moniteurs", + "xpack.synthetics.monitorManagement.loading.label": "Chargement de la liste Gestion des moniteurs", + "xpack.synthetics.monitorManagement.loadingSteps": "Chargement des étapes...", + "xpack.synthetics.monitorManagement.monitorAddedSuccessMessage": "Moniteur ajouté avec succès.", + "xpack.synthetics.monitorManagement.monitorAdvancedOptions.dataStreamConfiguration.description": "Configurez les options de flux de données supplémentaires.", + "xpack.synthetics.monitorManagement.monitorAdvancedOptions.dataStreamConfiguration.title": "Paramètres de flux de données", + "xpack.synthetics.monitorManagement.monitorAdvancedOptions.monitorNamespaceFieldLabel": "Espace de nom", + "xpack.synthetics.monitorManagement.monitorAdvancedOptions.namespaceHelpLabel": "Modifiez l'espace de nom par défaut. Ce paramètre modifie le nom du flux de données du moniteur. {learnMore}.", + "xpack.synthetics.monitorManagement.monitorAdvancedOptions.namespaceHelpLearnMoreLabel": "En savoir plus", + "xpack.synthetics.monitorManagement.monitorDeleteFailureMessage": "Impossible de supprimer le moniteur. Réessayez plus tard.", + "xpack.synthetics.monitorManagement.monitorDeleteLoadingMessage": "Suppression du moniteur...", + "xpack.synthetics.monitorManagement.monitorDeleteSuccessMessage": "Moniteur supprimé avec succès.", + "xpack.synthetics.monitorManagement.monitorDisabledSuccessMessage": "Moniteur {name} désactivé avec succès.", + "xpack.synthetics.monitorManagement.monitorEditedSuccessMessage": "Moniteur mis à jour avec succès.", + "xpack.synthetics.monitorManagement.monitorEnabledSuccessMessage": "Moniteur {name} activé avec succès.", + "xpack.synthetics.monitorManagement.monitorEnabledUpdateFailureMessage": "Impossible de mettre à jour le moniteur {name}.", + "xpack.synthetics.monitorManagement.monitorFailureMessage": "Impossible d'enregistrer le moniteur. Réessayez plus tard.", + "xpack.synthetics.monitorManagement.monitorList.actions": "Actions", + "xpack.synthetics.monitorManagement.monitorList.enabled": "Activé", + "xpack.synthetics.monitorManagement.monitorList.locations": "Emplacements", + "xpack.synthetics.monitorManagement.monitorList.monitorName": "Nom de moniteur", + "xpack.synthetics.monitorManagement.monitorList.monitorType": "Type de moniteur", + "xpack.synthetics.monitorManagement.monitorList.schedule": "Fréquence (min)", + "xpack.synthetics.monitorManagement.monitorList.tags": "Balises", + "xpack.synthetics.monitorManagement.monitorList.title": "Liste Gestion des moniteurs", + "xpack.synthetics.monitorManagement.monitorList.URL": "URL", + "xpack.synthetics.monitorManagement.monitorLocationsLabel": "Emplacements des moniteurs", + "xpack.synthetics.monitorManagement.monitorManagementCrumb": "Gestion des moniteurs", + "xpack.synthetics.monitorManagement.monitorNameFieldError": "Le nom de moniteur est requis", + "xpack.synthetics.monitorManagement.monitorNameFieldLabel": "Nom de moniteur", + "xpack.synthetics.monitorManagement.noLabel": "Annuler", + "xpack.synthetics.monitorManagement.pageHeader.title": "Gérer les moniteurs", + "xpack.synthetics.monitorManagement.pending": "EN ATTENTE", + "xpack.synthetics.monitorManagement.publicBetaDescription": "La liste Gestion des moniteurs est disponible uniquement pour les utilisateurs de la version bêta publique sélectionnés. Avec un accès\nà la version bêta publique, vous pourrez ajouter des vérifications HTTP, TCP, ICMP et Navigateur qui seront\nexécutées sur les nœuds de service synthétiques gérés d'Elastic.", + "xpack.synthetics.monitorManagement.requestAccess": "Demander un accès", + "xpack.synthetics.monitorManagement.reRunTest": "Exécuter à nouveau le test", + "xpack.synthetics.monitorManagement.runTest": "Exécuter le test", + "xpack.synthetics.monitorManagement.saveMonitorLabel": "Enregistrer le moniteur", + "xpack.synthetics.monitorManagement.service.error.message": "Votre moniteur a été enregistré, mais un problème est survenu lors de la synchronisation de la configuration pour {location}. Nous réessaierons plus tard de façon automatique. Si le problème persiste, vos moniteurs arrêteront de fonctionner dans {location}. Veuillez contacter le support technique pour obtenir de l'aide.", + "xpack.synthetics.monitorManagement.service.error.reason": "Raison : {reason}.", + "xpack.synthetics.monitorManagement.service.error.status": "Statut : {status}. ", + "xpack.synthetics.monitorManagement.service.error.title": "Impossible de synchroniser la configuration du moniteur", + "xpack.synthetics.monitorManagement.serviceLocationsValidationError": "Au moins un emplacement de service doit être spécifié", + "xpack.synthetics.monitorManagement.stepCompleted": "{stepCount, number} {stepCount, plural, one {étape terminée} other {étapes terminées}}", + "xpack.synthetics.monitorManagement.testResult": "Résultat du test", + "xpack.synthetics.monitorManagement.timeTaken": "Durée de {timeTaken}", + "xpack.synthetics.monitorManagement.updateMonitorLabel": "Mettre à jour le moniteur", + "xpack.synthetics.monitorManagement.validationError": "Votre moniteur comporte des erreurs. Corrigez-les avant de l'enregistrer.", + "xpack.synthetics.monitorManagement.viewTestRunDetails": "Afficher les détails du résultat du test", + "xpack.synthetics.monitorManagement.yesLabel": "Supprimer", + "xpack.synthetics.monitorManagementRoute.title": "Gérer les moniteurs | {baseTitle}", + "xpack.synthetics.monitorRoute.title": "Moniteur | {baseTitle}", + "xpack.synthetics.monitorStatusBar.durationTextAriaLabel": "Durée du monitoring en millisecondes", + "xpack.synthetics.monitorStatusBar.healthStatusMessageAriaLabel": "Statut du moniteur", + "xpack.synthetics.monitorStatusBar.loadingMessage": "Chargement…", + "xpack.synthetics.monitorStatusBar.locations.oneLocStatus": "{status} dans {loc} emplacement", + "xpack.synthetics.monitorStatusBar.locations.upStatus": "{status} dans {loc} emplacements", + "xpack.synthetics.monitorStatusBar.monitor.availability": "Disponibilité générale", + "xpack.synthetics.monitorStatusBar.monitor.availabilityReport.availability": "Disponibilité", + "xpack.synthetics.monitorStatusBar.monitor.availabilityReport.lastCheck": "Dernière vérification", + "xpack.synthetics.monitorStatusBar.monitor.availabilityReport.location": "Emplacement", + "xpack.synthetics.monitorStatusBar.monitor.id": "ID de moniteur", + "xpack.synthetics.monitorStatusBar.monitor.monitoringFrom": "Monitoring à partir de", + "xpack.synthetics.monitorStatusBar.monitor.monitoringFrom.listToMap": "Passer à la vue de carte pour vérifier la disponibilité par emplacement.", + "xpack.synthetics.monitorStatusBar.monitor.monitoringFrom.MapToList": "Passer à la vue de liste pour vérifier la disponibilité par emplacement.", + "xpack.synthetics.monitorStatusBar.monitorUrlLinkAriaLabel": "Lien d'URL du moniteur", + "xpack.synthetics.monitorStatusBar.sslCertificate.title": "Certificat TLS", + "xpack.synthetics.monitorStatusBar.timestampFromNowTextAriaLabel": "Temps depuis la dernière vérification", + "xpack.synthetics.monitorStatusBar.type.ariaLabel": "Type de moniteur", + "xpack.synthetics.monitorStatusBar.type.label": "Type", + "xpack.synthetics.navigateToAlertingButton.content": "Gérer les règles", + "xpack.synthetics.navigateToAlertingUi": "Quitter Uptime et accéder à la page de gestion Alerting", + "xpack.synthetics.noDataConfig.beatsCard.description": "Monitorez de façon proactive la disponibilité de vos sites et services. Recevez des alertes et corrigez les problèmes plus rapidement pour optimiser l'expérience de vos utilisateurs.", + "xpack.synthetics.noDataConfig.beatsCard.title": "Ajouter des moniteurs avec Heartbeat", + "xpack.synthetics.noDataConfig.solutionName": "Observabilité", + "xpack.synthetics.notFountPage.homeLinkText": "Retour à l'accueil", + "xpack.synthetics.openAlertContextPanel.ariaLabel": "Ouvrez le panneau de contexte des règles pour choisir un type de règle", + "xpack.synthetics.openAlertContextPanel.label": "Créer une règle", + "xpack.synthetics.overview.alerts.disabled.failed": "La règle ne peut pas être désactivée !", + "xpack.synthetics.overview.alerts.disabled.success": "La règle a été correctement désactivée !", + "xpack.synthetics.overview.alerts.enabled.failed": "La règle ne peut pas être activée !", + "xpack.synthetics.overview.alerts.enabled.success": "La règle a été correctement activée ", + "xpack.synthetics.overview.alerts.enabled.success.description": "Un message sera envoyé à {actionConnectors} lorsque ce monitoring sera arrêté.", + "xpack.synthetics.overview.heading": "Moniteurs", + "xpack.synthetics.overview.pageHeader.syntheticsCallout.announcementLink": "Lire l'annonce", + "xpack.synthetics.overview.pageHeader.syntheticsCallout.content": "Uptime affiche maintenant l'aperçu du support pour les vérifications scriptées de disponibilité à plusieurs étapes. Cela signifie que vous pouvez interagir avec les éléments d'une page Web et vérifier la disponibilité d'un parcours complet (par exemple, effectuer un achat ou se connecter à un système) au lieu d'effectuer de simples petites vérifications. Veuillez cliquer ci-dessous pour en savoir plus et, si vous souhaitez être l'un des premiers à utiliser ces fonctionnalités, vous pouvez télécharger notre agent d'aperçu synthétique et visualiser vos vérifications synthétiques dans Uptime.", + "xpack.synthetics.overview.pageHeader.syntheticsCallout.dismissButtonText": "Rejeter", + "xpack.synthetics.overview.pageHeader.syntheticsCallout.title": "Elastic Synthetics", + "xpack.synthetics.overviewPage.headerText": "Aperçu", + "xpack.synthetics.overviewPageLink.disabled.ariaLabel": "Bouton de pagination désactivé indiquant qu'aucune autre navigation ne peut être effectuée dans la liste des moniteurs.", + "xpack.synthetics.overviewPageLink.next.ariaLabel": "Page de résultats suivante", + "xpack.synthetics.overviewPageLink.prev.ariaLabel": "Page de résultats précédente", + "xpack.synthetics.page_header.addDataLink.label": "Accédez à un tutoriel sur l'ajout de données Uptime", + "xpack.synthetics.page_header.analyzeData.label": "Accédez à la vue \"Explorer les données\" pour visualiser les données synthétiques/d'utilisateur", + "xpack.synthetics.page_header.defineConnector.popover.defaultLink": "Définir un connecteur par défaut", + "xpack.synthetics.page_header.defineConnector.settingsLink": "Paramètres", + "xpack.synthetics.page_header.manageLink.label": "Accéder à la page de gestion des moniteurs Uptime", + "xpack.synthetics.page_header.settingsLink": "Paramètres", + "xpack.synthetics.page_header.settingsLink.label": "Accédez à la page de paramètres Uptime", + "xpack.synthetics.pingHistogram.analyze": "Analyser", + "xpack.synthetics.pingist.durationSecondsColumnFormatting": "{seconds} secondes", + "xpack.synthetics.pingist.durationSecondsColumnFormatting.singular": "{seconds} seconde", + "xpack.synthetics.pingList.checkHistoryTitle": "Historique", + "xpack.synthetics.pingList.collapseRow": "Réduire", + "xpack.synthetics.pingList.columns.failedStep": "Étape ayant échoué", + "xpack.synthetics.pingList.drawer.body.docsLink": "documents", + "xpack.synthetics.pingList.durationMsColumnFormatting": "{millis} ms", + "xpack.synthetics.pingList.durationMsColumnLabel": "Durée", + "xpack.synthetics.pingList.errorColumnLabel": "Erreur", + "xpack.synthetics.pingList.errorTypeColumnLabel": "Type d'erreur", + "xpack.synthetics.pingList.expandedRow.bodySize": "La taille du corps est de {bodyBytes}.", + "xpack.synthetics.pingList.expandedRow.error": "Erreur", + "xpack.synthetics.pingList.expandedRow.response_body": "Corps de réponse", + "xpack.synthetics.pingList.expandedRow.response_body.notRecorded": "Corps non enregistré. Lisez notre {docsLink} pour en savoir plus sur l'enregistrement des corps de réponse.", + "xpack.synthetics.pingList.expandedRow.truncated": "Affichage des {contentBytes} premiers octets.", + "xpack.synthetics.pingList.expandRow": "Développer", + "xpack.synthetics.pingList.headers.title": "En-têtes de réponse", + "xpack.synthetics.pingList.ipAddressColumnLabel": "IP", + "xpack.synthetics.pingList.locationNameColumnLabel": "Emplacement", + "xpack.synthetics.pingList.pingsLoadingMesssage": "Chargement de l'historique...", + "xpack.synthetics.pingList.pingsUnavailableMessage": "Aucun historique trouvé", + "xpack.synthetics.pingList.recencyMessage": "Vérifié {fromNow}", + "xpack.synthetics.pingList.responseCodeColumnLabel": "Code de réponse", + "xpack.synthetics.pingList.statusColumnLabel": "Statut", + "xpack.synthetics.pingList.stepDurationHeader": "Durée de l’étape", + "xpack.synthetics.pingList.synthetics.performanceBreakDown": "Afficher la répartition des performances", + "xpack.synthetics.pingList.synthetics.waterfall.filters.collapseRequestsLabel": "Réduire pour afficher uniquement les requêtes correspondantes", + "xpack.synthetics.pingList.synthetics.waterfall.filters.popover": "Cliquer pour ouvrir les filtres de cascade", + "xpack.synthetics.pingList.timestampColumnLabel": "Horodatage", + "xpack.synthetics.pluginDescription": "Monitoring Uptime", + "xpack.synthetics.public.pages.mappingError.bodyDocsLink": "Vous pouvez apprendre à corriger ce problème dans la {docsLink}.", + "xpack.synthetics.public.pages.mappingError.bodyMessage": "Mappings incorrects détectés ! Vous avez peut-être oublié d'exécuter la commande {setup} Heartbeat ?", + "xpack.synthetics.public.pages.mappingError.title": "Mappings Heartbeat manquants", + "xpack.synthetics.routes.baseTitle": "Uptime - Kibana", + "xpack.synthetics.seconds.label": "secondes", + "xpack.synthetics.seconds.shortForm.label": "s", + "xpack.synthetics.settings.blank.error": "Ne peut pas être vide.", + "xpack.synthetics.settings.blankNumberField.error": "Doit être un nombre.", + "xpack.synthetics.settings.cannotEditText": "Actuellement, votre utilisateur possède les autorisations \"Lecture\" pour l'application Uptime. Activez un niveau d'autorisation \"Tout\" pour pouvoir modifier ces paramètres.", + "xpack.synthetics.settings.cannotEditTitle": "Vous ne disposez pas d'autorisation pour modifier les paramètres.", + "xpack.synthetics.settings.error.couldNotSave": "Impossible d'enregistrer les paramètres !", + "xpack.synthetics.settings.heading": "Paramètres Uptime", + "xpack.synthetics.settings.invalid.error": "La valeur doit être supérieure à 0.", + "xpack.synthetics.settings.invalid.nanError": "La valeur doit être un entier.", + "xpack.synthetics.settings.noSpace.error": "Les noms d'index ne doivent pas contenir d'espace", + "xpack.synthetics.settings.saveSuccess": "Paramètres enregistrés !", + "xpack.synthetics.settingsBreadcrumbText": "Paramètres", + "xpack.synthetics.settingsRoute.title": "Paramètres | {baseTitle}", + "xpack.synthetics.snapshot.donutChart.ariaLabel": "Camembert affichant le statut actuel. {down} moniteurs sur {total} sont arrêtés.", + "xpack.synthetics.snapshot.monitor": "Moniteur", + "xpack.synthetics.snapshot.monitors": "Moniteurs", + "xpack.synthetics.snapshot.noDataDescription": "Aucun ping dans la plage temporelle sélectionnée.", + "xpack.synthetics.snapshot.noDataTitle": "Pas de données ping disponibles", + "xpack.synthetics.snapshot.pingsOverTimeTitle": "Pings sur la durée", + "xpack.synthetics.snapshotHistogram.description": "Graphique à barres affichant le statut Uptime au fil du temps de {startTime} à {endTime}.", + "xpack.synthetics.snapshotHistogram.series.pings": "Monitorer les pings", + "xpack.synthetics.snapshotHistogram.xAxisId": "Axe X des pings", + "xpack.synthetics.snapshotHistogram.yAxis.title": "Pings", + "xpack.synthetics.snapshotHistogram.yAxisId": "Axe Y des pings", + "xpack.synthetics.sourceConfiguration.ageLimit.units.days": "Jours", + "xpack.synthetics.sourceConfiguration.ageLimitThresholdInput.ariaLabel": "Entrée contrôlant le nombre maximal de jours pendant lesquels un certificat TLS peut être valide avant que Kibana n'affiche un avertissement.", + "xpack.synthetics.sourceConfiguration.ageThresholdDefaultValue": "La valeur par défaut est {defaultValue}", + "xpack.synthetics.sourceConfiguration.alertConnectors": "Connecteurs d'alerte", + "xpack.synthetics.sourceConfiguration.alertConnectors.defaultEmail": "E-mail par défaut", + "xpack.synthetics.sourceConfiguration.alertDefaultForm.emailConnectorPlaceHolder": "À : pour le connecteur d'e-mails", + "xpack.synthetics.sourceConfiguration.alertDefaultForm.invalidEmail": "{val} n'est pas un e-mail valide.", + "xpack.synthetics.sourceConfiguration.alertDefaultForm.requiredEmail": "L'e-mail du destinataire est requis pour le connecteur d'e-mails", + "xpack.synthetics.sourceConfiguration.alertDefaultForm.selectConnector": "Veuillez sélectionner un ou plusieurs connecteurs", + "xpack.synthetics.sourceConfiguration.alertDefaults": "Valeurs par défaut des alertes", + "xpack.synthetics.sourceConfiguration.applySettingsButtonLabel": "Appliquer les modifications", + "xpack.synthetics.sourceConfiguration.certificateExpirationThresholdInput.ariaLabel": "Entrée contrôlant le nombre minimal de jours restants pour l'expiration du certificat TLS avant que Kibana n'affiche un avertissement.", + "xpack.synthetics.sourceConfiguration.certificateThresholdDescription": "Modifiez le seuil pour l'affichage et l'alerting lors d'erreurs de certificat. Remarque : cette action affectera toutes les alertes configurées.", + "xpack.synthetics.sourceConfiguration.certificationSectionTitle": "Expiration du certificat", + "xpack.synthetics.sourceConfiguration.defaultConnectors": "Connecteurs par défaut", + "xpack.synthetics.sourceConfiguration.defaultConnectors.description": "Connecteurs par défaut à utiliser pour envoyer une alerte.", + "xpack.synthetics.sourceConfiguration.defaultConnectors.description.defaultEmail": "Paramètres d'e-mails requis pour les connecteurs d'alertes d'e-mails sélectionnés.", + "xpack.synthetics.sourceConfiguration.discardSettingsButtonLabel": "Annuler", + "xpack.synthetics.sourceConfiguration.errorStateLabel": "Seuil d'expiration", + "xpack.synthetics.sourceConfiguration.expirationThreshold": "Seuils expiration/âge", + "xpack.synthetics.sourceConfiguration.expirationThresholdDefaultValue": "La valeur par défaut est {defaultValue}", + "xpack.synthetics.sourceConfiguration.heartbeatIndicesDefaultValue": "La valeur par défaut est {defaultValue}", + "xpack.synthetics.sourceConfiguration.heartbeatIndicesDescription": "Modèle d'indexation pour la correspondance d'index contenant des données Heartbeat", + "xpack.synthetics.sourceConfiguration.heartbeatIndicesLabel": "Index Heartbeat", + "xpack.synthetics.sourceConfiguration.heartbeatIndicesTitle": "Index Uptime", + "xpack.synthetics.sourceConfiguration.indicesSectionTitle": "Index", + "xpack.synthetics.sourceConfiguration.warningStateLabel": "Limite d'âge", + "xpack.synthetics.stepDetailRoute.title": "Détail synthétique | {baseTitle}", + "xpack.synthetics.stepList.collapseRow": "Réduire", + "xpack.synthetics.stepList.expandRow": "Développer", + "xpack.synthetics.stepList.stepName": "Nom de l'étape", + "xpack.synthetics.synthetics.consoleStepList.message": "Ce parcours n'a pas réussi à s'exécuter ; la sortie de la console enregistrée est affichée ci-dessous :", + "xpack.synthetics.synthetics.consoleStepList.title": "Aucune étape exécutée", + "xpack.synthetics.synthetics.emptyJourney.message.checkGroupField": "Le groupe de vérification du parcours est {codeBlock}.", + "xpack.synthetics.synthetics.emptyJourney.message.footer": "Aucune autre information à afficher.", + "xpack.synthetics.synthetics.emptyJourney.message.heading": "Le parcours ne contenait aucune étape.", + "xpack.synthetics.synthetics.emptyJourney.title": "Aucune étape pour ce parcours", + "xpack.synthetics.synthetics.executedStep.consoleOutput.label": "Sortie de la console", + "xpack.synthetics.synthetics.executedStep.errorHeading": "Message d'erreur", + "xpack.synthetics.synthetics.executedStep.screenshot.not": "Capture d'écran", + "xpack.synthetics.synthetics.executedStep.screenshot.notSucceeded": "Capture d'écran pour la vérification du statut {status}", + "xpack.synthetics.synthetics.executedStep.screenshot.success": "dernière vérification réussie", + "xpack.synthetics.synthetics.executedStep.screenshot.successfulLink": "Capture d'écran de {link}", + "xpack.synthetics.synthetics.executedStep.scriptHeading.label": "Script exécuté à cette étape", + "xpack.synthetics.synthetics.executedStep.stackTrace": "Trace de la Suite Elastic", + "xpack.synthetics.synthetics.imageLoadingSpinner.ariaLabel": "Boucle de progression animée indiquant que l'image est en train de se charger", + "xpack.synthetics.synthetics.journey.allFailedMessage": "{total} étapes - toutes échouées ou ignorées", + "xpack.synthetics.synthetics.journey.allSucceededMessage": "{total} étapes - toutes réussies", + "xpack.synthetics.synthetics.journey.loadingSteps": "Chargement des étapes...", + "xpack.synthetics.synthetics.journey.partialSuccessMessage": "{total} étapes - {succeeded} réussies", + "xpack.synthetics.synthetics.markers.explore": "Explorer", + "xpack.synthetics.synthetics.markers.noFieldIcon.label": "Icône indiquant que ce marqueur ne possède aucun champ associé", + "xpack.synthetics.synthetics.markers.openEmbeddableButton.label": "Utilisez ce bouton icône pour afficher les indicateurs pour ce marqueur d'annotation.", + "xpack.synthetics.synthetics.nextStepButton.ariaLabel": "Étape suivante", + "xpack.synthetics.synthetics.performanceBreakDown.label": "Répartition des performances", + "xpack.synthetics.synthetics.pingTimestamp.captionContent": "Étape : {stepNumber} sur {totalSteps}", + "xpack.synthetics.synthetics.prevStepButton.airaLabel": "Étape précédente", + "xpack.synthetics.synthetics.screenshot.noImageMessage": "Aucune image disponible", + "xpack.synthetics.synthetics.screenshotDisplay.altText": "Capture d'écran de l'étape portant le nom \"{stepName}\"", + "xpack.synthetics.synthetics.screenshotDisplay.altTextWithoutName": "Capture d'écran", + "xpack.synthetics.synthetics.service.apiKey": "Clé d'API du service Synthetics", + "xpack.synthetics.synthetics.statusBadge.failedMessage": "Échoué", + "xpack.synthetics.synthetics.statusBadge.skippedMessage": "Ignoré", + "xpack.synthetics.synthetics.statusBadge.succeededMessage": "Réussi", + "xpack.synthetics.synthetics.step.duration": "{value} secondes", + "xpack.synthetics.synthetics.step.durationTrend": "Tendance de durée de l'étape", + "xpack.synthetics.synthetics.stepDetail.nextCheckButtonText": "Vérification suivante", + "xpack.synthetics.synthetics.stepDetail.noData": "Aucune donnée n'a été trouvée pour cette étape", + "xpack.synthetics.synthetics.stepDetail.previousCheckButtonText": "Vérification précédente", + "xpack.synthetics.synthetics.stepDetail.totalSteps": "Étape {stepIndex} sur {totalSteps}", + "xpack.synthetics.synthetics.stepDetail.waterfall.loading": "Chargement du graphique en cascade", + "xpack.synthetics.synthetics.stepDetail.waterfallNoData": "Aucune donnée de cascade n'a été trouvée pour cette étape", + "xpack.synthetics.synthetics.stepDetail.waterfallUnsupported.description": "Le graphique en cascade ne peut pas être affiché. Vous utilisez peut-être une ancienne version de l'agent synthétique. Veuillez vérifier votre version et envisager d'effectuer une mise à niveau.", + "xpack.synthetics.synthetics.stepDetail.waterfallUnsupported.title": "Graphique en cascade non disponible", + "xpack.synthetics.synthetics.stepList.nextCheck": "Vérification suivante", + "xpack.synthetics.synthetics.stepList.previousCheck": "Vérification précédente", + "xpack.synthetics.synthetics.thumbnail.fullSize.alt": "Version plus grande de la capture d'écran de la miniature de l'étape du parcours.", + "xpack.synthetics.synthetics.waterfall.domContentLabel": "Contenu DOM chargé", + "xpack.synthetics.synthetics.waterfall.fcpLabel": "First Contentful Paint", + "xpack.synthetics.synthetics.waterfall.filterGroup.filterScreenreaderLabel": "Filtrer par", + "xpack.synthetics.synthetics.waterfall.filterGroup.removeFilterScreenReaderLabel": "Retirer le filtre Filtrer par", + "xpack.synthetics.synthetics.waterfall.flyout.certificates": "En-têtes de certificat", + "xpack.synthetics.synthetics.waterfall.flyout.details": "Détails", + "xpack.synthetics.synthetics.waterfall.flyout.requestHeaders": "En-têtes de la requête", + "xpack.synthetics.synthetics.waterfall.flyout.responseHeaders": "En-têtes de réponse", + "xpack.synthetics.synthetics.waterfall.layoutShiftLabel": "Layout Shift", + "xpack.synthetics.synthetics.waterfall.lcpLabel": "Largest Contentful Paint", + "xpack.synthetics.synthetics.waterfall.loadEventLabel": "Charger l'événement", + "xpack.synthetics.synthetics.waterfall.offsetUnit": "{offset} ms", + "xpack.synthetics.synthetics.waterfall.requestsHighlightedMessage": "({numHighlightedRequests} correspondent au filtre)", + "xpack.synthetics.synthetics.waterfall.requestsTotalMessage": "{numNetworkRequests} requêtes réseau", + "xpack.synthetics.synthetics.waterfall.requestsTotalMessage.first": "Premier(s)/première(s) {count}", + "xpack.synthetics.synthetics.waterfall.requestsTotalMessage.info": "La vue cascade ne peut pas afficher plus de 1 000 requêtes", + "xpack.synthetics.synthetics.waterfall.resource.externalLink": "Ouvrir la ressource dans un nouvel onglet", + "xpack.synthetics.synthetics.waterfall.searchBox.placeholder": "Filtrer les nouvelles requêtes réseau", + "xpack.synthetics.synthetics.waterfall.sidebar.filterMatchesScreenReaderLabel": "La ressource correspond au filtre", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.certificateExpiryDate": "Valide jusque", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.certificateIssueDate": "Valide depuis", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.certificateIssuer": "Émetteur", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.certificateSubject": "Nom courant", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.contentType": "Type de contenu", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.ip": "IP", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.requestStart": "Début de la requête", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.resourceSize": "Taille de la ressource", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.status": "Statut", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.transferSize": "Taille du transfert", + "xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.font": "Police", + "xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.html": "HTML", + "xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.media": "Support", + "xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.other": "Autre", + "xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.script": "JS", + "xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.stylesheet": "CSS", + "xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.xhr": "XHR", + "xpack.synthetics.synthetics.waterfallChart.labels.timings.blocked": "En file d'attente / Bloqué", + "xpack.synthetics.synthetics.waterfallChart.labels.timings.connect": "Connexion", + "xpack.synthetics.synthetics.waterfallChart.labels.timings.dns": "DNS", + "xpack.synthetics.synthetics.waterfallChart.labels.timings.receive": "Téléchargement du contenu", + "xpack.synthetics.synthetics.waterfallChart.labels.timings.send": "Envoi de la requête", + "xpack.synthetics.synthetics.waterfallChart.labels.timings.ssl": "TLS", + "xpack.synthetics.synthetics.waterfallChart.labels.timings.wait": "En attente (TTFB)", + "xpack.synthetics.syntheticsMonitors": "Uptime - Moniteur", + "xpack.synthetics.testRun.description": "Tester votre moniteur et vérifier les résultats avant d'enregistrer", + "xpack.synthetics.testRun.pushError": "Impossible d'envoyer le moniteur vers le service.", + "xpack.synthetics.testRun.pushErrorLabel": "Erreur d'envoi", + "xpack.synthetics.testRun.pushing.description": "Envoi du moniteur vers le service...", + "xpack.synthetics.title": "Uptime", + "xpack.synthetics.toggleAlertButton.content": "Règle de statut du moniteur", + "xpack.synthetics.toggleAlertFlyout.ariaLabel": "Ouvrir le menu volant d'ajout de règle", + "xpack.synthetics.toggleTlsAlertButton.ariaLabel": "Ouvrir le menu volant de règle TLS", + "xpack.synthetics.toggleTlsAlertButton.content": "Règle TLS", + "xpack.synthetics.uptimeFeatureCatalogueTitle": "Uptime", + "xpack.synthetics.uptimeSettings.index": "Paramètres Uptime - Index", + "xpack.synthetics.waterfallChart.sidebar.url.https": "https", "xpack.urlDrilldown.click.event.key.documentation": "Nom du champ derrière le point de données sur lequel l'utilisateur a cliqué.", "xpack.urlDrilldown.click.event.key.title": "Nom du champ sur lequel l'utilisateur a cliqué.", "xpack.urlDrilldown.click.event.negate.documentation": "Booléen, indiquant si le point de données sur lequel l'utilisateur a cliqué a généré un filtre négatif.", @@ -31086,6 +31093,137 @@ "xpack.watcher.watchActions.webhook.portIsRequiredValidationMessage": "Le port webhook est requis.", "xpack.watcher.watchActions.webhook.usernameIsRequiredIfPasswordValidationMessage": "Le nom d'utilisateur est requis.", "xpack.watcher.watchEdit.thresholdWatchExpression.aggType.fieldIsRequiredValidationMessage": "Ce champ est requis.", - "xpack.watcher.watcherDescription": "Détectez les modifications survenant dans vos données en créant, gérant et monitorant des alertes." + "xpack.watcher.watcherDescription": "Détectez les modifications survenant dans vos données en créant, gérant et monitorant des alertes.", + "unifiedSearch.noDataPopover.content": "Cette plage temporelle ne contient pas de données. Étendez ou ajustez la plage temporelle pour obtenir plus de champs et pouvoir créer des graphiques.", + "unifiedSearch.noDataPopover.dismissAction": "Ne plus afficher", + "unifiedSearch.noDataPopover.subtitle": "Conseil", + "unifiedSearch.noDataPopover.title": "Ensemble de données vide", + "unifiedSearch.query.queryBar.clearInputLabel": "Effacer l'entrée", + "unifiedSearch.query.queryBar.comboboxAriaLabel": "Rechercher et filtrer la page {pageType}", + "unifiedSearch.query.queryBar.kqlFullLanguageName": "Langage de requête Kibana", + "unifiedSearch.query.queryBar.kqlLanguageName": "KQL", + "unifiedSearch.query.queryBar.KQLNestedQuerySyntaxInfoDocLinkText": "documents", + "unifiedSearch.query.queryBar.KQLNestedQuerySyntaxInfoOptOutText": "Ne plus afficher", + "unifiedSearch.query.queryBar.KQLNestedQuerySyntaxInfoText": "Il semblerait que votre requête porte sur un champ imbriqué. Selon le résultat visé, il existe plusieurs façons de construire une syntaxe KQL pour des requêtes imbriquées. Apprenez-en plus avec notre {link}.", + "unifiedSearch.query.queryBar.KQLNestedQuerySyntaxInfoTitle": "Syntaxe de requête imbriquée KQL", + "unifiedSearch.query.queryBar.kqlOffLabel": "Désactivé", + "unifiedSearch.query.queryBar.kqlOnLabel": "Activé", + "unifiedSearch.query.queryBar.languageSwitcher.toText": "Passer au langage de requête Kibana pour la recherche", + "unifiedSearch.query.queryBar.luceneLanguageName": "Lucene", + "unifiedSearch.query.queryBar.searchInputAriaLabel": "Commencer à taper pour rechercher et filtrer la page {pageType}", + "unifiedSearch.query.queryBar.searchInputPlaceholder": "Recherche", + "unifiedSearch.query.queryBar.syntaxOptionsDescription": "{docsLink} (KQL) offre une syntaxe de requête simplifiée et la prise en charge des champs scriptés. KQL offre également une fonctionnalité de saisie semi-automatique. Si vous désactivez KQL, {nonKqlModeHelpText}.", + "unifiedSearch.query.queryBar.syntaxOptionsDescription.nonKqlModeHelpText": "Kibana utilise Lucene.", + "unifiedSearch.search.searchBar.savedQueryDescriptionLabelText": "Description", + "unifiedSearch.search.searchBar.savedQueryDescriptionText": "Enregistrez le texte et les filtres de la requête que vous souhaitez réutiliser.", + "unifiedSearch.search.searchBar.savedQueryForm.titleConflictText": "Ce nom est en conflit avec une requête enregistrée existante.", + "unifiedSearch.search.searchBar.savedQueryFormCancelButtonText": "Annuler", + "unifiedSearch.search.searchBar.savedQueryFormSaveButtonText": "Enregistrer", + "unifiedSearch.search.searchBar.savedQueryFormTitle": "Enregistrer la requête", + "unifiedSearch.search.searchBar.savedQueryIncludeFiltersLabelText": "Inclure les filtres", + "unifiedSearch.search.searchBar.savedQueryIncludeTimeFilterLabelText": "Inclure le filtre temporel", + "unifiedSearch.search.searchBar.savedQueryNameHelpText": "Un nom est requis. Le nom ne peut pas contenir d'espace vide au début ou à la fin. Le nom doit être unique.", + "unifiedSearch.search.searchBar.savedQueryNameLabelText": "Nom", + "unifiedSearch.search.searchBar.savedQueryNoSavedQueriesText": "Aucune requête enregistrée.", + "unifiedSearch.search.searchBar.savedQueryPopoverButtonText": "Voir les requêtes enregistrées", + "unifiedSearch.search.searchBar.savedQueryPopoverClearButtonAriaLabel": "Effacer la requête enregistrée en cours", + "unifiedSearch.search.searchBar.savedQueryPopoverClearButtonText": "Effacer", + "unifiedSearch.search.searchBar.savedQueryPopoverConfirmDeletionCancelButtonText": "Annuler", + "unifiedSearch.search.searchBar.savedQueryPopoverConfirmDeletionConfirmButtonText": "Supprimer", + "unifiedSearch.search.searchBar.savedQueryPopoverConfirmDeletionTitle": "Supprimer \"{savedQueryName}\" ?", + "unifiedSearch.search.searchBar.savedQueryPopoverDeleteButtonAriaLabel": "Supprimer la requête enregistrée {savedQueryName}", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveAsNewButtonAriaLabel": "Enregistrer en tant que nouvelle requête enregistrée", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveAsNewButtonText": "Enregistrer en tant que nouvelle", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveButtonAriaLabel": "Enregistrer une nouvelle requête enregistrée", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveButtonText": "Enregistrer la requête en cours", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveChangesButtonAriaLabel": "Enregistrer les modifications apportées à {title}", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveChangesButtonText": "Enregistrer les modifications", + "unifiedSearch.search.searchBar.savedQueryPopoverSavedQueryListItemButtonAriaLabel": "Bouton de requête enregistrée {savedQueryName}", + "unifiedSearch.search.searchBar.savedQueryPopoverSavedQueryListItemDescriptionAriaLabel": "Description de {savedQueryName}", + "unifiedSearch.search.searchBar.savedQueryPopoverSavedQueryListItemSelectedButtonAriaLabel": "Bouton de requête enregistrée {savedQueryName} sélectionné. Appuyez pour effacer les modifications.", + "unifiedSearch.search.searchBar.savedQueryPopoverTitleText": "Requêtes enregistrées", + "unifiedSearch.search.unableToGetSavedQueryToastTitle": "Impossible de charger la requête enregistrée {savedQueryId}", + "unifiedSearch.query.queryBar.syntaxOptionsTitle": "Options de syntaxe", + "unifiedSearch.filter.applyFilterActionTitle": "Appliquer le filtre à la vue en cours", + "unifiedSearch.filter.applyFilters.popupHeader": "Sélectionner les filtres à appliquer", + "unifiedSearch.filter.applyFiltersPopup.cancelButtonLabel": "Annuler", + "unifiedSearch.filter.applyFiltersPopup.saveButtonLabel": "Appliquer", + "unifiedSearch.filter.filterBar.addFilterButtonLabel": "Ajouter un filtre", + "unifiedSearch.filter.filterBar.deleteFilterButtonLabel": "Supprimer", + "unifiedSearch.filter.filterBar.disabledFilterPrefix": "Désactivé", + "unifiedSearch.filter.filterBar.disableFilterButtonLabel": "Désactiver temporairement", + "unifiedSearch.filter.filterBar.editFilterButtonLabel": "Modifier le filtre", + "unifiedSearch.filter.filterBar.enableFilterButtonLabel": "Réactiver", + "unifiedSearch.filter.filterBar.excludeFilterButtonLabel": "Exclure les résultats", + "unifiedSearch.filter.filterBar.filterItemBadgeAriaLabel": "Actions de filtrage", + "unifiedSearch.filter.filterBar.filterItemBadgeIconAriaLabel": "Supprimer {filter}", + "unifiedSearch.filter.filterBar.includeFilterButtonLabel": "Inclure les résultats", + "unifiedSearch.filter.filterBar.indexPatternSelectPlaceholder": "Sélectionner un modèle d'indexation", + "unifiedSearch.filter.filterBar.labelErrorInfo": "Modèle d'indexation {indexPattern} introuvable", + "unifiedSearch.filter.filterBar.labelErrorText": "Erreur", + "unifiedSearch.filter.filterBar.labelWarningInfo": "Le champ {fieldName} n'existe pas dans la vue en cours.", + "unifiedSearch.filter.filterBar.labelWarningText": "Avertissement", + "unifiedSearch.filter.filterBar.moreFilterActionsMessage": "Filtre : {innerText}. Sélectionner pour plus d’actions de filtrage.", + "unifiedSearch.filter.filterBar.negatedFilterPrefix": "NON ", + "unifiedSearch.filter.filterBar.pinFilterButtonLabel": "Épingler dans toutes les applications", + "unifiedSearch.filter.filterBar.pinnedFilterPrefix": "Épinglé", + "unifiedSearch.filter.filterBar.unpinFilterButtonLabel": "Désépingler", + "unifiedSearch.filter.filterEditor.cancelButtonLabel": "Annuler", + "unifiedSearch.filter.filterEditor.createCustomLabelInputLabel": "Étiquette personnalisée", + "unifiedSearch.filter.filterEditor.createCustomLabelSwitchLabel": "Créer une étiquette personnalisée ?", + "unifiedSearch.filter.filterEditor.doesNotExistOperatorOptionLabel": "n'existe pas", + "unifiedSearch.filter.filterEditor.editFilterPopupTitle": "Modifier le filtre", + "unifiedSearch.filter.filterEditor.editFilterValuesButtonLabel": "Modifier les valeurs du filtre", + "unifiedSearch.filter.filterEditor.editQueryDslButtonLabel": "Modifier en tant que Query DSL", + "unifiedSearch.filter.filterEditor.existsOperatorOptionLabel": "existe", + "unifiedSearch.filter.filterEditor.falseOptionLabel": "false", + "unifiedSearch.filter.filterEditor.fieldSelectLabel": "Champ", + "unifiedSearch.filter.filterEditor.fieldSelectPlaceholder": "Sélectionner d'abord un champ", + "unifiedSearch.filter.filterEditor.indexPatternSelectLabel": "Modèle d'indexation", + "unifiedSearch.filter.filterEditor.isBetweenOperatorOptionLabel": "est entre", + "unifiedSearch.filter.filterEditor.isNotBetweenOperatorOptionLabel": "n'est pas entre", + "unifiedSearch.filter.filterEditor.isNotOneOfOperatorOptionLabel": "n'est pas l'une des options suivantes", + "unifiedSearch.filter.filterEditor.isNotOperatorOptionLabel": "n'est pas", + "unifiedSearch.filter.filterEditor.isOneOfOperatorOptionLabel": "est l'une des options suivantes", + "unifiedSearch.filter.filterEditor.isOperatorOptionLabel": "est", + "unifiedSearch.filter.filterEditor.operatorSelectLabel": "Opérateur", + "unifiedSearch.filter.filterEditor.operatorSelectPlaceholderSelect": "Sélectionner", + "unifiedSearch.filter.filterEditor.operatorSelectPlaceholderWaiting": "En attente", + "unifiedSearch.filter.filterEditor.queryDslLabel": "Query DSL d'Elasticsearch", + "unifiedSearch.filter.filterEditor.rangeEndInputPlaceholder": "Fin de la plage", + "unifiedSearch.filter.filterEditor.rangeInputLabel": "Plage", + "unifiedSearch.filter.filterEditor.rangeStartInputPlaceholder": "Début de la plage", + "unifiedSearch.filter.filterEditor.saveButtonLabel": "Enregistrer", + "unifiedSearch.filter.filterEditor.trueOptionLabel": "vrai", + "unifiedSearch.filter.filterEditor.valueInputLabel": "Valeur", + "unifiedSearch.filter.filterEditor.valueInputPlaceholder": "Saisir une valeur", + "unifiedSearch.filter.filterEditor.valueSelectPlaceholder": "Sélectionner une valeur", + "unifiedSearch.filter.filterEditor.valuesSelectLabel": "Valeurs", + "unifiedSearch.filter.filterEditor.valuesSelectPlaceholder": "Sélectionner des valeurs", + "unifiedSearch.filter.options.changeAllFiltersButtonLabel": "Changer tous les filtres", + "unifiedSearch.filter.options.deleteAllFiltersButtonLabel": "Tout supprimer", + "unifiedSearch.filter.options.disableAllFiltersButtonLabel": "Tout désactiver", + "unifiedSearch.filter.options.enableAllFiltersButtonLabel": "Tout activer", + "unifiedSearch.filter.options.invertDisabledFiltersButtonLabel": "Inverser l’activation/désactivation", + "unifiedSearch.filter.options.invertNegatedFiltersButtonLabel": "Inverser l'inclusion", + "unifiedSearch.filter.options.pinAllFiltersButtonLabel": "Tout épingler", + "unifiedSearch.filter.options.unpinAllFiltersButtonLabel": "Tout désépingler", + "unifiedSearch.filter.searchBar.changeAllFiltersTitle": "Changer tous les filtres", + "unifiedSearch.kueryAutocomplete.andOperatorDescription": "Nécessite que {bothArguments} soient ''vrai''.", + "unifiedSearch.kueryAutocomplete.andOperatorDescription.bothArgumentsText": "les deux arguments", + "unifiedSearch.kueryAutocomplete.equalOperatorDescription": "{equals} une certaine valeur", + "unifiedSearch.kueryAutocomplete.equalOperatorDescription.equalsText": "égale", + "unifiedSearch.kueryAutocomplete.existOperatorDescription": "{exists} sous un certain format", + "unifiedSearch.kueryAutocomplete.existOperatorDescription.existsText": "existe", + "unifiedSearch.kueryAutocomplete.greaterThanOperatorDescription": "est {greaterThan} une certaine valeur", + "unifiedSearch.kueryAutocomplete.greaterThanOperatorDescription.greaterThanText": "supérieur à", + "unifiedSearch.kueryAutocomplete.greaterThanOrEqualOperatorDescription": "est {greaterThanOrEqualTo} une certaine valeur", + "unifiedSearch.kueryAutocomplete.greaterThanOrEqualOperatorDescription.greaterThanOrEqualToText": "supérieur ou égal à", + "unifiedSearch.kueryAutocomplete.lessThanOperatorDescription": "est {lessThan} une certaine valeur", + "unifiedSearch.kueryAutocomplete.lessThanOperatorDescription.lessThanText": "inférieur à", + "unifiedSearch.kueryAutocomplete.lessThanOrEqualOperatorDescription": "est {lessThanOrEqualTo} une certaine valeur", + "unifiedSearch.kueryAutocomplete.lessThanOrEqualOperatorDescription.lessThanOrEqualToText": "inférieur ou égal à", + "unifiedSearch.kueryAutocomplete.orOperatorDescription": "Nécessite qu’{oneOrMoreArguments} soit ''vrai''.", + "unifiedSearch.kueryAutocomplete.orOperatorDescription.oneOrMoreArgumentsText": "au moins un argument" } } diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 16bbd398379d1..4b8f0b344b2b5 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -442,28 +442,18 @@ "xpack.lens.indexPattern.dateHistogram.autoAdvancedExplanation": "間隔は次のロジックに従います。", "xpack.lens.indexPattern.dateHistogram.autoBasicExplanation": "自動日付ヒストグラムは、間隔でデータフィールドをバケットに分割します。", "xpack.lens.indexPattern.dateHistogram.autoBoundHeader": "対象間隔の測定", - "xpack.lens.indexPattern.dateHistogram.autoHelpText": "仕組み", - "xpack.lens.indexPattern.dateHistogram.autoInterval": "時間範囲のカスタマイズ", "xpack.lens.indexPattern.dateHistogram.autoIntervalHeader": "使用される間隔", "xpack.lens.indexPattern.dateHistogram.autoLongerExplanation": "間隔を選択するには、Lensは指定された時間範囲を{targetBarSetting}設定で除算します。Lensはデータに最適な間隔を計算します。たとえば、30分、1時間、12です。棒の最大数は{maxBarSetting}値で設定します。", "xpack.lens.indexPattern.dateHistogram.bindToGlobalTimePicker": "グローバル時刻ピッカーにバインド", - "xpack.lens.indexPattern.dateHistogram.days": "日", "xpack.lens.indexPattern.dateHistogram.dropPartialBuckets": "不完全なバケットをドロップ", "xpack.lens.indexPattern.dateHistogram.dropPartialBucketsHelp": "不完全なバケットのドロップは無効です。これらは、右上のグローバル時刻ピッカーにバインドされた時刻フィールドでのみ計算できます。", "xpack.lens.indexPattern.dateHistogram.globalTimePickerHelp": "右上のグローバル時刻ピッカーで選択したフィールドをフィルタリングします。現在のデータビューのデフォルト時刻フィールドではこの設定をオンにできません。", - "xpack.lens.indexPattern.dateHistogram.hours": "時間", "xpack.lens.indexPattern.dateHistogram.includeEmptyRows": "空の行を含める", - "xpack.lens.indexPattern.dateHistogram.milliseconds": "ミリ秒", "xpack.lens.indexPattern.dateHistogram.minimumInterval": "最低間隔", - "xpack.lens.indexPattern.dateHistogram.minutes": "分", - "xpack.lens.indexPattern.dateHistogram.month": "月", "xpack.lens.indexPattern.dateHistogram.moreThanYear": "1年を超える", "xpack.lens.indexPattern.dateHistogram.restrictedInterval": "集約の制限により間隔は {intervalValue} に固定されています。", - "xpack.lens.indexPattern.dateHistogram.seconds": "秒", "xpack.lens.indexPattern.dateHistogram.titleHelp": "自動日付ヒストグラムの仕組み", "xpack.lens.indexPattern.dateHistogram.upTo": "最大", - "xpack.lens.indexPattern.dateHistogram.week": "週", - "xpack.lens.indexPattern.dateHistogram.year": "年", "xpack.lens.indexPattern.dateHistogramTimeShift": "単一のレイヤーでは、前の時間範囲シフトと日付ヒストグラムを結合できません。\"{column}\"で明示的な時間シフト期間を使用するか、日付ヒストグラムを置換してください。", "xpack.lens.indexPattern.decimalPlacesLabel": "小数点以下", "xpack.lens.indexPattern.defaultFormatLabel": "デフォルト", @@ -540,7 +530,6 @@ "xpack.lens.indexPattern.incompleteOperation": "(未完了)", "xpack.lens.indexPattern.intervals": "間隔", "xpack.lens.indexPattern.invalidFieldLabel": "無効なフィールドです。データビューを確認するか、別のフィールドを選択してください。", - "xpack.lens.indexPattern.invalidInterval": "無効な間隔値", "xpack.lens.indexPattern.invalidOperationLabel": "選択した関数はこのフィールドで動作しません。", "xpack.lens.indexPattern.invalidReferenceConfiguration": "ディメンション\"{dimensionLabel}\"の構成が正しくありません", "xpack.lens.indexPattern.invalidTimeShift": "無効な時間シフトです。正の整数の後に単位s、m、h、d、w、M、yのいずれかを入力します。例:3時間は3hです", @@ -575,7 +564,6 @@ "xpack.lens.indexPattern.moving_average.signature": "メトリック:数値、[window]:数値", "xpack.lens.indexPattern.movingAverage": "移動平均", "xpack.lens.indexPattern.movingAverage.basicExplanation": "移動平均はデータ全体でウィンドウをスライドし、平均値を表示します。移動平均は日付ヒストグラムでのみサポートされています。", - "xpack.lens.indexPattern.movingAverage.helpText": "仕組み", "xpack.lens.indexPattern.movingAverage.limitations": "最初の移動平均値は2番目の項目から開始します。", "xpack.lens.indexPattern.movingAverage.longerExplanation": "移動平均を計算するには、Lensはウィンドウの平均値を使用し、ギャップのスキップポリシーを適用します。 見つからない値がある場合、バケットがスキップされます。次の値に対して計算が実行されます。", "xpack.lens.indexPattern.movingAverage.tableExplanation": "たとえば、データ[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]がある場合、ウィンドウサイズ5でシンプルな移動平均を計算できます。", @@ -2068,22 +2056,6 @@ "data.inspector.table.tableLabel": "テーブル{index}", "data.inspector.table.tablesDescription": "合計で{tablesCount, plural, other {# 個のテーブル} }があります", "data.inspector.table.tableSelectorLabel": "選択済み:", - "data.kueryAutocomplete.andOperatorDescription": "{bothArguments} が true であることを条件とする", - "data.kueryAutocomplete.andOperatorDescription.bothArgumentsText": "両方の引数", - "data.kueryAutocomplete.equalOperatorDescription": "一部の値に{equals}", - "data.kueryAutocomplete.equalOperatorDescription.equalsText": "一致する", - "data.kueryAutocomplete.existOperatorDescription": "いずれかの形式中に{exists}", - "data.kueryAutocomplete.existOperatorDescription.existsText": "存在する", - "data.kueryAutocomplete.greaterThanOperatorDescription": "が一部の値{greaterThan}", - "data.kueryAutocomplete.greaterThanOperatorDescription.greaterThanText": "より大きい", - "data.kueryAutocomplete.greaterThanOrEqualOperatorDescription": "が一部の値{greaterThanOrEqualTo}", - "data.kueryAutocomplete.greaterThanOrEqualOperatorDescription.greaterThanOrEqualToText": "よりも大きいまたは等しい", - "data.kueryAutocomplete.lessThanOperatorDescription": "が一部の値{lessThan}", - "data.kueryAutocomplete.lessThanOperatorDescription.lessThanText": "より小さい", - "data.kueryAutocomplete.lessThanOrEqualOperatorDescription": "が一部の値{lessThanOrEqualTo}", - "data.kueryAutocomplete.lessThanOrEqualOperatorDescription.lessThanOrEqualToText": "より小さいまたは等しい", - "data.kueryAutocomplete.orOperatorDescription": "{oneOrMoreArguments} が true であることを条件とする", - "data.kueryAutocomplete.orOperatorDescription.oneOrMoreArgumentsText": "1つ以上の引数", "data.painlessError.buttonTxt": "スクリプトを編集", "data.painlessError.painlessScriptedFieldErrorMessage": "インデックスパターン{indexPatternName}でのランタイムフィールドまたはスクリプトフィールドの実行エラー", "data.parseEsInterval.invalidEsCalendarIntervalErrorMessage": "無効なカレンダー間隔:{interval}、1よりも大きな値が必要です", @@ -2734,6 +2706,110 @@ "dataViews.deprecations.scriptedFields.manualStepTwoMessage": "ランタイムフィールドを使用するには、スクリプト化されたフィールドがある{numberOfIndexPatternsWithScriptedFields}データビューを更新します。ほとんどの場合、既存のスクリプトを移行するには、「return ;」から「emit();」に変更する必要があります。1つ以上のスクリプト化されたフィールドがあるデータビュー:{allTitles}", "dataViews.deprecations.scriptedFieldsMessage": "スクリプト化されたフィールドを使用する{numberOfIndexPatternsWithScriptedFields}データビュー({titlesPreview}...)があります。スクリプト化されたフィールドは廃止予定であり、今後は削除されます。ランタイムフィールドを使用してください。", "dataViews.deprecations.scriptedFieldsTitle": "スクリプト化されたフィールドを使用しているデータビューが見つかりました。", + "data.mgmt.searchSessions.actionDelete": "削除", + "data.mgmt.searchSessions.actionExtend": "延長", + "data.mgmt.searchSessions.actionRename": "名前を編集", + "data.mgmt.searchSessions.actions.tooltip.moreActions": "さらにアクションを表示", + "data.mgmt.searchSessions.api.deleted": "検索セッションが削除されました。", + "data.mgmt.searchSessions.api.deletedError": "検索セッションを削除できませんでした。", + "data.mgmt.searchSessions.api.extended": "検索セッションが延長されました。", + "data.mgmt.searchSessions.api.extendError": "検索セッションを延長できませんでした。", + "data.mgmt.searchSessions.api.fetchError": "ページを更新できませんでした。", + "data.mgmt.searchSessions.api.fetchTimeout": "{timeout}秒後に検索セッション情報の取得がタイムアウトしました", + "data.mgmt.searchSessions.api.rename": "検索セッション名が変更されました", + "data.mgmt.searchSessions.api.renameError": "検索セッション名を変更できませんでした", + "data.mgmt.searchSessions.appTitle": "検索セッション", + "data.mgmt.searchSessions.ariaLabel.moreActions": "さらにアクションを表示", + "data.mgmt.searchSessions.cancelModal.cancelButton": "キャンセル", + "data.mgmt.searchSessions.cancelModal.deleteButton": "削除", + "data.mgmt.searchSessions.cancelModal.message": "検索セッション'{name}'を削除すると、キャッシュに保存されているすべての結果が削除されます。", + "data.mgmt.searchSessions.cancelModal.title": "検索セッションの削除", + "data.mgmt.searchSessions.extendModal.dontExtendButton": "キャンセル", + "data.mgmt.searchSessions.extendModal.extendButton": "有効期限を延長", + "data.mgmt.searchSessions.extendModal.extendMessage": "検索セッション'{name}'の有効期限が{newExpires}まで延長されます。", + "data.mgmt.searchSessions.extendModal.title": "検索セッションの有効期限を延長", + "data.mgmt.searchSessions.flyoutTitle": "検査", + "data.mgmt.searchSessions.main.backgroundSessionsDocsLinkText": "ドキュメント", + "data.mgmt.searchSessions.main.sectionDescription": "保存された検索セッションを管理します。", + "data.mgmt.searchSessions.main.sectionTitle": "検索セッション", + "data.mgmt.searchSessions.renameModal.cancelButton": "キャンセル", + "data.mgmt.searchSessions.renameModal.renameButton": "保存", + "data.mgmt.searchSessions.renameModal.searchSessionNameInputLabel": "検索セッション名", + "data.mgmt.searchSessions.renameModal.title": "検索セッション名を編集", + "data.mgmt.searchSessions.search.filterApp": "アプリ", + "data.mgmt.searchSessions.search.filterStatus": "ステータス", + "data.mgmt.searchSessions.search.tools.refresh": "更新", + "data.mgmt.searchSessions.status.expireDateUnknown": "不明", + "data.mgmt.searchSessions.status.expiresOn": "有効期限:{expireDate}", + "data.mgmt.searchSessions.status.expiresSoonInDays": "{numDays}日後に期限切れ", + "data.mgmt.searchSessions.status.expiresSoonInDaysTooltip": "{numDays}日", + "data.mgmt.searchSessions.status.expiresSoonInHours": "このセッションは{numHours}時間後に期限切れになります", + "data.mgmt.searchSessions.status.expiresSoonInHoursTooltip": "{numHours}時間", + "data.mgmt.searchSessions.status.label.cancelled": "キャンセル済み", + "data.mgmt.searchSessions.status.label.complete": "完了", + "data.mgmt.searchSessions.status.label.error": "エラー", + "data.mgmt.searchSessions.status.label.expired": "期限切れ", + "data.mgmt.searchSessions.status.label.inProgress": "進行中", + "data.mgmt.searchSessions.status.message.cancelled": "ユーザーがキャンセル", + "data.mgmt.searchSessions.status.message.createdOn": "有効期限:{expireDate}", + "data.mgmt.searchSessions.status.message.error": "エラー:{error}", + "data.mgmt.searchSessions.status.message.expiredOn": "有効期限:{expireDate}", + "data.mgmt.searchSessions.table.headerExpiration": "有効期限", + "data.mgmt.searchSessions.table.headerName": "名前", + "data.mgmt.searchSessions.table.headerStarted": "作成済み", + "data.mgmt.searchSessions.table.headerStatus": "ステータス", + "data.mgmt.searchSessions.table.headerType": "アプリ", + "data.mgmt.searchSessions.table.notRestorableWarning": "検索セッションはもう一度実行されます。今後使用するために保存できます。", + "data.mgmt.searchSessions.table.numSearches": "# 検索", + "data.mgmt.searchSessions.table.versionIncompatibleWarning": "この検索は別のバージョンを実行しているKibanaインスタンスで作成されました。正常に復元されない可能性があります。", + "data.search.statusError": "検索は{errorCode}ステータスで完了しました", + "data.search.statusThrow": "検索ステータスはエラー{message}({errorCode})ステータスを返しました", + "data.searchSessionIndicator.cancelButtonText": "セッションの停止", + "data.searchSessionIndicator.canceledDescriptionText": "不完全なデータを表示しています。", + "data.searchSessionIndicator.canceledIconAriaLabel": "検索セッションが停止しました", + "data.searchSessionIndicator.canceledTitleText": "検索セッションが停止しました", + "data.searchSessionIndicator.canceledTooltipText": "検索セッションが停止しました", + "data.searchSessionIndicator.canceledWhenText": "停止:{when}", + "data.searchSessionIndicator.continueInBackgroundButtonText": "セッションの保存", + "data.searchSessionIndicator.disabledDueToDisabledGloballyMessage": "検索セッションを管理するアクセス権がありません", + "data.searchSessionIndicator.disabledDueToTimeoutMessage": "検索セッション結果が期限切れです。", + "data.searchSessionIndicator.loadingInTheBackgroundDescriptionText": "管理から完了した結果に戻ることができます。", + "data.searchSessionIndicator.loadingInTheBackgroundIconAriaLabel": "保存されたセッションを実行中です", + "data.searchSessionIndicator.loadingInTheBackgroundIconTooltipText": "保存されたセッションを実行中です", + "data.searchSessionIndicator.loadingInTheBackgroundTitleText": "保存されたセッションを実行中です", + "data.searchSessionIndicator.loadingInTheBackgroundWhenText": "開始:{when}", + "data.searchSessionIndicator.loadingResultsDescription": "セッションを保存して作業を続け、完了した結果に戻ってください。", + "data.searchSessionIndicator.loadingResultsIconAriaLabel": "検索セッションを読み込んでいます", + "data.searchSessionIndicator.loadingResultsIconTooltipText": "検索セッションを読み込んでいます", + "data.searchSessionIndicator.loadingResultsTitle": "検索に少し時間がかかっています...", + "data.searchSessionIndicator.loadingResultsWhenText": "開始:{when}", + "data.searchSessionIndicator.restoredDescriptionText": "特定の時間範囲からキャッシュに保存されたデータを表示しています。時間範囲またはフィルターを変更すると、セッションが再実行されます。", + "data.searchSessionIndicator.restoredResultsIconAriaLabel": "保存されたセッションが復元されました", + "data.searchSessionIndicator.restoredResultsTooltipText": "検索セッションが復元されました", + "data.searchSessionIndicator.restoredTitleText": "検索セッションが復元されました", + "data.searchSessionIndicator.restoredWhenText": "完了:{when}", + "data.searchSessionIndicator.resultLoadedInTheBackgroundDescriptionText": "管理からこれらの結果に戻ることができます。", + "data.searchSessionIndicator.resultLoadedInTheBackgroundIconAriaLabel": "保存されたセッションが完了しました", + "data.searchSessionIndicator.resultLoadedInTheBackgroundIconTooltipText": "保存されたセッションが完了しました", + "data.searchSessionIndicator.resultLoadedInTheBackgroundTitleText": "検索セッションが保存されました", + "data.searchSessionIndicator.resultLoadedInTheBackgroundWhenText": "完了:{when}", + "data.searchSessionIndicator.resultsLoadedDescriptionText": "セッションを保存して、後から戻ります。", + "data.searchSessionIndicator.resultsLoadedIconAriaLabel": "検索セッションが完了しました", + "data.searchSessionIndicator.resultsLoadedIconTooltipText": "検索セッションが完了しました", + "data.searchSessionIndicator.resultsLoadedText": "検索セッションが完了しました", + "data.searchSessionIndicator.resultsLoadedWhenText": "完了:{when}", + "data.searchSessionIndicator.saveButtonText": "セッションの保存", + "data.searchSessionIndicator.viewSearchSessionsLinkText": "セッションの管理", + "data.searchSessionName.ariaLabelText": "検索セッション名", + "data.searchSessionName.editAriaLabelText": "検索セッション名を編集", + "data.searchSessionName.placeholderText": "検索セッションの名前を入力", + "data.searchSessionName.saveButtonText": "保存", + "data.sessions.management.flyoutText": "この検索セッションの構成", + "data.sessions.management.flyoutTitle": "検索セッションの検査", + "dataViews.deprecations.scriptedFields.manualStepOneMessage": "[スタック管理]>[Kibana]>[インデックスパターン]に移動します。", + "dataViews.deprecations.scriptedFields.manualStepTwoMessage": "ランタイムフィールドを使用するには、スクリプト化されたフィールドがある{numberOfIndexPatternsWithScriptedFields}インデックスパターンを更新します。ほとんどの場合、既存のスクリプトを移行するには、「return ;」から「emit();」に変更する必要があります。1つ以上のスクリプト化されたフィールドがあるインデックスパターン:{allTitles}", + "dataViews.deprecations.scriptedFieldsMessage": "スクリプト化されたフィールドを使用する{numberOfIndexPatternsWithScriptedFields}インデックスパターン({titlesPreview}...)があります。スクリプト化されたフィールドは廃止予定であり、今後は削除されます。ランタイムフィールドを使用してください。", + "dataViews.deprecations.scriptedFieldsTitle": "スクリプト化されたフィールドを使用しているインデックスパターンが見つかりました", "dataViews.ensureDefaultIndexPattern.bannerLabel": "Kibanaでデータの可視化と閲覧を行うには、Elasticsearchからデータを取得するためのインデックスパターンの作成が必要です。", "dataViews.fetchFieldErrorTitle": "データビューのフィールド取得中にエラーが発生 {title}(ID:{id})", "dataViews.functions.dataViewLoad.help": "データビューを読み込みます", @@ -7392,7 +7468,6 @@ "xpack.apm.filter.environment.allLabel": "すべて", "xpack.apm.filter.environment.label": "環境", "xpack.apm.filter.environment.notDefinedLabel": "未定義", - "xpack.apm.filter.environment.selectEnvironmentLabel": "環境を選択", "xpack.apm.fleet_integration.settings.advancedOptionsLavel": "高度なオプション", "xpack.apm.fleet_integration.settings.agentAuthorization.anonymousAllowAgentHelpText": "匿名アクセスの許可されたエージェント名。", "xpack.apm.fleet_integration.settings.agentAuthorization.anonymousAllowAgentLabel": "許可されたエージェント", @@ -7617,7 +7692,6 @@ "xpack.apm.propertiesTable.tabs.metadataLabel": "メタデータ", "xpack.apm.propertiesTable.tabs.timelineLabel": "Timeline", "xpack.apm.searchInput.filter": "フィルター...", - "xpack.apm.selectCustomOptionText": "\\{searchValue\\}を新しいオプションとして追加", "xpack.apm.selectPlaceholder": "オプションを選択:", "xpack.apm.serviceDependencies.breakdownChartTitle": "依存関係にかかった時間", "xpack.apm.serviceDetails.dependenciesTabLabel": "依存関係", @@ -10152,7 +10226,6 @@ "xpack.csp.passed": "合格", "xpack.csp.posture_score": "態勢スコア", "xpack.csp.posture_score_trend": "態勢スコア傾向", - "xpack.csp.resource_type": "リソースタイプ", "xpack.csp.rules.activateAllButtonLabel": "{count, plural, other {#個のルール}}をアクティブ化", "xpack.csp.rules.activatedLabel": "有効化", "xpack.csp.rules.activateLabel": "有効化", @@ -10203,107 +10276,6 @@ "xpack.dashboard.drilldown.goToDashboard": "ダッシュボードに移動", "xpack.dashboard.FlyoutCreateDrilldownAction.displayName": "ドリルダウンを作成", "xpack.dashboard.panel.openFlyoutEditDrilldown.displayName": "ドリルダウンを管理", - "xpack.data.mgmt.searchSessions.actionDelete": "削除", - "xpack.data.mgmt.searchSessions.actionExtend": "延長", - "xpack.data.mgmt.searchSessions.actionRename": "名前を編集", - "xpack.data.mgmt.searchSessions.actions.tooltip.moreActions": "さらにアクションを表示", - "xpack.data.mgmt.searchSessions.api.deleted": "検索セッションが削除されました。", - "xpack.data.mgmt.searchSessions.api.deletedError": "検索セッションを削除できませんでした。", - "xpack.data.mgmt.searchSessions.api.extended": "検索セッションが延長されました。", - "xpack.data.mgmt.searchSessions.api.extendError": "検索セッションを延長できませんでした。", - "xpack.data.mgmt.searchSessions.api.fetchError": "ページを更新できませんでした。", - "xpack.data.mgmt.searchSessions.api.fetchTimeout": "{timeout}秒後に検索セッション情報の取得がタイムアウトしました", - "xpack.data.mgmt.searchSessions.api.rename": "検索セッション名が変更されました", - "xpack.data.mgmt.searchSessions.api.renameError": "検索セッション名を変更できませんでした", - "xpack.data.mgmt.searchSessions.appTitle": "検索セッション", - "xpack.data.mgmt.searchSessions.ariaLabel.moreActions": "さらにアクションを表示", - "xpack.data.mgmt.searchSessions.cancelModal.cancelButton": "キャンセル", - "xpack.data.mgmt.searchSessions.cancelModal.deleteButton": "削除", - "xpack.data.mgmt.searchSessions.cancelModal.message": "検索セッション'{name}'を削除すると、キャッシュに保存されているすべての結果が削除されます。", - "xpack.data.mgmt.searchSessions.cancelModal.title": "検索セッションの削除", - "xpack.data.mgmt.searchSessions.extendModal.dontExtendButton": "キャンセル", - "xpack.data.mgmt.searchSessions.extendModal.extendButton": "有効期限を延長", - "xpack.data.mgmt.searchSessions.extendModal.extendMessage": "検索セッション'{name}'の有効期限が{newExpires}まで延長されます。", - "xpack.data.mgmt.searchSessions.extendModal.title": "検索セッションの有効期限を延長", - "xpack.data.mgmt.searchSessions.flyoutTitle": "検査", - "xpack.data.mgmt.searchSessions.main.backgroundSessionsDocsLinkText": "ドキュメント", - "xpack.data.mgmt.searchSessions.main.sectionDescription": "保存された検索セッションを管理します。", - "xpack.data.mgmt.searchSessions.main.sectionTitle": "検索セッション", - "xpack.data.mgmt.searchSessions.renameModal.cancelButton": "キャンセル", - "xpack.data.mgmt.searchSessions.renameModal.renameButton": "保存", - "xpack.data.mgmt.searchSessions.renameModal.searchSessionNameInputLabel": "検索セッション名", - "xpack.data.mgmt.searchSessions.renameModal.title": "検索セッション名を編集", - "xpack.data.mgmt.searchSessions.search.filterApp": "アプリ", - "xpack.data.mgmt.searchSessions.search.filterStatus": "ステータス", - "xpack.data.mgmt.searchSessions.search.tools.refresh": "更新", - "xpack.data.mgmt.searchSessions.status.expireDateUnknown": "不明", - "xpack.data.mgmt.searchSessions.status.expiresOn": "有効期限:{expireDate}", - "xpack.data.mgmt.searchSessions.status.expiresSoonInDays": "{numDays}日後に期限切れ", - "xpack.data.mgmt.searchSessions.status.expiresSoonInDaysTooltip": "{numDays}日", - "xpack.data.mgmt.searchSessions.status.expiresSoonInHours": "このセッションは{numHours}時間後に期限切れになります", - "xpack.data.mgmt.searchSessions.status.expiresSoonInHoursTooltip": "{numHours}時間", - "xpack.data.mgmt.searchSessions.status.label.cancelled": "キャンセル済み", - "xpack.data.mgmt.searchSessions.status.label.complete": "完了", - "xpack.data.mgmt.searchSessions.status.label.error": "エラー", - "xpack.data.mgmt.searchSessions.status.label.expired": "期限切れ", - "xpack.data.mgmt.searchSessions.status.label.inProgress": "進行中", - "xpack.data.mgmt.searchSessions.status.message.cancelled": "ユーザーがキャンセル", - "xpack.data.mgmt.searchSessions.status.message.createdOn": "有効期限:{expireDate}", - "xpack.data.mgmt.searchSessions.status.message.error": "エラー:{error}", - "xpack.data.mgmt.searchSessions.status.message.expiredOn": "有効期限:{expireDate}", - "xpack.data.mgmt.searchSessions.table.headerExpiration": "有効期限", - "xpack.data.mgmt.searchSessions.table.headerName": "名前", - "xpack.data.mgmt.searchSessions.table.headerStarted": "作成済み", - "xpack.data.mgmt.searchSessions.table.headerStatus": "ステータス", - "xpack.data.mgmt.searchSessions.table.headerType": "アプリ", - "xpack.data.mgmt.searchSessions.table.mlAppName": "機械学習", - "xpack.data.mgmt.searchSessions.table.notRestorableWarning": "検索セッションはもう一度実行されます。今後使用するために保存できます。", - "xpack.data.mgmt.searchSessions.table.numSearches": "# 検索", - "xpack.data.mgmt.searchSessions.table.versionIncompatibleWarning": "この検索は別のバージョンを実行しているKibanaインスタンスで作成されました。正常に復元されない可能性があります。", - "xpack.data.search.statusError": "検索は{errorCode}ステータスで完了しました", - "xpack.data.search.statusThrow": "検索ステータスはエラー{message}({errorCode})ステータスを返しました", - "xpack.data.searchSessionIndicator.cancelButtonText": "セッションの停止", - "xpack.data.searchSessionIndicator.canceledDescriptionText": "不完全なデータを表示しています。", - "xpack.data.searchSessionIndicator.canceledIconAriaLabel": "検索セッションが停止しました", - "xpack.data.searchSessionIndicator.canceledTitleText": "検索セッションが停止しました", - "xpack.data.searchSessionIndicator.canceledTooltipText": "検索セッションが停止しました", - "xpack.data.searchSessionIndicator.canceledWhenText": "停止:{when}", - "xpack.data.searchSessionIndicator.continueInBackgroundButtonText": "セッションの保存", - "xpack.data.searchSessionIndicator.disabledDueToDisabledGloballyMessage": "検索セッションを管理するアクセス権がありません", - "xpack.data.searchSessionIndicator.disabledDueToTimeoutMessage": "検索セッション結果が期限切れです。", - "xpack.data.searchSessionIndicator.loadingInTheBackgroundDescriptionText": "管理から完了した結果に戻ることができます。", - "xpack.data.searchSessionIndicator.loadingInTheBackgroundIconAriaLabel": "保存されたセッションを実行中です", - "xpack.data.searchSessionIndicator.loadingInTheBackgroundIconTooltipText": "保存されたセッションを実行中です", - "xpack.data.searchSessionIndicator.loadingInTheBackgroundTitleText": "保存されたセッションを実行中です", - "xpack.data.searchSessionIndicator.loadingInTheBackgroundWhenText": "開始:{when}", - "xpack.data.searchSessionIndicator.loadingResultsDescription": "セッションを保存して作業を続け、完了した結果に戻ってください。", - "xpack.data.searchSessionIndicator.loadingResultsIconAriaLabel": "検索セッションを読み込んでいます", - "xpack.data.searchSessionIndicator.loadingResultsIconTooltipText": "検索セッションを読み込んでいます", - "xpack.data.searchSessionIndicator.loadingResultsTitle": "検索に少し時間がかかっています...", - "xpack.data.searchSessionIndicator.loadingResultsWhenText": "開始:{when}", - "xpack.data.searchSessionIndicator.restoredDescriptionText": "特定の時間範囲からキャッシュに保存されたデータを表示しています。時間範囲またはフィルターを変更すると、セッションが再実行されます。", - "xpack.data.searchSessionIndicator.restoredResultsIconAriaLabel": "保存されたセッションが復元されました", - "xpack.data.searchSessionIndicator.restoredResultsTooltipText": "検索セッションが復元されました", - "xpack.data.searchSessionIndicator.restoredTitleText": "検索セッションが復元されました", - "xpack.data.searchSessionIndicator.restoredWhenText": "完了:{when}", - "xpack.data.searchSessionIndicator.resultLoadedInTheBackgroundDescriptionText": "管理からこれらの結果に戻ることができます。", - "xpack.data.searchSessionIndicator.resultLoadedInTheBackgroundIconAriaLabel": "保存されたセッションが完了しました", - "xpack.data.searchSessionIndicator.resultLoadedInTheBackgroundIconTooltipText": "保存されたセッションが完了しました", - "xpack.data.searchSessionIndicator.resultLoadedInTheBackgroundTitleText": "検索セッションが保存されました", - "xpack.data.searchSessionIndicator.resultLoadedInTheBackgroundWhenText": "完了:{when}", - "xpack.data.searchSessionIndicator.resultsLoadedDescriptionText": "セッションを保存して、後から戻ります。", - "xpack.data.searchSessionIndicator.resultsLoadedIconAriaLabel": "検索セッションが完了しました", - "xpack.data.searchSessionIndicator.resultsLoadedIconTooltipText": "検索セッションが完了しました", - "xpack.data.searchSessionIndicator.resultsLoadedText": "検索セッションが完了しました", - "xpack.data.searchSessionIndicator.resultsLoadedWhenText": "完了:{when}", - "xpack.data.searchSessionIndicator.saveButtonText": "セッションの保存", - "xpack.data.searchSessionIndicator.viewSearchSessionsLinkText": "セッションの管理", - "xpack.data.searchSessionName.ariaLabelText": "検索セッション名", - "xpack.data.searchSessionName.editAriaLabelText": "検索セッション名を編集", - "xpack.data.searchSessionName.placeholderText": "検索セッションの名前を入力", - "xpack.data.searchSessionName.saveButtonText": "保存", - "xpack.data.sessions.management.flyoutText": "この検索セッションの構成", - "xpack.data.sessions.management.flyoutTitle": "検索セッションの検査", "xpack.dataVisualizer.addCombinedFieldsLabel": "結合されたフィールドを追加", "xpack.dataVisualizer.choroplethMap.topValuesCount": "{fieldName}の上位の値件数", "xpack.dataVisualizer.chrome.help.appName": "データビジュアライザー", @@ -11939,7 +11911,6 @@ "xpack.enterpriseSearch.workplaceSearch.groups.newGroup.action": "グループを管理", "xpack.enterpriseSearch.workplaceSearch.groups.newGroupSavedSuccess": "{groupName}が正常に作成されました", "xpack.enterpriseSearch.workplaceSearch.groups.noSourcesMessage": "組織コンテンツソースがありません", - "xpack.enterpriseSearch.workplaceSearch.groups.noUsersMessage": "ユーザーがありません", "xpack.enterpriseSearch.workplaceSearch.groups.overview.confirmRemoveButtonText": "{name}を削除", "xpack.enterpriseSearch.workplaceSearch.groups.overview.confirmRemoveDescription": "グループはWorkplace Searchから削除されます。{name}を削除してよろしいですか?", "xpack.enterpriseSearch.workplaceSearch.groups.overview.confirmTitleText": "確認", @@ -12925,7 +12896,6 @@ "xpack.fleet.fleetServerSetup.cloudDeploymentLink": "デプロイを編集", "xpack.fleet.fleetServerSetup.cloudSetupText": "Fleetにエージェントを登録する前に、Fleetサーバーが必要です。取得するための最も簡単な方法は、Fleetサーバー統合を実行する統合サーバーを追加することです。クラウドコンソールでデプロイに追加できます。詳細は{link}をご覧ください。", "xpack.fleet.fleetServerSetup.cloudSetupTitle": "Fleetサーバーを有効にする", - "xpack.fleet.fleetServerSetup.continueButton": "続行", "xpack.fleet.fleetServerSetup.deploymentModeProductionOption": "{production} – 独自の証明書を指定します。このオプションでは、Fleetに登録するときに、エージェントで証明書鍵を指定する必要があります。", "xpack.fleet.fleetServerSetup.deploymentModeQuickStartOption": "{quickStart} – Fleetサーバーは自己署名証明書を生成します。後続のエージェントは--insecureフラグを使用して登録する必要があります。本番ユースケースには推奨されません。", "xpack.fleet.fleetServerSetup.errorAddingFleetServerHostTitle": "Fleetサーバーホストの追加エラー", @@ -12934,23 +12904,16 @@ "xpack.fleet.fleetServerSetup.fleetSettingsLink": "Fleet設定", "xpack.fleet.fleetServerSetup.generateServiceTokenButton": "サービストークンを生成", "xpack.fleet.fleetServerSetup.generateServiceTokenDescription": "サービストークンは、Elasticsearchに書き込むためのFleetサーバーアクセス権を付与します。", - "xpack.fleet.fleetServerSetup.installAgentDescription": "エージェントディレクトリから、適切なクイックスタートコマンドをコピーして実行し、生成されたトークンと自己署名証明書を使用して、ElasticエージェントをFleetサーバーとして起動します。本番デプロイで独自の証明書を使用する手順については、{userGuideLink}を参照してください。すべてのコマンドには管理者権限が必要です。", "xpack.fleet.fleetServerSetup.productionText": "本番運用", "xpack.fleet.fleetServerSetup.quickStartText": "クイックスタート", "xpack.fleet.fleetServerSetup.saveServiceTokenDescription": "サービストークン情報を保存します。これは1回だけ表示されます。", "xpack.fleet.fleetServerSetup.serviceTokenLabel": "サービストークン", "xpack.fleet.fleetServerSetup.setupGuideLink": "FleetおよびElasticエージェントガイド", - "xpack.fleet.fleetServerSetup.setupText": "Fleetにエージェントを登録する前に、Fleetサーバーが必要です。Fleetサーバーのセットアップについては、次の手順に従ってください。詳細については、{userGuideLink}を参照してください。", - "xpack.fleet.fleetServerSetup.setupTitle": "Fleetサーバーを追加", "xpack.fleet.fleetServerSetup.stepCreateAgentPolicyTitle": "Fleetサーバーをホストするエージェントポリシーを作成", "xpack.fleet.fleetServerSetup.stepDeploymentModeDescriptionText": "FleetはTransport Layer Security(TLS)を使用して、ElasticエージェントとElastic Stackの他のコンポーネントとの間の通信を暗号化します。デプロイモードを選択し、証明書を処理する方法を決定します。選択内容は後続のステップに表示されるFleetサーバーセットアップコマンドに影響します。", "xpack.fleet.fleetServerSetup.stepDeploymentModeTitle": "セキュリティのデプロイモードを選択", - "xpack.fleet.fleetServerSetup.stepFleetServerCompleteDescription": "エージェントをFleetに登録できます。", - "xpack.fleet.fleetServerSetup.stepFleetServerCompleteTitle": "Fleetサーバーが接続されました", "xpack.fleet.fleetServerSetup.stepGenerateServiceTokenTitle": "サービストークンを生成", - "xpack.fleet.fleetServerSetup.stepInstallAgentTitle": "Fleetサーバーを起動", "xpack.fleet.fleetServerSetup.stepSelectAgentPolicyTitle": "Fleetサーバーをホストするエージェントポリシーを選択", - "xpack.fleet.fleetServerSetup.stepWaitingForFleetServerTitle": "Fleetサーバーの接続を待機しています...", "xpack.fleet.fleetServerSetup.waitingText": "Fleetサーバーの接続を待機しています...", "xpack.fleet.fleetServerSetupPermissionDeniedErrorMessage": "Fleetサーバーを設定する必要があります。これには{roleName}クラスター権限が必要です。管理者にお問い合わせください。", "xpack.fleet.fleetServerSetupPermissionDeniedErrorTitle": "パーミッションが拒否されました", @@ -18649,7 +18612,6 @@ "xpack.ml.jobsList.alertingRules.tooltipContent": "ジョブ{rulesCount}はアラート{rulesCount, plural, other { ルール}}に関連付けられています", "xpack.ml.jobsList.analyticsSpacesLabel": "スペース", "xpack.ml.jobsList.auditMessageColumn.screenReaderDescription": "この列は、過去24時間にエラーまたは警告があった場合にアイコンを表示します", - "xpack.ml.jobsList.breadcrumb": "ジョブ", "xpack.ml.jobsList.cannotSelectRowForJobMessage": "ジョブID {jobId}を選択できません", "xpack.ml.jobsList.cloneJobErrorMessage": "{jobId} のクローンを作成できませんでした。ジョブが見つかりませんでした", "xpack.ml.jobsList.closeActionStatusText": "閉じる", @@ -19992,13 +19954,10 @@ "xpack.ml.trainedModels.testModelsFlyout.headerLabel": "学習済みモデルのテスト", "xpack.ml.trainedModels.testModelsFlyout.inferenceError": "エラーが発生しました", "xpack.ml.trainedModels.testModelsFlyout.langIdent.inputText": "入力テキスト", - "xpack.ml.trainedModels.testModelsFlyout.langIdent.markupTab": "アウトプット", "xpack.ml.trainedModels.testModelsFlyout.langIdent.output.language_title": "言語", "xpack.ml.trainedModels.testModelsFlyout.langIdent.output.probability_title": "確率", "xpack.ml.trainedModels.testModelsFlyout.langIdent.output.title": "これは{lang}のようになります", "xpack.ml.trainedModels.testModelsFlyout.langIdent.output.titleUnknown": "不明な言語コード:{code}", - "xpack.ml.trainedModels.testModelsFlyout.langIdent.rawOutput": "元の出力", - "xpack.ml.trainedModels.testModelsFlyout.langIdent.runButton": "テスト", "xpack.ml.trainedModels.testModelsFlyout.ner.output.probabilityTitle": "確率", "xpack.ml.trainedModels.testModelsFlyout.ner.output.typeTitle": "型", "xpack.ml.trainedModelsBreadcrumbs.nodeOverviewLabel": "ノード", @@ -21838,12 +21797,6 @@ "xpack.observability.noDataConfig.beatsCard.title": "統合の追加", "xpack.observability.noDataConfig.solutionName": "Observability", "xpack.observability.notAvailable": "N/A", - "xpack.observability.overview.alert.allTypes": "すべてのタイプ", - "xpack.observability.overview.alert.appLink": "すべてのアラートを表示", - "xpack.observability.overview.alert.errorMessage": "アラートデータの読み込みエラーが発生しました。しばらくたってから再試行してください。", - "xpack.observability.overview.alert.errorTitle": "アラートデータを読み込めませんでした", - "xpack.observability.overview.alerts.appLink": "アラートを表示", - "xpack.observability.overview.alerts.muted": "ミュート", "xpack.observability.overview.alerts.title": "アラート", "xpack.observability.overview.apm.appLink": "サービスインベントリを表示", "xpack.observability.overview.apm.services": "サービス", @@ -22150,9 +22103,6 @@ "xpack.osquery.liveQueryDetails.viewLiveQueriesHistoryTitle": "ライブクエリ履歴を表示", "xpack.osquery.liveQueryForm.form.saveForLaterButtonLabel": "後で使用するために保存する", "xpack.osquery.liveQueryForm.form.submitButtonLabel": "送信", - "xpack.osquery.liveQueryForm.steps.agentsStepHeading": "エージェントを選択", - "xpack.osquery.liveQueryForm.steps.queryStepHeading": "クエリを入力", - "xpack.osquery.liveQueryForm.steps.resultsStepHeading": "結果を確認", "xpack.osquery.liveQueryResults.table.agentColumnTitle": "エージェント", "xpack.osquery.liveQueryResults.table.fieldMappedLabel": "フィールドは以下にマッピングされています", "xpack.osquery.newLiveQuery.pageTitle": "新しいライブクエリ", @@ -22633,7 +22583,6 @@ "xpack.reporting.publicNotifier.csvContainsFormulas.formulaReportMessage": "レポート'{reportObjectTitle}'には、スプレッドシートアプリケーションで式と解釈される可能性のある文字が含まれています。", "xpack.reporting.publicNotifier.csvContainsFormulas.formulaReportTitle": "{reportType}には式を含めることができます", "xpack.reporting.publicNotifier.downloadReportButtonLabel": "レポートをダウンロード", - "xpack.reporting.publicNotifier.error.calloutTitle": "レポートジョブが失敗しました", "xpack.reporting.publicNotifier.error.checkManagement": "詳細については、{path}に移動してください。", "xpack.reporting.publicNotifier.error.couldNotCreateReportTitle": "'{reportObjectTitle}'の{reportType}レポートを作成できませんでした。", "xpack.reporting.publicNotifier.error.reportingSectionUrlLinkLabel": "スタック管理 > Kibana > レポート", @@ -25645,17 +25594,11 @@ "xpack.securitySolution.endpoint.policyResponse.appliedOn": "{date}に改訂{rev}が適用されました", "xpack.securitySolution.endpoint.policyResponse.backLinkTitle": "エンドポイント詳細", "xpack.securitySolution.endpoint.policyResponse.title": "ポリシー応答", - "xpack.securitySolution.endpoint.resolver.compactBillions": "B", - "xpack.securitySolution.endpoint.resolver.compactMillions": "M", - "xpack.securitySolution.endpoint.resolver.compactOverflow": "+", - "xpack.securitySolution.endpoint.resolver.compactThousands": "k", - "xpack.securitySolution.endpoint.resolver.compactTrillions": "T", "xpack.securitySolution.endpoint.resolver.eitherLineageLimitExceeded": "以下のビジュアライゼーションとイベントリストの一部のプロセスイベントを表示できませんでした。データの上限に達しました。", "xpack.securitySolution.endpoint.resolver.elapsedTime": "{duration} {durationType}", "xpack.securitySolution.endpoint.resolver.errorProcess": "エラープロセス", "xpack.securitySolution.endpoint.resolver.loadingError": "データの読み込み中にエラーが発生しました。", "xpack.securitySolution.endpoint.resolver.loadingProcess": "プロセスの読み込み中", - "xpack.securitySolution.endpoint.resolver.node.pillNumber": "{mantissa}{scale}{hasRemainder}", "xpack.securitySolution.endpoint.resolver.panel.error.error": "エラー", "xpack.securitySolution.endpoint.resolver.panel.error.events": "イベント", "xpack.securitySolution.endpoint.resolver.panel.error.goBack": "すべてのプロセスを表示", @@ -26980,8 +26923,6 @@ "xpack.securitySolution.trustedApps.assignmentSectionDescription": "すべてのポリシーでグローバルにこの信頼できるアプリケーションを割り当てるか、特定のポリシーに割り当てます。", "xpack.securitySolution.trustedapps.card.operator.is": "is", "xpack.securitySolution.trustedapps.card.operator.matches": "一致", - "xpack.securitySolution.trustedApps.conditionsSectionDescription": "オペレーティングシステムを選択して、条件を追加します。条件の可用性は選択したOSによって異なる場合があります。", - "xpack.securitySolution.trustedApps.conditionsSectionTitle": "条件", "xpack.securitySolution.trustedapps.create.conditionFieldDegradedPerformanceMsg": "[{row}] ファイル名のワイルドカードはエンドポイントのパフォーマンスに影響します", "xpack.securitySolution.trustedapps.create.conditionFieldDuplicatedMsg": "{field}を複数回追加できません", "xpack.securitySolution.trustedapps.create.conditionFieldInvalidHashMsg": "[{row}] 無効なハッシュ値", @@ -26989,39 +26930,9 @@ "xpack.securitySolution.trustedapps.create.conditionFieldValueRequiredMsg": "[{row}] フィールドエントリには値が必要です", "xpack.securitySolution.trustedapps.create.conditionRequiredMsg": "1つ以上のフィールド定義が必要です", "xpack.securitySolution.trustedapps.create.description": "説明", - "xpack.securitySolution.trustedapps.create.name": "信頼できるアプリケーションに名前を付ける", "xpack.securitySolution.trustedapps.create.nameRequiredMsg": "名前が必要です", - "xpack.securitySolution.trustedapps.create.os": "オペレーティングシステムを選択", "xpack.securitySolution.trustedapps.create.osRequiredMsg": "オペレーティングシステムは必須です", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.cancelButton": "キャンセル", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.createSaveButton": "信頼できるアプリケーションを追加", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.createTitle": "信頼できるアプリケーションを追加", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.editSaveButton": "保存", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.editTitle": "信頼できるアプリケーションを編集", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.expiredLicenseMessage": "Kibanaライセンスがダウングレードされました。今後のポリシー構成はグローバルにすべてのポリシーに割り当てられます。詳細はご覧ください。 ", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.expiredLicenseTitle": "失効したライセンス", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.notFoundToastMessage": "信頼できるアプリケーションを編集できません({apiMsg})", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.successToastTitle": "\"{name}\"は信頼できるアプリケーションリストに追加されました。", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.updateSuccessToastTitle": "\"{name}\"が更新されました。", - "xpack.securitySolution.trustedapps.creationSuccess.title": "成功!", - "xpack.securitySolution.trustedapps.deletionDialog.calloutMessage": "このエントリを削除すると、{count}個の関連付けられた{count, plural, other {ポリシー}}から削除されます。", - "xpack.securitySolution.trustedapps.deletionDialog.calloutTitle": "警告", - "xpack.securitySolution.trustedapps.deletionDialog.cancelButton": "キャンセル", - "xpack.securitySolution.trustedapps.deletionDialog.confirmButton": "削除", - "xpack.securitySolution.trustedapps.deletionDialog.subMessage": "この操作は元に戻すことができません。続行していいですか?", - "xpack.securitySolution.trustedapps.deletionDialog.title": "\"{name}\"を削除", - "xpack.securitySolution.trustedapps.deletionError.text": "信頼できるアプリケーションリストから\"{name}\"を削除できません。理由:{message}", - "xpack.securitySolution.trustedapps.deletionError.title": "削除失敗", - "xpack.securitySolution.trustedapps.deletionSuccess.text": "\"{name}\"は信頼できるアプリケーションリストから削除されました。", - "xpack.securitySolution.trustedapps.deletionSuccess.title": "正常に削除されました", - "xpack.securitySolution.trustedApps.detailsSectionTitle": "詳細", - "xpack.securitySolution.trustedapps.docsLink": "信頼できるアプリケーションドキュメント。", - "xpack.securitySolution.trustedapps.grid.cardAction.delete": "信頼できるアプリケーションを削除", - "xpack.securitySolution.trustedapps.grid.cardAction.edit": "信頼できるアプリケーションを編集", - "xpack.securitySolution.trustedapps.grid.policyDetailsLinkBackLabel": "信頼できるアプリケーションに戻る", "xpack.securitySolution.trustedapps.list.addButton": "信頼できるアプリケーションを追加", - "xpack.securitySolution.trustedapps.list.pageTitle": "信頼できるアプリケーション", - "xpack.securitySolution.trustedapps.list.search.placeholder": "次のフィールドで検索:名前、説明、値", "xpack.securitySolution.trustedapps.listEmptyState.message": "パフォーマンスを改善したり、ホストで実行されている他のアプリケーションとの競合を解消したりするには、信頼できるアプリケーションを追加します。", "xpack.securitySolution.trustedapps.listEmptyState.title": "最初の信頼できるアプリケーションを追加", "xpack.securitySolution.trustedapps.logicalConditionBuilder.entry.field.description.hash": "md5、sha1、sha256", @@ -27033,14 +26944,9 @@ "xpack.securitySolution.trustedapps.logicalConditionBuilder.entry.removeLabel": "エントリを削除", "xpack.securitySolution.trustedapps.logicalConditionBuilder.group.andOperator": "AND", "xpack.securitySolution.trustedapps.logicalConditionBuilder.noEntries": "条件が定義されていません", - "xpack.securitySolution.trustedapps.middleware.editIdMissing": "IDが指定されていません", "xpack.securitySolution.trustedapps.trustedapp.entry.field": "フィールド", "xpack.securitySolution.trustedapps.trustedapp.entry.operator": "演算子", "xpack.securitySolution.trustedapps.trustedapp.entry.value": "値", - "xpack.securitySolution.trustedapps.updateSuccess.title": "成功!", - "xpack.securitySolution.trustedapps.view.toggle.grid": "グリッドビュー", - "xpack.securitySolution.trustedapps.view.toggle.list": "リストビュー", - "xpack.securitySolution.trustedapps.viewTypeToggle.controlLegend": "ビュータイプ", "xpack.securitySolution.trustedAppsTab": "信頼できるアプリケーション", "xpack.securitySolution.uiSettings.defaultAnomalyScoreDescription": "

機械学習ジョブの異常がこの値を超えると、セキュリティアプリに表示されます。

有効な値:0 ~ 100。

", "xpack.securitySolution.uiSettings.defaultAnomalyScoreLabel": "デフォルトの異常しきい値", @@ -28284,13 +28190,6 @@ "xpack.timelines.clipboard.copy.to.the.clipboard": "クリップボードにコピー", "xpack.timelines.clipboard.to.the.clipboard": "クリップボードに", "xpack.timelines.copyToClipboardTooltip": "クリップボードにコピー", - "xpack.timelines.draggables.field.categoryLabel": "カテゴリー", - "xpack.timelines.draggables.field.fieldLabel": "フィールド", - "xpack.timelines.draggables.field.typeLabel": "型", - "xpack.timelines.draggables.field.viewCategoryTooltip": "カテゴリーを表示します", - "xpack.timelines.emptyString.emptyStringDescription": "空の文字列", - "xpack.timelines.eventDetails.copyToClipboardTooltip": "クリップボードにコピー", - "xpack.timelines.exitFullScreenButton": "全画面を終了", "xpack.timelines.fieldBrowser.categoriesCountTitle": "{totalCount} {totalCount, plural, other {カテゴリ}}", "xpack.timelines.fieldBrowser.categoriesTitle": "カテゴリー", "xpack.timelines.fieldBrowser.categoryLabel": "カテゴリー", @@ -28381,8 +28280,6 @@ "xpack.timelines.timeline.closedAlertSuccessToastMessage": "{totalAlerts} {totalAlerts, plural, other {件のアラート}}を正常にクローズしました。", "xpack.timelines.timeline.closeSelectedTitle": "クローズ済みに設定", "xpack.timelines.timeline.descriptionTooltip": "説明", - "xpack.timelines.timeline.eventHasEventRendererScreenReaderOnly": "行{row}のイベントにはイベントレンダラーがあります。Shiftと下矢印を押すとフォーカスします。", - "xpack.timelines.timeline.eventHasNotesScreenReaderOnly": "行{row}のイベントには{notesCount, plural, other {{notesCount}個のメモ}}があります。Shiftと右矢印を押すとメモをフォーカスします。", "xpack.timelines.timeline.eventsTableAriaLabel": "イベント; {activePage}/{totalPages} ページ", "xpack.timelines.timeline.fieldTooltip": "フィールド", "xpack.timelines.timeline.flyout.pane.removeColumnButtonLabel": "列を削除", @@ -28399,7 +28296,6 @@ "xpack.timelines.timeline.updateAlertStatusFailedDetailed": "{ updated } {updated, plural, other {アラート}}が正常に更新されましたが、{ conflicts }は更新できませんでした。\n { conflicts, plural, other {}}すでに修正されています。", "xpack.timelines.timeline.updateAlertStatusFailedSingleAlert": "アラートを更新できませんでした。アラートはすでに修正されています。", "xpack.timelines.timeline.youAreInAnEventRendererScreenReaderOnly": "行 {row} のイベントレンダラーを表示しています。上矢印キーを押すと、終了して現在の行に戻ります。下矢印キーを押すと、終了して次の行に進みます。", - "xpack.timelines.timeline.youAreInATableCellScreenReaderOnly": "表セルの行 {row}、列 {column} にいます", "xpack.timelines.timelineEvents.errorSearchDescription": "タイムラインイベント検索でエラーが発生しました", "xpack.timelines.toolbar.bulkActions.clearSelectionTitle": "選択した項目をクリア", "xpack.timelines.toolbar.bulkActions.selectAllAlertsTitle": "すべての{totalAlertsFormatted} {totalAlerts, plural, other {件のアラート}}を選択", @@ -29527,7 +29423,6 @@ "xpack.triggersActionsUI.sections.rulesList.ruleStatusActive": "アクティブ", "xpack.triggersActionsUI.sections.rulesList.ruleStatusDropdownMenuLabel": "ルールステータスまたはスヌーズを変更", "xpack.triggersActionsUI.sections.rulesList.ruleStatusError": "エラー", - "xpack.triggersActionsUI.sections.rulesList.ruleStatusFilterLabel": "前回の応答", "xpack.triggersActionsUI.sections.rulesList.ruleStatusLicenseError": "ライセンスエラー", "xpack.triggersActionsUI.sections.rulesList.ruleStatusOk": "OK", "xpack.triggersActionsUI.sections.rulesList.ruleStatusPending": "保留中", @@ -29951,872 +29846,872 @@ "xpack.upgradeAssistant.upgradedTitle": "クラスターがアップグレードされました", "xpack.upgradeAssistant.upgradingDescription": "1 つまたは複数の Elasticsearch ノードに、 Kibana よりも新しいバージョンの Elasticsearch があります。すべてのノードがアップグレードされた後で Kibana をアップグレードしてください。", "xpack.upgradeAssistant.upgradingTitle": "クラスターをアップグレード中です", - "xpack.uptime.addDataButtonLabel": "データの追加", - "xpack.uptime.addMonitor.pageHeader.title": "モニターを追加", - "xpack.uptime.addMonitorRoute.title": "モニターを追加 | {baseTitle}", - "xpack.uptime.alertDropdown.noWritePermissions": "このアプリでアラートを作成するには、アップタイムへの読み書きアクセス権が必要です。", - "xpack.uptime.alerts.anomaly.criteriaExpression.ariaLabel": "選択したモニターの条件を表示する式。", - "xpack.uptime.alerts.anomaly.criteriaExpression.description": "監視するとき", - "xpack.uptime.alerts.anomaly.scoreExpression.ariaLabel": "異常アラートしきい値の条件を表示する式。", - "xpack.uptime.alerts.anomaly.scoreExpression.description": "異常と重要度があります", - "xpack.uptime.alerts.createRulesPanel.title": "ルールを作成", - "xpack.uptime.alerts.durationAnomaly": "アップタイム期間異常", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.anomalyStartTimestamp": "異常の開始のISO8601タイムスタンプ", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.expectedResponseTime": "想定応答時間", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.monitor": "名前、IDS、優先名の人間にとってわかりやすい表示(My Monitorなど)", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.monitorId": "モニターのID。", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.monitorUrl": "モニターのURL。", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.observerLocation": "Heartbeatチェックが実行されるオブサーバーの位置情報。", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.severity": "異常の重要度。", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.severityScore": "異常重要度スコア。", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.slowestAnomalyResponse": "単位(ミリ秒、秒)が関連付けられた異常バケット中の最も遅い応答時間。", - "xpack.uptime.alerts.durationAnomaly.clientName": "アップタイム期間異常", - "xpack.uptime.alerts.durationAnomaly.defaultActionMessage": "{anomalyStartTimestamp}に、{monitor}、url {monitorUrl}で異常({severity}レベル)応答時間が検出されました。異常重要度スコアは{severityScore}です。\n位置情報{observerLocation}から高い応答時間{slowestAnomalyResponse}が検出されました。想定された応答時間は{expectedResponseTime}です。", - "xpack.uptime.alerts.durationAnomaly.description": "アップタイム監視期間が異常なときにアラートを発行します。", - "xpack.uptime.alerts.monitorExpression.label": "フィルター{title}を削除", - "xpack.uptime.alerts.monitorStatus": "稼働状況の監視ステータス", - "xpack.uptime.alerts.monitorStatus.actionVariables.availabilityMessage": "{interval}の可用性は{availabilityRatio}%です。{expectedAvailability}%未満のときにアラートを発行します。", - "xpack.uptime.alerts.monitorStatus.actionVariables.context.alertReasonMessage.description": "アラートの理由の簡潔な説明", - "xpack.uptime.alerts.monitorStatus.actionVariables.context.downMonitorsWithGeo.description": "アラートによって「ダウン」と検知された一部またはすべてのモニターを示す、生成された概要。", - "xpack.uptime.alerts.monitorStatus.actionVariables.context.message.description": "現在ダウンしているモニターを要約する生成されたメッセージ。", - "xpack.uptime.alerts.monitorStatus.actionVariables.context.viewInAppUrl.description": "アラートとコンテキストを調査するために使用できる、Elastic内のビューまたは機能へのリンク", - "xpack.uptime.alerts.monitorStatus.actionVariables.down": "過去{interval}に{count}回失敗しました。{numTimes}を超えるとアラートを発行します。", - "xpack.uptime.alerts.monitorStatus.actionVariables.downAndAvailabilityMessage": "{downMonitorsMessage} {availabilityBreachMessage}", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.currentTriggerStarted": "アラートがトリガーされた場合、現在のトリガー状態が開始するときを示すタイムスタンプ", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.firstCheckedAt": "このアラートが最初に確認されるときを示すタイムスタンプ", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.firstTriggeredAt": "このアラートが最初にトリガーされたときを示すタイムスタンプ", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.isTriggered": "アラートが現在トリガーしているかどうかを示すフラグ", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.lastCheckedAt": "アラートの直近の確認時刻を示すタイムスタンプ", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.lastErrorMessage": "最新のエラーメッセージを監視", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.lastResolvedAt": "このアラートの直近の解決を示すタイムスタンプ", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.lastTriggeredAt": "アラートの直近のトリガー時刻を示すタイムスタンプ", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.monitor": "名前、IDS、優先名の人間にとってわかりやすい表示(My Monitorなど)", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.monitorId": "モニターのID。", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.monitorType": "モニターのタイプ(HTTP/TCPなど)。", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.monitorUrl": "モニターのURL。", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.observerHostname": "Heartbeatチェックが実行されるオブザーバーのホスト名。", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.observerLocation": "Heartbeatチェックが実行されるオブザーバーの位置情報。", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.statusMessage": "ステータスメッセージ。例:停止、または可用性チェックの場合は可用性しきい値未満、あるいは両方", - "xpack.uptime.alerts.monitorStatus.addFilter": "フィルターを追加します", - "xpack.uptime.alerts.monitorStatus.addFilter.location": "場所", - "xpack.uptime.alerts.monitorStatus.addFilter.port": "ポート", - "xpack.uptime.alerts.monitorStatus.addFilter.tag": "タグ", - "xpack.uptime.alerts.monitorStatus.addFilter.type": "型", - "xpack.uptime.alerts.monitorStatus.availability.isEnabledCheckbox.label": "可用性", - "xpack.uptime.alerts.monitorStatus.availability.threshold.anyMonitorDescription": "任意のモニターがアップ", - "xpack.uptime.alerts.monitorStatus.availability.threshold.ariaLabel": "このアラートの可用性しきい値を指定", - "xpack.uptime.alerts.monitorStatus.availability.threshold.description": "一致するモニターがアップしています", - "xpack.uptime.alerts.monitorStatus.availability.threshold.input.ariaLabel": "このアラートで確認する可用性しきい値を入力", - "xpack.uptime.alerts.monitorStatus.availability.threshold.value": "< チェックの{value}%", - "xpack.uptime.alerts.monitorStatus.availability.timerangeValueField.ariaLabel": "アラートの可用性チェックの時間単位の数を入力", - "xpack.uptime.alerts.monitorStatus.availability.timerangeValueField.expression": "最後内", - "xpack.uptime.alerts.monitorStatus.availability.timerangeValueField.popover.ariaLabel": "可用性追跡時間範囲を指定", - "xpack.uptime.alerts.monitorStatus.availability.unit.headline": "時間範囲単位を選択します", - "xpack.uptime.alerts.monitorStatus.availability.unit.selectable": "この選択を使用して、このアラートの可用性範囲単位を設定", - "xpack.uptime.alerts.monitorStatus.clientName": "稼働状況の監視ステータス", - "xpack.uptime.alerts.monitorStatus.defaultActionMessage": "{observerLocation}からのurl {monitorUrl}のモニター{monitorName} {statusMessage} 最新のエラーメッセージは{latestErrorMessage}", - "xpack.uptime.alerts.monitorStatus.description": "監視が停止しているか、可用性しきい値に違反したときにアラートを発行します。", - "xpack.uptime.alerts.monitorStatus.filterBar.ariaLabel": "監視状態アラートのフィルター基準を許可するインプット", - "xpack.uptime.alerts.monitorStatus.filters.anyLocation": "任意の場所", - "xpack.uptime.alerts.monitorStatus.filters.anyPort": "任意のポート", - "xpack.uptime.alerts.monitorStatus.filters.anyTag": "任意のタグ", - "xpack.uptime.alerts.monitorStatus.filters.anyType": "任意のタイプ", - "xpack.uptime.alerts.monitorStatus.filters.from": "開始:", - "xpack.uptime.alerts.monitorStatus.filters.fromLocation": "開始場所", - "xpack.uptime.alerts.monitorStatus.filters.location.label": "アラートのクエリに適用する場所フィルターを選択します。", - "xpack.uptime.alerts.monitorStatus.filters.of": "/", - "xpack.uptime.alerts.monitorStatus.filters.ofType": "型", - "xpack.uptime.alerts.monitorStatus.filters.port.label": "アラートのクエリに適用するポートフィルターを選択します。", - "xpack.uptime.alerts.monitorStatus.filters.scheme.label": "アラートのクエリに適用するプロトコルスキームフィルターを選択します。", - "xpack.uptime.alerts.monitorStatus.filters.tag.label": "アラートのクエリに適用するタグフィルターを選択します。", - "xpack.uptime.alerts.monitorStatus.filters.using": "使用", - "xpack.uptime.alerts.monitorStatus.filters.usingPort": "ポートを使用", - "xpack.uptime.alerts.monitorStatus.filters.with": "使用", - "xpack.uptime.alerts.monitorStatus.filters.withTag": "タグを使用", - "xpack.uptime.alerts.monitorStatus.monitorCallOut.title": "このアラートは約{snapshotCount}個のモニターに適用されます。", - "xpack.uptime.alerts.monitorStatus.numTimesExpression.anyMonitors.description": "任意のモニターがダウン >", - "xpack.uptime.alerts.monitorStatus.numTimesExpression.ariaLabel": "ダウンカウントインプットのポップオーバーを開く", - "xpack.uptime.alerts.monitorStatus.numTimesExpression.matchingMonitors.description": "一致するモニターがダウン >", - "xpack.uptime.alerts.monitorStatus.numTimesField.ariaLabel": "アラートのトリガーに必要な停止回数を入力します", - "xpack.uptime.alerts.monitorStatus.oldAlertCallout.title": "古いアラートを編集している可能性があります。一部のフィールドは自動入力されない場合があります。", - "xpack.uptime.alerts.monitorStatus.recoveryMessage": "url {url}のモニター{monitor}は起動時に回復しました", - "xpack.uptime.alerts.monitorStatus.statusEnabledCheck.label": "ステータス確認", - "xpack.uptime.alerts.monitorStatus.timerangeOption.days": "日", - "xpack.uptime.alerts.monitorStatus.timerangeOption.hours": "時間", - "xpack.uptime.alerts.monitorStatus.timerangeOption.minutes": "分", - "xpack.uptime.alerts.monitorStatus.timerangeOption.months": "か月", - "xpack.uptime.alerts.monitorStatus.timerangeOption.seconds": "秒", - "xpack.uptime.alerts.monitorStatus.timerangeOption.weeks": "週間", - "xpack.uptime.alerts.monitorStatus.timerangeOption.years": "年", - "xpack.uptime.alerts.monitorStatus.timerangeSelectionHeader": "時間範囲単位を選択します", - "xpack.uptime.alerts.monitorStatus.timerangeUnitExpression.ariaLabel": "時間範囲単位選択フィールドのポップオーバーを開く", - "xpack.uptime.alerts.monitorStatus.timerangeUnitSelectable": "アラートで使用する時間範囲単位の選択可能フィールド", - "xpack.uptime.alerts.monitorStatus.timerangeValueExpression.ariaLabel": "時間範囲値フィールドのポップオーバーを開く", - "xpack.uptime.alerts.monitorStatus.timerangeValueField.ariaLabel": "アラートの範囲のための時間単位の数を入力してください", - "xpack.uptime.alerts.monitorStatus.timerangeValueField.expression": "within", - "xpack.uptime.alerts.monitorStatus.timerangeValueField.value": "最終{value}", - "xpack.uptime.alerts.searchPlaceholder.kql": "KQL構文を使用してフィルタリング", - "xpack.uptime.alerts.settings.addConnector": "コネクターの追加", - "xpack.uptime.alerts.timerangeUnitSelectable.daysOption.ariaLabel": "「日」の時間範囲選択項目", - "xpack.uptime.alerts.timerangeUnitSelectable.hoursOption.ariaLabel": "「時間」の時間範囲選択項目", - "xpack.uptime.alerts.timerangeUnitSelectable.minutesOption.ariaLabel": "「分」の時間範囲選択項目", - "xpack.uptime.alerts.timerangeUnitSelectable.monthsOption.ariaLabel": "「月」の時間範囲選択項目", - "xpack.uptime.alerts.timerangeUnitSelectable.secondsOption.ariaLabel": "「秒」の時間範囲選択項目", - "xpack.uptime.alerts.timerangeUnitSelectable.weeksOption.ariaLabel": "「週」の時間範囲選択項目", - "xpack.uptime.alerts.timerangeUnitSelectable.yearsOption.ariaLabel": "「年」の時間範囲選択項目", - "xpack.uptime.alerts.tls": "アップタイムTLS", - "xpack.uptime.alerts.tls.actionVariables.state.agingCommonNameAndDate": "検出された証明書の共通名と有効期限日時。", - "xpack.uptime.alerts.tls.actionVariables.state.agingCount": "検出された古くなりすぎた証明書数。", - "xpack.uptime.alerts.tls.actionVariables.state.count": "アラート実行によって検出された証明書数", - "xpack.uptime.alerts.tls.actionVariables.state.expiringCommonNameAndDate": "検出された証明書の共通名と有効期限日時", - "xpack.uptime.alerts.tls.actionVariables.state.expiringCount": "アラートによって検出された期限切れになる証明書数", - "xpack.uptime.alerts.tls.ageExpression.ariaLabel": "古い証明書のTLSアラートをトリガーするしきい値を示す式", - "xpack.uptime.alerts.tls.ageExpression.description": "または", - "xpack.uptime.alerts.tls.ageExpression.value": "{value}日以内に期限切れになる", - "xpack.uptime.alerts.tls.agingLabel": "古すぎます", - "xpack.uptime.alerts.tls.clientName": "アップタイムTLS", - "xpack.uptime.alerts.tls.criteriaExpression.ariaLabel": "このアラートで監視されるモニターの条件を示す式", - "xpack.uptime.alerts.tls.criteriaExpression.description": "タイミング", - "xpack.uptime.alerts.tls.criteriaExpression.value": "任意のモニター", - "xpack.uptime.alerts.tls.defaultActionMessage": "発行者{issuer}の検出されたTLS証明書{commonName}は{status}です。証明書{summary}\n", - "xpack.uptime.alerts.tls.description": "アップタイム監視の TLS 証明書の有効期限が近いときにアラートを発行します。", - "xpack.uptime.alerts.tls.expirationExpression.ariaLabel": "証明書有効期限の TLS アラートをトリガーするしきい値を示す式", - "xpack.uptime.alerts.tls.expirationExpression.description": "証明書が", - "xpack.uptime.alerts.tls.expirationExpression.value": "{value}日以内に期限切れになる", - "xpack.uptime.alerts.tls.expiredLabel": "期限切れ", - "xpack.uptime.alerts.tls.expiringLabel": "まもなく期限切れ", - "xpack.uptime.alerts.tls.invalidLabel": "無効", - "xpack.uptime.alerts.tls.legacy.clientName": "アップタイムTLS(レガシー)", - "xpack.uptime.alerts.tls.legacy.defaultActionMessage": "期限切れになるか古くなりすぎた{count} TLS個のTLS証明書証明書を検知しました。\n{expiringConditionalOpen}\n期限切れになる証明書数:{expiringCount}\n期限切れになる証明書:{expiringCommonNameAndDate}\n{expiringConditionalClose}\n{agingConditionalOpen}\n古い証明書数:{agingCount}\n古い証明書:{agingCommonNameAndDate}\n{agingConditionalClose}\n", - "xpack.uptime.alerts.tls.legacy.description": "アップタイム監視の TLS 証明書の有効期限が近いときにアラートを発行します。このアラートは将来のバージョンで廃止予定です。", - "xpack.uptime.alerts.tls.settingsPageNav.text": "これらのしきい値は{settingsPageLink}で編集できます。", - "xpack.uptime.alerts.tls.validAfterExpiredString": "{relativeDate}日前、{date}に期限切れになりました。", - "xpack.uptime.alerts.tls.validAfterExpiringString": "{relativeDate}日以内、{date}に期限切れになります。", - "xpack.uptime.alerts.tls.validBeforeExpiredString": "{relativeDate}日前、{date}以降有効です。", - "xpack.uptime.alerts.tls.validBeforeExpiringString": "今から{relativeDate}日間、{date}まで無効です。", - "xpack.uptime.alerts.tlsLegacy": "アップタイムTLS(レガシー)", - "xpack.uptime.alerts.toggleAlertFlyoutButtonText": "アラートとルール", - "xpack.uptime.alertsPopover.toggleButton.ariaLabel": "アラートおよびルールコンテキストメニューを開く", - "xpack.uptime.analyzeDataButtonLabel": "データの探索", - "xpack.uptime.analyzeDataButtonLabel.message": "データの探索では、任意のディメンションの結果データを選択してフィルタリングし、パフォーマンスの問題の原因または影響を調査することができます。", - "xpack.uptime.apmIntegrationAction.description": "このモニターの検索 APM", - "xpack.uptime.apmIntegrationAction.text": "APMデータを表示", - "xpack.uptime.availabilityLabelText": "{value} %", - "xpack.uptime.badge.readOnly.text": "読み取り専用", - "xpack.uptime.badge.readOnly.tooltip": "を保存できませんでした", - "xpack.uptime.breadcrumbs.observabilityText": "Observability", - "xpack.uptime.breadcrumbs.overviewBreadcrumbText": "アップタイム", - "xpack.uptime.certificates.heading": "TLS証明書({total})", - "xpack.uptime.certificates.loading": "証明書を読み込んでいます...", - "xpack.uptime.certificates.refresh": "更新", - "xpack.uptime.certificatesPage.heading": "TLS証明書", - "xpack.uptime.certificatesRoute.title": "証明書 | {baseTitle}", - "xpack.uptime.certs.expired": "期限切れ", - "xpack.uptime.certs.expires": "有効期限", - "xpack.uptime.certs.expireSoon": "まもなく期限切れ", - "xpack.uptime.certs.list.ageCol": "年齢", - "xpack.uptime.certs.list.commonName": "共通名", - "xpack.uptime.certs.list.copyFingerprint": "クリックすると、フィンガープリント値をコピーします", - "xpack.uptime.certs.list.days": "日", - "xpack.uptime.certs.list.empty": "証明書が見つかりません。注:証明書は Heartbeat 7.8 以上でのみ表示されます。", - "xpack.uptime.certs.list.expirationDate": "指紋", - "xpack.uptime.certs.list.issuedBy": "発行者", - "xpack.uptime.certs.list.monitors": "監視", - "xpack.uptime.certs.list.status": "ステータス", - "xpack.uptime.certs.list.status.old": "古すぎます", - "xpack.uptime.certs.list.validUntil": "有効期限:", - "xpack.uptime.certs.ok": "OK", - "xpack.uptime.certs.searchCerts": "証明書を検索", - "xpack.uptime.certs.status.ok.label": " for {okRelativeDate}", - "xpack.uptime.charts.mlAnnotation.header": "スコア:{score}", - "xpack.uptime.charts.mlAnnotation.severity": "深刻度:{severity}", - "xpack.uptime.controls.selectSeverity.criticalLabel": "致命的", - "xpack.uptime.controls.selectSeverity.majorLabel": "メジャー", - "xpack.uptime.controls.selectSeverity.minorLabel": "マイナー", - "xpack.uptime.controls.selectSeverity.scoreDetailsDescription": "スコア{value}以上", - "xpack.uptime.controls.selectSeverity.warningLabel": "警告", - "xpack.uptime.createPackagePolicy.stepConfigure.browser.scriptRecorder.experimentalLabel": "テクニカルプレビュー", - "xpack.uptime.createPackagePolicy.stepConfigure.browser.scriptRecorder.experimentalTooltip": "Elastic Synthetics Recorderを使用してElastic Synthetics監視スクリプトを作成する最も簡単な方法をプレビュー", - "xpack.uptime.createPackagePolicy.stepConfigure.browser.scriptRecorder.label": "スクリプトの記録", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.description": "Syntheticsエージェントの微調整された構成を提供します。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.filtering.description": "これらのオプションを使用すると、選択したモニター設定をスイートのテストのサブセットに適用します。構成されたサブセットのみがこのモニターによって実行されます。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.filtering.title": "選択テスト", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.ignoreHttpsErrors.helpText": "このオプションをtrueに設定すると、SyntheticsブラウザーでTLS/SSL検証を無効にします。これは自己署名証明書を使用するサイトのテストで役立ちます。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.ignoreHttpsErrors.label": "HTTPSエラーを無視", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersMatch.helpText": "このモニターの指定されたglobと一致する名前のジャーニーのみを実行します。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersMatch.label": "一致のフィルター", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersTags.helpText": "このモニターの特定のタグのジャーニーのみを実行します。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersTags.label": "タグのフィルター", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.screenshots.helpText": "このオプションを設定すると、Syntheticsエージェントでキャプチャされたスクリーンショットを管理します。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.screenshots.label": "スクリーンショットオプション", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.syntheticsArgs.helpText": "Syntheticsエージェントパッケージに渡す追加の引数。文字列のリストを取ります。これはごくまれなシナリオで有用ですが、通常は設定する必要がありません。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.syntheticsArgs.label": "Synthetics引数", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.automatic_node_cap.message": "スロットリングを無効にするときには、モニターが実行されているSyntheticsノードの構成によって、モニターの帯域幅がまだ制限されます。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.automatic_node_cap.title": "自動制限", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.description": "モニターのダウンロードおよびアップロードの速度、ならびにレイテンシを制御し、低速または遅延しているネットワークでアプリケーションの動作をシミュレートしてください。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.download.error": "ダウンロード速度は0よりも大きい値でなければなりません。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.download.label": "ダウンロード速度", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.exceeded_throttling.message": "Syntheticsノード帯域幅上限より大きいスロットリング値を使用するときには、モニターの帯域幅がまだ制限されます。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.exceeded_throttling.title": "Syntheticsノード帯域幅上限を超えました", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.latency.error": "レイテンシは負数にできません。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.latency.label": "レイテンシ", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.switch.description": "スロットリングを有効にする", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.title": "スロットリングオプション", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.upload.error": "アップロード速度は0よりも大きい値でなければなりません。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.upload.label": "アップロード速度", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.title": "Syntheticsエージェントオプション", - "xpack.uptime.createPackagePolicy.stepConfigure.certificateSettings.enableSSLSettings.label": "TLS構成を有効にする", - "xpack.uptime.createPackagePolicy.stepConfigure.certificateSettings.enableZipUrlSSLSettings.label": "Zip URLのTLS構成を有効にする", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificate.helpText": "TLSクライアント認証用のPEM形式の証明書。", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificate.label": "証明書", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificateAuthorities.helpText": "PEM形式のカスタム認証局。", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificateAuthorities.label": "認証局", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificateKey.helpText": "TLSクライアント認証用のPEM形式の証明書鍵。", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificateKey.label": "キー", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificateKeyPassphrase.helpText": "TLSクライアント認証用の証明書鍵パスフレーズ。", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificateKeyPassphrase.label": "鍵パスフレーズ", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.legend": "証明書設定", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.tlsRole.client": "クライアント", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.tlsRole.server": "サーバー", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.certificate.description": "指定された証明書が信頼できる機関(CA)によって署名されていることを検証します。ホスト名検証は実行しません。", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.certificate.label": "証明書", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.full.description": "指定された証明書が信頼できる機関(CA)によって署名されていることを検証し、サーバーのホスト名(またはIPアドレス)が証明書で指定された名前と一致していることも検証します。", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.full.label": "完全", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.label": "認証モード", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.none.description": "サーバーの証明書の検証は実行しません。主に、TLSエラーの解決を試みるときの一時的な診断メカニズムの目的を果たします。本番環境では使用しないことを強くお勧めします。", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.none.label": "なし", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.strict.description": "指定された証明書が信頼できる機関(CA)によって署名されていることを検証し、サーバーのホスト名(またはIPアドレス)が証明書で指定された名前と一致していることも検証します。サブジェクトの別名が空の場合、エラーが返されます。", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.strict.label": "厳密", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.warning.description": "このモードでは、SSL/TLSの多数のセキュリティの利点が無効になります。十分に検討してから使用してください。", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.warning.title": "TLSを無効にしています", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.version.label": "サポートされているTLSプロトコル", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.version.placeholder": "1つ以上TLSプロトコルを選択します。", - "xpack.uptime.createPackagePolicy.stepConfigure.headerField.addHeader.label": "ヘッダーを追加", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions": "詳細HTTPオプション", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.indexResponseBody.helpText": "HTTP応答本文コンテンツのインデックスを制御します ", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.indexResponseHeaders.helpText": "HTTP応答ヘッダーのインデックスを制御します ", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestBody.helpText": "リクエスト本文コンテンツ。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.description": "方式、本文、ヘッダーを含むリモートホストに送信する任意のリクエストを構成します。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.requestBody": "リクエスト本文", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.requestHeaders": "要求ヘッダー", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.requestMethod.label": "リクエストメソッド", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.title": "リクエスト構成", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestHeadersField.error": "ヘッダーキーは有効なHTTPトークンでなければなりません。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestHeadersField.helpText": "送信する追加のHTTPヘッダーのディクショナリ。デフォルトでは、クライアントを特定するためにユーザーエージェントヘッダーが設定されます。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestMethod.helpText": "使用するHTTP方式。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseBodyCheckNegative.helpText": "本文出力と一致しない正規表現のリスト。Enterキーを押すと、新しい式を追加します。単一の式が一致する場合、一致の失敗が返されます。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseBodyCheckPositive.helpText": "本文出力と一致する正規表現のリスト。Enterキーを押すと、新しい式を追加します。単一の式のみが一致する必要があります。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseCheckNegative.label": "確認応答本文には含まれません", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseCheckPositive.label": "確認応答本文に含まれます", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.checkResponseHeadersContain": "確認応答ヘッダーに含まれます", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.description": "想定されているHTTP応答を構成します。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.responseStatusCheck.error": "ステータスコードには数字のみを使用する必要があります。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.responseStatusCheck.helpText": "想定されているステータスコードのリスト。Enterキーを押すと、新しいコードを追加します。デフォルトでは、4xxおよび5xxコードはダウンと見なされます。他のコードはアップと見なされます。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.responseStatusCheck.label": "確認応答ステータスは等しいです", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.title": "応答チェック", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfig.indexResponseBody": "インデックス応答本文", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfig.indexResponseHeaders": "インデックス応答ヘッダー", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfig.responseBodyIndexPolicy": "応答本文インデックスポリシー", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfiguration.description": "HTTP応答コンテンツのインデックスを制御します。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfiguration.title": "応答構成", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseHeadersField.error": "ヘッダーキーは有効なHTTPトークンでなければなりません。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseHeadersField.helpText": "想定されている応答ヘッダーのリスト。", - "xpack.uptime.createPackagePolicy.stepConfigure.icmpAdvancedOptions": "詳細ICMPオプション", - "xpack.uptime.createPackagePolicy.stepConfigure.inputVarFieldOptionalLabel": "オプション", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.helpText": "このモニターのAPMサービス名。service.name ECSフィールドに対応します。APMを使用して、アップタイムとKibanaのAPMデータ間の統合を有効にするアプリを監視しているときには、これを設定します。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.label": "APMサービス名", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.brower.proxyURL.label": "プロキシZip URL", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.http.helpText": "Zip URLのHTTPプロキシ。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.error": "スクリプトが必要です", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.helpText": "インラインで定義されたSyntheticテストスクリプトを実行します。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.label": "インラインスクリプト", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.params.helpText": "テストで必要な変数を定義するJSONオブジェクト。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.params.label": "パラメーター", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.scriptRecorder.closeButtonLabel": "スクリプトフライアウトを閉じる", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.scriptRecorder.mockFileName": "test_script.js", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.sourceType.label": "ソースタイプ", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.fieldLabel": "テストスクリプト", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.invalidFileError": "無効なファイルタイプです。Elastic Synthetics Recorderで生成された.jsファイルをアップロードしてください。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.label": "レコーダーで生成された.jsファイルを選択", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.parsingError": "ファイルのアップロードエラーです。インラインスクリプト形式でElastic Synthetics Recorderによって生成された.jsファイルをアップロードしてください。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.error": "Zip URLは必須です", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.helpText": "Syntheticsプロジェクトリポジトリzipファイルの場所。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.label": "Zip URL", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.recorderLink": "Elastic Synthetics Recorderをダウンロード", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.removeScriptLabel": "スクリプトを削除", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.showScriptLabel": "スクリプトを表示", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlFolder.helpText": "Synthetic journeyファイルが配置されるリポジトリの相対ディレクトリパス。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlFolder.label": "フォルダー", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlPassword.abel": "Zip URLパスワード", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlPassword.helpText": "zipエンドポイントに対して認証するためのパスワード。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlUsername.helpText": "zipエンドポイントに対して認証するためのユーザー名。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlUsername.label": "Zip URLユーザー名", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browserLabel": "ブラウザー(ベータ)", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.enabled.helpText": "この構成をオフにすると、モニターが無効になります。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.enabled.label": "有効", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.icmp.hosts": "ホスト", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.icmp.hosts.error": "ホストは必須です", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.maxRedirects": "最大リダイレクト数", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.maxRedirects.error": "最大リダイレクト数は0以上でなければなりません", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.maxRedirects.helpText": "従うリダイレクトの合計数。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorInterval": "頻度", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorInterval.error": "監視頻度は必須です", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType": "モニタータイプ", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.description": "「Browser」モニターを作成するには、elastic-agent-complete Dockerコンテナーを使用していることを確認します。これには、これらのモニターを実行するための依存関係が含まれています。詳細については、{link}をご覧ください。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.link": "Syntheticsドキュメンテーション", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.error": "モニタータイプは必須です", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.password.helpText": "サーバーと認証するためのパスワード。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.password.label": "パスワード", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyUrl.http.helpText": "HTTPプロキシURL。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyURL.http.label": "プロキシURL", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyURL.label": "プロキシURL", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyUrl.tcp.helpText": "サーバーに接続するときに使用するSOCKS5プロキシのURL。値はURLとスキーマsocks5://でなければなりません。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.resolveHostnamesLocally": "ローカルでホスト名を解決", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tags.helpText": "モニターイベントで送信されるタグのリスト。Enterキーを押すと、新しいタグを追加します。アップタイムに表示され、タグによる検索を有効にします。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tags.label": "タグ", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tcp.hosts": "ホスト:ポート", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tcp.hosts.error": "ホストとポートは必須です", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.helpText": "接続のテストとデータの交換に許可された合計時間。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.label": "タイムアウト(秒)", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.lessThanIntervalError": "タイムアウトは監視頻度未満でなければなりません", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.moreThanZeroError": "タイムアウトは0以上でなければなりません", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.URL": "URL", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.URL.error": "URLが必要です", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.username.helpText": "サーバーと認証するためのユーザー名。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.username.label": "ユーザー名", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.wait.error": "待機時間は0以上でなければなりません", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.wait.helpText": "応答が受信されない場合に、他のICMPエコーリクエストを発行する前に待機する期間。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.wait.label": "待機時間(秒)", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSectionDescription": "次のオプションでモニターを構成します。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSectionTitle": "モニター設定", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBody.codeEditor.javascript.ariaLabel": "JavaScriptコードエディター", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBody.codeEditor.json.ariaLabel": "JSONコードエディター", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBody.codeEditor.text.ariaLabel": "テキストコードエディター", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBody.codeEditor.xml.ariaLabel": "XMLコードエディター", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBody.formField.addFormField.label": "フォームフィールドを追加", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBodyType.form": "フォーム", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBodyType.JSON": "JSON", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBodyType.text": "テキスト", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBodyType.XML": "XML", - "xpack.uptime.createPackagePolicy.stepConfigure.responseBodyIndex.always": "常に実行", - "xpack.uptime.createPackagePolicy.stepConfigure.responseBodyIndex.onError": "エラー時", - "xpack.uptime.createPackagePolicy.stepConfigure.scheduleField.minutes": "分", - "xpack.uptime.createPackagePolicy.stepConfigure.scheduleField.number": "数字", - "xpack.uptime.createPackagePolicy.stepConfigure.scheduleField.seconds": "秒", - "xpack.uptime.createPackagePolicy.stepConfigure.scheduleField.unit": "単位", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.description": "リモートホストに送信されるペイロードを構成します。", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.requestPayload.helpText": "リモートホストに送信するペイロード文字列。", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.requestPayload.label": "リクエストペイロード", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.title": "リクエスト構成", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.responseConfiguration.responseContains.helpText": "想定されたリモートホスト応答。", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.responseConfiguration.responseContains.label": "確認応答には含まれます", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvancedOptions.responseConfiguration.description": "リモートホストから想定された応答を構成します。", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvancedOptions.responseConfiguration.title": "応答チェック", - "xpack.uptime.createPackagePolicy.stepConfigure.tlsSettings.description": "検証モード、認証局、クライアント証明書を含む、TLSオプションを構成します。", - "xpack.uptime.createPackagePolicy.stepConfigure.tlsSettings.label": "TLS設定", - "xpack.uptime.durationChart.emptyPrompt.description": "このモニターは選択された時間範囲で一度も{emphasizedText}していません。", - "xpack.uptime.durationChart.emptyPrompt.title": "利用可能な期間データがありません", - "xpack.uptime.editMonitor.pageHeader.title": "モニターを編集", - "xpack.uptime.editMonitorRoute.title": "モニターを編集 | {baseTitle}", - "xpack.uptime.emptyState.loadingMessage": "読み込み中…", - "xpack.uptime.emptyStateError.notAuthorized": "アップタイムデータの表示が承認されていません。システム管理者にお問い合わせください。", - "xpack.uptime.emptyStateError.notFoundPage": "ページが見つかりません", - "xpack.uptime.emptyStateError.title": "エラー", - "xpack.uptime.enableAlert.editAlert": "アラートを編集", - "xpack.uptime.filterBar.ariaLabel": "概要ページのインプットフィルター基準", - "xpack.uptime.filterBar.filterAllLabel": "すべて", - "xpack.uptime.filterBar.options.location.name": "場所", - "xpack.uptime.filterBar.options.portLabel": "ポート", - "xpack.uptime.filterBar.options.schemeLabel": "スキーム", - "xpack.uptime.filterBar.options.tagsLabel": "タグ", - "xpack.uptime.fleetIntegration.assets.description": "アップタイムでモニターを表示", - "xpack.uptime.fleetIntegration.assets.name": "監視", - "xpack.uptime.inspectButtonText": "検査", - "xpack.uptime.integrationLink.missingDataMessage": "この統合に必要なデータが見つかりませんでした。", - "xpack.uptime.keyValuePairsField.deleteItem.label": "項目番号{index}、{key}を削除:{value}", - "xpack.uptime.keyValuePairsField.key.ariaLabel": "キー", - "xpack.uptime.keyValuePairsField.key.label": "キー", - "xpack.uptime.keyValuePairsField.value.ariaLabel": "値", - "xpack.uptime.keyValuePairsField.value.label": "値", - "xpack.uptime.kueryBar.searchPlaceholder.kql": "KQL構文を使用して、モニターID、名前、タイプ(例:monitor.type: \"http\" AND tags: \"dev\")などを検索", - "xpack.uptime.kueryBar.searchPlaceholder.simple": "モニターID、名前、またはURL(例:http://)で検索", - "xpack.uptime.locationName.helpLinkAnnotation": "場所を追加", - "xpack.uptime.mappingErrorRoute.breadcrumb": "マッピングエラー", - "xpack.uptime.mappingErrorRoute.pageHeader.title": "マッピングエラー", - "xpack.uptime.mappingErrorRoute.title": "Synthetics | マッピングエラー", - "xpack.uptime.millisecond.abbreviation.label": "ms", - "xpack.uptime.ml.durationChart.exploreInMlApp": "ML アプリで探索", - "xpack.uptime.ml.enableAnomalyDetectionPanel.add_job_permissions_needed": "権限が必要です", - "xpack.uptime.ml.enableAnomalyDetectionPanel.anomalyDetectionTitle": "異常検知", - "xpack.uptime.ml.enableAnomalyDetectionPanel.cancelLabel": "キャンセル", - "xpack.uptime.ml.enableAnomalyDetectionPanel.createMLJobDescription": "ここでは機械学習ジョブを作成し、\n アップタイム監視の対応期間の異常スコアを計算できます。有効にすると、詳細ページの監視期間グラフには\n 想定された境界が表示され、異常があるグラフに注釈が付けられます。また、\n 地理的な地域にわたって遅延が増える期間を特定することもできます。", - "xpack.uptime.ml.enableAnomalyDetectionPanel.createNewJobButtonLabel": "新規ジョブを作成", - "xpack.uptime.ml.enableAnomalyDetectionPanel.disableAnomalyAlert": "異常アラートを無効にする", - "xpack.uptime.ml.enableAnomalyDetectionPanel.disableAnomalyDetectionTitle": "異常検知を無効にする", - "xpack.uptime.ml.enableAnomalyDetectionPanel.enable_or_manage_job": "異常検知ジョブを有効にできます。ジョブがすでに存在する場合はジョブまたはアラートを管理できます。", - "xpack.uptime.ml.enableAnomalyDetectionPanel.enableAnomalyAlert": "異常アラートを有効にする", - "xpack.uptime.ml.enableAnomalyDetectionPanel.enableAnomalyDetectionTitle": "異常検知を有効にする", - "xpack.uptime.ml.enableAnomalyDetectionPanel.insufficient_permissions_add_job": "機械学習でこの機能を使用するには、Kibana権限が必要です。", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreatedLazyNotificationText": "分析は機械学習ノードが使用可能になるのを待機しています。応答時間グラフに結果が追加されるまで、しばらく時間がかかる可能性があります。", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreatedNotificationText": "これで応答時間グラフについての分析が実行されます。応答時間グラフに結果が追加されるまで、しばらく時間がかかる可能性があります。", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreatedNotificationText.viewJobLinkText": "ジョブを表示", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreatedNotificationTitle": "ジョブの作成が正常に完了しました", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreationFailedNotificationText": "現在のライセンスでは機械学習ジョブの作成が許可されていないか、ジョブがすでに存在する可能性があります。", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreationFailedNotificationTitle": "ジョブの作成に失敗", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobDeletionConfirmLabel": "異常検知ジョブを削除しますか?", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobDeletionNotificationTitle": "ジョブを削除しました", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobDeletionSuccessNotificationText": "ジョブの削除が正常に完了しました", - "xpack.uptime.ml.enableAnomalyDetectionPanel.manageAnomalyDetectionTitle": "異常検知を管理", - "xpack.uptime.ml.enableAnomalyDetectionPanel.manageMLJobDescription": "ジョブの作成後、{mlJobsPageLink} でそれを管理し、詳細を確認できます。", - "xpack.uptime.ml.enableAnomalyDetectionPanel.manageMLJobDescription.mlJobsPageLinkText": "機械学習ジョブの管理ページ", - "xpack.uptime.ml.enableAnomalyDetectionPanel.manageMLJobDescription.noteText": "注:ジョブが結果の計算を開始するまでに少し時間がかかる場合があります。", - "xpack.uptime.ml.enableAnomalyDetectionPanel.noPermissionsTooltip": "異常アラートを作成するには、アップタイムへの読み書きアクセス権が必要です。", - "xpack.uptime.ml.enableAnomalyDetectionPanel.startTrial": "無料の 14 日トライアルを開始", - "xpack.uptime.ml.enableAnomalyDetectionPanel.startTrialDesc": "期間異常検知機能を利用するには、Elastic Platinum ライセンスが必要です。", - "xpack.uptime.monitor.simpleStatusAlert.email.subject": "url {url}のモニター{monitor}はダウンしています", - "xpack.uptime.monitorCharts.durationChart.leftAxis.title": "期間({unit})", - "xpack.uptime.monitorCharts.durationChart.wrapper.label": "場所でグループ化された、モニターのping期間を示すグラフ。", - "xpack.uptime.monitorCharts.monitorDuration.titleLabel": "監視期間", - "xpack.uptime.monitorCharts.monitorDuration.titleLabelWithAnomaly": "監視期間(異常:{noOfAnomalies})", - "xpack.uptime.monitorDetails.ml.confirmAlertDeleteMessage": "異常のアラートを削除しますか?", - "xpack.uptime.monitorDetails.ml.confirmDeleteMessage": "このジョブを削除してよろしいですか?", - "xpack.uptime.monitorDetails.ml.deleteJobWarning": "ジョブの削除に時間がかかる可能性があります。削除はバックグラウンドで実行され、データの表示がすぐに消えないことがあります。", - "xpack.uptime.monitorDetails.ml.deleteMessage": "ジョブを削除中...", - "xpack.uptime.monitorDetails.statusBar.pingType.browser": "ブラウザー", - "xpack.uptime.monitorDetails.statusBar.pingType.http": "HTTP", - "xpack.uptime.monitorDetails.statusBar.pingType.icmp": "ICMP", - "xpack.uptime.monitorDetails.statusBar.pingType.tcp": "TCP", - "xpack.uptime.monitorDetails.title.disclaimer.description": "(ベータ)", - "xpack.uptime.monitorDetails.title.disclaimer.link": "詳細を表示", - "xpack.uptime.monitorDetails.title.pingType.browser": "ブラウザー", - "xpack.uptime.monitorDetails.title.pingType.http": "HTTP ping", - "xpack.uptime.monitorDetails.title.pingType.icmp": "ICMP ping", - "xpack.uptime.monitorDetails.title.pingType.tcp": "TCP ping", - "xpack.uptime.monitorList.allMonitors": "すべてのモニター", - "xpack.uptime.monitorList.anomalyColumn.label": "レスポンス異常スコア", - "xpack.uptime.monitorList.defineConnector.description": "{link}でデフォルトコネクターを定義し、モニターステータスアラートを有効にします。", - "xpack.uptime.monitorList.defineConnector.popover.description": "ステータスアラートを受信します。", - "xpack.uptime.monitorList.disableDownAlert": "ステータスアラートを無効にする", - "xpack.uptime.monitorList.downLineSeries.downLabel": "ダウン", - "xpack.uptime.monitorList.drawer.missingLocation": "一部の Heartbeat インスタンスには位置情報が定義されていません。Heartbeat 構成への{link}。", - "xpack.uptime.monitorList.drawer.mostRecentRun": "直近のテスト実行", - "xpack.uptime.monitorList.drawer.statusRowLocationList": "前回の確認時に\"{status}\"ステータスだった場所のリスト。", - "xpack.uptime.monitorList.drawer.url": "Url", - "xpack.uptime.monitorList.enabledAlerts.noAlert": "このモニターではルールが有効ではありません。", - "xpack.uptime.monitorList.enabledAlerts.title": "有効なルール", - "xpack.uptime.monitorList.enableDownAlert": "ステータスアラートを有効にする", - "xpack.uptime.monitorList.errorSummary": "エラー概要", - "xpack.uptime.monitorList.expandDrawerButton.ariaLabel": "ID {id}のモニターの行を展開", - "xpack.uptime.monitorList.geoName.helpLinkAnnotation": "場所を追加", - "xpack.uptime.monitorList.infraIntegrationAction.container.message": "コンテナーメトリックを表示", - "xpack.uptime.monitorList.infraIntegrationAction.docker.description": "このモニターのコンテナー ID のインフラストラクチャ UI を確認します", - "xpack.uptime.monitorList.infraIntegrationAction.docker.tooltip": "コンテナー ID「{containerId}」のインフラストラクチャ UI を確認します", - "xpack.uptime.monitorList.infraIntegrationAction.ip.ariaLabel": "このモニターの IP アドレスのインフラストラクチャ UI を確認します", - "xpack.uptime.monitorList.infraIntegrationAction.ip.message": "ホストメトリックを表示", - "xpack.uptime.monitorList.infraIntegrationAction.ip.tooltip": "IP「{ip}」のインフラストラクチャ UI を確認します", - "xpack.uptime.monitorList.infraIntegrationAction.kubernetes.description": "このモニターのポッド ID のインフラストラクチャ UI を確認します", - "xpack.uptime.monitorList.infraIntegrationAction.kubernetes.message": "ポッドメトリックを表示", - "xpack.uptime.monitorList.infraIntegrationAction.kubernetes.tooltip": "ポッド UID「{podUid}」のインフラストラクチャ UI を確認します。", - "xpack.uptime.monitorList.integrationGroup.emptyMessage": "統合されたアプリケーションがありません", - "xpack.uptime.monitorList.invalidMonitors": "無効なモニター", - "xpack.uptime.monitorList.loading": "読み込み中...", - "xpack.uptime.monitorList.locations.expand": "クリックすると、残りの場所が表示されます", - "xpack.uptime.monitorList.loggingIntegrationAction.container.id": "コンテナーログを表示", - "xpack.uptime.monitorList.loggingIntegrationAction.container.message": "コンテナーログを表示", - "xpack.uptime.monitorList.loggingIntegrationAction.container.tooltip": "コンテナー ID「{containerId}」のロギング UI を確認します", - "xpack.uptime.monitorList.loggingIntegrationAction.ip.description": "このモニターのIPアドレスのロギングUIを確認", - "xpack.uptime.monitorList.loggingIntegrationAction.ip.message": "ホストログを表示", - "xpack.uptime.monitorList.loggingIntegrationAction.ip.tooltip": "IP\"{ip}\"のロギングUIを確認", - "xpack.uptime.monitorList.loggingIntegrationAction.kubernetes.ariaLabel": "ポッドログを表示", - "xpack.uptime.monitorList.loggingIntegrationAction.kubernetes.message": "ポッドログを表示", - "xpack.uptime.monitorList.loggingIntegrationAction.kubernetes.tooltip": "ポッド UID「{podUid}」のログを確認します", - "xpack.uptime.monitorList.monitorHistoryColumnLabel": "ダウンタイム履歴", - "xpack.uptime.monitorList.monitoringStatusTitle": "監視", - "xpack.uptime.monitorList.monitorType.filter": "タイプ {type} ですべての監視をフィルター", - "xpack.uptime.monitorList.mostRecentError.title": "直近のエラー({timestamp})", - "xpack.uptime.monitorList.nameColumnLabel": "名前", - "xpack.uptime.monitorList.noDownHistory": "このモニターは選択された時間範囲で一度も{emphasizedText}していません。", - "xpack.uptime.monitorList.noItemForSelectedFiltersMessage": "選択されたフィルター条件でモニターが見つかりませんでした", - "xpack.uptime.monitorList.noItemMessage": "アップタイムモニターが見つかりません", - "xpack.uptime.monitorList.observabilityIntegrationsColumn.apmIntegrationLink.tooltip": "ここをクリックすると、APMのドメイン「{domain}」、または明示的に定義された「サービス名」を確認します。", - "xpack.uptime.monitorList.observabilityIntegrationsColumn.popoverIconButton.ariaLabel": "URL {monitorUrl}で監査のための移行ポップオーバーを開く", - "xpack.uptime.monitorList.observabilityInvestigateColumn.popoverIconButton.label": "調査", - "xpack.uptime.monitorList.pageSizePopoverButtonText": "ページあたりの行数:{size}", - "xpack.uptime.monitorList.pageSizeSelect.numRowsItemMessage": "{numRows}行", - "xpack.uptime.monitorList.redirects.description": "Pingの実行中にHeartbeatは{number}リダイレクトに従いました。", - "xpack.uptime.monitorList.redirects.openWindow": "リンクは新しいウィンドウで開きます。", - "xpack.uptime.monitorList.redirects.title": "リダイレクト", - "xpack.uptime.monitorList.redirects.title.number": "{number}", - "xpack.uptime.monitorList.refresh": "更新", - "xpack.uptime.monitorList.statusAlert.label": "ステータスアラート", - "xpack.uptime.monitorList.statusColumn.checkedTimestamp": "チェック済み{timestamp}", - "xpack.uptime.monitorList.statusColumn.completeLabel": "完了", - "xpack.uptime.monitorList.statusColumn.downLabel": "ダウン", - "xpack.uptime.monitorList.statusColumn.error.logs": "エラーログ", - "xpack.uptime.monitorList.statusColumn.error.message": "{message}。詳細はクリックしてください。", - "xpack.uptime.monitorList.statusColumn.error.messageLabel": "{message}。詳細はクリックしてください。", - "xpack.uptime.monitorList.statusColumn.failedLabel": "失敗", - "xpack.uptime.monitorList.statusColumn.locStatusMessage": "場所 {noLoc} か所", - "xpack.uptime.monitorList.statusColumn.locStatusMessage.multiple": "場所 {noLoc} か所", - "xpack.uptime.monitorList.statusColumn.locStatusMessage.tooltip.down": "{locs} でダウン", - "xpack.uptime.monitorList.statusColumn.locStatusMessage.tooltip.up": "{locs} でアップ", - "xpack.uptime.monitorList.statusColumn.upLabel": "アップ", - "xpack.uptime.monitorList.statusColumnLabel": "ステータス", - "xpack.uptime.monitorList.table.description": "列にステータス、名前、URL、IP、ダウンタイム履歴、統合が入力されたモニターステータス表です。この表は現在 {length} 項目を表示しています。", - "xpack.uptime.monitorList.table.tags.name": "タグ", - "xpack.uptime.monitorList.table.url.name": "Url", - "xpack.uptime.monitorList.tags.expand": "クリックすると、残りのタグが表示されます", - "xpack.uptime.monitorList.tags.filter": "タグ {tag} ですべての監視をフィルター", - "xpack.uptime.monitorList.testNow.AriaLabel": "クリックすると今すぐテストを実行します", - "xpack.uptime.monitorList.testNow.available": "現在、テストはモニター管理で追加されたモニターでのみ使用できます。", - "xpack.uptime.monitorList.testNow.label": "今すぐテストを実行", - "xpack.uptime.monitorList.testNow.scheduled": "テストはすでにスケジュールされています", - "xpack.uptime.monitorList.testRunLogs": "テスト実行ログ", - "xpack.uptime.monitorList.timestamp": "タイムスタンプ", - "xpack.uptime.monitorList.tlsColumnLabel": "TLS 証明書", - "xpack.uptime.monitorList.viewInDiscover": "Discoverに表示", - "xpack.uptime.monitorManagement.addMonitorCrumb": "モニターを追加", - "xpack.uptime.monitorManagement.addMonitorError": "サービスの場所を読み込めませんでした。しばらくたってから再試行してください。", - "xpack.uptime.monitorManagement.addMonitorLabel": "モニターを追加", - "xpack.uptime.monitorManagement.addMonitorLoadingError": "モニター管理の読み込みエラー", - "xpack.uptime.monitorManagement.addMonitorLoadingLabel": "モニター管理を読み込んでいます", - "xpack.uptime.monitorManagement.addMonitorServiceLocationsLoadingError": "サービスの場所を読み込めませんでした。しばらくたってから再試行してください。", - "xpack.uptime.monitorManagement.apiKeysDisabledToolTip": "このクラスターのAPIキーが無効です。モニター管理では、Elasticsearchクラスターに書き込むためにAPIキーを使用する必要があります。APIキーを有効にするには、管理者に連絡してください。", - "xpack.uptime.monitorManagement.callout.description.disabled": "モニター管理は現在無効です。Elasticで管理されたSyntheticsサービスでモニターを実行するには、モニター管理を有効にします。既存のモニターが一時停止しています。", - "xpack.uptime.monitorManagement.callout.disabled": "モニター管理が無効です", - "xpack.uptime.monitorManagement.callout.disabled.adminContact": "モニター管理を有効にするには、管理者に連絡してください。", - "xpack.uptime.monitorManagement.closeButtonLabel": "閉じる", - "xpack.uptime.monitorManagement.completed": "完了", - "xpack.uptime.monitorManagement.confirmDescriptionLabel": "このアクションにより、モニターが削除されますが、収集されたデータはすべて保持されます。この操作は元に戻すことができません。", - "xpack.uptime.monitorManagement.deleteMonitorLabel": "モニターの削除", - "xpack.uptime.monitorManagement.disableMonitorLabel": "モニターを無効にする", - "xpack.uptime.monitorManagement.discardLabel": "破棄", - "xpack.uptime.monitorManagement.duplicateNameError": "モニター名はすでに存在します。", - "xpack.uptime.monitorManagement.editMonitorCrumb": "モニターを編集", - "xpack.uptime.monitorManagement.editMonitorError": "モニター管理の読み込みエラー", - "xpack.uptime.monitorManagement.editMonitorError.description": "モニター管理設定を読み込めませんでした。サポートに問い合わせてください。", - "xpack.uptime.monitorManagement.editMonitorErrorBody": "モニター構成を読み込めませんでした。しばらくたってから再試行してください。", - "xpack.uptime.monitorManagement.editMonitorLabel": "モニターを編集", - "xpack.uptime.monitorManagement.editMonitorLoadingLabel": "モニターを読み込んでいます", - "xpack.uptime.monitorManagement.emptyState.enablement": "モニター管理を有効にすると、世界中のホスティングされたテスト場所から軽量でリアルなブラウザーモニターを実行できます。モニター管理を有効にすると、APIキーが生成され、SyntheticsサービスはElasticsearchクラスターに書き込むことができます。", - "xpack.uptime.monitorManagement.emptyState.enablement.disabled.title": "モニター管理が無効です", - "xpack.uptime.monitorManagement.emptyState.enablement.disabledDescription": "モニター管理は現在無効です。モニター管理では、世界中のホスティングされたテスト場所から軽量のチェックとリアルなブラウザーモニターを実行できます。モニター管理を有効にするには、管理者に連絡してください。", - "xpack.uptime.monitorManagement.emptyState.enablement.doc": "ドキュメントを読む", - "xpack.uptime.monitorManagement.emptyState.enablement.enabled.title": "モニター管理を有効にする", - "xpack.uptime.monitorManagement.emptyState.enablement.learnMore": "詳細について", - "xpack.uptime.monitorManagement.emptyState.enablement.title": "有効にする", - "xpack.uptime.monitorManagement.enableMonitorLabel": "モニターを有効にする", - "xpack.uptime.monitorManagement.failed": "失敗", - "xpack.uptime.monitorManagement.failedRun": "ステップを実行できませんでした", - "xpack.uptime.monitorManagement.inProgress": "進行中", - "xpack.uptime.monitorManagement.label": "モニター管理", - "xpack.uptime.monitorManagement.loading.label": "モニター管理を読み込んでいます", - "xpack.uptime.monitorManagement.loadingSteps": "ステップを読み込んでいます...", - "xpack.uptime.monitorManagement.manageMonitorLoadingLabel": "モニター管理を読み込んでいます", - "xpack.uptime.monitorManagement.manageMonitorLoadingLabel.callout.learnMore": "詳細情報", - "xpack.uptime.monitorManagement.monitorAddedSuccessMessage": "モニターが正常に追加されました。", - "xpack.uptime.monitorManagement.monitorAdvancedOptions.dataStreamConfiguration.description": "追加のデータストリームオプションを構成します。", - "xpack.uptime.monitorManagement.monitorAdvancedOptions.dataStreamConfiguration.title": "データストリーム設定", - "xpack.uptime.monitorManagement.monitorAdvancedOptions.monitorNamespaceFieldLabel": "名前空間", - "xpack.uptime.monitorManagement.monitorAdvancedOptions.namespaceHelpLabel": "デフォルト名前空間を変更します。この設定により、モニターのデータストリームの名前が変更されます。{learnMore}。", - "xpack.uptime.monitorManagement.monitorAdvancedOptions.namespaceHelpLearnMoreLabel": "詳細情報", - "xpack.uptime.monitorManagement.monitorDeleteFailureMessage": "モニターを削除できませんでした。しばらくたってから再試行してください。", - "xpack.uptime.monitorManagement.monitorDeleteLoadingMessage": "モニターを削除しています...", - "xpack.uptime.monitorManagement.monitorDeleteSuccessMessage": "モニターが正常に削除されました。", - "xpack.uptime.monitorManagement.monitorDisabledSuccessMessage": "モニター{name}は正常に無効にされました。", - "xpack.uptime.monitorManagement.monitorEditedSuccessMessage": "モニターは正常に更新されました。", - "xpack.uptime.monitorManagement.monitorEnabledSuccessMessage": "モニター{name}は正常に有効にされました。", - "xpack.uptime.monitorManagement.monitorEnabledUpdateFailureMessage": "モニター{name}を更新できません。", - "xpack.uptime.monitorManagement.monitorFailureMessage": "モニターを保存できませんでした。しばらくたってから再試行してください。", - "xpack.uptime.monitorManagement.monitorList.actions": "アクション", - "xpack.uptime.monitorManagement.monitorList.enabled": "有効", - "xpack.uptime.monitorManagement.monitorList.locations": "場所", - "xpack.uptime.monitorManagement.monitorList.monitorName": "モニター名", - "xpack.uptime.monitorManagement.monitorList.monitorType": "モニタータイプ", - "xpack.uptime.monitorManagement.monitorList.schedule": "頻度(分)", - "xpack.uptime.monitorManagement.monitorList.tags": "タグ", - "xpack.uptime.monitorManagement.monitorList.title": "モニター管理リスト", - "xpack.uptime.monitorManagement.monitorList.URL": "URL", - "xpack.uptime.monitorManagement.monitorLocationsLabel": "モニターの場所", - "xpack.uptime.monitorManagement.monitorManagementCrumb": "モニター管理", - "xpack.uptime.monitorManagement.monitorNameFieldError": "モニター名は必須です", - "xpack.uptime.monitorManagement.monitorNameFieldLabel": "モニター名", - "xpack.uptime.monitorManagement.monitorSync.failure.content": "1つ以上の場所でモニターを同期するときに問題が発生しました。", - "xpack.uptime.monitorManagement.monitorSync.failure.dismissLabel": "閉じる", - "xpack.uptime.monitorManagement.monitorSync.failure.reasonLabel": "理由", - "xpack.uptime.monitorManagement.monitorSync.failure.statusLabel": "ステータス", - "xpack.uptime.monitorManagement.monitorSync.failure.title": "モニターをSyntheticsサービスと同期できませんでした", - "xpack.uptime.monitorManagement.noLabel": "キャンセル", - "xpack.uptime.monitorManagement.pageHeader.title": "モニターの管理", - "xpack.uptime.monitorManagement.pending": "保留中", - "xpack.uptime.monitorManagement.publicBetaDescription": "選択した一般ベータユーザーでのみモニター管理を使用できます。一般\nベータアクセスでは、HTTP、TCP、ICMPを追加できます。ブラウザーは\nElasticで管理されたSyntheticsサービスノードでどれが実行されるのかを確認します。", - "xpack.uptime.monitorManagement.requestAccess": "アクセスをリクエストする", - "xpack.uptime.monitorManagement.reRunTest": "テストの再実行", - "xpack.uptime.monitorManagement.runTest": "テストの実行", - "xpack.uptime.monitorManagement.saveMonitorLabel": "モニターを保存", - "xpack.uptime.monitorManagement.service.error.message": "モニターは保存されますが、{location}の構成の同期中に問題が発生しました。しばらくたってから自動的に再試行されます。問題が解決しない場合は、{location}でのモニターの実行が停止します。ヘルプについては、サポートに問い合わせてください。", - "xpack.uptime.monitorManagement.service.error.reason": "理由:{reason}。", - "xpack.uptime.monitorManagement.service.error.status": "ステータス:{status}。", - "xpack.uptime.monitorManagement.service.error.title": "モニター構成を同期できません", - "xpack.uptime.monitorManagement.serviceLocationsValidationError": "1つ以上のサービスの場所を指定する必要があります", - "xpack.uptime.monitorManagement.stepCompleted": "{stepCount, number} {stepCount, plural, other {個のステップ}}が完了しました", - "xpack.uptime.monitorManagement.syntheticsDisabled": "モニター管理は現在無効です。モニター管理を有効にするには、管理者に連絡してください。", - "xpack.uptime.monitorManagement.syntheticsDisabledFailure": "モニター管理を無効にできませんでした。サポートに問い合わせてください。", - "xpack.uptime.monitorManagement.syntheticsDisabledSuccess": "モニター管理は正常に無効にされました。", - "xpack.uptime.monitorManagement.syntheticsDisableToolTip": "モニター管理を無効にすると、すべてのテスト場所でモニターの実行が即時停止され、新しいモニターの作成が防止されます。", - "xpack.uptime.monitorManagement.syntheticsEnabledFailure": "モニター管理を有効にできませんでした。サポートに問い合わせてください。", - "xpack.uptime.monitorManagement.syntheticsEnableLabel": "有効にする", - "xpack.uptime.monitorManagement.syntheticsEnableLabel.management": "モニター管理を有効にする", - "xpack.uptime.monitorManagement.syntheticsEnableSuccess": "モニター管理は正常に有効にされました。", - "xpack.uptime.monitorManagement.syntheticsEnableToolTip": "モニター管理を有効にすると、世界中の場所から軽量でリアルなブラウザーモニターを作成できます。", - "xpack.uptime.monitorManagement.testResult": "テスト結果", - "xpack.uptime.monitorManagement.timeTaken": "かかった時間{timeTaken}", - "xpack.uptime.monitorManagement.updateMonitorLabel": "モニターの更新", - "xpack.uptime.monitorManagement.validationError": "モニターにはエラーがあります。保存前に修正してください。", - "xpack.uptime.monitorManagement.viewTestRunDetails": "テスト結果詳細を表示", - "xpack.uptime.monitorManagement.yesLabel": "削除", - "xpack.uptime.monitorManagementRoute.title": "モニターの管理 | {baseTitle}", - "xpack.uptime.monitorRoute.title": "モニター | {baseTitle}", - "xpack.uptime.monitorStatusBar.durationTextAriaLabel": "ミリ秒単位の監視時間", - "xpack.uptime.monitorStatusBar.healthStatusMessageAriaLabel": "監視ステータス", - "xpack.uptime.monitorStatusBar.loadingMessage": "読み込み中…", - "xpack.uptime.monitorStatusBar.locations.oneLocStatus": "{loc}場所での{status}", - "xpack.uptime.monitorStatusBar.locations.upStatus": "{loc}場所での{status}", - "xpack.uptime.monitorStatusBar.monitor.availability": "全体的な可用性", - "xpack.uptime.monitorStatusBar.monitor.availabilityReport.availability": "可用性", - "xpack.uptime.monitorStatusBar.monitor.availabilityReport.lastCheck": "最終確認", - "xpack.uptime.monitorStatusBar.monitor.availabilityReport.location": "場所", - "xpack.uptime.monitorStatusBar.monitor.id": "監視ID", - "xpack.uptime.monitorStatusBar.monitor.monitoringFrom": "監視元", - "xpack.uptime.monitorStatusBar.monitor.monitoringFrom.listToMap": "マップビューに変更し、場所別に可用性を確認します。", - "xpack.uptime.monitorStatusBar.monitor.monitoringFrom.MapToList": "リストビューに変更し、場所別に可用性を確認します。", - "xpack.uptime.monitorStatusBar.monitorUrlLinkAriaLabel": "監視 URL リンク", - "xpack.uptime.monitorStatusBar.sslCertificate.title": "TLS 証明書", - "xpack.uptime.monitorStatusBar.timestampFromNowTextAriaLabel": "最終確認からの経過時間", - "xpack.uptime.monitorStatusBar.type.ariaLabel": "モニタータイプ", - "xpack.uptime.monitorStatusBar.type.label": "型", - "xpack.uptime.navigateToAlertingButton.content": "ルールの管理", - "xpack.uptime.navigateToAlertingUi": "Uptime を離れてアラート管理ページに移動します", - "xpack.uptime.noDataConfig.beatsCard.description": "サイトとサービスの可用性をアクティブに監視するアラートを受信し、問題をより迅速に解決して、ユーザーエクスペリエンスを最適化します。", - "xpack.uptime.noDataConfig.beatsCard.title": "Heartbeatでモニターを追加", - "xpack.uptime.noDataConfig.solutionName": "Observability", - "xpack.uptime.notFountPage.homeLinkText": "ホームへ戻る", - "xpack.uptime.openAlertContextPanel.ariaLabel": "ルールコンテキストパネルを開くと、ルールタイプを選択できます", - "xpack.uptime.openAlertContextPanel.label": "ルールを作成", - "xpack.uptime.overview.alerts.disabled.failed": "ルールを無効にできません。", - "xpack.uptime.overview.alerts.disabled.success": "ルールが正常に無効にされました。", - "xpack.uptime.overview.alerts.enabled.failed": "ルールを有効にできません。", - "xpack.uptime.overview.alerts.enabled.success": "ルールが正常に有効にされました。 ", - "xpack.uptime.overview.alerts.enabled.success.description": "この監視が停止しているときには、メッセージが {actionConnectors} に送信されます。", - "xpack.uptime.overview.heading": "監視", - "xpack.uptime.overview.pageHeader.syntheticsCallout.announcementLink": "お知らせを読む", - "xpack.uptime.overview.pageHeader.syntheticsCallout.content": "アップタイムは、スクリプト化された複数ステップの可用性チェックのサポートをプレビューしています。つまり、単に単一のページのアップ/ダウンのチェックだけではなく、Webページの要素を操作したり、全体的な可用性を確認したりできます(購入やシステムへのサインインなど)。詳細については以下をクリックしてください。これらの機能を先駆けて使用したい場合は、プレビュー合成エージェントをダウンロードし、アップタイムでチェックを表示できます。", - "xpack.uptime.overview.pageHeader.syntheticsCallout.dismissButtonText": "閉じる", - "xpack.uptime.overview.pageHeader.syntheticsCallout.title": "Elastic Synthetics", - "xpack.uptime.overviewPage.headerText": "概要", - "xpack.uptime.overviewPageLink.disabled.ariaLabel": "無効になったページ付けボタンです。モニターリストがこれ以上ナビゲーションできないことを示しています。", - "xpack.uptime.overviewPageLink.next.ariaLabel": "次の結果ページ", - "xpack.uptime.overviewPageLink.prev.ariaLabel": "前の結果ページ", - "xpack.uptime.page_header.addDataLink.label": "アップタイムデータの追加に関するチュートリアルに移動", - "xpack.uptime.page_header.analyzeData.label": "[データの探索]ビューに移動して、合成/ユーザーデータを可視化", - "xpack.uptime.page_header.defineConnector.popover.defaultLink": "デフォルトのコネクターを定義", - "xpack.uptime.page_header.defineConnector.settingsLink": "設定", - "xpack.uptime.page_header.manageLink.label": "アップタイムモニター管理ページに移動", - "xpack.uptime.page_header.settingsLink": "設定", - "xpack.uptime.page_header.settingsLink.label": "アップタイム設定ページに移動", - "xpack.uptime.pingHistogram.analyze": "分析", - "xpack.uptime.pingist.durationSecondsColumnFormatting": "{seconds}秒", - "xpack.uptime.pingist.durationSecondsColumnFormatting.singular": "{seconds}秒", - "xpack.uptime.pingList.checkHistoryTitle": "履歴", - "xpack.uptime.pingList.collapseRow": "縮小", - "xpack.uptime.pingList.columns.failedStep": "失敗したステップ", - "xpack.uptime.pingList.drawer.body.docsLink": "ドキュメント", - "xpack.uptime.pingList.durationMsColumnFormatting": "{millis}ミリ秒", - "xpack.uptime.pingList.durationMsColumnLabel": "期間", - "xpack.uptime.pingList.errorColumnLabel": "エラー", - "xpack.uptime.pingList.errorTypeColumnLabel": "エラータイプ", - "xpack.uptime.pingList.expandedRow.bodySize": "本文サイズは {bodyBytes} です。", - "xpack.uptime.pingList.expandedRow.error": "エラー", - "xpack.uptime.pingList.expandedRow.response_body": "応答本文", - "xpack.uptime.pingList.expandedRow.response_body.notRecorded": "本文が記録されていません。応答本文の記録に関する詳細は、{docsLink}をお読みください。", - "xpack.uptime.pingList.expandedRow.truncated": "初めの {contentBytes} バイトを表示中。", - "xpack.uptime.pingList.expandRow": "拡張", - "xpack.uptime.pingList.headers.title": "応答ヘッダー", - "xpack.uptime.pingList.ipAddressColumnLabel": "IP", - "xpack.uptime.pingList.locationNameColumnLabel": "場所", - "xpack.uptime.pingList.pingsLoadingMesssage": "履歴を読み込んでいます...", - "xpack.uptime.pingList.pingsUnavailableMessage": "履歴が見つかりません", - "xpack.uptime.pingList.recencyMessage": "最終確認 {fromNow}", - "xpack.uptime.pingList.responseCodeColumnLabel": "応答コード", - "xpack.uptime.pingList.statusColumnLabel": "ステータス", - "xpack.uptime.pingList.stepDurationHeader": "ステップ期間", - "xpack.uptime.pingList.synthetics.performanceBreakDown": "パフォーマンスの内訳を表示", - "xpack.uptime.pingList.synthetics.waterfall.filters.collapseRequestsLabel": "折りたたむと、一致する要求のみが表示されます", - "xpack.uptime.pingList.synthetics.waterfall.filters.popover": "クリックすると、ウォーターフォールフィルターが開きます", - "xpack.uptime.pingList.timestampColumnLabel": "タイムスタンプ", - "xpack.uptime.pluginDescription": "アップタイム監視", - "xpack.uptime.public.pages.mappingError.bodyDocsLink": "この問題のトラブルシューティングについては、{docsLink}を参照してください。", - "xpack.uptime.public.pages.mappingError.bodyMessage": "正しくないマッピングが検出されました。Heartbeat {setup}コマンドを実行していない可能性があります。", - "xpack.uptime.public.pages.mappingError.title": "Heartbeatマッピングが見つかりません", - "xpack.uptime.routes.baseTitle": "アップタイム - Kibana", - "xpack.uptime.seconds.label": "秒", - "xpack.uptime.seconds.shortForm.label": "秒", - "xpack.uptime.settings.blank.error": "空白にすることはできません。", - "xpack.uptime.settings.blankNumberField.error": "数値でなければなりません。", - "xpack.uptime.settings.cannotEditText": "現在、このユーザーには Uptime アプリの「読み取り」権があります。これらの設定を編集するには「すべて」のパーミッションレベルを有効にします。", - "xpack.uptime.settings.cannotEditTitle": "設定を編集するパーミッションがありません。", - "xpack.uptime.settings.error.couldNotSave": "設定を保存できませんでした!", - "xpack.uptime.settings.heading": "アップタイム設定", - "xpack.uptime.settings.invalid.error": "値は0よりも大きい値でなければなりません。", - "xpack.uptime.settings.invalid.nanError": "値は整数でなければなりません。", - "xpack.uptime.settings.noSpace.error": "インデックス名にはスペースを使用できません", - "xpack.uptime.settings.saveSuccess": "設定が保存されました。", - "xpack.uptime.settingsBreadcrumbText": "設定", - "xpack.uptime.settingsRoute.title": "設定 | {baseTitle}", - "xpack.uptime.snapshot.donutChart.ariaLabel": "現在のステータスを表す円グラフ、{total} 個中 {down} 個のモニターがダウンしています。", - "xpack.uptime.snapshot.monitor": "監視", - "xpack.uptime.snapshot.monitors": "監視", - "xpack.uptime.snapshot.noDataDescription": "選択した時間範囲に ping はありません。", - "xpack.uptime.snapshot.noDataTitle": "利用可能な ping データがありません", - "xpack.uptime.snapshot.pingsOverTimeTitle": "一定時間のピング", - "xpack.uptime.snapshotHistogram.description": "{startTime} から {endTime} までの期間のアップタイムステータスを表示する棒グラフです。", - "xpack.uptime.snapshotHistogram.series.pings": "モニター接続確認", - "xpack.uptime.snapshotHistogram.xAxisId": "ピング X 軸", - "xpack.uptime.snapshotHistogram.yAxis.title": "ピング", - "xpack.uptime.snapshotHistogram.yAxisId": "ピングY軸", - "xpack.uptime.sourceConfiguration.ageLimit.units.days": "日", - "xpack.uptime.sourceConfiguration.ageLimitThresholdInput.ariaLabel": "TLS証明書が有効である最大日数を制御するインプット。この期間を過ぎると、Kibanaで警告が表示されます。", - "xpack.uptime.sourceConfiguration.ageThresholdDefaultValue": "デフォルト値は{defaultValue}です", - "xpack.uptime.sourceConfiguration.alertConnectors": "アラートコネクター", - "xpack.uptime.sourceConfiguration.alertConnectors.defaultEmail": "デフォルトの電子メールアドレス", - "xpack.uptime.sourceConfiguration.alertDefaultForm.emailConnectorPlaceHolder": "終了:電子メールコネクターの電子メールアドレス", - "xpack.uptime.sourceConfiguration.alertDefaultForm.invalidEmail": "{val}は有効な電子メールアドレスではありません。", - "xpack.uptime.sourceConfiguration.alertDefaultForm.requiredEmail": "電子メールコネクターには宛先電子メールアドレスが必須です", - "xpack.uptime.sourceConfiguration.alertDefaultForm.selectConnector": "1つ以上のコネクターを選択してください", - "xpack.uptime.sourceConfiguration.alertDefaults": "アラートデフォルト", - "xpack.uptime.sourceConfiguration.applySettingsButtonLabel": "変更を適用", - "xpack.uptime.sourceConfiguration.certificateExpirationThresholdInput.ariaLabel": "TLS証明書の満了日までの最小日数を制御するインプット。この期間を過ぎると、Kibanaで警告が表示されます。", - "xpack.uptime.sourceConfiguration.certificateThresholdDescription": "証明書エラーを表示し、アラートを通知するしきい値を変更します。注:すべての構成されたアラートに影響します。", - "xpack.uptime.sourceConfiguration.certificationSectionTitle": "証明書の有効期限", - "xpack.uptime.sourceConfiguration.defaultConnectors": "デフォルトコネクター", - "xpack.uptime.sourceConfiguration.defaultConnectors.description": "アラートを送信するために使用されるデフォルトコネクター。", - "xpack.uptime.sourceConfiguration.defaultConnectors.description.defaultEmail": "選択した電子メールアラートコネクターには電子メール設定が必須です。", - "xpack.uptime.sourceConfiguration.discardSettingsButtonLabel": "キャンセル", - "xpack.uptime.sourceConfiguration.errorStateLabel": "有効期限しきい値", - "xpack.uptime.sourceConfiguration.expirationThreshold": "有効期限/使用期間しきい値", - "xpack.uptime.sourceConfiguration.expirationThresholdDefaultValue": "デフォルト値は{defaultValue}です", - "xpack.uptime.sourceConfiguration.heartbeatIndicesDefaultValue": "デフォルト値は{defaultValue}です", - "xpack.uptime.sourceConfiguration.heartbeatIndicesDescription": "Heartbeat データを含むインデックス照合用のインデックスパターン", - "xpack.uptime.sourceConfiguration.heartbeatIndicesLabel": "Heartbeat インデックス", - "xpack.uptime.sourceConfiguration.heartbeatIndicesTitle": "アップタイムインデックス", - "xpack.uptime.sourceConfiguration.indicesSectionTitle": "インデックス", - "xpack.uptime.sourceConfiguration.warningStateLabel": "使用期間上限", - "xpack.uptime.stepDetailRoute.title": "Synthetics詳細 | {baseTitle}", - "xpack.uptime.stepList.collapseRow": "縮小", - "xpack.uptime.stepList.expandRow": "拡張", - "xpack.uptime.stepList.stepName": "ステップ名", - "xpack.uptime.synthetics.consoleStepList.message": "実行できませんでした。記録されたコンソール出力は次のとおりです。", - "xpack.uptime.synthetics.consoleStepList.title": "ステップが実行されませんでした", - "xpack.uptime.synthetics.emptyJourney.message.checkGroupField": "チェックグループは{codeBlock}です。", - "xpack.uptime.synthetics.emptyJourney.message.footer": "表示する詳細情報はありません。", - "xpack.uptime.synthetics.emptyJourney.message.heading": "ステップが含まれていませんでした。", - "xpack.uptime.synthetics.emptyJourney.title": "ステップがありません。", - "xpack.uptime.synthetics.executedStep.consoleOutput.label": "コンソール出力", - "xpack.uptime.synthetics.executedStep.errorHeading": "エラーメッセージ", - "xpack.uptime.synthetics.executedStep.screenshot.not": "スクリーンショット", - "xpack.uptime.synthetics.executedStep.screenshot.notSucceeded": "{status}チェックのスクリーンショット", - "xpack.uptime.synthetics.executedStep.screenshot.success": "前回成功したチェック", - "xpack.uptime.synthetics.executedStep.screenshot.successfulLink": "{link}からのスクリーンショット", - "xpack.uptime.synthetics.executedStep.scriptHeading.label": "このステップで実行されたスクリプト", - "xpack.uptime.synthetics.executedStep.stackTrace": "スタックトレース", - "xpack.uptime.synthetics.imageLoadingSpinner.ariaLabel": "画像を示すアニメーションスピナーを読み込んでいます", - "xpack.uptime.synthetics.journey.allFailedMessage": "{total}ステップ - すべて失敗またはスキップされました", - "xpack.uptime.synthetics.journey.allSucceededMessage": "{total}ステップ - すべて成功しました", - "xpack.uptime.synthetics.journey.loadingSteps": "ステップを読み込んでいます...", - "xpack.uptime.synthetics.journey.partialSuccessMessage": "{total}ステップ - {succeeded}成功しました", - "xpack.uptime.synthetics.markers.explore": "探索", - "xpack.uptime.synthetics.markers.noFieldIcon.label": "このマーカーにフィールドが関連付けられていないことを示すアイコン", - "xpack.uptime.synthetics.markers.openEmbeddableButton.label": "このアイコンボタンを使用して、この注釈マーカーのメトリックを表示します。", - "xpack.uptime.synthetics.nextStepButton.ariaLabel": "次のステップ", - "xpack.uptime.synthetics.performanceBreakDown.label": "パフォーマンスの内訳", - "xpack.uptime.synthetics.pingTimestamp.captionContent": "ステップ:{stepNumber}/{totalSteps}", - "xpack.uptime.synthetics.prevStepButton.airaLabel": "前のステップ", - "xpack.uptime.synthetics.screenshot.noImageMessage": "画像がありません", - "xpack.uptime.synthetics.screenshotDisplay.altText": "名前「{stepName}」のステップのスクリーンショット", - "xpack.uptime.synthetics.screenshotDisplay.altTextWithoutName": "スクリーンショット", - "xpack.uptime.synthetics.service.apiKey": "SyntheticsサービスAPIキー", - "xpack.uptime.synthetics.statusBadge.failedMessage": "失敗", - "xpack.uptime.synthetics.statusBadge.skippedMessage": "スキップ", - "xpack.uptime.synthetics.statusBadge.succeededMessage": "成功", - "xpack.uptime.synthetics.step.duration": "{value}秒", - "xpack.uptime.synthetics.step.durationTrend": "ステップ期間傾向", - "xpack.uptime.synthetics.stepDetail.nextCheckButtonText": "次の確認", - "xpack.uptime.synthetics.stepDetail.noData": "このステップのデータが見つかりませんでした", - "xpack.uptime.synthetics.stepDetail.previousCheckButtonText": "前の確認", - "xpack.uptime.synthetics.stepDetail.totalSteps": "Step {stepIndex} of {totalSteps}", - "xpack.uptime.synthetics.stepDetail.waterfall.loading": "ウォーターフォールグラフを読み込んでいます", - "xpack.uptime.synthetics.stepDetail.waterfallNoData": "このステップのウォーターフォールデータが見つかりませんでした", - "xpack.uptime.synthetics.stepDetail.waterfallUnsupported.description": "ウォーターフォールグラフを表示できません。古いバージョンのSyntheticエージェントを使用している可能性があります。バージョンを確認して、アップグレードを検討してください。", - "xpack.uptime.synthetics.stepDetail.waterfallUnsupported.title": "ウォーターフォールグラフを使用できません", - "xpack.uptime.synthetics.stepList.nextCheck": "次の確認", - "xpack.uptime.synthetics.stepList.previousCheck": "前の確認", - "xpack.uptime.synthetics.thumbnail.fullSize.alt": "このステップのサムネイルのスクリーンショットの大きいバージョン。", - "xpack.uptime.synthetics.waterfall.domContentLabel": "DOMコンテンツが読み込まれました", - "xpack.uptime.synthetics.waterfall.fcpLabel": "初回コンテンツの描画", - "xpack.uptime.synthetics.waterfall.filterGroup.filterScreenreaderLabel": "フィルタリング条件", - "xpack.uptime.synthetics.waterfall.filterGroup.removeFilterScreenReaderLabel": "フィルターを削除", - "xpack.uptime.synthetics.waterfall.flyout.certificates": "証明書ヘッダー", - "xpack.uptime.synthetics.waterfall.flyout.details": "詳細", - "xpack.uptime.synthetics.waterfall.flyout.requestHeaders": "要求ヘッダー", - "xpack.uptime.synthetics.waterfall.flyout.responseHeaders": "応答ヘッダー", - "xpack.uptime.synthetics.waterfall.layoutShiftLabel": "レイアウトシフト", - "xpack.uptime.synthetics.waterfall.lcpLabel": "最大コンテンツの描画", - "xpack.uptime.synthetics.waterfall.loadEventLabel": "イベントの読み込み", - "xpack.uptime.synthetics.waterfall.offsetUnit": "{offset} ms", - "xpack.uptime.synthetics.waterfall.requestsHighlightedMessage": "({numHighlightedRequests}はフィルターと一致します)", - "xpack.uptime.synthetics.waterfall.requestsTotalMessage": "{numNetworkRequests}ネットワーク要求", - "xpack.uptime.synthetics.waterfall.requestsTotalMessage.first": "最初の{count}件", - "xpack.uptime.synthetics.waterfall.requestsTotalMessage.info": "ウォーターフォールビューには最大1000件の要求が表示されます", - "xpack.uptime.synthetics.waterfall.resource.externalLink": "新しいタブでリソースを開く", - "xpack.uptime.synthetics.waterfall.searchBox.placeholder": "ネットワーク要求をフィルター", - "xpack.uptime.synthetics.waterfall.sidebar.filterMatchesScreenReaderLabel": "リソースがフィルターと一致します", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.certificateExpiryDate": "有効期限:", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.certificateIssueDate": "有効期間の開始", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.certificateIssuer": "発行者", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.certificateSubject": "共通名", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.contentType": "コンテンツタイプ", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.ip": "IP", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.requestStart": "要求開始", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.resourceSize": "リソースサイズ", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.status": "ステータス", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.transferSize": "転送サイズ", - "xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.font": "フォント", - "xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.html": "HTML", - "xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.media": "メディア", - "xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.other": "その他", - "xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.script": "JS", - "xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.stylesheet": "CSS", - "xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.xhr": "XHR", - "xpack.uptime.synthetics.waterfallChart.labels.timings.blocked": "キュー/ブロック", - "xpack.uptime.synthetics.waterfallChart.labels.timings.connect": "接続中", - "xpack.uptime.synthetics.waterfallChart.labels.timings.dns": "DNS", - "xpack.uptime.synthetics.waterfallChart.labels.timings.receive": "コンテンツダウンロード", - "xpack.uptime.synthetics.waterfallChart.labels.timings.send": "要求を送信しています", - "xpack.uptime.synthetics.waterfallChart.labels.timings.ssl": "TLS", - "xpack.uptime.synthetics.waterfallChart.labels.timings.wait": "待機中(TTFB)", - "xpack.uptime.syntheticsMonitors": "アップタイム - モニター", - "xpack.uptime.testRun.description": "モニターをテストし、保存する前に結果を検証します", - "xpack.uptime.testRun.pushError": "モニターをサービスにプッシュできませんでした。", - "xpack.uptime.testRun.pushErrorLabel": "プッシュエラー", - "xpack.uptime.testRun.pushing.description": "モニターをサービスにプッシュしています...", - "xpack.uptime.title": "アップタイム", - "xpack.uptime.toggleAlertButton.content": "監視ステータスルール", - "xpack.uptime.toggleAlertFlyout.ariaLabel": "ルールの追加フライアウトを開く", - "xpack.uptime.toggleTlsAlertButton.ariaLabel": "TLSルールフライアウトを開く", - "xpack.uptime.toggleTlsAlertButton.content": "TLSルール", - "xpack.uptime.uptimeFeatureCatalogueTitle": "アップタイム", - "xpack.uptime.uptimeSettings.index": "アップタイム設定 - インデックス", - "xpack.uptime.waterfallChart.sidebar.url.https": "https", + "xpack.synthetics.addDataButtonLabel": "データの追加", + "xpack.synthetics.addMonitor.pageHeader.title": "モニターを追加", + "xpack.synthetics.addMonitorRoute.title": "モニターを追加 | {baseTitle}", + "xpack.synthetics.alertDropdown.noWritePermissions": "このアプリでアラートを作成するには、アップタイムへの読み書きアクセス権が必要です。", + "xpack.synthetics.alerts.anomaly.criteriaExpression.ariaLabel": "選択したモニターの条件を表示する式。", + "xpack.synthetics.alerts.anomaly.criteriaExpression.description": "監視するとき", + "xpack.synthetics.alerts.anomaly.scoreExpression.ariaLabel": "異常アラートしきい値の条件を表示する式。", + "xpack.synthetics.alerts.anomaly.scoreExpression.description": "異常と重要度があります", + "xpack.synthetics.alerts.createRulesPanel.title": "ルールを作成", + "xpack.synthetics.alerts.durationAnomaly": "アップタイム期間異常", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.anomalyStartTimestamp": "異常の開始のISO8601タイムスタンプ", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.expectedResponseTime": "想定応答時間", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.monitor": "名前、IDS、優先名の人間にとってわかりやすい表示(My Monitorなど)", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.monitorId": "モニターのID。", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.monitorUrl": "モニターのURL。", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.observerLocation": "Heartbeatチェックが実行されるオブサーバーの位置情報。", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.severity": "異常の重要度。", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.severityScore": "異常重要度スコア。", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.slowestAnomalyResponse": "単位(ミリ秒、秒)が関連付けられた異常バケット中の最も遅い応答時間。", + "xpack.synthetics.alerts.durationAnomaly.clientName": "アップタイム期間異常", + "xpack.synthetics.alerts.durationAnomaly.defaultActionMessage": "{anomalyStartTimestamp}に、{monitor}、url {monitorUrl}で異常({severity}レベル)応答時間が検出されました。異常重要度スコアは{severityScore}です。\n位置情報{observerLocation}から高い応答時間{slowestAnomalyResponse}が検出されました。想定された応答時間は{expectedResponseTime}です。", + "xpack.synthetics.alerts.durationAnomaly.description": "アップタイム監視期間が異常なときにアラートを発行します。", + "xpack.synthetics.alerts.monitorExpression.label": "フィルター{title}を削除", + "xpack.synthetics.alerts.monitorStatus": "稼働状況の監視ステータス", + "xpack.synthetics.alerts.monitorStatus.actionVariables.availabilityMessage": "{interval}の可用性は{availabilityRatio}%です。{expectedAvailability}%未満のときにアラートを発行します。", + "xpack.synthetics.alerts.monitorStatus.actionVariables.context.alertReasonMessage.description": "アラートの理由の簡潔な説明", + "xpack.synthetics.alerts.monitorStatus.actionVariables.context.downMonitorsWithGeo.description": "アラートによって「ダウン」と検知された一部またはすべてのモニターを示す、生成された概要。", + "xpack.synthetics.alerts.monitorStatus.actionVariables.context.message.description": "現在ダウンしているモニターを要約する生成されたメッセージ。", + "xpack.synthetics.alerts.monitorStatus.actionVariables.context.viewInAppUrl.description": "アラートとコンテキストを調査するために使用できる、Elastic内のビューまたは機能へのリンク", + "xpack.synthetics.alerts.monitorStatus.actionVariables.down": "過去{interval}に{count}回失敗しました。{numTimes}を超えるとアラートを発行します。", + "xpack.synthetics.alerts.monitorStatus.actionVariables.downAndAvailabilityMessage": "{downMonitorsMessage} {availabilityBreachMessage}", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.currentTriggerStarted": "アラートがトリガーされた場合、現在のトリガー状態が開始するときを示すタイムスタンプ", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.firstCheckedAt": "このアラートが最初に確認されるときを示すタイムスタンプ", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.firstTriggeredAt": "このアラートが最初にトリガーされたときを示すタイムスタンプ", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.isTriggered": "アラートが現在トリガーしているかどうかを示すフラグ", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.lastCheckedAt": "アラートの直近の確認時刻を示すタイムスタンプ", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.lastErrorMessage": "最新のエラーメッセージを監視", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.lastResolvedAt": "このアラートの直近の解決を示すタイムスタンプ", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.lastTriggeredAt": "アラートの直近のトリガー時刻を示すタイムスタンプ", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.monitor": "名前、IDS、優先名の人間にとってわかりやすい表示(My Monitorなど)", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.monitorId": "モニターのID。", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.monitorType": "モニターのタイプ(HTTP/TCPなど)。", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.monitorUrl": "モニターのURL。", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.observerHostname": "Heartbeatチェックが実行されるオブザーバーのホスト名。", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.observerLocation": "Heartbeatチェックが実行されるオブザーバーの位置情報。", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.statusMessage": "ステータスメッセージ。例:停止、または可用性チェックの場合は可用性しきい値未満、あるいは両方", + "xpack.synthetics.alerts.monitorStatus.addFilter": "フィルターを追加します", + "xpack.synthetics.alerts.monitorStatus.addFilter.location": "場所", + "xpack.synthetics.alerts.monitorStatus.addFilter.port": "ポート", + "xpack.synthetics.alerts.monitorStatus.addFilter.tag": "タグ", + "xpack.synthetics.alerts.monitorStatus.addFilter.type": "型", + "xpack.synthetics.alerts.monitorStatus.availability.isEnabledCheckbox.label": "可用性", + "xpack.synthetics.alerts.monitorStatus.availability.threshold.anyMonitorDescription": "任意のモニターがアップ", + "xpack.synthetics.alerts.monitorStatus.availability.threshold.ariaLabel": "このアラートの可用性しきい値を指定", + "xpack.synthetics.alerts.monitorStatus.availability.threshold.description": "一致するモニターがアップしています", + "xpack.synthetics.alerts.monitorStatus.availability.threshold.input.ariaLabel": "このアラートで確認する可用性しきい値を入力", + "xpack.synthetics.alerts.monitorStatus.availability.threshold.value": "< チェックの{value}%", + "xpack.synthetics.alerts.monitorStatus.availability.timerangeValueField.ariaLabel": "アラートの可用性チェックの時間単位の数を入力", + "xpack.synthetics.alerts.monitorStatus.availability.timerangeValueField.expression": "最後内", + "xpack.synthetics.alerts.monitorStatus.availability.timerangeValueField.popover.ariaLabel": "可用性追跡時間範囲を指定", + "xpack.synthetics.alerts.monitorStatus.availability.unit.headline": "時間範囲単位を選択します", + "xpack.synthetics.alerts.monitorStatus.availability.unit.selectable": "この選択を使用して、このアラートの可用性範囲単位を設定", + "xpack.synthetics.alerts.monitorStatus.clientName": "稼働状況の監視ステータス", + "xpack.synthetics.alerts.monitorStatus.defaultActionMessage": "{observerLocation}からのurl {monitorUrl}のモニター{monitorName} {statusMessage} 最新のエラーメッセージは{latestErrorMessage}", + "xpack.synthetics.alerts.monitorStatus.description": "監視が停止しているか、可用性しきい値に違反したときにアラートを発行します。", + "xpack.synthetics.alerts.monitorStatus.filterBar.ariaLabel": "監視状態アラートのフィルター基準を許可するインプット", + "xpack.synthetics.alerts.monitorStatus.filters.anyLocation": "任意の場所", + "xpack.synthetics.alerts.monitorStatus.filters.anyPort": "任意のポート", + "xpack.synthetics.alerts.monitorStatus.filters.anyTag": "任意のタグ", + "xpack.synthetics.alerts.monitorStatus.filters.anyType": "任意のタイプ", + "xpack.synthetics.alerts.monitorStatus.filters.from": "開始:", + "xpack.synthetics.alerts.monitorStatus.filters.fromLocation": "開始場所", + "xpack.synthetics.alerts.monitorStatus.filters.location.label": "アラートのクエリに適用する場所フィルターを選択します。", + "xpack.synthetics.alerts.monitorStatus.filters.of": "/", + "xpack.synthetics.alerts.monitorStatus.filters.ofType": "型", + "xpack.synthetics.alerts.monitorStatus.filters.port.label": "アラートのクエリに適用するポートフィルターを選択します。", + "xpack.synthetics.alerts.monitorStatus.filters.scheme.label": "アラートのクエリに適用するプロトコルスキームフィルターを選択します。", + "xpack.synthetics.alerts.monitorStatus.filters.tag.label": "アラートのクエリに適用するタグフィルターを選択します。", + "xpack.synthetics.alerts.monitorStatus.filters.using": "使用", + "xpack.synthetics.alerts.monitorStatus.filters.usingPort": "ポートを使用", + "xpack.synthetics.alerts.monitorStatus.filters.with": "使用", + "xpack.synthetics.alerts.monitorStatus.filters.withTag": "タグを使用", + "xpack.synthetics.alerts.monitorStatus.monitorCallOut.title": "このアラートは約{snapshotCount}個のモニターに適用されます。", + "xpack.synthetics.alerts.monitorStatus.numTimesExpression.anyMonitors.description": "任意のモニターがダウン >", + "xpack.synthetics.alerts.monitorStatus.numTimesExpression.ariaLabel": "ダウンカウントインプットのポップオーバーを開く", + "xpack.synthetics.alerts.monitorStatus.numTimesExpression.matchingMonitors.description": "一致するモニターがダウン >", + "xpack.synthetics.alerts.monitorStatus.numTimesField.ariaLabel": "アラートのトリガーに必要な停止回数を入力します", + "xpack.synthetics.alerts.monitorStatus.oldAlertCallout.title": "古いアラートを編集している可能性があります。一部のフィールドは自動入力されない場合があります。", + "xpack.synthetics.alerts.monitorStatus.recoveryMessage": "url {url}のモニター{monitor}は起動時に回復しました", + "xpack.synthetics.alerts.monitorStatus.statusEnabledCheck.label": "ステータス確認", + "xpack.synthetics.alerts.monitorStatus.timerangeOption.days": "日", + "xpack.synthetics.alerts.monitorStatus.timerangeOption.hours": "時間", + "xpack.synthetics.alerts.monitorStatus.timerangeOption.minutes": "分", + "xpack.synthetics.alerts.monitorStatus.timerangeOption.months": "か月", + "xpack.synthetics.alerts.monitorStatus.timerangeOption.seconds": "秒", + "xpack.synthetics.alerts.monitorStatus.timerangeOption.weeks": "週間", + "xpack.synthetics.alerts.monitorStatus.timerangeOption.years": "年", + "xpack.synthetics.alerts.monitorStatus.timerangeSelectionHeader": "時間範囲単位を選択します", + "xpack.synthetics.alerts.monitorStatus.timerangeUnitExpression.ariaLabel": "時間範囲単位選択フィールドのポップオーバーを開く", + "xpack.synthetics.alerts.monitorStatus.timerangeUnitSelectable": "アラートで使用する時間範囲単位の選択可能フィールド", + "xpack.synthetics.alerts.monitorStatus.timerangeValueExpression.ariaLabel": "時間範囲値フィールドのポップオーバーを開く", + "xpack.synthetics.alerts.monitorStatus.timerangeValueField.ariaLabel": "アラートの範囲のための時間単位の数を入力してください", + "xpack.synthetics.alerts.monitorStatus.timerangeValueField.expression": "within", + "xpack.synthetics.alerts.monitorStatus.timerangeValueField.value": "最終{value}", + "xpack.synthetics.alerts.searchPlaceholder.kql": "KQL構文を使用してフィルタリング", + "xpack.synthetics.alerts.settings.addConnector": "コネクターの追加", + "xpack.synthetics.alerts.timerangeUnitSelectable.daysOption.ariaLabel": "「日」の時間範囲選択項目", + "xpack.synthetics.alerts.timerangeUnitSelectable.hoursOption.ariaLabel": "「時間」の時間範囲選択項目", + "xpack.synthetics.alerts.timerangeUnitSelectable.minutesOption.ariaLabel": "「分」の時間範囲選択項目", + "xpack.synthetics.alerts.timerangeUnitSelectable.monthsOption.ariaLabel": "「月」の時間範囲選択項目", + "xpack.synthetics.alerts.timerangeUnitSelectable.secondsOption.ariaLabel": "「秒」の時間範囲選択項目", + "xpack.synthetics.alerts.timerangeUnitSelectable.weeksOption.ariaLabel": "「週」の時間範囲選択項目", + "xpack.synthetics.alerts.timerangeUnitSelectable.yearsOption.ariaLabel": "「年」の時間範囲選択項目", + "xpack.synthetics.alerts.tls": "アップタイムTLS", + "xpack.synthetics.alerts.tls.actionVariables.state.agingCommonNameAndDate": "検出された証明書の共通名と有効期限日時。", + "xpack.synthetics.alerts.tls.actionVariables.state.agingCount": "検出された古くなりすぎた証明書数。", + "xpack.synthetics.alerts.tls.actionVariables.state.count": "アラート実行によって検出された証明書数", + "xpack.synthetics.alerts.tls.actionVariables.state.expiringCommonNameAndDate": "検出された証明書の共通名と有効期限日時", + "xpack.synthetics.alerts.tls.actionVariables.state.expiringCount": "アラートによって検出された期限切れになる証明書数", + "xpack.synthetics.alerts.tls.ageExpression.ariaLabel": "古い証明書のTLSアラートをトリガーするしきい値を示す式", + "xpack.synthetics.alerts.tls.ageExpression.description": "または", + "xpack.synthetics.alerts.tls.ageExpression.value": "{value}日以内に期限切れになる", + "xpack.synthetics.alerts.tls.agingLabel": "古すぎます", + "xpack.synthetics.alerts.tls.clientName": "アップタイムTLS", + "xpack.synthetics.alerts.tls.criteriaExpression.ariaLabel": "このアラートで監視されるモニターの条件を示す式", + "xpack.synthetics.alerts.tls.criteriaExpression.description": "タイミング", + "xpack.synthetics.alerts.tls.criteriaExpression.value": "任意のモニター", + "xpack.synthetics.alerts.tls.defaultActionMessage": "発行者{issuer}の検出されたTLS証明書{commonName}は{status}です。証明書{summary}\n", + "xpack.synthetics.alerts.tls.description": "アップタイム監視の TLS 証明書の有効期限が近いときにアラートを発行します。", + "xpack.synthetics.alerts.tls.expirationExpression.ariaLabel": "証明書有効期限の TLS アラートをトリガーするしきい値を示す式", + "xpack.synthetics.alerts.tls.expirationExpression.description": "証明書が", + "xpack.synthetics.alerts.tls.expirationExpression.value": "{value}日以内に期限切れになる", + "xpack.synthetics.alerts.tls.expiredLabel": "期限切れ", + "xpack.synthetics.alerts.tls.expiringLabel": "まもなく期限切れ", + "xpack.synthetics.alerts.tls.invalidLabel": "無効", + "xpack.synthetics.alerts.tls.legacy.clientName": "アップタイムTLS(レガシー)", + "xpack.synthetics.alerts.tls.legacy.defaultActionMessage": "期限切れになるか古くなりすぎた{count} TLS個のTLS証明書証明書を検知しました。\n{expiringConditionalOpen}\n期限切れになる証明書数:{expiringCount}\n期限切れになる証明書:{expiringCommonNameAndDate}\n{expiringConditionalClose}\n{agingConditionalOpen}\n古い証明書数:{agingCount}\n古い証明書:{agingCommonNameAndDate}\n{agingConditionalClose}\n", + "xpack.synthetics.alerts.tls.legacy.description": "アップタイム監視の TLS 証明書の有効期限が近いときにアラートを発行します。このアラートは将来のバージョンで廃止予定です。", + "xpack.synthetics.alerts.tls.settingsPageNav.text": "これらのしきい値は{settingsPageLink}で編集できます。", + "xpack.synthetics.alerts.tls.validAfterExpiredString": "{relativeDate}日前、{date}に期限切れになりました。", + "xpack.synthetics.alerts.tls.validAfterExpiringString": "{relativeDate}日以内、{date}に期限切れになります。", + "xpack.synthetics.alerts.tls.validBeforeExpiredString": "{relativeDate}日前、{date}以降有効です。", + "xpack.synthetics.alerts.tls.validBeforeExpiringString": "今から{relativeDate}日間、{date}まで無効です。", + "xpack.synthetics.alerts.tlsLegacy": "アップタイムTLS(レガシー)", + "xpack.synthetics.alerts.toggleAlertFlyoutButtonText": "アラートとルール", + "xpack.synthetics.alertsPopover.toggleButton.ariaLabel": "アラートおよびルールコンテキストメニューを開く", + "xpack.synthetics.analyzeDataButtonLabel": "データの探索", + "xpack.synthetics.analyzeDataButtonLabel.message": "データの探索では、任意のディメンションの結果データを選択してフィルタリングし、パフォーマンスの問題の原因または影響を調査することができます。", + "xpack.synthetics.apmIntegrationAction.description": "このモニターの検索 APM", + "xpack.synthetics.apmIntegrationAction.text": "APMデータを表示", + "xpack.synthetics.availabilityLabelText": "{value} %", + "xpack.synthetics.badge.readOnly.text": "読み取り専用", + "xpack.synthetics.badge.readOnly.tooltip": "を保存できませんでした", + "xpack.synthetics.breadcrumbs.observabilityText": "Observability", + "xpack.synthetics.breadcrumbs.overviewBreadcrumbText": "アップタイム", + "xpack.synthetics.certificates.heading": "TLS証明書({total})", + "xpack.synthetics.certificates.loading": "証明書を読み込んでいます...", + "xpack.synthetics.certificates.refresh": "更新", + "xpack.synthetics.certificatesPage.heading": "TLS証明書", + "xpack.synthetics.certificatesRoute.title": "証明書 | {baseTitle}", + "xpack.synthetics.certs.expired": "期限切れ", + "xpack.synthetics.certs.expires": "有効期限", + "xpack.synthetics.certs.expireSoon": "まもなく期限切れ", + "xpack.synthetics.certs.list.ageCol": "年齢", + "xpack.synthetics.certs.list.commonName": "共通名", + "xpack.synthetics.certs.list.copyFingerprint": "クリックすると、フィンガープリント値をコピーします", + "xpack.synthetics.certs.list.days": "日", + "xpack.synthetics.certs.list.empty": "証明書が見つかりません。注:証明書は Heartbeat 7.8 以上でのみ表示されます。", + "xpack.synthetics.certs.list.expirationDate": "指紋", + "xpack.synthetics.certs.list.issuedBy": "発行者", + "xpack.synthetics.certs.list.monitors": "監視", + "xpack.synthetics.certs.list.status": "ステータス", + "xpack.synthetics.certs.list.status.old": "古すぎます", + "xpack.synthetics.certs.list.validUntil": "有効期限:", + "xpack.synthetics.certs.ok": "OK", + "xpack.synthetics.certs.searchCerts": "証明書を検索", + "xpack.synthetics.certs.status.ok.label": " for {okRelativeDate}", + "xpack.synthetics.charts.mlAnnotation.header": "スコア:{score}", + "xpack.synthetics.charts.mlAnnotation.severity": "深刻度:{severity}", + "xpack.synthetics.controls.selectSeverity.criticalLabel": "致命的", + "xpack.synthetics.controls.selectSeverity.majorLabel": "メジャー", + "xpack.synthetics.controls.selectSeverity.minorLabel": "マイナー", + "xpack.synthetics.controls.selectSeverity.scoreDetailsDescription": "スコア{value}以上", + "xpack.synthetics.controls.selectSeverity.warningLabel": "警告", + "xpack.synthetics.createPackagePolicy.stepConfigure.browser.scriptRecorder.experimentalLabel": "テクニカルプレビュー", + "xpack.synthetics.createPackagePolicy.stepConfigure.browser.scriptRecorder.experimentalTooltip": "Elastic Synthetics Recorderを使用してElastic Synthetics監視スクリプトを作成する最も簡単な方法をプレビュー", + "xpack.synthetics.createPackagePolicy.stepConfigure.browser.scriptRecorder.label": "スクリプトの記録", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.description": "Syntheticsエージェントの微調整された構成を提供します。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.filtering.description": "これらのオプションを使用すると、選択したモニター設定をスイートのテストのサブセットに適用します。構成されたサブセットのみがこのモニターによって実行されます。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.filtering.title": "選択テスト", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.ignoreHttpsErrors.helpText": "このオプションをtrueに設定すると、SyntheticsブラウザーでTLS/SSL検証を無効にします。これは自己署名証明書を使用するサイトのテストで役立ちます。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.ignoreHttpsErrors.label": "HTTPSエラーを無視", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersMatch.helpText": "このモニターの指定されたglobと一致する名前のジャーニーのみを実行します。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersMatch.label": "一致のフィルター", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersTags.helpText": "このモニターの特定のタグのジャーニーのみを実行します。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersTags.label": "タグのフィルター", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.screenshots.helpText": "このオプションを設定すると、Syntheticsエージェントでキャプチャされたスクリーンショットを管理します。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.screenshots.label": "スクリーンショットオプション", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.syntheticsArgs.helpText": "Syntheticsエージェントパッケージに渡す追加の引数。文字列のリストを取ります。これはごくまれなシナリオで有用ですが、通常は設定する必要がありません。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.syntheticsArgs.label": "Synthetics引数", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.automatic_node_cap.message": "スロットリングを無効にするときには、モニターが実行されているSyntheticsノードの構成によって、モニターの帯域幅がまだ制限されます。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.automatic_node_cap.title": "自動制限", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.description": "モニターのダウンロードおよびアップロードの速度、ならびにレイテンシを制御し、低速または遅延しているネットワークでアプリケーションの動作をシミュレートしてください。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.download.error": "ダウンロード速度は0よりも大きい値でなければなりません。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.download.label": "ダウンロード速度", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.exceeded_throttling.message": "Syntheticsノード帯域幅上限より大きいスロットリング値を使用するときには、モニターの帯域幅がまだ制限されます。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.exceeded_throttling.title": "Syntheticsノード帯域幅上限を超えました", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.latency.error": "レイテンシは負数にできません。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.latency.label": "レイテンシ", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.switch.description": "スロットリングを有効にする", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.title": "スロットリングオプション", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.upload.error": "アップロード速度は0よりも大きい値でなければなりません。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.upload.label": "アップロード速度", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.title": "Syntheticsエージェントオプション", + "xpack.synthetics.createPackagePolicy.stepConfigure.certificateSettings.enableSSLSettings.label": "TLS構成を有効にする", + "xpack.synthetics.createPackagePolicy.stepConfigure.certificateSettings.enableZipUrlSSLSettings.label": "Zip URLのTLS構成を有効にする", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificate.helpText": "TLSクライアント認証用のPEM形式の証明書。", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificate.label": "証明書", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificateAuthorities.helpText": "PEM形式のカスタム認証局。", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificateAuthorities.label": "認証局", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificateKey.helpText": "TLSクライアント認証用のPEM形式の証明書鍵。", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificateKey.label": "キー", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificateKeyPassphrase.helpText": "TLSクライアント認証用の証明書鍵パスフレーズ。", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificateKeyPassphrase.label": "鍵パスフレーズ", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.legend": "証明書設定", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.tlsRole.client": "クライアント", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.tlsRole.server": "サーバー", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.certificate.description": "指定された証明書が信頼できる機関(CA)によって署名されていることを検証します。ホスト名検証は実行しません。", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.certificate.label": "証明書", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.full.description": "指定された証明書が信頼できる機関(CA)によって署名されていることを検証し、サーバーのホスト名(またはIPアドレス)が証明書で指定された名前と一致していることも検証します。", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.full.label": "完全", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.label": "認証モード", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.none.description": "サーバーの証明書の検証は実行しません。主に、TLSエラーの解決を試みるときの一時的な診断メカニズムの目的を果たします。本番環境では使用しないことを強くお勧めします。", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.none.label": "なし", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.strict.description": "指定された証明書が信頼できる機関(CA)によって署名されていることを検証し、サーバーのホスト名(またはIPアドレス)が証明書で指定された名前と一致していることも検証します。サブジェクトの別名が空の場合、エラーが返されます。", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.strict.label": "厳密", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.warning.description": "このモードでは、SSL/TLSの多数のセキュリティの利点が無効になります。十分に検討してから使用してください。", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.warning.title": "TLSを無効にしています", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.version.label": "サポートされているTLSプロトコル", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.version.placeholder": "1つ以上TLSプロトコルを選択します。", + "xpack.synthetics.createPackagePolicy.stepConfigure.headerField.addHeader.label": "ヘッダーを追加", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions": "詳細HTTPオプション", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.indexResponseBody.helpText": "HTTP応答本文コンテンツのインデックスを制御します ", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.indexResponseHeaders.helpText": "HTTP応答ヘッダーのインデックスを制御します ", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestBody.helpText": "リクエスト本文コンテンツ。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.description": "方式、本文、ヘッダーを含むリモートホストに送信する任意のリクエストを構成します。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.requestBody": "リクエスト本文", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.requestHeaders": "要求ヘッダー", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.requestMethod.label": "リクエストメソッド", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.title": "リクエスト構成", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestHeadersField.error": "ヘッダーキーは有効なHTTPトークンでなければなりません。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestHeadersField.helpText": "送信する追加のHTTPヘッダーのディクショナリ。デフォルトでは、クライアントを特定するためにユーザーエージェントヘッダーが設定されます。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestMethod.helpText": "使用するHTTP方式。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseBodyCheckNegative.helpText": "本文出力と一致しない正規表現のリスト。Enterキーを押すと、新しい式を追加します。単一の式が一致する場合、一致の失敗が返されます。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseBodyCheckPositive.helpText": "本文出力と一致する正規表現のリスト。Enterキーを押すと、新しい式を追加します。単一の式のみが一致する必要があります。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseCheckNegative.label": "確認応答本文には含まれません", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseCheckPositive.label": "確認応答本文に含まれます", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.checkResponseHeadersContain": "確認応答ヘッダーに含まれます", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.description": "想定されているHTTP応答を構成します。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.responseStatusCheck.error": "ステータスコードには数字のみを使用する必要があります。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.responseStatusCheck.helpText": "想定されているステータスコードのリスト。Enterキーを押すと、新しいコードを追加します。デフォルトでは、4xxおよび5xxコードはダウンと見なされます。他のコードはアップと見なされます。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.responseStatusCheck.label": "確認応答ステータスは等しいです", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.title": "応答チェック", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfig.indexResponseBody": "インデックス応答本文", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfig.indexResponseHeaders": "インデックス応答ヘッダー", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfig.responseBodyIndexPolicy": "応答本文インデックスポリシー", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfiguration.description": "HTTP応答コンテンツのインデックスを制御します。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfiguration.title": "応答構成", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseHeadersField.error": "ヘッダーキーは有効なHTTPトークンでなければなりません。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseHeadersField.helpText": "想定されている応答ヘッダーのリスト。", + "xpack.synthetics.createPackagePolicy.stepConfigure.icmpAdvancedOptions": "詳細ICMPオプション", + "xpack.synthetics.createPackagePolicy.stepConfigure.inputVarFieldOptionalLabel": "オプション", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.helpText": "このモニターのAPMサービス名。service.name ECSフィールドに対応します。APMを使用して、アップタイムとKibanaのAPMデータ間の統合を有効にするアプリを監視しているときには、これを設定します。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.label": "APMサービス名", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.brower.proxyURL.label": "プロキシZip URL", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.http.helpText": "Zip URLのHTTPプロキシ。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.error": "スクリプトが必要です", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.helpText": "インラインで定義されたSyntheticテストスクリプトを実行します。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.label": "インラインスクリプト", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.params.helpText": "テストで必要な変数を定義するJSONオブジェクト。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.params.label": "パラメーター", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.scriptRecorder.closeButtonLabel": "スクリプトフライアウトを閉じる", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.scriptRecorder.mockFileName": "test_script.js", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.sourceType.label": "ソースタイプ", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.fieldLabel": "テストスクリプト", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.invalidFileError": "無効なファイルタイプです。Elastic Synthetics Recorderで生成された.jsファイルをアップロードしてください。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.label": "レコーダーで生成された.jsファイルを選択", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.parsingError": "ファイルのアップロードエラーです。インラインスクリプト形式でElastic Synthetics Recorderによって生成された.jsファイルをアップロードしてください。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.error": "Zip URLは必須です", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.helpText": "Syntheticsプロジェクトリポジトリzipファイルの場所。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.label": "Zip URL", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.recorderLink": "Elastic Synthetics Recorderをダウンロード", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.removeScriptLabel": "スクリプトを削除", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.showScriptLabel": "スクリプトを表示", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlFolder.helpText": "Synthetic journeyファイルが配置されるリポジトリの相対ディレクトリパス。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlFolder.label": "フォルダー", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlPassword.abel": "Zip URLパスワード", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlPassword.helpText": "zipエンドポイントに対して認証するためのパスワード。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlUsername.helpText": "zipエンドポイントに対して認証するためのユーザー名。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlUsername.label": "Zip URLユーザー名", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browserLabel": "ブラウザー(ベータ)", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.enabled.helpText": "この構成をオフにすると、モニターが無効になります。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.enabled.label": "有効", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.icmp.hosts": "ホスト", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.icmp.hosts.error": "ホストは必須です", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.maxRedirects": "最大リダイレクト数", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.maxRedirects.error": "最大リダイレクト数は0以上でなければなりません", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.maxRedirects.helpText": "従うリダイレクトの合計数。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorInterval": "頻度", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorInterval.error": "監視頻度は必須です", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType": "モニタータイプ", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.description": "「Browser」モニターを作成するには、elastic-agent-complete Dockerコンテナーを使用していることを確認します。これには、これらのモニターを実行するための依存関係が含まれています。詳細については、{link}をご覧ください。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.link": "Syntheticsドキュメンテーション", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.error": "モニタータイプは必須です", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.password.helpText": "サーバーと認証するためのパスワード。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.password.label": "パスワード", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyUrl.http.helpText": "HTTPプロキシURL。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyURL.http.label": "プロキシURL", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyURL.label": "プロキシURL", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyUrl.tcp.helpText": "サーバーに接続するときに使用するSOCKS5プロキシのURL。値はURLとスキーマsocks5://でなければなりません。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.resolveHostnamesLocally": "ローカルでホスト名を解決", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tags.helpText": "モニターイベントで送信されるタグのリスト。Enterキーを押すと、新しいタグを追加します。アップタイムに表示され、タグによる検索を有効にします。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tags.label": "タグ", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tcp.hosts": "ホスト:ポート", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tcp.hosts.error": "ホストとポートは必須です", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.helpText": "接続のテストとデータの交換に許可された合計時間。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.label": "タイムアウト(秒)", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.lessThanIntervalError": "タイムアウトは監視頻度未満でなければなりません", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.moreThanZeroError": "タイムアウトは0以上でなければなりません", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.URL": "URL", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.URL.error": "URLが必要です", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.username.helpText": "サーバーと認証するためのユーザー名。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.username.label": "ユーザー名", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.wait.error": "待機時間は0以上でなければなりません", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.wait.helpText": "応答が受信されない場合に、他のICMPエコーリクエストを発行する前に待機する期間。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.wait.label": "待機時間(秒)", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSectionDescription": "次のオプションでモニターを構成します。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSectionTitle": "モニター設定", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBody.codeEditor.javascript.ariaLabel": "JavaScriptコードエディター", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBody.codeEditor.json.ariaLabel": "JSONコードエディター", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBody.codeEditor.text.ariaLabel": "テキストコードエディター", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBody.codeEditor.xml.ariaLabel": "XMLコードエディター", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBody.formField.addFormField.label": "フォームフィールドを追加", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBodyType.form": "フォーム", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBodyType.JSON": "JSON", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBodyType.text": "テキスト", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBodyType.XML": "XML", + "xpack.synthetics.createPackagePolicy.stepConfigure.responseBodyIndex.always": "常に実行", + "xpack.synthetics.createPackagePolicy.stepConfigure.responseBodyIndex.onError": "エラー時", + "xpack.synthetics.createPackagePolicy.stepConfigure.scheduleField.minutes": "分", + "xpack.synthetics.createPackagePolicy.stepConfigure.scheduleField.number": "数字", + "xpack.synthetics.createPackagePolicy.stepConfigure.scheduleField.seconds": "秒", + "xpack.synthetics.createPackagePolicy.stepConfigure.scheduleField.unit": "単位", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.description": "リモートホストに送信されるペイロードを構成します。", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.requestPayload.helpText": "リモートホストに送信するペイロード文字列。", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.requestPayload.label": "リクエストペイロード", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.title": "リクエスト構成", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.responseConfiguration.responseContains.helpText": "想定されたリモートホスト応答。", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.responseConfiguration.responseContains.label": "確認応答には含まれます", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvancedOptions.responseConfiguration.description": "リモートホストから想定された応答を構成します。", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvancedOptions.responseConfiguration.title": "応答チェック", + "xpack.synthetics.createPackagePolicy.stepConfigure.tlsSettings.description": "検証モード、認証局、クライアント証明書を含む、TLSオプションを構成します。", + "xpack.synthetics.createPackagePolicy.stepConfigure.tlsSettings.label": "TLS設定", + "xpack.synthetics.durationChart.emptyPrompt.description": "このモニターは選択された時間範囲で一度も{emphasizedText}していません。", + "xpack.synthetics.durationChart.emptyPrompt.title": "利用可能な期間データがありません", + "xpack.synthetics.editMonitor.pageHeader.title": "モニターを編集", + "xpack.synthetics.editMonitorRoute.title": "モニターを編集 | {baseTitle}", + "xpack.synthetics.emptyState.loadingMessage": "読み込み中…", + "xpack.synthetics.emptyStateError.notAuthorized": "アップタイムデータの表示が承認されていません。システム管理者にお問い合わせください。", + "xpack.synthetics.emptyStateError.notFoundPage": "ページが見つかりません", + "xpack.synthetics.emptyStateError.title": "エラー", + "xpack.synthetics.enableAlert.editAlert": "アラートを編集", + "xpack.synthetics.filterBar.ariaLabel": "概要ページのインプットフィルター基準", + "xpack.synthetics.filterBar.filterAllLabel": "すべて", + "xpack.synthetics.filterBar.options.location.name": "場所", + "xpack.synthetics.filterBar.options.portLabel": "ポート", + "xpack.synthetics.filterBar.options.schemeLabel": "スキーム", + "xpack.synthetics.filterBar.options.tagsLabel": "タグ", + "xpack.synthetics.fleetIntegration.assets.description": "アップタイムでモニターを表示", + "xpack.synthetics.fleetIntegration.assets.name": "監視", + "xpack.synthetics.inspectButtonText": "検査", + "xpack.synthetics.integrationLink.missingDataMessage": "この統合に必要なデータが見つかりませんでした。", + "xpack.synthetics.keyValuePairsField.deleteItem.label": "項目番号{index}、{key}を削除:{value}", + "xpack.synthetics.keyValuePairsField.key.ariaLabel": "キー", + "xpack.synthetics.keyValuePairsField.key.label": "キー", + "xpack.synthetics.keyValuePairsField.value.ariaLabel": "値", + "xpack.synthetics.keyValuePairsField.value.label": "値", + "xpack.synthetics.kueryBar.searchPlaceholder.kql": "KQL構文を使用して、モニターID、名前、タイプ(例:monitor.type: \"http\" AND tags: \"dev\")などを検索", + "xpack.synthetics.kueryBar.searchPlaceholder.simple": "モニターID、名前、またはURL(例:http://)で検索", + "xpack.synthetics.locationName.helpLinkAnnotation": "場所を追加", + "xpack.synthetics.mappingErrorRoute.breadcrumb": "マッピングエラー", + "xpack.synthetics.mappingErrorRoute.pageHeader.title": "マッピングエラー", + "xpack.synthetics.mappingErrorRoute.title": "Synthetics | マッピングエラー", + "xpack.synthetics.millisecond.abbreviation.label": "ms", + "xpack.synthetics.ml.durationChart.exploreInMlApp": "ML アプリで探索", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.add_job_permissions_needed": "権限が必要です", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.anomalyDetectionTitle": "異常検知", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.cancelLabel": "キャンセル", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.createMLJobDescription": "ここでは機械学習ジョブを作成し、\n アップタイム監視の対応期間の異常スコアを計算できます。有効にすると、詳細ページの監視期間グラフには\n 想定された境界が表示され、異常があるグラフに注釈が付けられます。また、\n 地理的な地域にわたって遅延が増える期間を特定することもできます。", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.createNewJobButtonLabel": "新規ジョブを作成", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.disableAnomalyAlert": "異常アラートを無効にする", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.disableAnomalyDetectionTitle": "異常検知を無効にする", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.enable_or_manage_job": "異常検知ジョブを有効にできます。ジョブがすでに存在する場合はジョブまたはアラートを管理できます。", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.enableAnomalyAlert": "異常アラートを有効にする", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.enableAnomalyDetectionTitle": "異常検知を有効にする", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.insufficient_permissions_add_job": "機械学習でこの機能を使用するには、Kibana権限が必要です。", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreatedLazyNotificationText": "分析は機械学習ノードが使用可能になるのを待機しています。応答時間グラフに結果が追加されるまで、しばらく時間がかかる可能性があります。", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreatedNotificationText": "これで応答時間グラフについての分析が実行されます。応答時間グラフに結果が追加されるまで、しばらく時間がかかる可能性があります。", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreatedNotificationText.viewJobLinkText": "ジョブを表示", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreatedNotificationTitle": "ジョブの作成が正常に完了しました", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreationFailedNotificationText": "現在のライセンスでは機械学習ジョブの作成が許可されていないか、ジョブがすでに存在する可能性があります。", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreationFailedNotificationTitle": "ジョブの作成に失敗", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobDeletionConfirmLabel": "異常検知ジョブを削除しますか?", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobDeletionNotificationTitle": "ジョブを削除しました", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobDeletionSuccessNotificationText": "ジョブの削除が正常に完了しました", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.manageAnomalyDetectionTitle": "異常検知を管理", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.manageMLJobDescription": "ジョブの作成後、{mlJobsPageLink} でそれを管理し、詳細を確認できます。", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.manageMLJobDescription.mlJobsPageLinkText": "機械学習ジョブの管理ページ", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.manageMLJobDescription.noteText": "注:ジョブが結果の計算を開始するまでに少し時間がかかる場合があります。", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.noPermissionsTooltip": "異常アラートを作成するには、アップタイムへの読み書きアクセス権が必要です。", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.startTrial": "無料の 14 日トライアルを開始", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.startTrialDesc": "期間異常検知機能を利用するには、Elastic Platinum ライセンスが必要です。", + "xpack.synthetics.monitor.simpleStatusAlert.email.subject": "url {url}のモニター{monitor}はダウンしています", + "xpack.synthetics.monitorCharts.durationChart.leftAxis.title": "期間({unit})", + "xpack.synthetics.monitorCharts.durationChart.wrapper.label": "場所でグループ化された、モニターのping期間を示すグラフ。", + "xpack.synthetics.monitorCharts.monitorDuration.titleLabel": "監視期間", + "xpack.synthetics.monitorCharts.monitorDuration.titleLabelWithAnomaly": "監視期間(異常:{noOfAnomalies})", + "xpack.synthetics.monitorDetails.ml.confirmAlertDeleteMessage": "異常のアラートを削除しますか?", + "xpack.synthetics.monitorDetails.ml.confirmDeleteMessage": "このジョブを削除してよろしいですか?", + "xpack.synthetics.monitorDetails.ml.deleteJobWarning": "ジョブの削除に時間がかかる可能性があります。削除はバックグラウンドで実行され、データの表示がすぐに消えないことがあります。", + "xpack.synthetics.monitorDetails.ml.deleteMessage": "ジョブを削除中...", + "xpack.synthetics.monitorDetails.statusBar.pingType.browser": "ブラウザー", + "xpack.synthetics.monitorDetails.statusBar.pingType.http": "HTTP", + "xpack.synthetics.monitorDetails.statusBar.pingType.icmp": "ICMP", + "xpack.synthetics.monitorDetails.statusBar.pingType.tcp": "TCP", + "xpack.synthetics.monitorDetails.title.disclaimer.description": "(ベータ)", + "xpack.synthetics.monitorDetails.title.disclaimer.link": "詳細を表示", + "xpack.synthetics.monitorDetails.title.pingType.browser": "ブラウザー", + "xpack.synthetics.monitorDetails.title.pingType.http": "HTTP ping", + "xpack.synthetics.monitorDetails.title.pingType.icmp": "ICMP ping", + "xpack.synthetics.monitorDetails.title.pingType.tcp": "TCP ping", + "xpack.synthetics.monitorList.allMonitors": "すべてのモニター", + "xpack.synthetics.monitorList.anomalyColumn.label": "レスポンス異常スコア", + "xpack.synthetics.monitorList.defineConnector.description": "{link}でデフォルトコネクターを定義し、モニターステータスアラートを有効にします。", + "xpack.synthetics.monitorList.defineConnector.popover.description": "ステータスアラートを受信します。", + "xpack.synthetics.monitorList.disableDownAlert": "ステータスアラートを無効にする", + "xpack.synthetics.monitorList.downLineSeries.downLabel": "ダウン", + "xpack.synthetics.monitorList.drawer.missingLocation": "一部の Heartbeat インスタンスには位置情報が定義されていません。Heartbeat 構成への{link}。", + "xpack.synthetics.monitorList.drawer.mostRecentRun": "直近のテスト実行", + "xpack.synthetics.monitorList.drawer.statusRowLocationList": "前回の確認時に\"{status}\"ステータスだった場所のリスト。", + "xpack.synthetics.monitorList.drawer.url": "Url", + "xpack.synthetics.monitorList.enabledAlerts.noAlert": "このモニターではルールが有効ではありません。", + "xpack.synthetics.monitorList.enabledAlerts.title": "有効なルール", + "xpack.synthetics.monitorList.enableDownAlert": "ステータスアラートを有効にする", + "xpack.synthetics.monitorList.errorSummary": "エラー概要", + "xpack.synthetics.monitorList.expandDrawerButton.ariaLabel": "ID {id}のモニターの行を展開", + "xpack.synthetics.monitorList.geoName.helpLinkAnnotation": "場所を追加", + "xpack.synthetics.monitorList.infraIntegrationAction.container.message": "コンテナーメトリックを表示", + "xpack.synthetics.monitorList.infraIntegrationAction.docker.description": "このモニターのコンテナー ID のインフラストラクチャ UI を確認します", + "xpack.synthetics.monitorList.infraIntegrationAction.docker.tooltip": "コンテナー ID「{containerId}」のインフラストラクチャ UI を確認します", + "xpack.synthetics.monitorList.infraIntegrationAction.ip.ariaLabel": "このモニターの IP アドレスのインフラストラクチャ UI を確認します", + "xpack.synthetics.monitorList.infraIntegrationAction.ip.message": "ホストメトリックを表示", + "xpack.synthetics.monitorList.infraIntegrationAction.ip.tooltip": "IP「{ip}」のインフラストラクチャ UI を確認します", + "xpack.synthetics.monitorList.infraIntegrationAction.kubernetes.description": "このモニターのポッド ID のインフラストラクチャ UI を確認します", + "xpack.synthetics.monitorList.infraIntegrationAction.kubernetes.message": "ポッドメトリックを表示", + "xpack.synthetics.monitorList.infraIntegrationAction.kubernetes.tooltip": "ポッド UID「{podUid}」のインフラストラクチャ UI を確認します。", + "xpack.synthetics.monitorList.integrationGroup.emptyMessage": "統合されたアプリケーションがありません", + "xpack.synthetics.monitorList.invalidMonitors": "無効なモニター", + "xpack.synthetics.monitorList.loading": "読み込み中...", + "xpack.synthetics.monitorList.locations.expand": "クリックすると、残りの場所が表示されます", + "xpack.synthetics.monitorList.loggingIntegrationAction.container.id": "コンテナーログを表示", + "xpack.synthetics.monitorList.loggingIntegrationAction.container.message": "コンテナーログを表示", + "xpack.synthetics.monitorList.loggingIntegrationAction.container.tooltip": "コンテナー ID「{containerId}」のロギング UI を確認します", + "xpack.synthetics.monitorList.loggingIntegrationAction.ip.description": "このモニターのIPアドレスのロギングUIを確認", + "xpack.synthetics.monitorList.loggingIntegrationAction.ip.message": "ホストログを表示", + "xpack.synthetics.monitorList.loggingIntegrationAction.ip.tooltip": "IP\"{ip}\"のロギングUIを確認", + "xpack.synthetics.monitorList.loggingIntegrationAction.kubernetes.ariaLabel": "ポッドログを表示", + "xpack.synthetics.monitorList.loggingIntegrationAction.kubernetes.message": "ポッドログを表示", + "xpack.synthetics.monitorList.loggingIntegrationAction.kubernetes.tooltip": "ポッド UID「{podUid}」のログを確認します", + "xpack.synthetics.monitorList.monitorHistoryColumnLabel": "ダウンタイム履歴", + "xpack.synthetics.monitorList.monitoringStatusTitle": "監視", + "xpack.synthetics.monitorList.monitorType.filter": "タイプ {type} ですべての監視をフィルター", + "xpack.synthetics.monitorList.mostRecentError.title": "直近のエラー({timestamp})", + "xpack.synthetics.monitorList.nameColumnLabel": "名前", + "xpack.synthetics.monitorList.noDownHistory": "このモニターは選択された時間範囲で一度も{emphasizedText}していません。", + "xpack.synthetics.monitorList.noItemForSelectedFiltersMessage": "選択されたフィルター条件でモニターが見つかりませんでした", + "xpack.synthetics.monitorList.noItemMessage": "アップタイムモニターが見つかりません", + "xpack.synthetics.monitorList.observabilityIntegrationsColumn.apmIntegrationLink.tooltip": "ここをクリックすると、APMのドメイン「{domain}」、または明示的に定義された「サービス名」を確認します。", + "xpack.synthetics.monitorList.observabilityIntegrationsColumn.popoverIconButton.ariaLabel": "URL {monitorUrl}で監査のための移行ポップオーバーを開く", + "xpack.synthetics.monitorList.observabilityInvestigateColumn.popoverIconButton.label": "調査", + "xpack.synthetics.monitorList.pageSizePopoverButtonText": "ページあたりの行数:{size}", + "xpack.synthetics.monitorList.pageSizeSelect.numRowsItemMessage": "{numRows}行", + "xpack.synthetics.monitorList.redirects.description": "Pingの実行中にHeartbeatは{number}リダイレクトに従いました。", + "xpack.synthetics.monitorList.redirects.openWindow": "リンクは新しいウィンドウで開きます。", + "xpack.synthetics.monitorList.redirects.title": "リダイレクト", + "xpack.synthetics.monitorList.redirects.title.number": "{number}", + "xpack.synthetics.monitorList.refresh": "更新", + "xpack.synthetics.monitorList.statusAlert.label": "ステータスアラート", + "xpack.synthetics.monitorList.statusColumn.checkedTimestamp": "チェック済み{timestamp}", + "xpack.synthetics.monitorList.statusColumn.completeLabel": "完了", + "xpack.synthetics.monitorList.statusColumn.downLabel": "ダウン", + "xpack.synthetics.monitorList.statusColumn.error.logs": "エラーログ", + "xpack.synthetics.monitorList.statusColumn.error.message": "{message}。詳細はクリックしてください。", + "xpack.synthetics.monitorList.statusColumn.error.messageLabel": "{message}。詳細はクリックしてください。", + "xpack.synthetics.monitorList.statusColumn.failedLabel": "失敗", + "xpack.synthetics.monitorList.statusColumn.locStatusMessage": "場所 {noLoc} か所", + "xpack.synthetics.monitorList.statusColumn.locStatusMessage.multiple": "場所 {noLoc} か所", + "xpack.synthetics.monitorList.statusColumn.locStatusMessage.tooltip.down": "{locs} でダウン", + "xpack.synthetics.monitorList.statusColumn.locStatusMessage.tooltip.up": "{locs} でアップ", + "xpack.synthetics.monitorList.statusColumn.upLabel": "アップ", + "xpack.synthetics.monitorList.statusColumnLabel": "ステータス", + "xpack.synthetics.monitorList.table.description": "列にステータス、名前、URL、IP、ダウンタイム履歴、統合が入力されたモニターステータス表です。この表は現在 {length} 項目を表示しています。", + "xpack.synthetics.monitorList.table.tags.name": "タグ", + "xpack.synthetics.monitorList.table.url.name": "Url", + "xpack.synthetics.monitorList.tags.expand": "クリックすると、残りのタグが表示されます", + "xpack.synthetics.monitorList.tags.filter": "タグ {tag} ですべての監視をフィルター", + "xpack.synthetics.monitorList.testNow.AriaLabel": "クリックすると今すぐテストを実行します", + "xpack.synthetics.monitorList.testNow.available": "現在、テストはモニター管理で追加されたモニターでのみ使用できます。", + "xpack.synthetics.monitorList.testNow.label": "今すぐテストを実行", + "xpack.synthetics.monitorList.testNow.scheduled": "テストはすでにスケジュールされています", + "xpack.synthetics.monitorList.testRunLogs": "テスト実行ログ", + "xpack.synthetics.monitorList.timestamp": "タイムスタンプ", + "xpack.synthetics.monitorList.tlsColumnLabel": "TLS 証明書", + "xpack.synthetics.monitorList.viewInDiscover": "Discoverに表示", + "xpack.synthetics.monitorManagement.addMonitorCrumb": "モニターを追加", + "xpack.synthetics.monitorManagement.addMonitorError": "サービスの場所を読み込めませんでした。しばらくたってから再試行してください。", + "xpack.synthetics.monitorManagement.addMonitorLabel": "モニターを追加", + "xpack.synthetics.monitorManagement.addMonitorLoadingError": "モニター管理の読み込みエラー", + "xpack.synthetics.monitorManagement.addMonitorLoadingLabel": "モニター管理を読み込んでいます", + "xpack.synthetics.monitorManagement.addMonitorServiceLocationsLoadingError": "サービスの場所を読み込めませんでした。しばらくたってから再試行してください。", + "xpack.synthetics.monitorManagement.apiKeysDisabledToolTip": "このクラスターのAPIキーが無効です。モニター管理では、Elasticsearchクラスターに書き込むためにAPIキーを使用する必要があります。APIキーを有効にするには、管理者に連絡してください。", + "xpack.synthetics.monitorManagement.callout.description.disabled": "モニター管理は現在無効です。Elasticで管理されたSyntheticsサービスでモニターを実行するには、モニター管理を有効にします。既存のモニターが一時停止しています。", + "xpack.synthetics.monitorManagement.callout.disabled": "モニター管理が無効です", + "xpack.synthetics.monitorManagement.callout.disabled.adminContact": "モニター管理を有効にするには、管理者に連絡してください。", + "xpack.synthetics.monitorManagement.closeButtonLabel": "閉じる", + "xpack.synthetics.monitorManagement.completed": "完了", + "xpack.synthetics.monitorManagement.confirmDescriptionLabel": "このアクションにより、モニターが削除されますが、収集されたデータはすべて保持されます。この操作は元に戻すことができません。", + "xpack.synthetics.monitorManagement.deleteMonitorLabel": "モニターの削除", + "xpack.synthetics.monitorManagement.disableMonitorLabel": "モニターを無効にする", + "xpack.synthetics.monitorManagement.discardLabel": "破棄", + "xpack.synthetics.monitorManagement.duplicateNameError": "モニター名はすでに存在します。", + "xpack.synthetics.monitorManagement.editMonitorCrumb": "モニターを編集", + "xpack.synthetics.monitorManagement.editMonitorError": "モニター管理の読み込みエラー", + "xpack.synthetics.monitorManagement.editMonitorError.description": "モニター管理設定を読み込めませんでした。サポートに問い合わせてください。", + "xpack.synthetics.monitorManagement.editMonitorErrorBody": "モニター構成を読み込めませんでした。しばらくたってから再試行してください。", + "xpack.synthetics.monitorManagement.editMonitorLabel": "モニターを編集", + "xpack.synthetics.monitorManagement.editMonitorLoadingLabel": "モニターを読み込んでいます", + "xpack.synthetics.monitorManagement.emptyState.enablement": "モニター管理を有効にすると、世界中のホスティングされたテスト場所から軽量でリアルなブラウザーモニターを実行できます。モニター管理を有効にすると、APIキーが生成され、SyntheticsサービスはElasticsearchクラスターに書き込むことができます。", + "xpack.synthetics.monitorManagement.emptyState.enablement.disabled.title": "モニター管理が無効です", + "xpack.synthetics.monitorManagement.emptyState.enablement.disabledDescription": "モニター管理は現在無効です。モニター管理では、世界中のホスティングされたテスト場所から軽量のチェックとリアルなブラウザーモニターを実行できます。モニター管理を有効にするには、管理者に連絡してください。", + "xpack.synthetics.monitorManagement.emptyState.enablement.doc": "ドキュメントを読む", + "xpack.synthetics.monitorManagement.emptyState.enablement.enabled.title": "モニター管理を有効にする", + "xpack.synthetics.monitorManagement.emptyState.enablement.learnMore": "詳細について", + "xpack.synthetics.monitorManagement.emptyState.enablement.title": "有効にする", + "xpack.synthetics.monitorManagement.enableMonitorLabel": "モニターを有効にする", + "xpack.synthetics.monitorManagement.failed": "失敗", + "xpack.synthetics.monitorManagement.failedRun": "ステップを実行できませんでした", + "xpack.synthetics.monitorManagement.inProgress": "進行中", + "xpack.synthetics.monitorManagement.label": "モニター管理", + "xpack.synthetics.monitorManagement.loading.label": "モニター管理を読み込んでいます", + "xpack.synthetics.monitorManagement.loadingSteps": "ステップを読み込んでいます...", + "xpack.synthetics.monitorManagement.manageMonitorLoadingLabel": "モニター管理を読み込んでいます", + "xpack.synthetics.monitorManagement.manageMonitorLoadingLabel.callout.learnMore": "詳細情報", + "xpack.synthetics.monitorManagement.monitorAddedSuccessMessage": "モニターが正常に追加されました。", + "xpack.synthetics.monitorManagement.monitorAdvancedOptions.dataStreamConfiguration.description": "追加のデータストリームオプションを構成します。", + "xpack.synthetics.monitorManagement.monitorAdvancedOptions.dataStreamConfiguration.title": "データストリーム設定", + "xpack.synthetics.monitorManagement.monitorAdvancedOptions.monitorNamespaceFieldLabel": "名前空間", + "xpack.synthetics.monitorManagement.monitorAdvancedOptions.namespaceHelpLabel": "デフォルト名前空間を変更します。この設定により、モニターのデータストリームの名前が変更されます。{learnMore}。", + "xpack.synthetics.monitorManagement.monitorAdvancedOptions.namespaceHelpLearnMoreLabel": "詳細情報", + "xpack.synthetics.monitorManagement.monitorDeleteFailureMessage": "モニターを削除できませんでした。しばらくたってから再試行してください。", + "xpack.synthetics.monitorManagement.monitorDeleteLoadingMessage": "モニターを削除しています...", + "xpack.synthetics.monitorManagement.monitorDeleteSuccessMessage": "モニターが正常に削除されました。", + "xpack.synthetics.monitorManagement.monitorDisabledSuccessMessage": "モニター{name}は正常に無効にされました。", + "xpack.synthetics.monitorManagement.monitorEditedSuccessMessage": "モニターは正常に更新されました。", + "xpack.synthetics.monitorManagement.monitorEnabledSuccessMessage": "モニター{name}は正常に有効にされました。", + "xpack.synthetics.monitorManagement.monitorEnabledUpdateFailureMessage": "モニター{name}を更新できません。", + "xpack.synthetics.monitorManagement.monitorFailureMessage": "モニターを保存できませんでした。しばらくたってから再試行してください。", + "xpack.synthetics.monitorManagement.monitorList.actions": "アクション", + "xpack.synthetics.monitorManagement.monitorList.enabled": "有効", + "xpack.synthetics.monitorManagement.monitorList.locations": "場所", + "xpack.synthetics.monitorManagement.monitorList.monitorName": "モニター名", + "xpack.synthetics.monitorManagement.monitorList.monitorType": "モニタータイプ", + "xpack.synthetics.monitorManagement.monitorList.schedule": "頻度(分)", + "xpack.synthetics.monitorManagement.monitorList.tags": "タグ", + "xpack.synthetics.monitorManagement.monitorList.title": "モニター管理リスト", + "xpack.synthetics.monitorManagement.monitorList.URL": "URL", + "xpack.synthetics.monitorManagement.monitorLocationsLabel": "モニターの場所", + "xpack.synthetics.monitorManagement.monitorManagementCrumb": "モニター管理", + "xpack.synthetics.monitorManagement.monitorNameFieldError": "モニター名は必須です", + "xpack.synthetics.monitorManagement.monitorNameFieldLabel": "モニター名", + "xpack.synthetics.monitorManagement.monitorSync.failure.content": "1つ以上の場所でモニターを同期するときに問題が発生しました。", + "xpack.synthetics.monitorManagement.monitorSync.failure.dismissLabel": "閉じる", + "xpack.synthetics.monitorManagement.monitorSync.failure.reasonLabel": "理由", + "xpack.synthetics.monitorManagement.monitorSync.failure.statusLabel": "ステータス", + "xpack.synthetics.monitorManagement.monitorSync.failure.title": "モニターをSyntheticsサービスと同期できませんでした", + "xpack.synthetics.monitorManagement.noLabel": "キャンセル", + "xpack.synthetics.monitorManagement.pageHeader.title": "モニターの管理", + "xpack.synthetics.monitorManagement.pending": "保留中", + "xpack.synthetics.monitorManagement.publicBetaDescription": "選択した一般ベータユーザーでのみモニター管理を使用できます。一般\nベータアクセスでは、HTTP、TCP、ICMPを追加できます。ブラウザーは\nElasticで管理されたSyntheticsサービスノードでどれが実行されるのかを確認します。", + "xpack.synthetics.monitorManagement.requestAccess": "アクセスをリクエストする", + "xpack.synthetics.monitorManagement.reRunTest": "テストの再実行", + "xpack.synthetics.monitorManagement.runTest": "テストの実行", + "xpack.synthetics.monitorManagement.saveMonitorLabel": "モニターを保存", + "xpack.synthetics.monitorManagement.service.error.message": "モニターは保存されますが、{location}の構成の同期中に問題が発生しました。しばらくたってから自動的に再試行されます。問題が解決しない場合は、{location}でのモニターの実行が停止します。ヘルプについては、サポートに問い合わせてください。", + "xpack.synthetics.monitorManagement.service.error.reason": "理由:{reason}。", + "xpack.synthetics.monitorManagement.service.error.status": "ステータス:{status}。", + "xpack.synthetics.monitorManagement.service.error.title": "モニター構成を同期できません", + "xpack.synthetics.monitorManagement.serviceLocationsValidationError": "1つ以上のサービスの場所を指定する必要があります", + "xpack.synthetics.monitorManagement.stepCompleted": "{stepCount, number} {stepCount, plural, other {個のステップ}}が完了しました", + "xpack.synthetics.monitorManagement.syntheticsDisabled": "モニター管理は現在無効です。モニター管理を有効にするには、管理者に連絡してください。", + "xpack.synthetics.monitorManagement.syntheticsDisabledFailure": "モニター管理を無効にできませんでした。サポートに問い合わせてください。", + "xpack.synthetics.monitorManagement.syntheticsDisabledSuccess": "モニター管理は正常に無効にされました。", + "xpack.synthetics.monitorManagement.syntheticsDisableToolTip": "モニター管理を無効にすると、すべてのテスト場所でモニターの実行が即時停止され、新しいモニターの作成が防止されます。", + "xpack.synthetics.monitorManagement.syntheticsEnabledFailure": "モニター管理を有効にできませんでした。サポートに問い合わせてください。", + "xpack.synthetics.monitorManagement.syntheticsEnableLabel": "有効にする", + "xpack.synthetics.monitorManagement.syntheticsEnableLabel.management": "モニター管理を有効にする", + "xpack.synthetics.monitorManagement.syntheticsEnableSuccess": "モニター管理は正常に有効にされました。", + "xpack.synthetics.monitorManagement.syntheticsEnableToolTip": "モニター管理を有効にすると、世界中の場所から軽量でリアルなブラウザーモニターを作成できます。", + "xpack.synthetics.monitorManagement.testResult": "テスト結果", + "xpack.synthetics.monitorManagement.timeTaken": "かかった時間{timeTaken}", + "xpack.synthetics.monitorManagement.updateMonitorLabel": "モニターの更新", + "xpack.synthetics.monitorManagement.validationError": "モニターにはエラーがあります。保存前に修正してください。", + "xpack.synthetics.monitorManagement.viewTestRunDetails": "テスト結果詳細を表示", + "xpack.synthetics.monitorManagement.yesLabel": "削除", + "xpack.synthetics.monitorManagementRoute.title": "モニターの管理 | {baseTitle}", + "xpack.synthetics.monitorRoute.title": "モニター | {baseTitle}", + "xpack.synthetics.monitorStatusBar.durationTextAriaLabel": "ミリ秒単位の監視時間", + "xpack.synthetics.monitorStatusBar.healthStatusMessageAriaLabel": "監視ステータス", + "xpack.synthetics.monitorStatusBar.loadingMessage": "読み込み中…", + "xpack.synthetics.monitorStatusBar.locations.oneLocStatus": "{loc}場所での{status}", + "xpack.synthetics.monitorStatusBar.locations.upStatus": "{loc}場所での{status}", + "xpack.synthetics.monitorStatusBar.monitor.availability": "全体的な可用性", + "xpack.synthetics.monitorStatusBar.monitor.availabilityReport.availability": "可用性", + "xpack.synthetics.monitorStatusBar.monitor.availabilityReport.lastCheck": "最終確認", + "xpack.synthetics.monitorStatusBar.monitor.availabilityReport.location": "場所", + "xpack.synthetics.monitorStatusBar.monitor.id": "監視ID", + "xpack.synthetics.monitorStatusBar.monitor.monitoringFrom": "監視元", + "xpack.synthetics.monitorStatusBar.monitor.monitoringFrom.listToMap": "マップビューに変更し、場所別に可用性を確認します。", + "xpack.synthetics.monitorStatusBar.monitor.monitoringFrom.MapToList": "リストビューに変更し、場所別に可用性を確認します。", + "xpack.synthetics.monitorStatusBar.monitorUrlLinkAriaLabel": "監視 URL リンク", + "xpack.synthetics.monitorStatusBar.sslCertificate.title": "TLS 証明書", + "xpack.synthetics.monitorStatusBar.timestampFromNowTextAriaLabel": "最終確認からの経過時間", + "xpack.synthetics.monitorStatusBar.type.ariaLabel": "モニタータイプ", + "xpack.synthetics.monitorStatusBar.type.label": "型", + "xpack.synthetics.navigateToAlertingButton.content": "ルールの管理", + "xpack.synthetics.navigateToAlertingUi": "Uptime を離れてアラート管理ページに移動します", + "xpack.synthetics.noDataConfig.beatsCard.description": "サイトとサービスの可用性をアクティブに監視するアラートを受信し、問題をより迅速に解決して、ユーザーエクスペリエンスを最適化します。", + "xpack.synthetics.noDataConfig.beatsCard.title": "Heartbeatでモニターを追加", + "xpack.synthetics.noDataConfig.solutionName": "Observability", + "xpack.synthetics.notFountPage.homeLinkText": "ホームへ戻る", + "xpack.synthetics.openAlertContextPanel.ariaLabel": "ルールコンテキストパネルを開くと、ルールタイプを選択できます", + "xpack.synthetics.openAlertContextPanel.label": "ルールを作成", + "xpack.synthetics.overview.alerts.disabled.failed": "ルールを無効にできません。", + "xpack.synthetics.overview.alerts.disabled.success": "ルールが正常に無効にされました。", + "xpack.synthetics.overview.alerts.enabled.failed": "ルールを有効にできません。", + "xpack.synthetics.overview.alerts.enabled.success": "ルールが正常に有効にされました。 ", + "xpack.synthetics.overview.alerts.enabled.success.description": "この監視が停止しているときには、メッセージが {actionConnectors} に送信されます。", + "xpack.synthetics.overview.heading": "監視", + "xpack.synthetics.overview.pageHeader.syntheticsCallout.announcementLink": "お知らせを読む", + "xpack.synthetics.overview.pageHeader.syntheticsCallout.content": "アップタイムは、スクリプト化された複数ステップの可用性チェックのサポートをプレビューしています。つまり、単に単一のページのアップ/ダウンのチェックだけではなく、Webページの要素を操作したり、全体的な可用性を確認したりできます(購入やシステムへのサインインなど)。詳細については以下をクリックしてください。これらの機能を先駆けて使用したい場合は、プレビュー合成エージェントをダウンロードし、アップタイムでチェックを表示できます。", + "xpack.synthetics.overview.pageHeader.syntheticsCallout.dismissButtonText": "閉じる", + "xpack.synthetics.overview.pageHeader.syntheticsCallout.title": "Elastic Synthetics", + "xpack.synthetics.overviewPage.headerText": "概要", + "xpack.synthetics.overviewPageLink.disabled.ariaLabel": "無効になったページ付けボタンです。モニターリストがこれ以上ナビゲーションできないことを示しています。", + "xpack.synthetics.overviewPageLink.next.ariaLabel": "次の結果ページ", + "xpack.synthetics.overviewPageLink.prev.ariaLabel": "前の結果ページ", + "xpack.synthetics.page_header.addDataLink.label": "アップタイムデータの追加に関するチュートリアルに移動", + "xpack.synthetics.page_header.analyzeData.label": "[データの探索]ビューに移動して、合成/ユーザーデータを可視化", + "xpack.synthetics.page_header.defineConnector.popover.defaultLink": "デフォルトのコネクターを定義", + "xpack.synthetics.page_header.defineConnector.settingsLink": "設定", + "xpack.synthetics.page_header.manageLink.label": "アップタイムモニター管理ページに移動", + "xpack.synthetics.page_header.settingsLink": "設定", + "xpack.synthetics.page_header.settingsLink.label": "アップタイム設定ページに移動", + "xpack.synthetics.pingHistogram.analyze": "分析", + "xpack.synthetics.pingist.durationSecondsColumnFormatting": "{seconds}秒", + "xpack.synthetics.pingist.durationSecondsColumnFormatting.singular": "{seconds}秒", + "xpack.synthetics.pingList.checkHistoryTitle": "履歴", + "xpack.synthetics.pingList.collapseRow": "縮小", + "xpack.synthetics.pingList.columns.failedStep": "失敗したステップ", + "xpack.synthetics.pingList.drawer.body.docsLink": "ドキュメント", + "xpack.synthetics.pingList.durationMsColumnFormatting": "{millis}ミリ秒", + "xpack.synthetics.pingList.durationMsColumnLabel": "期間", + "xpack.synthetics.pingList.errorColumnLabel": "エラー", + "xpack.synthetics.pingList.errorTypeColumnLabel": "エラータイプ", + "xpack.synthetics.pingList.expandedRow.bodySize": "本文サイズは {bodyBytes} です。", + "xpack.synthetics.pingList.expandedRow.error": "エラー", + "xpack.synthetics.pingList.expandedRow.response_body": "応答本文", + "xpack.synthetics.pingList.expandedRow.response_body.notRecorded": "本文が記録されていません。応答本文の記録に関する詳細は、{docsLink}をお読みください。", + "xpack.synthetics.pingList.expandedRow.truncated": "初めの {contentBytes} バイトを表示中。", + "xpack.synthetics.pingList.expandRow": "拡張", + "xpack.synthetics.pingList.headers.title": "応答ヘッダー", + "xpack.synthetics.pingList.ipAddressColumnLabel": "IP", + "xpack.synthetics.pingList.locationNameColumnLabel": "場所", + "xpack.synthetics.pingList.pingsLoadingMesssage": "履歴を読み込んでいます...", + "xpack.synthetics.pingList.pingsUnavailableMessage": "履歴が見つかりません", + "xpack.synthetics.pingList.recencyMessage": "最終確認 {fromNow}", + "xpack.synthetics.pingList.responseCodeColumnLabel": "応答コード", + "xpack.synthetics.pingList.statusColumnLabel": "ステータス", + "xpack.synthetics.pingList.stepDurationHeader": "ステップ期間", + "xpack.synthetics.pingList.synthetics.performanceBreakDown": "パフォーマンスの内訳を表示", + "xpack.synthetics.pingList.synthetics.waterfall.filters.collapseRequestsLabel": "折りたたむと、一致する要求のみが表示されます", + "xpack.synthetics.pingList.synthetics.waterfall.filters.popover": "クリックすると、ウォーターフォールフィルターが開きます", + "xpack.synthetics.pingList.timestampColumnLabel": "タイムスタンプ", + "xpack.synthetics.pluginDescription": "アップタイム監視", + "xpack.synthetics.public.pages.mappingError.bodyDocsLink": "この問題のトラブルシューティングについては、{docsLink}を参照してください。", + "xpack.synthetics.public.pages.mappingError.bodyMessage": "正しくないマッピングが検出されました。Heartbeat {setup}コマンドを実行していない可能性があります。", + "xpack.synthetics.public.pages.mappingError.title": "Heartbeatマッピングが見つかりません", + "xpack.synthetics.routes.baseTitle": "アップタイム - Kibana", + "xpack.synthetics.seconds.label": "秒", + "xpack.synthetics.seconds.shortForm.label": "秒", + "xpack.synthetics.settings.blank.error": "空白にすることはできません。", + "xpack.synthetics.settings.blankNumberField.error": "数値でなければなりません。", + "xpack.synthetics.settings.cannotEditText": "現在、このユーザーには Uptime アプリの「読み取り」権があります。これらの設定を編集するには「すべて」のパーミッションレベルを有効にします。", + "xpack.synthetics.settings.cannotEditTitle": "設定を編集するパーミッションがありません。", + "xpack.synthetics.settings.error.couldNotSave": "設定を保存できませんでした!", + "xpack.synthetics.settings.heading": "アップタイム設定", + "xpack.synthetics.settings.invalid.error": "値は0よりも大きい値でなければなりません。", + "xpack.synthetics.settings.invalid.nanError": "値は整数でなければなりません。", + "xpack.synthetics.settings.noSpace.error": "インデックス名にはスペースを使用できません", + "xpack.synthetics.settings.saveSuccess": "設定が保存されました。", + "xpack.synthetics.settingsBreadcrumbText": "設定", + "xpack.synthetics.settingsRoute.title": "設定 | {baseTitle}", + "xpack.synthetics.snapshot.donutChart.ariaLabel": "現在のステータスを表す円グラフ、{total} 個中 {down} 個のモニターがダウンしています。", + "xpack.synthetics.snapshot.monitor": "監視", + "xpack.synthetics.snapshot.monitors": "監視", + "xpack.synthetics.snapshot.noDataDescription": "選択した時間範囲に ping はありません。", + "xpack.synthetics.snapshot.noDataTitle": "利用可能な ping データがありません", + "xpack.synthetics.snapshot.pingsOverTimeTitle": "一定時間のピング", + "xpack.synthetics.snapshotHistogram.description": "{startTime} から {endTime} までの期間のアップタイムステータスを表示する棒グラフです。", + "xpack.synthetics.snapshotHistogram.series.pings": "モニター接続確認", + "xpack.synthetics.snapshotHistogram.xAxisId": "ピング X 軸", + "xpack.synthetics.snapshotHistogram.yAxis.title": "ピング", + "xpack.synthetics.snapshotHistogram.yAxisId": "ピングY軸", + "xpack.synthetics.sourceConfiguration.ageLimit.units.days": "日", + "xpack.synthetics.sourceConfiguration.ageLimitThresholdInput.ariaLabel": "TLS証明書が有効である最大日数を制御するインプット。この期間を過ぎると、Kibanaで警告が表示されます。", + "xpack.synthetics.sourceConfiguration.ageThresholdDefaultValue": "デフォルト値は{defaultValue}です", + "xpack.synthetics.sourceConfiguration.alertConnectors": "アラートコネクター", + "xpack.synthetics.sourceConfiguration.alertConnectors.defaultEmail": "デフォルトの電子メールアドレス", + "xpack.synthetics.sourceConfiguration.alertDefaultForm.emailConnectorPlaceHolder": "終了:電子メールコネクターの電子メールアドレス", + "xpack.synthetics.sourceConfiguration.alertDefaultForm.invalidEmail": "{val}は有効な電子メールアドレスではありません。", + "xpack.synthetics.sourceConfiguration.alertDefaultForm.requiredEmail": "電子メールコネクターには宛先電子メールアドレスが必須です", + "xpack.synthetics.sourceConfiguration.alertDefaultForm.selectConnector": "1つ以上のコネクターを選択してください", + "xpack.synthetics.sourceConfiguration.alertDefaults": "アラートデフォルト", + "xpack.synthetics.sourceConfiguration.applySettingsButtonLabel": "変更を適用", + "xpack.synthetics.sourceConfiguration.certificateExpirationThresholdInput.ariaLabel": "TLS証明書の満了日までの最小日数を制御するインプット。この期間を過ぎると、Kibanaで警告が表示されます。", + "xpack.synthetics.sourceConfiguration.certificateThresholdDescription": "証明書エラーを表示し、アラートを通知するしきい値を変更します。注:すべての構成されたアラートに影響します。", + "xpack.synthetics.sourceConfiguration.certificationSectionTitle": "証明書の有効期限", + "xpack.synthetics.sourceConfiguration.defaultConnectors": "デフォルトコネクター", + "xpack.synthetics.sourceConfiguration.defaultConnectors.description": "アラートを送信するために使用されるデフォルトコネクター。", + "xpack.synthetics.sourceConfiguration.defaultConnectors.description.defaultEmail": "選択した電子メールアラートコネクターには電子メール設定が必須です。", + "xpack.synthetics.sourceConfiguration.discardSettingsButtonLabel": "キャンセル", + "xpack.synthetics.sourceConfiguration.errorStateLabel": "有効期限しきい値", + "xpack.synthetics.sourceConfiguration.expirationThreshold": "有効期限/使用期間しきい値", + "xpack.synthetics.sourceConfiguration.expirationThresholdDefaultValue": "デフォルト値は{defaultValue}です", + "xpack.synthetics.sourceConfiguration.heartbeatIndicesDefaultValue": "デフォルト値は{defaultValue}です", + "xpack.synthetics.sourceConfiguration.heartbeatIndicesDescription": "Heartbeat データを含むインデックス照合用のインデックスパターン", + "xpack.synthetics.sourceConfiguration.heartbeatIndicesLabel": "Heartbeat インデックス", + "xpack.synthetics.sourceConfiguration.heartbeatIndicesTitle": "アップタイムインデックス", + "xpack.synthetics.sourceConfiguration.indicesSectionTitle": "インデックス", + "xpack.synthetics.sourceConfiguration.warningStateLabel": "使用期間上限", + "xpack.synthetics.stepDetailRoute.title": "Synthetics詳細 | {baseTitle}", + "xpack.synthetics.stepList.collapseRow": "縮小", + "xpack.synthetics.stepList.expandRow": "拡張", + "xpack.synthetics.stepList.stepName": "ステップ名", + "xpack.synthetics.synthetics.consoleStepList.message": "実行できませんでした。記録されたコンソール出力は次のとおりです。", + "xpack.synthetics.synthetics.consoleStepList.title": "ステップが実行されませんでした", + "xpack.synthetics.synthetics.emptyJourney.message.checkGroupField": "チェックグループは{codeBlock}です。", + "xpack.synthetics.synthetics.emptyJourney.message.footer": "表示する詳細情報はありません。", + "xpack.synthetics.synthetics.emptyJourney.message.heading": "ステップが含まれていませんでした。", + "xpack.synthetics.synthetics.emptyJourney.title": "ステップがありません。", + "xpack.synthetics.synthetics.executedStep.consoleOutput.label": "コンソール出力", + "xpack.synthetics.synthetics.executedStep.errorHeading": "エラーメッセージ", + "xpack.synthetics.synthetics.executedStep.screenshot.not": "スクリーンショット", + "xpack.synthetics.synthetics.executedStep.screenshot.notSucceeded": "{status}チェックのスクリーンショット", + "xpack.synthetics.synthetics.executedStep.screenshot.success": "前回成功したチェック", + "xpack.synthetics.synthetics.executedStep.screenshot.successfulLink": "{link}からのスクリーンショット", + "xpack.synthetics.synthetics.executedStep.scriptHeading.label": "このステップで実行されたスクリプト", + "xpack.synthetics.synthetics.executedStep.stackTrace": "スタックトレース", + "xpack.synthetics.synthetics.imageLoadingSpinner.ariaLabel": "画像を示すアニメーションスピナーを読み込んでいます", + "xpack.synthetics.synthetics.journey.allFailedMessage": "{total}ステップ - すべて失敗またはスキップされました", + "xpack.synthetics.synthetics.journey.allSucceededMessage": "{total}ステップ - すべて成功しました", + "xpack.synthetics.synthetics.journey.loadingSteps": "ステップを読み込んでいます...", + "xpack.synthetics.synthetics.journey.partialSuccessMessage": "{total}ステップ - {succeeded}成功しました", + "xpack.synthetics.synthetics.markers.explore": "探索", + "xpack.synthetics.synthetics.markers.noFieldIcon.label": "このマーカーにフィールドが関連付けられていないことを示すアイコン", + "xpack.synthetics.synthetics.markers.openEmbeddableButton.label": "このアイコンボタンを使用して、この注釈マーカーのメトリックを表示します。", + "xpack.synthetics.synthetics.nextStepButton.ariaLabel": "次のステップ", + "xpack.synthetics.synthetics.performanceBreakDown.label": "パフォーマンスの内訳", + "xpack.synthetics.synthetics.pingTimestamp.captionContent": "ステップ:{stepNumber}/{totalSteps}", + "xpack.synthetics.synthetics.prevStepButton.airaLabel": "前のステップ", + "xpack.synthetics.synthetics.screenshot.noImageMessage": "画像がありません", + "xpack.synthetics.synthetics.screenshotDisplay.altText": "名前「{stepName}」のステップのスクリーンショット", + "xpack.synthetics.synthetics.screenshotDisplay.altTextWithoutName": "スクリーンショット", + "xpack.synthetics.synthetics.service.apiKey": "SyntheticsサービスAPIキー", + "xpack.synthetics.synthetics.statusBadge.failedMessage": "失敗", + "xpack.synthetics.synthetics.statusBadge.skippedMessage": "スキップ", + "xpack.synthetics.synthetics.statusBadge.succeededMessage": "成功", + "xpack.synthetics.synthetics.step.duration": "{value}秒", + "xpack.synthetics.synthetics.step.durationTrend": "ステップ期間傾向", + "xpack.synthetics.synthetics.stepDetail.nextCheckButtonText": "次の確認", + "xpack.synthetics.synthetics.stepDetail.noData": "このステップのデータが見つかりませんでした", + "xpack.synthetics.synthetics.stepDetail.previousCheckButtonText": "前の確認", + "xpack.synthetics.synthetics.stepDetail.totalSteps": "Step {stepIndex} of {totalSteps}", + "xpack.synthetics.synthetics.stepDetail.waterfall.loading": "ウォーターフォールグラフを読み込んでいます", + "xpack.synthetics.synthetics.stepDetail.waterfallNoData": "このステップのウォーターフォールデータが見つかりませんでした", + "xpack.synthetics.synthetics.stepDetail.waterfallUnsupported.description": "ウォーターフォールグラフを表示できません。古いバージョンのSyntheticエージェントを使用している可能性があります。バージョンを確認して、アップグレードを検討してください。", + "xpack.synthetics.synthetics.stepDetail.waterfallUnsupported.title": "ウォーターフォールグラフを使用できません", + "xpack.synthetics.synthetics.stepList.nextCheck": "次の確認", + "xpack.synthetics.synthetics.stepList.previousCheck": "前の確認", + "xpack.synthetics.synthetics.thumbnail.fullSize.alt": "このステップのサムネイルのスクリーンショットの大きいバージョン。", + "xpack.synthetics.synthetics.waterfall.domContentLabel": "DOMコンテンツが読み込まれました", + "xpack.synthetics.synthetics.waterfall.fcpLabel": "初回コンテンツの描画", + "xpack.synthetics.synthetics.waterfall.filterGroup.filterScreenreaderLabel": "フィルタリング条件", + "xpack.synthetics.synthetics.waterfall.filterGroup.removeFilterScreenReaderLabel": "フィルターを削除", + "xpack.synthetics.synthetics.waterfall.flyout.certificates": "証明書ヘッダー", + "xpack.synthetics.synthetics.waterfall.flyout.details": "詳細", + "xpack.synthetics.synthetics.waterfall.flyout.requestHeaders": "要求ヘッダー", + "xpack.synthetics.synthetics.waterfall.flyout.responseHeaders": "応答ヘッダー", + "xpack.synthetics.synthetics.waterfall.layoutShiftLabel": "レイアウトシフト", + "xpack.synthetics.synthetics.waterfall.lcpLabel": "最大コンテンツの描画", + "xpack.synthetics.synthetics.waterfall.loadEventLabel": "イベントの読み込み", + "xpack.synthetics.synthetics.waterfall.offsetUnit": "{offset} ms", + "xpack.synthetics.synthetics.waterfall.requestsHighlightedMessage": "({numHighlightedRequests}はフィルターと一致します)", + "xpack.synthetics.synthetics.waterfall.requestsTotalMessage": "{numNetworkRequests}ネットワーク要求", + "xpack.synthetics.synthetics.waterfall.requestsTotalMessage.first": "最初の{count}件", + "xpack.synthetics.synthetics.waterfall.requestsTotalMessage.info": "ウォーターフォールビューには最大1000件の要求が表示されます", + "xpack.synthetics.synthetics.waterfall.resource.externalLink": "新しいタブでリソースを開く", + "xpack.synthetics.synthetics.waterfall.searchBox.placeholder": "ネットワーク要求をフィルター", + "xpack.synthetics.synthetics.waterfall.sidebar.filterMatchesScreenReaderLabel": "リソースがフィルターと一致します", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.certificateExpiryDate": "有効期限:", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.certificateIssueDate": "有効期間の開始", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.certificateIssuer": "発行者", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.certificateSubject": "共通名", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.contentType": "コンテンツタイプ", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.ip": "IP", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.requestStart": "要求開始", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.resourceSize": "リソースサイズ", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.status": "ステータス", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.transferSize": "転送サイズ", + "xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.font": "フォント", + "xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.html": "HTML", + "xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.media": "メディア", + "xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.other": "その他", + "xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.script": "JS", + "xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.stylesheet": "CSS", + "xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.xhr": "XHR", + "xpack.synthetics.synthetics.waterfallChart.labels.timings.blocked": "キュー/ブロック", + "xpack.synthetics.synthetics.waterfallChart.labels.timings.connect": "接続中", + "xpack.synthetics.synthetics.waterfallChart.labels.timings.dns": "DNS", + "xpack.synthetics.synthetics.waterfallChart.labels.timings.receive": "コンテンツダウンロード", + "xpack.synthetics.synthetics.waterfallChart.labels.timings.send": "要求を送信しています", + "xpack.synthetics.synthetics.waterfallChart.labels.timings.ssl": "TLS", + "xpack.synthetics.synthetics.waterfallChart.labels.timings.wait": "待機中(TTFB)", + "xpack.synthetics.syntheticsMonitors": "アップタイム - モニター", + "xpack.synthetics.testRun.description": "モニターをテストし、保存する前に結果を検証します", + "xpack.synthetics.testRun.pushError": "モニターをサービスにプッシュできませんでした。", + "xpack.synthetics.testRun.pushErrorLabel": "プッシュエラー", + "xpack.synthetics.testRun.pushing.description": "モニターをサービスにプッシュしています...", + "xpack.synthetics.title": "アップタイム", + "xpack.synthetics.toggleAlertButton.content": "監視ステータスルール", + "xpack.synthetics.toggleAlertFlyout.ariaLabel": "ルールの追加フライアウトを開く", + "xpack.synthetics.toggleTlsAlertButton.ariaLabel": "TLSルールフライアウトを開く", + "xpack.synthetics.toggleTlsAlertButton.content": "TLSルール", + "xpack.synthetics.uptimeFeatureCatalogueTitle": "アップタイム", + "xpack.synthetics.uptimeSettings.index": "アップタイム設定 - インデックス", + "xpack.synthetics.waterfallChart.sidebar.url.https": "https", "xpack.urlDrilldown.click.event.key.documentation": "クリックしたデータポイントの後ろのフィールド名。", "xpack.urlDrilldown.click.event.key.title": "クリックしたフィールドの名前。", "xpack.urlDrilldown.click.event.negate.documentation": "クリックしたデータポイントが否定フィルターになったかどうかを示すブール値。", @@ -31299,6 +31194,138 @@ "xpack.watcher.watchActions.webhook.portIsRequiredValidationMessage": "Webフックポートが必要です。", "xpack.watcher.watchActions.webhook.usernameIsRequiredIfPasswordValidationMessage": "ユーザー名が必要です。", "xpack.watcher.watchEdit.thresholdWatchExpression.aggType.fieldIsRequiredValidationMessage": "フィールドを選択してください。", - "xpack.watcher.watcherDescription": "アラートの作成、管理、監視によりデータへの変更を検知します。" + "xpack.watcher.watcherDescription": "アラートの作成、管理、監視によりデータへの変更を検知します。", + "unifiedSearch.search.searchBar.savedQueryDescriptionLabelText": "説明", + "unifiedSearch.search.searchBar.savedQueryDescriptionText": "再度使用するクエリテキストとフィルターを保存します。", + "unifiedSearch.search.searchBar.savedQueryForm.titleConflictText": "タイトルがすでに保存されているクエリに使用されています", + "unifiedSearch.search.searchBar.savedQueryFormCancelButtonText": "キャンセル", + "unifiedSearch.search.searchBar.savedQueryFormSaveButtonText": "保存", + "unifiedSearch.search.searchBar.savedQueryFormTitle": "クエリを保存", + "unifiedSearch.search.searchBar.savedQueryIncludeFiltersLabelText": "フィルターを含める", + "unifiedSearch.search.searchBar.savedQueryIncludeTimeFilterLabelText": "時間フィルターを含める", + "unifiedSearch.search.searchBar.savedQueryNameHelpText": "名前は必須です。名前の始めと終わりにはスペースを使用できません。名前は一意でなければなりません。", + "unifiedSearch.search.searchBar.savedQueryNameLabelText": "名前", + "unifiedSearch.search.searchBar.savedQueryNoSavedQueriesText": "保存されたクエリがありません。", + "unifiedSearch.search.searchBar.savedQueryPopoverButtonText": "保存されたクエリを表示", + "unifiedSearch.search.searchBar.savedQueryPopoverClearButtonAriaLabel": "現在保存されているクエリを消去", + "unifiedSearch.search.searchBar.savedQueryPopoverClearButtonText": "クリア", + "unifiedSearch.search.searchBar.savedQueryPopoverConfirmDeletionCancelButtonText": "キャンセル", + "unifiedSearch.search.searchBar.savedQueryPopoverConfirmDeletionConfirmButtonText": "削除", + "unifiedSearch.search.searchBar.savedQueryPopoverConfirmDeletionTitle": "「{savedQueryName}」を削除しますか?", + "unifiedSearch.search.searchBar.savedQueryPopoverDeleteButtonAriaLabel": "保存されたクエリ {savedQueryName} を削除", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveAsNewButtonAriaLabel": "新規保存クエリを保存", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveAsNewButtonText": "新規保存", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveButtonAriaLabel": "新規保存クエリを保存", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveButtonText": "現在のクエリを保存", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveChangesButtonAriaLabel": "{title} への変更を保存", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveChangesButtonText": "変更を保存", + "unifiedSearch.search.searchBar.savedQueryPopoverSavedQueryListItemButtonAriaLabel": "保存クエリボタン {savedQueryName}", + "unifiedSearch.search.searchBar.savedQueryPopoverSavedQueryListItemDescriptionAriaLabel": "{savedQueryName}の説明", + "unifiedSearch.search.searchBar.savedQueryPopoverSavedQueryListItemSelectedButtonAriaLabel": "選択されたクエリボタン {savedQueryName} を保存しました。変更を破棄するには押してください。", + "unifiedSearch.search.searchBar.savedQueryPopoverTitleText": "保存されたクエリ", + "unifiedSearch.noDataPopover.content": "この時間範囲にはデータが含まれていません。表示するフィールドを増やし、グラフを作成するには、時間範囲を広げるか、調整してください。", + "unifiedSearch.noDataPopover.dismissAction": "今後表示しない", + "unifiedSearch.noDataPopover.subtitle": "ヒント", + "unifiedSearch.noDataPopover.title": "空のデータセット", + "unifiedSearch.query.queryBar.clearInputLabel": "インプットを消去", + "unifiedSearch.query.queryBar.comboboxAriaLabel": "{pageType} ページの検索とフィルタリング", + "unifiedSearch.query.queryBar.kqlFullLanguageName": "Kibana クエリ言語", + "unifiedSearch.query.queryBar.kqlLanguageName": "KQL", + "unifiedSearch.query.queryBar.KQLNestedQuerySyntaxInfoDocLinkText": "ドキュメント", + "unifiedSearch.query.queryBar.KQLNestedQuerySyntaxInfoOptOutText": "今後表示しない", + "unifiedSearch.query.queryBar.KQLNestedQuerySyntaxInfoText": "ネストされたフィールドをクエリされているようです。ネストされたクエリに対しては、ご希望の結果により異なる方法で KQL 構文を構築することができます。詳細については、{link}をご覧ください。", + "unifiedSearch.query.queryBar.KQLNestedQuerySyntaxInfoTitle": "KQL ネストされたクエリ構文", + "unifiedSearch.query.queryBar.kqlOffLabel": "オフ", + "unifiedSearch.query.queryBar.kqlOnLabel": "オン", + "unifiedSearch.query.queryBar.languageSwitcher.toText": "検索用にKibana Query Languageに切り替える", + "unifiedSearch.query.queryBar.luceneLanguageName": "Lucene", + "unifiedSearch.query.queryBar.searchInputAriaLabel": "{pageType} ページの検索とフィルタリングを行うには入力を開始してください", + "unifiedSearch.query.queryBar.searchInputPlaceholder": "検索", + "unifiedSearch.query.queryBar.syntaxOptionsDescription": "{docsLink}(KQL)は、シンプルなクエリ構文とスクリプトフィールドのサポートを提供します。KQLにはオートコンプリート機能もあります。KQLをオフにする場合は、{nonKqlModeHelpText}", + "unifiedSearch.query.queryBar.syntaxOptionsDescription.nonKqlModeHelpText": "KibanaはLuceneを使用します。", + "unifiedSearch.search.unableToGetSavedQueryToastTitle": "保存したクエリ {savedQueryId} を読み込めません", + "unifiedSearch.query.queryBar.syntaxOptionsTitle": "構文オプション", + "unifiedSearch.filter.applyFilterActionTitle": "現在のビューにフィルターを適用", + "unifiedSearch.filter.applyFilters.popupHeader": "適用するフィルターの選択", + "unifiedSearch.filter.applyFiltersPopup.cancelButtonLabel": "キャンセル", + "unifiedSearch.filter.applyFiltersPopup.saveButtonLabel": "適用", + "unifiedSearch.filter.filterBar.addFilterButtonLabel": "フィルターを追加します", + "unifiedSearch.filter.filterBar.deleteFilterButtonLabel": "削除", + "unifiedSearch.filter.filterBar.disabledFilterPrefix": "無効", + "unifiedSearch.filter.filterBar.disableFilterButtonLabel": "一時的に無効にする", + "unifiedSearch.filter.filterBar.editFilterButtonLabel": "フィルターを編集", + "unifiedSearch.filter.filterBar.enableFilterButtonLabel": "再度有効にする", + "unifiedSearch.filter.filterBar.excludeFilterButtonLabel": "結果を除外", + "unifiedSearch.filter.filterBar.filterItemBadgeAriaLabel": "フィルターアクション", + "unifiedSearch.filter.filterBar.filterItemBadgeIconAriaLabel": "{filter}を削除", + "unifiedSearch.filter.filterBar.includeFilterButtonLabel": "結果を含める", + "unifiedSearch.filter.filterBar.indexPatternSelectPlaceholder": "インデックスパターンの選択", + "unifiedSearch.filter.filterBar.labelErrorInfo": "インデックスパターン{indexPattern}が見つかりません", + "unifiedSearch.filter.filterBar.labelErrorText": "エラー", + "unifiedSearch.filter.filterBar.labelWarningInfo": "フィールド{fieldName}は現在のビューに存在しません", + "unifiedSearch.filter.filterBar.labelWarningText": "警告", + "unifiedSearch.filter.filterBar.moreFilterActionsMessage": "フィルター:{innerText}。他のフィルターアクションを使用するには選択してください。", + "unifiedSearch.filter.filterBar.negatedFilterPrefix": "NOT ", + "unifiedSearch.filter.filterBar.pinFilterButtonLabel": "すべてのアプリにピン付け", + "unifiedSearch.filter.filterBar.pinnedFilterPrefix": "ピン付け済み", + "unifiedSearch.filter.filterBar.unpinFilterButtonLabel": "ピンを外す", + "unifiedSearch.filter.filterEditor.cancelButtonLabel": "キャンセル", + "unifiedSearch.filter.filterEditor.createCustomLabelInputLabel": "カスタムラベル", + "unifiedSearch.filter.filterEditor.createCustomLabelSwitchLabel": "カスタムラベルを作成しますか?", + "unifiedSearch.filter.filterEditor.doesNotExistOperatorOptionLabel": "存在しない", + "unifiedSearch.filter.filterEditor.editFilterPopupTitle": "フィルターを編集", + "unifiedSearch.filter.filterEditor.editFilterValuesButtonLabel": "フィルター値を編集", + "unifiedSearch.filter.filterEditor.editQueryDslButtonLabel": "クエリ DSL として編集", + "unifiedSearch.filter.filterEditor.existsOperatorOptionLabel": "存在する", + "unifiedSearch.filter.filterEditor.falseOptionLabel": "false", + "unifiedSearch.filter.filterEditor.fieldSelectLabel": "フィールド", + "unifiedSearch.filter.filterEditor.fieldSelectPlaceholder": "フィールドを選択", + "unifiedSearch.filter.filterEditor.indexPatternSelectLabel": "インデックスパターン", + "unifiedSearch.filter.filterEditor.isBetweenOperatorOptionLabel": "is between", + "unifiedSearch.filter.filterEditor.isNotBetweenOperatorOptionLabel": "is not between", + "unifiedSearch.filter.filterEditor.isNotOneOfOperatorOptionLabel": "is not one of", + "unifiedSearch.filter.filterEditor.isNotOperatorOptionLabel": "is not", + "unifiedSearch.filter.filterEditor.isOneOfOperatorOptionLabel": "is one of", + "unifiedSearch.filter.filterEditor.isOperatorOptionLabel": "is", + "unifiedSearch.filter.filterEditor.operatorSelectLabel": "演算子", + "unifiedSearch.filter.filterEditor.operatorSelectPlaceholderSelect": "選択してください", + "unifiedSearch.filter.filterEditor.operatorSelectPlaceholderWaiting": "待機中", + "unifiedSearch.filter.filterEditor.queryDslAriaLabel": "ElasticsearchクエリDSLエディター", + "unifiedSearch.filter.filterEditor.queryDslLabel": "Elasticsearch クエリ DSL", + "unifiedSearch.filter.filterEditor.rangeEndInputPlaceholder": "範囲の終了値", + "unifiedSearch.filter.filterEditor.rangeInputLabel": "範囲", + "unifiedSearch.filter.filterEditor.rangeStartInputPlaceholder": "範囲の開始値", + "unifiedSearch.filter.filterEditor.saveButtonLabel": "保存", + "unifiedSearch.filter.filterEditor.trueOptionLabel": "true", + "unifiedSearch.filter.filterEditor.valueInputLabel": "値", + "unifiedSearch.filter.filterEditor.valueInputPlaceholder": "値を入力", + "unifiedSearch.filter.filterEditor.valueSelectPlaceholder": "値を選択", + "unifiedSearch.filter.filterEditor.valuesSelectLabel": "値", + "unifiedSearch.filter.filterEditor.valuesSelectPlaceholder": "値を選択", + "unifiedSearch.filter.options.changeAllFiltersButtonLabel": "すべてのフィルターの変更", + "unifiedSearch.filter.options.deleteAllFiltersButtonLabel": "すべて削除", + "unifiedSearch.filter.options.disableAllFiltersButtonLabel": "すべて無効にする", + "unifiedSearch.filter.options.enableAllFiltersButtonLabel": "すべて有効にする", + "unifiedSearch.filter.options.invertDisabledFiltersButtonLabel": "有効・無効を反転", + "unifiedSearch.filter.options.invertNegatedFiltersButtonLabel": "含める・除外を反転", + "unifiedSearch.filter.options.pinAllFiltersButtonLabel": "すべてピン付け", + "unifiedSearch.filter.options.unpinAllFiltersButtonLabel": "すべてのピンを外す", + "unifiedSearch.filter.searchBar.changeAllFiltersTitle": "すべてのフィルターの変更", + "unifiedSearch.kueryAutocomplete.andOperatorDescription": "{bothArguments} が true であることを条件とする", + "unifiedSearch.kueryAutocomplete.andOperatorDescription.bothArgumentsText": "両方の引数", + "unifiedSearch.kueryAutocomplete.equalOperatorDescription": "一部の値に{equals}", + "unifiedSearch.kueryAutocomplete.equalOperatorDescription.equalsText": "一致する", + "unifiedSearch.kueryAutocomplete.existOperatorDescription": "いずれかの形式中に{exists}", + "unifiedSearch.kueryAutocomplete.existOperatorDescription.existsText": "存在する", + "unifiedSearch.kueryAutocomplete.greaterThanOperatorDescription": "が一部の値{greaterThan}", + "unifiedSearch.kueryAutocomplete.greaterThanOperatorDescription.greaterThanText": "より大きい", + "unifiedSearch.kueryAutocomplete.greaterThanOrEqualOperatorDescription": "が一部の値{greaterThanOrEqualTo}", + "unifiedSearch.kueryAutocomplete.greaterThanOrEqualOperatorDescription.greaterThanOrEqualToText": "よりも大きいまたは等しい", + "unifiedSearch.kueryAutocomplete.lessThanOperatorDescription": "が一部の値{lessThan}", + "unifiedSearch.kueryAutocomplete.lessThanOperatorDescription.lessThanText": "より小さい", + "unifiedSearch.kueryAutocomplete.lessThanOrEqualOperatorDescription": "が一部の値{lessThanOrEqualTo}", + "unifiedSearch.kueryAutocomplete.lessThanOrEqualOperatorDescription.lessThanOrEqualToText": "より小さいまたは等しい", + "unifiedSearch.kueryAutocomplete.orOperatorDescription": "{oneOrMoreArguments} が true であることを条件とする", + "unifiedSearch.kueryAutocomplete.orOperatorDescription.oneOrMoreArgumentsText": "1つ以上の引数" } } diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 36deeedc095e7..649d6e648c0ec 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -447,28 +447,18 @@ "xpack.lens.indexPattern.dateHistogram.autoAdvancedExplanation": "时间间隔遵循以下逻辑:", "xpack.lens.indexPattern.dateHistogram.autoBasicExplanation": "自动日期直方图按时间间隔将数据字段拆分为桶。", "xpack.lens.indexPattern.dateHistogram.autoBoundHeader": "已度量目标时间间隔", - "xpack.lens.indexPattern.dateHistogram.autoHelpText": "运作方式", - "xpack.lens.indexPattern.dateHistogram.autoInterval": "定制时间间隔", "xpack.lens.indexPattern.dateHistogram.autoIntervalHeader": "已用时间间隔", "xpack.lens.indexPattern.dateHistogram.autoLongerExplanation": "要选择时间间隔,Lens 按 {targetBarSetting} 设置分割指定的时间范围。Lens 为您的数据计算最佳时间间隔。例如 30m、1h 和 12。最大条形数由 {maxBarSetting} 值设置。", "xpack.lens.indexPattern.dateHistogram.bindToGlobalTimePicker": "绑定到全局时间选取器", - "xpack.lens.indexPattern.dateHistogram.days": "天", "xpack.lens.indexPattern.dateHistogram.dropPartialBuckets": "丢弃部分存储桶", "xpack.lens.indexPattern.dateHistogram.dropPartialBucketsHelp": "禁止丢弃部分存储桶,因为只可以为绑定到右上角的全局时间选取器的时间字段计算这些存储桶。", "xpack.lens.indexPattern.dateHistogram.globalTimePickerHelp": "按右上角的全局时间选取器筛选选定字段。不能对当前数据视图的默认时间字段关闭此设置。", - "xpack.lens.indexPattern.dateHistogram.hours": "小时", "xpack.lens.indexPattern.dateHistogram.includeEmptyRows": "包括空行", - "xpack.lens.indexPattern.dateHistogram.milliseconds": "毫秒", "xpack.lens.indexPattern.dateHistogram.minimumInterval": "最小时间间隔", - "xpack.lens.indexPattern.dateHistogram.minutes": "分钟", - "xpack.lens.indexPattern.dateHistogram.month": "个月", "xpack.lens.indexPattern.dateHistogram.moreThanYear": "1 年以上", "xpack.lens.indexPattern.dateHistogram.restrictedInterval": "由于聚合限制,时间间隔固定为 {intervalValue}。", - "xpack.lens.indexPattern.dateHistogram.seconds": "秒", "xpack.lens.indexPattern.dateHistogram.titleHelp": "自动日期直方图的工作原理", "xpack.lens.indexPattern.dateHistogram.upTo": "最多", - "xpack.lens.indexPattern.dateHistogram.week": "周", - "xpack.lens.indexPattern.dateHistogram.year": "年", "xpack.lens.indexPattern.dateHistogramTimeShift": "在单个图层中,您无法组合上一时间范围偏移与 Date Histogram。在“{column}”中使用显式时间偏移持续时间,或替换 Date Histogram。", "xpack.lens.indexPattern.decimalPlacesLabel": "小数", "xpack.lens.indexPattern.defaultFormatLabel": "默认", @@ -545,7 +535,6 @@ "xpack.lens.indexPattern.incompleteOperation": "(不完整)", "xpack.lens.indexPattern.intervals": "时间间隔", "xpack.lens.indexPattern.invalidFieldLabel": "字段无效。检查数据视图或选取其他字段。", - "xpack.lens.indexPattern.invalidInterval": "时间间隔值无效", "xpack.lens.indexPattern.invalidOperationLabel": "此字段不适用于选定函数。", "xpack.lens.indexPattern.invalidReferenceConfiguration": "维度“{dimensionLabel}”配置不正确", "xpack.lens.indexPattern.invalidTimeShift": "时间偏移无效。输入正整数数量,后跟以下单位之一:s、m、h、d、w、M、y。例如,3h 表示 3 小时", @@ -580,7 +569,6 @@ "xpack.lens.indexPattern.moving_average.signature": "指标:数字,[window]:数字", "xpack.lens.indexPattern.movingAverage": "移动平均值", "xpack.lens.indexPattern.movingAverage.basicExplanation": "移动平均值在数据上滑动时间窗并显示平均值。仅日期直方图支持移动平均值。", - "xpack.lens.indexPattern.movingAverage.helpText": "运作方式", "xpack.lens.indexPattern.movingAverage.limitations": "第一个移动平均值开始于第二项。", "xpack.lens.indexPattern.movingAverage.longerExplanation": "要计算移动平均值,Lens 使用时间窗的平均值,并为缺口应用跳过策略。 对于缺失值,将跳过桶,计算将基于下一个值执行。", "xpack.lens.indexPattern.movingAverage.tableExplanation": "例如,如果数据为 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],则可以使用时间窗大小 5 计算简单移动平均值:", @@ -2076,22 +2064,6 @@ "data.inspector.table.tableLabel": "表 {index}", "data.inspector.table.tablesDescription": "总共有 {tablesCount, plural, other {# 个表} }", "data.inspector.table.tableSelectorLabel": "已选定:", - "data.kueryAutocomplete.andOperatorDescription": "需要{bothArguments}为 true", - "data.kueryAutocomplete.andOperatorDescription.bothArgumentsText": "两个参数都", - "data.kueryAutocomplete.equalOperatorDescription": "{equals}某一值", - "data.kueryAutocomplete.equalOperatorDescription.equalsText": "等于", - "data.kueryAutocomplete.existOperatorDescription": "以任意形式{exists}", - "data.kueryAutocomplete.existOperatorDescription.existsText": "存在", - "data.kueryAutocomplete.greaterThanOperatorDescription": "{greaterThan}某一值", - "data.kueryAutocomplete.greaterThanOperatorDescription.greaterThanText": "大于", - "data.kueryAutocomplete.greaterThanOrEqualOperatorDescription": "{greaterThanOrEqualTo}某一值", - "data.kueryAutocomplete.greaterThanOrEqualOperatorDescription.greaterThanOrEqualToText": "大于或等于", - "data.kueryAutocomplete.lessThanOperatorDescription": "{lessThan}某一值", - "data.kueryAutocomplete.lessThanOperatorDescription.lessThanText": "小于", - "data.kueryAutocomplete.lessThanOrEqualOperatorDescription": "{lessThanOrEqualTo}某一值", - "data.kueryAutocomplete.lessThanOrEqualOperatorDescription.lessThanOrEqualToText": "小于或等于", - "data.kueryAutocomplete.orOperatorDescription": "需要{oneOrMoreArguments}为 true", - "data.kueryAutocomplete.orOperatorDescription.oneOrMoreArgumentsText": "一个或多个参数", "data.painlessError.buttonTxt": "编辑脚本", "data.painlessError.painlessScriptedFieldErrorMessage": "在索引模式 {indexPatternName} 上执行运行时字段或脚本字段时出错", "data.parseEsInterval.invalidEsCalendarIntervalErrorMessage": "无效的日历时间间隔:{interval},值必须为 1", @@ -2738,6 +2710,110 @@ "data.searchSessions.sessionService.sessionObjectFetchError": "无法提取搜索会话信息", "data.triggers.applyFilterDescription": "应用 kibana 筛选时。可能是单个值或范围筛选。", "data.triggers.applyFilterTitle": "应用筛选", + "data.mgmt.searchSessions.actionDelete": "删除", + "data.mgmt.searchSessions.actionExtend": "延长", + "data.mgmt.searchSessions.actionRename": "编辑名称", + "data.mgmt.searchSessions.actions.tooltip.moreActions": "更多操作", + "data.mgmt.searchSessions.api.deleted": "搜索会话已删除。", + "data.mgmt.searchSessions.api.deletedError": "无法删除搜索会话!", + "data.mgmt.searchSessions.api.extended": "搜索会话已延长。", + "data.mgmt.searchSessions.api.extendError": "无法延长搜索会话!", + "data.mgmt.searchSessions.api.fetchError": "无法刷新页面!", + "data.mgmt.searchSessions.api.fetchTimeout": "获取搜索会话信息在 {timeout} 秒后已超时", + "data.mgmt.searchSessions.api.rename": "搜索会话已重命名", + "data.mgmt.searchSessions.api.renameError": "无法重命名搜索会话", + "data.mgmt.searchSessions.appTitle": "搜索会话", + "data.mgmt.searchSessions.ariaLabel.moreActions": "更多操作", + "data.mgmt.searchSessions.cancelModal.cancelButton": "取消", + "data.mgmt.searchSessions.cancelModal.deleteButton": "删除", + "data.mgmt.searchSessions.cancelModal.message": "删除搜索会话“{name}”将会删除所有缓存的结果。", + "data.mgmt.searchSessions.cancelModal.title": "删除搜索会话", + "data.mgmt.searchSessions.extendModal.dontExtendButton": "取消", + "data.mgmt.searchSessions.extendModal.extendButton": "延长过期时间", + "data.mgmt.searchSessions.extendModal.extendMessage": "搜索会话“{name}”过期时间将延长至 {newExpires}。", + "data.mgmt.searchSessions.extendModal.title": "延长搜索会话过期时间", + "data.mgmt.searchSessions.flyoutTitle": "检查", + "data.mgmt.searchSessions.main.backgroundSessionsDocsLinkText": "文档", + "data.mgmt.searchSessions.main.sectionDescription": "管理已保存搜索会话。", + "data.mgmt.searchSessions.main.sectionTitle": "搜索会话", + "data.mgmt.searchSessions.renameModal.cancelButton": "取消", + "data.mgmt.searchSessions.renameModal.renameButton": "保存", + "data.mgmt.searchSessions.renameModal.searchSessionNameInputLabel": "搜索会话名称", + "data.mgmt.searchSessions.renameModal.title": "编辑搜索会话名称", + "data.mgmt.searchSessions.search.filterApp": "应用", + "data.mgmt.searchSessions.search.filterStatus": "状态", + "data.mgmt.searchSessions.search.tools.refresh": "刷新", + "data.mgmt.searchSessions.status.expireDateUnknown": "未知", + "data.mgmt.searchSessions.status.expiresOn": "于 {expireDate}过期", + "data.mgmt.searchSessions.status.expiresSoonInDays": "将于 {numDays} 天后过期", + "data.mgmt.searchSessions.status.expiresSoonInDaysTooltip": "{numDays} 天", + "data.mgmt.searchSessions.status.expiresSoonInHours": "此会话将于 {numHours} 小时后过期", + "data.mgmt.searchSessions.status.expiresSoonInHoursTooltip": "{numHours} 小时", + "data.mgmt.searchSessions.status.label.cancelled": "已取消", + "data.mgmt.searchSessions.status.label.complete": "已完成", + "data.mgmt.searchSessions.status.label.error": "错误", + "data.mgmt.searchSessions.status.label.expired": "已过期", + "data.mgmt.searchSessions.status.label.inProgress": "进行中", + "data.mgmt.searchSessions.status.message.cancelled": "用户已取消", + "data.mgmt.searchSessions.status.message.createdOn": "于 {expireDate}过期", + "data.mgmt.searchSessions.status.message.error": "错误:{error}", + "data.mgmt.searchSessions.status.message.expiredOn": "已于 {expireDate}过期", + "data.mgmt.searchSessions.table.headerExpiration": "到期", + "data.mgmt.searchSessions.table.headerName": "名称", + "data.mgmt.searchSessions.table.headerStarted": "创建时间", + "data.mgmt.searchSessions.table.headerStatus": "状态", + "data.mgmt.searchSessions.table.headerType": "应用", + "data.mgmt.searchSessions.table.notRestorableWarning": "搜索会话将重新执行。然后,您可以将其保存,供未来使用。", + "data.mgmt.searchSessions.table.numSearches": "搜索数", + "data.mgmt.searchSessions.table.versionIncompatibleWarning": "此搜索会话在运行不同版本的 Kibana 实例中已创建。其可能不会正确还原。", + "data.search.statusError": "搜索完成,状态为 {errorCode}", + "data.search.statusThrow": "搜索状态引发错误 {message} ({errorCode}) 状态", + "data.searchSessionIndicator.cancelButtonText": "停止会话", + "data.searchSessionIndicator.canceledDescriptionText": "您正查看不完整的数据", + "data.searchSessionIndicator.canceledIconAriaLabel": "搜索会话已停止", + "data.searchSessionIndicator.canceledTitleText": "搜索会话已停止", + "data.searchSessionIndicator.canceledTooltipText": "搜索会话已停止", + "data.searchSessionIndicator.canceledWhenText": "已于 {when} 停止", + "data.searchSessionIndicator.continueInBackgroundButtonText": "保存会话", + "data.searchSessionIndicator.disabledDueToDisabledGloballyMessage": "您无权管理搜索会话", + "data.searchSessionIndicator.disabledDueToTimeoutMessage": "搜索会话结果已过期。", + "data.searchSessionIndicator.loadingInTheBackgroundDescriptionText": "可以从“管理”中返回至完成的结果", + "data.searchSessionIndicator.loadingInTheBackgroundIconAriaLabel": "已保存会话正在进行中", + "data.searchSessionIndicator.loadingInTheBackgroundIconTooltipText": "已保存会话正在进行中", + "data.searchSessionIndicator.loadingInTheBackgroundTitleText": "已保存会话正在进行中", + "data.searchSessionIndicator.loadingInTheBackgroundWhenText": "已于 {when} 启动", + "data.searchSessionIndicator.loadingResultsDescription": "保存您的会话,继续您的工作,然后返回到完成的结果", + "data.searchSessionIndicator.loadingResultsIconAriaLabel": "搜索会话正在加载", + "data.searchSessionIndicator.loadingResultsIconTooltipText": "搜索会话正在加载", + "data.searchSessionIndicator.loadingResultsTitle": "您的搜索将需要一些时间......", + "data.searchSessionIndicator.loadingResultsWhenText": "已于 {when} 启动", + "data.searchSessionIndicator.restoredDescriptionText": "您在查看特定时间范围的缓存数据。更改时间范围或筛选将会重新运行会话", + "data.searchSessionIndicator.restoredResultsIconAriaLabel": "已保存会话已还原", + "data.searchSessionIndicator.restoredResultsTooltipText": "搜索会话已还原", + "data.searchSessionIndicator.restoredTitleText": "搜索会话已还原", + "data.searchSessionIndicator.restoredWhenText": "已于 {when} 完成", + "data.searchSessionIndicator.resultLoadedInTheBackgroundDescriptionText": "可以从“管理”中返回到这些结果", + "data.searchSessionIndicator.resultLoadedInTheBackgroundIconAriaLabel": "已保存会话已完成", + "data.searchSessionIndicator.resultLoadedInTheBackgroundIconTooltipText": "已保存会话已完成", + "data.searchSessionIndicator.resultLoadedInTheBackgroundTitleText": "搜索会话已保存", + "data.searchSessionIndicator.resultLoadedInTheBackgroundWhenText": "已于 {when} 完成", + "data.searchSessionIndicator.resultsLoadedDescriptionText": "保存您的会话,之后可返回", + "data.searchSessionIndicator.resultsLoadedIconAriaLabel": "搜索会话已完成", + "data.searchSessionIndicator.resultsLoadedIconTooltipText": "搜索会话已完成", + "data.searchSessionIndicator.resultsLoadedText": "搜索会话已完成", + "data.searchSessionIndicator.resultsLoadedWhenText": "已于 {when} 完成", + "data.searchSessionIndicator.saveButtonText": "保存会话", + "data.searchSessionIndicator.viewSearchSessionsLinkText": "管理会话", + "data.searchSessionName.ariaLabelText": "搜索会话名称", + "data.searchSessionName.editAriaLabelText": "编辑搜索会话名称", + "data.searchSessionName.placeholderText": "为搜索会话输入名称", + "data.searchSessionName.saveButtonText": "保存", + "data.sessions.management.flyoutText": "此搜索会话的配置", + "data.sessions.management.flyoutTitle": "检查搜索会话", + "dataViews.deprecations.scriptedFields.manualStepOneMessage": "导航到“堆栈管理”>“Kibana”>“索引模式”。", + "dataViews.deprecations.scriptedFields.manualStepTwoMessage": "更新 {numberOfIndexPatternsWithScriptedFields} 个具有脚本字段的索引模式以改为使用运行时字段。多数情况下,要迁移现有脚本,您需要将“return ;”更改为“emit();”。至少有一个脚本字段的索引模式:{allTitles}", + "dataViews.deprecations.scriptedFieldsMessage": "您具有 {numberOfIndexPatternsWithScriptedFields} 个使用脚本字段的索引模式 ({titlesPreview}...)。脚本字段已过时,将在未来移除。请改为使用运行时脚本。", + "dataViews.deprecations.scriptedFieldsTitle": "找到使用脚本字段的索引模式", "dataViews.deprecations.scriptedFields.manualStepOneMessage": "导航到“堆栈管理”>“Kibana”>“数据视图”。", "dataViews.deprecations.scriptedFields.manualStepTwoMessage": "更新 {numberOfIndexPatternsWithScriptedFields} 个具有脚本字段的数据视图以改为使用运行时字段。多数情况下,要迁移现有脚本,您需要将“return ;”更改为“emit();”。至少有一个脚本字段的数据视图:{allTitles}", "dataViews.deprecations.scriptedFieldsMessage": "您具有 {numberOfIndexPatternsWithScriptedFields} 个使用脚本字段的数据视图 ({titlesPreview}...)。脚本字段已过时,将在未来移除。请改为使用运行时脚本。", @@ -7410,7 +7486,6 @@ "xpack.apm.filter.environment.allLabel": "全部", "xpack.apm.filter.environment.label": "环境", "xpack.apm.filter.environment.notDefinedLabel": "未定义", - "xpack.apm.filter.environment.selectEnvironmentLabel": "选择环境", "xpack.apm.fleet_integration.settings.advancedOptionsLavel": "高级选项", "xpack.apm.fleet_integration.settings.agentAuthorization.anonymousAllowAgentHelpText": "允许进行匿名访问的代理名称。", "xpack.apm.fleet_integration.settings.agentAuthorization.anonymousAllowAgentLabel": "允许的代理", @@ -7637,7 +7712,6 @@ "xpack.apm.propertiesTable.tabs.metadataLabel": "元数据", "xpack.apm.propertiesTable.tabs.timelineLabel": "时间线", "xpack.apm.searchInput.filter": "筛选...", - "xpack.apm.selectCustomOptionText": "将 \\{searchValue\\} 添加为新选项", "xpack.apm.selectPlaceholder": "选择选项:", "xpack.apm.serviceDependencies.breakdownChartTitle": "依赖项花费的时间", "xpack.apm.serviceDetails.dependenciesTabLabel": "依赖项", @@ -10174,7 +10248,6 @@ "xpack.csp.passed": "通过", "xpack.csp.posture_score": "态势分数", "xpack.csp.posture_score_trend": "态势分数趋势", - "xpack.csp.resource_type": "资源类型", "xpack.csp.rules.activateAllButtonLabel": "激活 {count, plural, other {# 个规则}}", "xpack.csp.rules.activatedLabel": "已激活", "xpack.csp.rules.activateLabel": "激活", @@ -10225,107 +10298,6 @@ "xpack.dashboard.drilldown.goToDashboard": "前往仪表板", "xpack.dashboard.FlyoutCreateDrilldownAction.displayName": "创建向下钻取", "xpack.dashboard.panel.openFlyoutEditDrilldown.displayName": "管理向下钻取", - "xpack.data.mgmt.searchSessions.actionDelete": "删除", - "xpack.data.mgmt.searchSessions.actionExtend": "延长", - "xpack.data.mgmt.searchSessions.actionRename": "编辑名称", - "xpack.data.mgmt.searchSessions.actions.tooltip.moreActions": "更多操作", - "xpack.data.mgmt.searchSessions.api.deleted": "搜索会话已删除。", - "xpack.data.mgmt.searchSessions.api.deletedError": "无法删除搜索会话!", - "xpack.data.mgmt.searchSessions.api.extended": "搜索会话已延长。", - "xpack.data.mgmt.searchSessions.api.extendError": "无法延长搜索会话!", - "xpack.data.mgmt.searchSessions.api.fetchError": "无法刷新页面!", - "xpack.data.mgmt.searchSessions.api.fetchTimeout": "获取搜索会话信息在 {timeout} 秒后已超时", - "xpack.data.mgmt.searchSessions.api.rename": "搜索会话已重命名", - "xpack.data.mgmt.searchSessions.api.renameError": "无法重命名搜索会话", - "xpack.data.mgmt.searchSessions.appTitle": "搜索会话", - "xpack.data.mgmt.searchSessions.ariaLabel.moreActions": "更多操作", - "xpack.data.mgmt.searchSessions.cancelModal.cancelButton": "取消", - "xpack.data.mgmt.searchSessions.cancelModal.deleteButton": "删除", - "xpack.data.mgmt.searchSessions.cancelModal.message": "删除搜索会话“{name}”将会删除所有缓存的结果。", - "xpack.data.mgmt.searchSessions.cancelModal.title": "删除搜索会话", - "xpack.data.mgmt.searchSessions.extendModal.dontExtendButton": "取消", - "xpack.data.mgmt.searchSessions.extendModal.extendButton": "延长过期时间", - "xpack.data.mgmt.searchSessions.extendModal.extendMessage": "搜索会话“{name}”过期时间将延长至 {newExpires}。", - "xpack.data.mgmt.searchSessions.extendModal.title": "延长搜索会话过期时间", - "xpack.data.mgmt.searchSessions.flyoutTitle": "检查", - "xpack.data.mgmt.searchSessions.main.backgroundSessionsDocsLinkText": "文档", - "xpack.data.mgmt.searchSessions.main.sectionDescription": "管理已保存搜索会话。", - "xpack.data.mgmt.searchSessions.main.sectionTitle": "搜索会话", - "xpack.data.mgmt.searchSessions.renameModal.cancelButton": "取消", - "xpack.data.mgmt.searchSessions.renameModal.renameButton": "保存", - "xpack.data.mgmt.searchSessions.renameModal.searchSessionNameInputLabel": "搜索会话名称", - "xpack.data.mgmt.searchSessions.renameModal.title": "编辑搜索会话名称", - "xpack.data.mgmt.searchSessions.search.filterApp": "应用", - "xpack.data.mgmt.searchSessions.search.filterStatus": "状态", - "xpack.data.mgmt.searchSessions.search.tools.refresh": "刷新", - "xpack.data.mgmt.searchSessions.status.expireDateUnknown": "未知", - "xpack.data.mgmt.searchSessions.status.expiresOn": "于 {expireDate}过期", - "xpack.data.mgmt.searchSessions.status.expiresSoonInDays": "将于 {numDays} 天后过期", - "xpack.data.mgmt.searchSessions.status.expiresSoonInDaysTooltip": "{numDays} 天", - "xpack.data.mgmt.searchSessions.status.expiresSoonInHours": "此会话将于 {numHours} 小时后过期", - "xpack.data.mgmt.searchSessions.status.expiresSoonInHoursTooltip": "{numHours} 小时", - "xpack.data.mgmt.searchSessions.status.label.cancelled": "已取消", - "xpack.data.mgmt.searchSessions.status.label.complete": "已完成", - "xpack.data.mgmt.searchSessions.status.label.error": "错误", - "xpack.data.mgmt.searchSessions.status.label.expired": "已过期", - "xpack.data.mgmt.searchSessions.status.label.inProgress": "进行中", - "xpack.data.mgmt.searchSessions.status.message.cancelled": "用户已取消", - "xpack.data.mgmt.searchSessions.status.message.createdOn": "于 {expireDate}过期", - "xpack.data.mgmt.searchSessions.status.message.error": "错误:{error}", - "xpack.data.mgmt.searchSessions.status.message.expiredOn": "已于 {expireDate}过期", - "xpack.data.mgmt.searchSessions.table.headerExpiration": "到期", - "xpack.data.mgmt.searchSessions.table.headerName": "名称", - "xpack.data.mgmt.searchSessions.table.headerStarted": "创建时间", - "xpack.data.mgmt.searchSessions.table.headerStatus": "状态", - "xpack.data.mgmt.searchSessions.table.headerType": "应用", - "xpack.data.mgmt.searchSessions.table.mlAppName": "Machine Learning", - "xpack.data.mgmt.searchSessions.table.notRestorableWarning": "搜索会话将重新执行。然后,您可以将其保存,供未来使用。", - "xpack.data.mgmt.searchSessions.table.numSearches": "搜索数", - "xpack.data.mgmt.searchSessions.table.versionIncompatibleWarning": "此搜索会话在运行不同版本的 Kibana 实例中已创建。其可能不会正确还原。", - "xpack.data.search.statusError": "搜索完成,状态为 {errorCode}", - "xpack.data.search.statusThrow": "搜索状态引发错误 {message} ({errorCode}) 状态", - "xpack.data.searchSessionIndicator.cancelButtonText": "停止会话", - "xpack.data.searchSessionIndicator.canceledDescriptionText": "您正查看不完整的数据", - "xpack.data.searchSessionIndicator.canceledIconAriaLabel": "搜索会话已停止", - "xpack.data.searchSessionIndicator.canceledTitleText": "搜索会话已停止", - "xpack.data.searchSessionIndicator.canceledTooltipText": "搜索会话已停止", - "xpack.data.searchSessionIndicator.canceledWhenText": "已于 {when} 停止", - "xpack.data.searchSessionIndicator.continueInBackgroundButtonText": "保存会话", - "xpack.data.searchSessionIndicator.disabledDueToDisabledGloballyMessage": "您无权管理搜索会话", - "xpack.data.searchSessionIndicator.disabledDueToTimeoutMessage": "搜索会话结果已过期。", - "xpack.data.searchSessionIndicator.loadingInTheBackgroundDescriptionText": "可以从“管理”中返回至完成的结果", - "xpack.data.searchSessionIndicator.loadingInTheBackgroundIconAriaLabel": "已保存会话正在进行中", - "xpack.data.searchSessionIndicator.loadingInTheBackgroundIconTooltipText": "已保存会话正在进行中", - "xpack.data.searchSessionIndicator.loadingInTheBackgroundTitleText": "已保存会话正在进行中", - "xpack.data.searchSessionIndicator.loadingInTheBackgroundWhenText": "已于 {when} 启动", - "xpack.data.searchSessionIndicator.loadingResultsDescription": "保存您的会话,继续您的工作,然后返回到完成的结果", - "xpack.data.searchSessionIndicator.loadingResultsIconAriaLabel": "搜索会话正在加载", - "xpack.data.searchSessionIndicator.loadingResultsIconTooltipText": "搜索会话正在加载", - "xpack.data.searchSessionIndicator.loadingResultsTitle": "您的搜索将需要一些时间......", - "xpack.data.searchSessionIndicator.loadingResultsWhenText": "已于 {when} 启动", - "xpack.data.searchSessionIndicator.restoredDescriptionText": "您在查看特定时间范围的缓存数据。更改时间范围或筛选将会重新运行会话", - "xpack.data.searchSessionIndicator.restoredResultsIconAriaLabel": "已保存会话已还原", - "xpack.data.searchSessionIndicator.restoredResultsTooltipText": "搜索会话已还原", - "xpack.data.searchSessionIndicator.restoredTitleText": "搜索会话已还原", - "xpack.data.searchSessionIndicator.restoredWhenText": "已于 {when} 完成", - "xpack.data.searchSessionIndicator.resultLoadedInTheBackgroundDescriptionText": "可以从“管理”中返回到这些结果", - "xpack.data.searchSessionIndicator.resultLoadedInTheBackgroundIconAriaLabel": "已保存会话已完成", - "xpack.data.searchSessionIndicator.resultLoadedInTheBackgroundIconTooltipText": "已保存会话已完成", - "xpack.data.searchSessionIndicator.resultLoadedInTheBackgroundTitleText": "搜索会话已保存", - "xpack.data.searchSessionIndicator.resultLoadedInTheBackgroundWhenText": "已于 {when} 完成", - "xpack.data.searchSessionIndicator.resultsLoadedDescriptionText": "保存您的会话,之后可返回", - "xpack.data.searchSessionIndicator.resultsLoadedIconAriaLabel": "搜索会话已完成", - "xpack.data.searchSessionIndicator.resultsLoadedIconTooltipText": "搜索会话已完成", - "xpack.data.searchSessionIndicator.resultsLoadedText": "搜索会话已完成", - "xpack.data.searchSessionIndicator.resultsLoadedWhenText": "已于 {when} 完成", - "xpack.data.searchSessionIndicator.saveButtonText": "保存会话", - "xpack.data.searchSessionIndicator.viewSearchSessionsLinkText": "管理会话", - "xpack.data.searchSessionName.ariaLabelText": "搜索会话名称", - "xpack.data.searchSessionName.editAriaLabelText": "编辑搜索会话名称", - "xpack.data.searchSessionName.placeholderText": "为搜索会话输入名称", - "xpack.data.searchSessionName.saveButtonText": "保存", - "xpack.data.sessions.management.flyoutText": "此搜索会话的配置", - "xpack.data.sessions.management.flyoutTitle": "检查搜索会话", "xpack.dataVisualizer.addCombinedFieldsLabel": "添加组合字段", "xpack.dataVisualizer.choroplethMap.topValuesCount": "{fieldName} 的排名最前值计数", "xpack.dataVisualizer.chrome.help.appName": "数据可视化工具", @@ -11962,7 +11934,6 @@ "xpack.enterpriseSearch.workplaceSearch.groups.newGroup.action": "管理组", "xpack.enterpriseSearch.workplaceSearch.groups.newGroupSavedSuccess": "已成功创建 {groupName}", "xpack.enterpriseSearch.workplaceSearch.groups.noSourcesMessage": "无组织内容源", - "xpack.enterpriseSearch.workplaceSearch.groups.noUsersMessage": "无用户", "xpack.enterpriseSearch.workplaceSearch.groups.overview.confirmRemoveButtonText": "删除 {name}", "xpack.enterpriseSearch.workplaceSearch.groups.overview.confirmRemoveDescription": "您的组将从 Workplace Search 中删除。确定要移除 {name}?", "xpack.enterpriseSearch.workplaceSearch.groups.overview.confirmTitleText": "确认", @@ -12950,7 +12921,6 @@ "xpack.fleet.fleetServerSetup.cloudDeploymentLink": "编辑部署", "xpack.fleet.fleetServerSetup.cloudSetupText": "需要提供 Fleet 服务器,才能使用 Fleet 注册代理。获取 Fleet 服务器的最简单方法是添加集成服务器,它会运行 Fleet 服务器集成。您可以在云控制台中将其添加到部署中。有关更多信息,请参阅{link}", "xpack.fleet.fleetServerSetup.cloudSetupTitle": "启用 Fleet 服务器", - "xpack.fleet.fleetServerSetup.continueButton": "继续", "xpack.fleet.fleetServerSetup.deploymentModeProductionOption": "{production} – 提供您自己的证书。注册到 Fleet 时,此选项将需要代理指定证书密钥", "xpack.fleet.fleetServerSetup.deploymentModeQuickStartOption": "{quickStart} – Fleet 服务器将生成自签名证书。必须使用 --insecure 标志注册后续代理。不推荐用于生产用例。", "xpack.fleet.fleetServerSetup.errorAddingFleetServerHostTitle": "添加 Fleet 服务器主机时出错", @@ -12959,23 +12929,16 @@ "xpack.fleet.fleetServerSetup.fleetSettingsLink": "Fleet 设置", "xpack.fleet.fleetServerSetup.generateServiceTokenButton": "生成服务令牌", "xpack.fleet.fleetServerSetup.generateServiceTokenDescription": "服务令牌授予 Fleet 服务器向 Elasticsearch 写入的权限。", - "xpack.fleet.fleetServerSetup.installAgentDescription": "从代理目录中,复制并运行适当的快速启动命令,以使用生成的令牌和自签名证书将 Elastic 代理启动为 Fleet 服务器。有关如何将自己的证书用于生产部署,请参阅 {userGuideLink}。所有命令都需要管理员权限。", "xpack.fleet.fleetServerSetup.productionText": "生产", "xpack.fleet.fleetServerSetup.quickStartText": "快速启动", "xpack.fleet.fleetServerSetup.saveServiceTokenDescription": "保存服务令牌信息。其仅显示一次。", "xpack.fleet.fleetServerSetup.serviceTokenLabel": "服务令牌", "xpack.fleet.fleetServerSetup.setupGuideLink": "Fleet 和 Elastic 代理指南", - "xpack.fleet.fleetServerSetup.setupText": "需要提供 Fleet 服务器,才能使用 Fleet 注册代理。按照下面的说明设置 Fleet 服务器。有关详细信息,请参阅{userGuideLink}。", - "xpack.fleet.fleetServerSetup.setupTitle": "添加 Fleet 服务器", "xpack.fleet.fleetServerSetup.stepCreateAgentPolicyTitle": "创建代理策略来托管 Fleet 服务器", "xpack.fleet.fleetServerSetup.stepDeploymentModeDescriptionText": "Fleet 使用传输层安全 (TLS) 加密 Elastic 代理和 Elastic Stack 中的其他组件之间的流量。选择部署模式来决定处理证书的方式。您的选择将影响后面步骤中显示的 Fleet 服务器设置命令。", "xpack.fleet.fleetServerSetup.stepDeploymentModeTitle": "为安全选择部署模式", - "xpack.fleet.fleetServerSetup.stepFleetServerCompleteDescription": "现在可以将代理注册到 Fleet。", - "xpack.fleet.fleetServerSetup.stepFleetServerCompleteTitle": "Fleet 服务器已连接", "xpack.fleet.fleetServerSetup.stepGenerateServiceTokenTitle": "生成服务令牌", - "xpack.fleet.fleetServerSetup.stepInstallAgentTitle": "启动 Fleet 服务器", "xpack.fleet.fleetServerSetup.stepSelectAgentPolicyTitle": "选择代理策略来托管 Fleet 服务器", - "xpack.fleet.fleetServerSetup.stepWaitingForFleetServerTitle": "正在等待 Fleet 服务器连接......", "xpack.fleet.fleetServerSetup.waitingText": "等候 Fleet 服务器连接......", "xpack.fleet.fleetServerSetupPermissionDeniedErrorMessage": "需要设置 Fleet 服务器。这需要 {roleName} 集群权限。请联系您的管理员。", "xpack.fleet.fleetServerSetupPermissionDeniedErrorTitle": "权限被拒绝", @@ -18677,7 +18640,6 @@ "xpack.ml.jobsList.alertingRules.tooltipContent": "作业具有 {rulesCount} 个关联的告警{rulesCount, plural, other {规则}}", "xpack.ml.jobsList.analyticsSpacesLabel": "工作区", "xpack.ml.jobsList.auditMessageColumn.screenReaderDescription": "过去 24 小时里该作业有错误或警告时,此列显示图标", - "xpack.ml.jobsList.breadcrumb": "作业", "xpack.ml.jobsList.cannotSelectRowForJobMessage": "无法选择作业 ID {jobId}", "xpack.ml.jobsList.cloneJobErrorMessage": "无法克隆 {jobId}。找不到作业", "xpack.ml.jobsList.closeActionStatusText": "关闭", @@ -20023,13 +19985,10 @@ "xpack.ml.trainedModels.testModelsFlyout.headerLabel": "测试已训练模型", "xpack.ml.trainedModels.testModelsFlyout.inferenceError": "发生错误", "xpack.ml.trainedModels.testModelsFlyout.langIdent.inputText": "输入文本", - "xpack.ml.trainedModels.testModelsFlyout.langIdent.markupTab": "输出", "xpack.ml.trainedModels.testModelsFlyout.langIdent.output.language_title": "语言", "xpack.ml.trainedModels.testModelsFlyout.langIdent.output.probability_title": "可能性", "xpack.ml.trainedModels.testModelsFlyout.langIdent.output.title": "这像是 {lang}", "xpack.ml.trainedModels.testModelsFlyout.langIdent.output.titleUnknown": "语言代码未知:{code}", - "xpack.ml.trainedModels.testModelsFlyout.langIdent.rawOutput": "原始输出", - "xpack.ml.trainedModels.testModelsFlyout.langIdent.runButton": "测试", "xpack.ml.trainedModels.testModelsFlyout.ner.output.probabilityTitle": "可能性", "xpack.ml.trainedModels.testModelsFlyout.ner.output.typeTitle": "类型", "xpack.ml.trainedModelsBreadcrumbs.nodeOverviewLabel": "节点", @@ -21871,12 +21830,6 @@ "xpack.observability.noDataConfig.beatsCard.title": "添加集成", "xpack.observability.noDataConfig.solutionName": "Observability", "xpack.observability.notAvailable": "不可用", - "xpack.observability.overview.alert.allTypes": "所有类型", - "xpack.observability.overview.alert.appLink": "显示所有告警", - "xpack.observability.overview.alert.errorMessage": "加载告警数据时出现错误。请稍后重试。", - "xpack.observability.overview.alert.errorTitle": "我们无法加载告警数据", - "xpack.observability.overview.alerts.appLink": "显示告警", - "xpack.observability.overview.alerts.muted": "已静音", "xpack.observability.overview.alerts.title": "告警", "xpack.observability.overview.apm.appLink": "显示服务库存", "xpack.observability.overview.apm.services": "服务", @@ -22182,9 +22135,6 @@ "xpack.osquery.liveQueryDetails.viewLiveQueriesHistoryTitle": "查看实时查询历史记录", "xpack.osquery.liveQueryForm.form.saveForLaterButtonLabel": "保存,以后继续", "xpack.osquery.liveQueryForm.form.submitButtonLabel": "提交", - "xpack.osquery.liveQueryForm.steps.agentsStepHeading": "选择代理", - "xpack.osquery.liveQueryForm.steps.queryStepHeading": "输入查询", - "xpack.osquery.liveQueryForm.steps.resultsStepHeading": "检查结果", "xpack.osquery.liveQueryResults.table.agentColumnTitle": "代理", "xpack.osquery.liveQueryResults.table.fieldMappedLabel": "字段已映射到", "xpack.osquery.newLiveQuery.pageTitle": "新建实时查询", @@ -22666,7 +22616,6 @@ "xpack.reporting.publicNotifier.csvContainsFormulas.formulaReportMessage": "报告“{reportObjectTitle}”包含电子表格应用程序可解释为公式的字符。", "xpack.reporting.publicNotifier.csvContainsFormulas.formulaReportTitle": "{reportType} 可能包含公式", "xpack.reporting.publicNotifier.downloadReportButtonLabel": "下载报告", - "xpack.reporting.publicNotifier.error.calloutTitle": "报告作业失败", "xpack.reporting.publicNotifier.error.checkManagement": "前往 {path} 了解详情。", "xpack.reporting.publicNotifier.error.couldNotCreateReportTitle": "无法为“{reportObjectTitle}”创建 {reportType} 报告。", "xpack.reporting.publicNotifier.error.reportingSectionUrlLinkLabel": "堆栈管理 > Kibana > Reporting", @@ -25680,17 +25629,11 @@ "xpack.securitySolution.endpoint.policyResponse.appliedOn": "修订 {rev} 应用于 {date}", "xpack.securitySolution.endpoint.policyResponse.backLinkTitle": "终端详情", "xpack.securitySolution.endpoint.policyResponse.title": "策略响应", - "xpack.securitySolution.endpoint.resolver.compactBillions": "B", - "xpack.securitySolution.endpoint.resolver.compactMillions": "M", - "xpack.securitySolution.endpoint.resolver.compactOverflow": "+", - "xpack.securitySolution.endpoint.resolver.compactThousands": "k", - "xpack.securitySolution.endpoint.resolver.compactTrillions": "T", "xpack.securitySolution.endpoint.resolver.eitherLineageLimitExceeded": "下面可视化和事件列表中的一些进程事件无法显示,因为已达到数据限制。", "xpack.securitySolution.endpoint.resolver.elapsedTime": "{duration} {durationType}", "xpack.securitySolution.endpoint.resolver.errorProcess": "进程错误", "xpack.securitySolution.endpoint.resolver.loadingError": "加载数据时出错。", "xpack.securitySolution.endpoint.resolver.loadingProcess": "正在加载进程", - "xpack.securitySolution.endpoint.resolver.node.pillNumber": "{mantissa}{scale}{hasRemainder}", "xpack.securitySolution.endpoint.resolver.panel.error.error": "错误", "xpack.securitySolution.endpoint.resolver.panel.error.events": "事件", "xpack.securitySolution.endpoint.resolver.panel.error.goBack": "查看所有进程", @@ -27015,8 +26958,6 @@ "xpack.securitySolution.trustedApps.assignmentSectionDescription": "跨所有策略全局分配此受信任的应用程序,或将其分配给特定策略。", "xpack.securitySolution.trustedapps.card.operator.is": "是", "xpack.securitySolution.trustedapps.card.operator.matches": "匹配", - "xpack.securitySolution.trustedApps.conditionsSectionDescription": "选择操作系统,然后添加条件。条件的可用性可能取决于您选定的 OS。", - "xpack.securitySolution.trustedApps.conditionsSectionTitle": "条件", "xpack.securitySolution.trustedapps.create.conditionFieldDegradedPerformanceMsg": "[{row}] 文件名中存在通配符将影响终端性能", "xpack.securitySolution.trustedapps.create.conditionFieldDuplicatedMsg": "不能多次添加 {field}", "xpack.securitySolution.trustedapps.create.conditionFieldInvalidHashMsg": "[{row}] 无效的哈希值", @@ -27024,40 +26965,9 @@ "xpack.securitySolution.trustedapps.create.conditionFieldValueRequiredMsg": "[{row}] 字段条目必须包含值", "xpack.securitySolution.trustedapps.create.conditionRequiredMsg": "至少需要一个字段定义", "xpack.securitySolution.trustedapps.create.description": "描述", - "xpack.securitySolution.trustedapps.create.name": "命名受信任的应用程序", "xpack.securitySolution.trustedapps.create.nameRequiredMsg": "“名称”必填", - "xpack.securitySolution.trustedapps.create.os": "选择操作系统", "xpack.securitySolution.trustedapps.create.osRequiredMsg": "“操作系统”必填", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.cancelButton": "取消", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.createSaveButton": "添加受信任的应用程序", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.createTitle": "添加受信任的应用程序", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.editSaveButton": "保存", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.editTitle": "编辑受信任的应用程序", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.expiredLicenseMessage": "您的 Kibana 许可证已降级。现在会将未来的策略配置全局分配给所有策略。有关更多信息,请参见 ", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.expiredLicenseTitle": "已过期许可证", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.notFoundToastMessage": "无法编辑受信任的应用程序 ({apiMsg})", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.successToastTitle": "“{name}”已添加到受信任的应用程序列表。", - "xpack.securitySolution.trustedapps.createTrustedAppFlyout.updateSuccessToastTitle": "“{name}”已更新。", - "xpack.securitySolution.trustedapps.creationSuccess.title": "成功!", - "xpack.securitySolution.trustedapps.deletionDialog.calloutMessage": "删除此条目会将其从 {count} 个关联{count, plural, other {策略}}中移除。", - "xpack.securitySolution.trustedapps.deletionDialog.calloutTitle": "警告", - "xpack.securitySolution.trustedapps.deletionDialog.cancelButton": "取消", - "xpack.securitySolution.trustedapps.deletionDialog.confirmButton": "删除", - "xpack.securitySolution.trustedapps.deletionDialog.subMessage": "此操作无法撤消。是否确定要继续?", - "xpack.securitySolution.trustedapps.deletionDialog.title": "删除“{name}”", - "xpack.securitySolution.trustedapps.deletionError.text": "无法从受信任的应用程序列表中移除“{name}”。原因:{message}", - "xpack.securitySolution.trustedapps.deletionError.title": "移除失败", - "xpack.securitySolution.trustedapps.deletionSuccess.text": "“{name}”已从受信任的应用程序列表中移除。", - "xpack.securitySolution.trustedapps.deletionSuccess.title": "已成功移除", - "xpack.securitySolution.trustedApps.detailsSectionTitle": "详情", - "xpack.securitySolution.trustedapps.docsLink": "受信任的应用程序文档。", - "xpack.securitySolution.trustedapps.grid.cardAction.delete": "删除受信任的应用程序", - "xpack.securitySolution.trustedapps.grid.cardAction.edit": "编辑受信任的应用程序", - "xpack.securitySolution.trustedapps.grid.policyDetailsLinkBackLabel": "返回到受信任的应用程序", "xpack.securitySolution.trustedapps.list.addButton": "添加受信任的应用程序", - "xpack.securitySolution.trustedapps.list.pageTitle": "受信任的应用程序", - "xpack.securitySolution.trustedapps.list.search.placeholder": "搜索下面的字段:name、description、value", - "xpack.securitySolution.trustedapps.list.totalCount": "正在显示 {totalItemsCount, plural, other {# 个受信任的应用程序}}", "xpack.securitySolution.trustedapps.listEmptyState.message": "添加受信任的应用程序,以提高性能或缓解与主机上运行的其他应用程序的冲突。", "xpack.securitySolution.trustedapps.listEmptyState.title": "添加您的首个受信任应用程序", "xpack.securitySolution.trustedapps.logicalConditionBuilder.entry.field.description.hash": "md5、sha1 或 sha256", @@ -27069,14 +26979,9 @@ "xpack.securitySolution.trustedapps.logicalConditionBuilder.entry.removeLabel": "移除条目", "xpack.securitySolution.trustedapps.logicalConditionBuilder.group.andOperator": "AND", "xpack.securitySolution.trustedapps.logicalConditionBuilder.noEntries": "未定义条件", - "xpack.securitySolution.trustedapps.middleware.editIdMissing": "未提供 ID", "xpack.securitySolution.trustedapps.trustedapp.entry.field": "字段", "xpack.securitySolution.trustedapps.trustedapp.entry.operator": "运算符", "xpack.securitySolution.trustedapps.trustedapp.entry.value": "值", - "xpack.securitySolution.trustedapps.updateSuccess.title": "成功!", - "xpack.securitySolution.trustedapps.view.toggle.grid": "网格视图", - "xpack.securitySolution.trustedapps.view.toggle.list": "列表视图", - "xpack.securitySolution.trustedapps.viewTypeToggle.controlLegend": "视图类型", "xpack.securitySolution.trustedAppsTab": "受信任的应用程序", "xpack.securitySolution.uiSettings.defaultAnomalyScoreDescription": "

要在 Security 应用中显示的 Machine Learning 作业异常所需超过的值。

有效值:0 到 100。

", "xpack.securitySolution.uiSettings.defaultAnomalyScoreLabel": "异常阈值", @@ -28320,13 +28225,6 @@ "xpack.timelines.clipboard.copy.to.the.clipboard": "复制到剪贴板", "xpack.timelines.clipboard.to.the.clipboard": "至剪贴板", "xpack.timelines.copyToClipboardTooltip": "复制到剪贴板", - "xpack.timelines.draggables.field.categoryLabel": "类别", - "xpack.timelines.draggables.field.fieldLabel": "字段", - "xpack.timelines.draggables.field.typeLabel": "类型", - "xpack.timelines.draggables.field.viewCategoryTooltip": "查看类别", - "xpack.timelines.emptyString.emptyStringDescription": "空字符串", - "xpack.timelines.eventDetails.copyToClipboardTooltip": "复制到剪贴板", - "xpack.timelines.exitFullScreenButton": "退出全屏", "xpack.timelines.fieldBrowser.categoriesCountTitle": "{totalCount} {totalCount, plural, other {个类别}}", "xpack.timelines.fieldBrowser.categoriesTitle": "类别", "xpack.timelines.fieldBrowser.categoryLabel": "类别", @@ -28417,8 +28315,6 @@ "xpack.timelines.timeline.closedAlertSuccessToastMessage": "已成功关闭 {totalAlerts} 个{totalAlerts, plural, other {告警}}。", "xpack.timelines.timeline.closeSelectedTitle": "标记为已关闭", "xpack.timelines.timeline.descriptionTooltip": "描述", - "xpack.timelines.timeline.eventHasEventRendererScreenReaderOnly": "位于行 {row} 的事件具有事件呈现程序。按 shift + 向下箭头键以对其聚焦。", - "xpack.timelines.timeline.eventHasNotesScreenReaderOnly": "位于行 {row} 的事件有{notesCount, plural, =1 {备注} other { {notesCount} 个备注}}。按 shift + 右箭头键以聚焦备注。", "xpack.timelines.timeline.eventsTableAriaLabel": "事件;第 {activePage} 页,共 {totalPages} 页", "xpack.timelines.timeline.fieldTooltip": "字段", "xpack.timelines.timeline.flyout.pane.removeColumnButtonLabel": "移除列", @@ -28435,7 +28331,6 @@ "xpack.timelines.timeline.updateAlertStatusFailedDetailed": "{ updated } 个{updated, plural, other {告警}}已成功更新,但是 { conflicts } 个无法更新,\n 因为{ conflicts, plural, other {其}}已被修改。", "xpack.timelines.timeline.updateAlertStatusFailedSingleAlert": "无法更新告警,因为它已被修改。", "xpack.timelines.timeline.youAreInAnEventRendererScreenReaderOnly": "您正处于第 {row} 行的事件呈现器中。按向上箭头键退出并返回当前行,或按向下箭头键退出并前进到下一行。", - "xpack.timelines.timeline.youAreInATableCellScreenReaderOnly": "您处在表单元格中。行:{row},列:{column}", "xpack.timelines.timelineEvents.errorSearchDescription": "搜索时间线事件时发生错误", "xpack.timelines.toolbar.bulkActions.clearSelectionTitle": "清除所选内容", "xpack.timelines.toolbar.bulkActions.selectAllAlertsTitle": "选择全部 {totalAlertsFormatted} 个{totalAlerts, plural, other {告警}}", @@ -29563,7 +29458,6 @@ "xpack.triggersActionsUI.sections.rulesList.ruleStatusActive": "活动", "xpack.triggersActionsUI.sections.rulesList.ruleStatusDropdownMenuLabel": "更改规则状态或暂停", "xpack.triggersActionsUI.sections.rulesList.ruleStatusError": "错误", - "xpack.triggersActionsUI.sections.rulesList.ruleStatusFilterLabel": "上次响应", "xpack.triggersActionsUI.sections.rulesList.ruleStatusLicenseError": "许可证错误", "xpack.triggersActionsUI.sections.rulesList.ruleStatusOk": "确定", "xpack.triggersActionsUI.sections.rulesList.ruleStatusPending": "待处理", @@ -29988,872 +29882,872 @@ "xpack.upgradeAssistant.upgradedTitle": "您的集群已升级", "xpack.upgradeAssistant.upgradingDescription": "一个或多个 Elasticsearch 节点的 Elasticsearch 版本比 Kibana 版本新。所有节点升级后,请升级 Kibana。", "xpack.upgradeAssistant.upgradingTitle": "您的集群正在升级", - "xpack.uptime.addDataButtonLabel": "添加数据", - "xpack.uptime.addMonitor.pageHeader.title": "添加监测", - "xpack.uptime.addMonitorRoute.title": "添加监测 | {baseTitle}", - "xpack.uptime.alertDropdown.noWritePermissions": "您需要 Uptime 的读写访问权限才能在此应用中创建告警。", - "xpack.uptime.alerts.anomaly.criteriaExpression.ariaLabel": "显示选定监测的条件的表达式。", - "xpack.uptime.alerts.anomaly.criteriaExpression.description": "当监测", - "xpack.uptime.alerts.anomaly.scoreExpression.ariaLabel": "显示异常告警阈值的条件的表达式。", - "xpack.uptime.alerts.anomaly.scoreExpression.description": "具有异常,严重性为", - "xpack.uptime.alerts.createRulesPanel.title": "创建规则", - "xpack.uptime.alerts.durationAnomaly": "Uptime 持续时间异常", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.anomalyStartTimestamp": "异常开始的 ISO8601 时间戳。", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.expectedResponseTime": "预期响应时间", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.monitor": "名称或 ID 的友好呈现,建议类似于 My Monitor 的名称", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.monitorId": "监测的 ID。", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.monitorUrl": "监测的 URL。", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.observerLocation": "执行 Heartbeat 检查的观察者位置。", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.severity": "异常的严重性。", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.severityScore": "异常严重性分数", - "xpack.uptime.alerts.durationAnomaly.actionVariables.state.slowestAnomalyResponse": "在附加单位(ms、s)的异常存储桶期间最慢的响应时间。", - "xpack.uptime.alerts.durationAnomaly.clientName": "Uptime 持续时间异常", - "xpack.uptime.alerts.durationAnomaly.defaultActionMessage": "{anomalyStartTimestamp} 在 url {monitorUrl} 的 {monitor} 上检测到异常({severity} 级别)响应时间。异常严重性分数为 {severityScore}。\n从位置 {observerLocation} 检测到高达 {slowestAnomalyResponse} 的响应时间。预期响应时间为 {expectedResponseTime}。", - "xpack.uptime.alerts.durationAnomaly.description": "运行时间监测持续时间异常时告警。", - "xpack.uptime.alerts.monitorExpression.label": "移除筛选 {title}", - "xpack.uptime.alerts.monitorStatus": "运行时间监测状态", - "xpack.uptime.alerts.monitorStatus.actionVariables.availabilityMessage": "{interval} 可用性为 {availabilityRatio}%。小于 {expectedAvailability}% 时告警。", - "xpack.uptime.alerts.monitorStatus.actionVariables.context.alertReasonMessage.description": "告警原因的简洁描述", - "xpack.uptime.alerts.monitorStatus.actionVariables.context.downMonitorsWithGeo.description": "生成的摘要,显示告警已检测为“关闭”的部分或所有监测", - "xpack.uptime.alerts.monitorStatus.actionVariables.context.message.description": "生成的消息,汇总当前关闭的监测", - "xpack.uptime.alerts.monitorStatus.actionVariables.context.viewInAppUrl.description": "Elastic 中可用于进一步调查告警及其上下文的视图或功能的链接", - "xpack.uptime.alerts.monitorStatus.actionVariables.down": "在过去 {interval}中失败 {count} 次。大于 {numTimes} 时告警。", - "xpack.uptime.alerts.monitorStatus.actionVariables.downAndAvailabilityMessage": "{downMonitorsMessage} {availabilityBreachMessage}", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.currentTriggerStarted": "表示告警触发时当前触发状况开始的时间戳", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.firstCheckedAt": "表示此告警首次检查的时间戳", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.firstTriggeredAt": "表示告警首次触发的时间戳", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.isTriggered": "表示告警当前是否触发的标志", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.lastCheckedAt": "表示告警最近检查时间的时间戳", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.lastErrorMessage": "监测最新错误消息", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.lastResolvedAt": "表示此告警最近解决时间的时间戳", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.lastTriggeredAt": "表示告警最近触发时间的时间戳", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.monitor": "名称或 ID 的友好呈现,建议类似于 My Monitor 的名称", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.monitorId": "监测的 ID。", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.monitorType": "监测的类型(例如 HTTP/TCP)。", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.monitorUrl": "监测的 URL。", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.observerHostname": "执行 Heartbeat 检查的观察者主机名。", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.observerLocation": "执行 Heartbeat 检查的观察者位置。", - "xpack.uptime.alerts.monitorStatus.actionVariables.state.statusMessage": "状态消息,例如关闭和/或低于可用性阈值(如果执行可用性检查)。", - "xpack.uptime.alerts.monitorStatus.addFilter": "添加筛选", - "xpack.uptime.alerts.monitorStatus.addFilter.location": "位置", - "xpack.uptime.alerts.monitorStatus.addFilter.port": "端口", - "xpack.uptime.alerts.monitorStatus.addFilter.tag": "标签", - "xpack.uptime.alerts.monitorStatus.addFilter.type": "类型", - "xpack.uptime.alerts.monitorStatus.availability.isEnabledCheckbox.label": "可用性", - "xpack.uptime.alerts.monitorStatus.availability.threshold.anyMonitorDescription": "任何监测启动于", - "xpack.uptime.alerts.monitorStatus.availability.threshold.ariaLabel": "指定此告警的可用性阈值", - "xpack.uptime.alerts.monitorStatus.availability.threshold.description": "匹配的监测运行于", - "xpack.uptime.alerts.monitorStatus.availability.threshold.input.ariaLabel": "输入用于检查此告警的可用性阈值", - "xpack.uptime.alerts.monitorStatus.availability.threshold.value": "< {value}% 的检查", - "xpack.uptime.alerts.monitorStatus.availability.timerangeValueField.ariaLabel": "输入告警可用性检查的单位数。", - "xpack.uptime.alerts.monitorStatus.availability.timerangeValueField.expression": "(之内)过去", - "xpack.uptime.alerts.monitorStatus.availability.timerangeValueField.popover.ariaLabel": "指定跟踪时间范围的可用性", - "xpack.uptime.alerts.monitorStatus.availability.unit.headline": "选择时间范围单位", - "xpack.uptime.alerts.monitorStatus.availability.unit.selectable": "使用此选择来设置此告警的可用性范围单位", - "xpack.uptime.alerts.monitorStatus.clientName": "运行时间监测状态", - "xpack.uptime.alerts.monitorStatus.defaultActionMessage": "在 {observerLocation},URL 为 {monitorUrl} 的监测 {monitorName} 是 {statusMessage} 最新错误消息是 {latestErrorMessage}", - "xpack.uptime.alerts.monitorStatus.description": "监测关闭或超出可用性阈值时告警。", - "xpack.uptime.alerts.monitorStatus.filterBar.ariaLabel": "允许对监测状态告警使用筛选条件的输入", - "xpack.uptime.alerts.monitorStatus.filters.anyLocation": "任意位置", - "xpack.uptime.alerts.monitorStatus.filters.anyPort": "任意端口", - "xpack.uptime.alerts.monitorStatus.filters.anyTag": "任意标签", - "xpack.uptime.alerts.monitorStatus.filters.anyType": "任意类型", - "xpack.uptime.alerts.monitorStatus.filters.from": "自", - "xpack.uptime.alerts.monitorStatus.filters.fromLocation": "来源位置", - "xpack.uptime.alerts.monitorStatus.filters.location.label": "选择要应用到告警查询的位置筛选。", - "xpack.uptime.alerts.monitorStatus.filters.of": "的", - "xpack.uptime.alerts.monitorStatus.filters.ofType": "类型", - "xpack.uptime.alerts.monitorStatus.filters.port.label": "选择要应用到告警查询的端口筛选。", - "xpack.uptime.alerts.monitorStatus.filters.scheme.label": "选择要应用到告警查询的协议方案筛选。", - "xpack.uptime.alerts.monitorStatus.filters.tag.label": "选择要应用到告警查询的标签筛选。", - "xpack.uptime.alerts.monitorStatus.filters.using": "使用", - "xpack.uptime.alerts.monitorStatus.filters.usingPort": "使用端口", - "xpack.uptime.alerts.monitorStatus.filters.with": "使用", - "xpack.uptime.alerts.monitorStatus.filters.withTag": "具有标签", - "xpack.uptime.alerts.monitorStatus.monitorCallOut.title": "此告警将应用到大约 {snapshotCount} 个监测。", - "xpack.uptime.alerts.monitorStatus.numTimesExpression.anyMonitors.description": "任何监测关闭 >", - "xpack.uptime.alerts.monitorStatus.numTimesExpression.ariaLabel": "打开弹出框以输入已关闭计数", - "xpack.uptime.alerts.monitorStatus.numTimesExpression.matchingMonitors.description": "匹配的监测关闭 >", - "xpack.uptime.alerts.monitorStatus.numTimesField.ariaLabel": "输入触发告警的已关闭计数", - "xpack.uptime.alerts.monitorStatus.oldAlertCallout.title": "您可能正在编辑较旧的告警,某些字段可能不自动填充。", - "xpack.uptime.alerts.monitorStatus.recoveryMessage": "url 为 {url} 的监测 {monitor} 已恢复,状态为“运行”", - "xpack.uptime.alerts.monitorStatus.statusEnabledCheck.label": "状态检查", - "xpack.uptime.alerts.monitorStatus.timerangeOption.days": "天", - "xpack.uptime.alerts.monitorStatus.timerangeOption.hours": "小时", - "xpack.uptime.alerts.monitorStatus.timerangeOption.minutes": "分钟", - "xpack.uptime.alerts.monitorStatus.timerangeOption.months": "个月", - "xpack.uptime.alerts.monitorStatus.timerangeOption.seconds": "秒", - "xpack.uptime.alerts.monitorStatus.timerangeOption.weeks": "周", - "xpack.uptime.alerts.monitorStatus.timerangeOption.years": "年", - "xpack.uptime.alerts.monitorStatus.timerangeSelectionHeader": "选择时间范围单位", - "xpack.uptime.alerts.monitorStatus.timerangeUnitExpression.ariaLabel": "打开时间范围单位选择字段的弹出框", - "xpack.uptime.alerts.monitorStatus.timerangeUnitSelectable": "告警应使用的时间范围单位的可选择字段", - "xpack.uptime.alerts.monitorStatus.timerangeValueExpression.ariaLabel": "打开时间范围值字段的弹出框", - "xpack.uptime.alerts.monitorStatus.timerangeValueField.ariaLabel": "输入告警范围的时间单位数目", - "xpack.uptime.alerts.monitorStatus.timerangeValueField.expression": "之内", - "xpack.uptime.alerts.monitorStatus.timerangeValueField.value": "上一 {value}", - "xpack.uptime.alerts.searchPlaceholder.kql": "使用 kql 语法筛选", - "xpack.uptime.alerts.settings.addConnector": "添加连接器", - "xpack.uptime.alerts.timerangeUnitSelectable.daysOption.ariaLabel": "“天”时间范围选择项", - "xpack.uptime.alerts.timerangeUnitSelectable.hoursOption.ariaLabel": "“小时”时间范围选择项", - "xpack.uptime.alerts.timerangeUnitSelectable.minutesOption.ariaLabel": "“分钟”时间范围选择项", - "xpack.uptime.alerts.timerangeUnitSelectable.monthsOption.ariaLabel": "“月”时间范围选择项", - "xpack.uptime.alerts.timerangeUnitSelectable.secondsOption.ariaLabel": "“秒”时间范围选择项", - "xpack.uptime.alerts.timerangeUnitSelectable.weeksOption.ariaLabel": "“周”时间范围选择项", - "xpack.uptime.alerts.timerangeUnitSelectable.yearsOption.ariaLabel": "“年”时间范围选择项", - "xpack.uptime.alerts.tls": "Uptime TLS", - "xpack.uptime.alerts.tls.actionVariables.state.agingCommonNameAndDate": "检测到的证书的常见名称和到期日期/时间。", - "xpack.uptime.alerts.tls.actionVariables.state.agingCount": "检测到即将过时的证书数目。", - "xpack.uptime.alerts.tls.actionVariables.state.count": "告警执行工具检测到的证书数目", - "xpack.uptime.alerts.tls.actionVariables.state.expiringCommonNameAndDate": "检测到的证书的常见名称和到期日期/时间", - "xpack.uptime.alerts.tls.actionVariables.state.expiringCount": "告警检测到的即将到期证书数目。", - "xpack.uptime.alerts.tls.ageExpression.ariaLabel": "显示将触发旧证书 TLS 告警的阈值的表达式", - "xpack.uptime.alerts.tls.ageExpression.description": "或超过", - "xpack.uptime.alerts.tls.ageExpression.value": "{value} 天内过期的证书", - "xpack.uptime.alerts.tls.agingLabel": "已过旧", - "xpack.uptime.alerts.tls.clientName": "Uptime TLS", - "xpack.uptime.alerts.tls.criteriaExpression.ariaLabel": "显示此告警监视的监测条件的表达式", - "xpack.uptime.alerts.tls.criteriaExpression.description": "当", - "xpack.uptime.alerts.tls.criteriaExpression.value": "任意监测", - "xpack.uptime.alerts.tls.defaultActionMessage": "检测到来自颁发者 {issuer} 的 TLS 证书 {commonName} 的状态为 {status}。证书 {summary}\n", - "xpack.uptime.alerts.tls.description": "运行时间监测的 TLS 证书即将过期时告警。", - "xpack.uptime.alerts.tls.expirationExpression.ariaLabel": "显示将触发证书过期 TLS 告警的阈值的表达式", - "xpack.uptime.alerts.tls.expirationExpression.description": "具有将在", - "xpack.uptime.alerts.tls.expirationExpression.value": "{value} 天内过期的证书", - "xpack.uptime.alerts.tls.expiredLabel": "已过期", - "xpack.uptime.alerts.tls.expiringLabel": "将到期", - "xpack.uptime.alerts.tls.invalidLabel": "无效", - "xpack.uptime.alerts.tls.legacy.clientName": "Uptime TLS(旧版)", - "xpack.uptime.alerts.tls.legacy.defaultActionMessage": "检测到 {count} 个 TLS 证书即将过期或即将过时。\n{expiringConditionalOpen}\n即将过期的证书计数:{expiringCount}\n即将过期的证书:{expiringCommonNameAndDate}\n{expiringConditionalClose}\n{agingConditionalOpen}\n过时的证书计数:{agingCount}\n过时的证书:{agingCommonNameAndDate}\n{agingConditionalClose}\n", - "xpack.uptime.alerts.tls.legacy.description": "运行时间监测的 TLS 证书即将过期时告警。未来的版本将弃用此告警。", - "xpack.uptime.alerts.tls.settingsPageNav.text": "可以在 {settingsPageLink}上编辑这些阈值。", - "xpack.uptime.alerts.tls.validAfterExpiredString": "已于 {relativeDate} 天前,即 {date}到期。", - "xpack.uptime.alerts.tls.validAfterExpiringString": "将在{relativeDate} 天后,即 {date}到期。", - "xpack.uptime.alerts.tls.validBeforeExpiredString": "自 {relativeDate} 天前,即 {date}开始生效。", - "xpack.uptime.alerts.tls.validBeforeExpiringString": "从现在到 {date}的 {relativeDate} 天里无效。", - "xpack.uptime.alerts.tlsLegacy": "Uptime TLS(旧版)", - "xpack.uptime.alerts.toggleAlertFlyoutButtonText": "告警和规则", - "xpack.uptime.alertsPopover.toggleButton.ariaLabel": "打开告警和规则上下文菜单", - "xpack.uptime.analyzeDataButtonLabel": "浏览数据", - "xpack.uptime.analyzeDataButtonLabel.message": "“浏览数据”允许您选择和筛选任意维度中的结果数据以及查找性能问题的原因或影响。", - "xpack.uptime.apmIntegrationAction.description": "在 APM 中搜索此监测", - "xpack.uptime.apmIntegrationAction.text": "显示 APM 数据", - "xpack.uptime.availabilityLabelText": "{value} %", - "xpack.uptime.badge.readOnly.text": "只读", - "xpack.uptime.badge.readOnly.tooltip": "无法保存", - "xpack.uptime.breadcrumbs.observabilityText": "Observability", - "xpack.uptime.breadcrumbs.overviewBreadcrumbText": "运行时间", - "xpack.uptime.certificates.heading": "TLS 证书 ({total})", - "xpack.uptime.certificates.loading": "正在加载证书......", - "xpack.uptime.certificates.refresh": "刷新", - "xpack.uptime.certificatesPage.heading": "TLS 证书", - "xpack.uptime.certificatesRoute.title": "证书 | {baseTitle}", - "xpack.uptime.certs.expired": "已过期", - "xpack.uptime.certs.expires": "过期", - "xpack.uptime.certs.expireSoon": "即将过期", - "xpack.uptime.certs.list.ageCol": "存在时间", - "xpack.uptime.certs.list.commonName": "常见名称", - "xpack.uptime.certs.list.copyFingerprint": "单击可复制指纹值", - "xpack.uptime.certs.list.days": "天", - "xpack.uptime.certs.list.empty": "找不到任何证书。注意:证书仅对 Heartbeat 7.8+ 可见", - "xpack.uptime.certs.list.expirationDate": "指纹", - "xpack.uptime.certs.list.issuedBy": "颁发者", - "xpack.uptime.certs.list.monitors": "监测", - "xpack.uptime.certs.list.status": "状态", - "xpack.uptime.certs.list.status.old": "过旧", - "xpack.uptime.certs.list.validUntil": "失效日期", - "xpack.uptime.certs.ok": "确定", - "xpack.uptime.certs.searchCerts": "搜索证书", - "xpack.uptime.certs.status.ok.label": " 对于 {okRelativeDate}", - "xpack.uptime.charts.mlAnnotation.header": "分数:{score}", - "xpack.uptime.charts.mlAnnotation.severity": "严重性:{severity}", - "xpack.uptime.controls.selectSeverity.criticalLabel": "紧急", - "xpack.uptime.controls.selectSeverity.majorLabel": "重大", - "xpack.uptime.controls.selectSeverity.minorLabel": "轻微", - "xpack.uptime.controls.selectSeverity.scoreDetailsDescription": "{value} 及以上分数", - "xpack.uptime.controls.selectSeverity.warningLabel": "警告", - "xpack.uptime.createPackagePolicy.stepConfigure.browser.scriptRecorder.experimentalLabel": "技术预览", - "xpack.uptime.createPackagePolicy.stepConfigure.browser.scriptRecorder.experimentalTooltip": "预览通过 Elastic Synthetics 记录器创建 Elastic Synthetics 监测脚本的最快方式", - "xpack.uptime.createPackagePolicy.stepConfigure.browser.scriptRecorder.label": "脚本记录器", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.description": "为 Synthetics 代理提供微调的配置。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.filtering.description": "使用这些选项可将选定监测设置应用于您套件中的测试子集。仅配置的子集由此监测运行。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.filtering.title": "选择性测试", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.ignoreHttpsErrors.helpText": "将此选项设为 true 可在 Synthetics 浏览器中禁用 TLS/SSL 验证。这对于使用自签名证书的测试站点很有用。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.ignoreHttpsErrors.label": "忽略 HTTPS 错误", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersMatch.helpText": "通过此监测仅运行名称与提供的 glob 匹配的过程。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersMatch.label": "筛选匹配", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersTags.helpText": "通过此监测仅运行具有给定标签的过程。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersTags.label": "筛选标签", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.screenshots.helpText": "设置此选项以管理 Synthetics 代理捕获的屏幕截图。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.screenshots.label": "屏幕截图选项", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.syntheticsArgs.helpText": "要传递给 Synthetics 代理软件包的附加参数。取字符串列表。这在极少情况下有用,通常应不需要设置。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.syntheticsArgs.label": "Synthetics 参数", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.automatic_node_cap.message": "禁用限制时,您的监测的带宽仍然由其中运行监测的 Synthetics 节点的配置设置上限。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.automatic_node_cap.title": "自动上限", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.description": "控制监测的下载和上传速度及其延迟,以在更缓慢或更迟缓的网络上模拟应用程序的行为。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.download.error": "下载速度必须大于零。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.download.label": "下载速度", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.exceeded_throttling.message": "使用大于 Synthetics 节点带宽限制的限值时,您的监测的带宽仍然具有上限。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.exceeded_throttling.title": "您已超出 Synthetics 节点带宽限制", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.latency.error": "延迟不得为负。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.latency.label": "延迟", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.switch.description": "启用限制", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.title": "限制选项", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.upload.error": "上传速度必须大于零。", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.upload.label": "上传速度", - "xpack.uptime.createPackagePolicy.stepConfigure.browserAdvancedSettings.title": "Synthetics 代理选项", - "xpack.uptime.createPackagePolicy.stepConfigure.certificateSettings.enableSSLSettings.label": "启用 TLS 配置", - "xpack.uptime.createPackagePolicy.stepConfigure.certificateSettings.enableZipUrlSSLSettings.label": "启用用于 Zip URL 的 TLS 配置", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificate.helpText": "用于 TLS 客户端身份验证的 PEM 格式证书。", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificate.label": "证书", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificateAuthorities.helpText": "PEM 格式自定义证书颁发机构。", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificateAuthorities.label": "证书颁发机构", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificateKey.helpText": "用于 TLS 客户端身份验证的 PEM 格式证书密钥。", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificateKey.label": "密钥", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificateKeyPassphrase.helpText": "用于 TLS 客户端身份验证的证书密钥密码。", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.certificateKeyPassphrase.label": "密钥密码", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.legend": "证书设置", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.tlsRole.client": "客户端", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.tlsRole.server": "服务器", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.certificate.description": "验证提供的证书是否由受信任颁发机构 (CA) 签署,但不执行任何主机名验证。", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.certificate.label": "证书", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.full.description": "验证提供的证书是否由受信任颁发机构 (CA) 签署,同时验证服务器的主机名(或 IP 地址)是否匹配证书内识别的名称。", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.full.label": "实线", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.label": "验证模式", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.none.description": "对服务器的证书不执行验证。主要用作尝试解决 TLS 错误时的临时诊断机制;强烈不建议在生产环境中使用它。", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.none.label": "无", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.strict.description": "验证提供的证书是否由受信任颁发机构 (CA) 签署,同时验证服务器的主机名(或 IP 地址)是否匹配证书内识别的名称。如果使用者备用名称为空,将返回错误。", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.strict.label": "严格", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.warning.description": "此模式禁用了许多 SSL/TLS 安全性功能,只能在谨慎考虑之后使用。", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.verificationMode.warning.title": "正在禁用 TLS", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.version.label": "支持的 TLS 协议", - "xpack.uptime.createPackagePolicy.stepConfigure.certsField.version.placeholder": "选择一个或多个 TLS 协议。", - "xpack.uptime.createPackagePolicy.stepConfigure.headerField.addHeader.label": "添加标头", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions": "高级 HTTP 选项", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.indexResponseBody.helpText": "控制将 HTTP 响应正文内容索引到 ", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.indexResponseHeaders.helpText": "控制将 HTTP 响应标头索引到 ", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestBody.helpText": "请求正文内容。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.description": "配置要发送到远程主机的可选请求,包括方法、正文和标头。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.requestBody": "请求正文", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.requestHeaders": "请求标头", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.requestMethod.label": "请求方法", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.title": "请求配置", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestHeadersField.error": "标头密钥必须是有效的 HTTP 令牌。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestHeadersField.helpText": "要发送的额外 HTTP 标头的字典。默认情况下,客户端将设置用户代理标头以自我标识。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestMethod.helpText": "要使用的 HTTP 方法。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseBodyCheckNegative.helpText": "负匹配正文输出的正则表达式列表。按 enter 键添加新的表达式。如果单个表达式匹配,返回匹配失败。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseBodyCheckPositive.helpText": "匹配正文输出的正则表达式列表。按 enter 键添加新的表达式。仅单个表达式需要匹配。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseCheckNegative.label": "检查响应正文不包含", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseCheckPositive.label": "检查响应正文包含", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.checkResponseHeadersContain": "检查响应标头包含", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.description": "配置预期的 HTTP 响应。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.responseStatusCheck.error": "状态代码只能包含数字。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.responseStatusCheck.helpText": "预期状态代码列表。按 enter 键添加新的代码。4xx 和 5xx 代码默认情况下被视为关闭。其他代码被视为运行。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.responseStatusCheck.label": "检查响应状态等于", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.title": "响应检查", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfig.indexResponseBody": "索引响应正文", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfig.indexResponseHeaders": "索引响应标头", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfig.responseBodyIndexPolicy": "响应正文索引策略", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfiguration.description": "控制 HTTP 响应标头的索引。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfiguration.title": "响应配置", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseHeadersField.error": "标头密钥必须是有效的 HTTP 令牌。", - "xpack.uptime.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseHeadersField.helpText": "预期响应标头的列表。", - "xpack.uptime.createPackagePolicy.stepConfigure.icmpAdvancedOptions": "高级 ICMP 选项", - "xpack.uptime.createPackagePolicy.stepConfigure.inputVarFieldOptionalLabel": "可选", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.helpText": "此监测的 APM 服务名称。对应于 service.name ECS 字段。监测也使用 APM 的应用时设置此选项以启用 Kibana 中的 Uptime 和 APM 数据之间的集成。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.label": "APM 服务名称", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.brower.proxyURL.label": "代理 Zip URL", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.http.helpText": "用于 Zip URL 的 HTTP 代理。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.error": "“脚本”必填", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.helpText": "运行内联定义的 Synthetics 测试脚本。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.label": "内联脚本", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.params.helpText": "JSON 对象,定义您的测试所需的任何变量。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.params.label": "参数", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.scriptRecorder.closeButtonLabel": "关闭脚本浮出控件", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.scriptRecorder.mockFileName": "test_script.js", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.sourceType.label": "源类型", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.fieldLabel": "正在测试脚本", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.invalidFileError": "文件类型无效。请上传由 Elastic Synthetics 记录器生成的 .js 文件。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.label": "选择记录器生成的 .js 文件", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.parsingError": "上传文件时出错。请上传 Elastic Synthetics 记录器以内联脚本格式生成的 .js 文件。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.error": "ZIP URL 必填", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.helpText": "Synthetics 项目存储库 zip 文件的位置。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.label": "Zip URL", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.recorderLink": "下载 Elastic Synthetics 记录器", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.removeScriptLabel": "移除脚本", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.showScriptLabel": "显示脚本", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlFolder.helpText": "合成旅程文件在存储库中所在的相对目录路径。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlFolder.label": "文件夹", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlPassword.abel": "Zip URL 密码", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlPassword.helpText": "用于在 zip 终端上进行身份验证的密码。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlUsername.helpText": "用于在 zip 终端上进行身份验证的用户名。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlUsername.label": "Zip URL 用户名", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browserLabel": "浏览器(公测版)", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.enabled.helpText": "关闭此配置以禁用监测。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.enabled.label": "已启用", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.icmp.hosts": "主机", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.icmp.hosts.error": "“主机”必填", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.maxRedirects": "最大重定向数", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.maxRedirects.error": "“最大重定向数”必须不小于 0", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.maxRedirects.helpText": "要跟随的重定向总数。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorInterval": "频率", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorInterval.error": "监测频率必填", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType": "监测类型", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.description": "要创建“浏览器”监测,请确保使用 elastic-agent-complete Docker 容器,其中包含运行这些监测的依赖项。有关更多信息,请访问我们的 {link}。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.link": "Synthetics 文档", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.error": "“监测类型”必填。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.password.helpText": "用于在服务器上进行身份验证的密码。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.password.label": "密码", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyUrl.http.helpText": "HTTP 代理 URL。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyURL.http.label": "代理 URL", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyURL.label": "代理 URL", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyUrl.tcp.helpText": "连接到服务器时要使用的 SOCKS5 代理的 URL。该值必须是具有 socks5:// 方案的 URL。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.resolveHostnamesLocally": "本地解析主机名", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tags.helpText": "将随监测事件一起发送的标签列表。按 enter 键添加新标签。显示在 Uptime 中并启用按标签搜索。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tags.label": "标签", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tcp.hosts": "主机:端口", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tcp.hosts.error": "主机和端口必填", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.helpText": "允许用于测试连接并交换数据的总时间。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.label": "超时(秒)", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.lessThanIntervalError": "超时必须小于监测频率", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.moreThanZeroError": "超时必须大于或等于 0", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.URL": "URL", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.URL.error": "“URL”必填", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.username.helpText": "用于在服务器上进行身份验证的用户名。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.username.label": "用户名", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.wait.error": "“等待时间”必须不小于 0", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.wait.helpText": "如果未收到响应,在发出另一个 ICMP 回显请求之前要等待的时长。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.wait.label": "等待时间(秒)", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSectionDescription": "使用以下选项配置您的监测。", - "xpack.uptime.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSectionTitle": "监测设置", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBody.codeEditor.javascript.ariaLabel": "JavaScript 代码编辑器", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBody.codeEditor.json.ariaLabel": "JSON 代码编辑器", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBody.codeEditor.text.ariaLabel": "文本代码编辑器", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBody.codeEditor.xml.ariaLabel": "XML 代码编辑器", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBody.formField.addFormField.label": "添加表单字段", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBodyType.form": "表单", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBodyType.JSON": "JSON", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBodyType.text": "文本", - "xpack.uptime.createPackagePolicy.stepConfigure.requestBodyType.XML": "XML", - "xpack.uptime.createPackagePolicy.stepConfigure.responseBodyIndex.always": "始终", - "xpack.uptime.createPackagePolicy.stepConfigure.responseBodyIndex.onError": "错误时", - "xpack.uptime.createPackagePolicy.stepConfigure.scheduleField.minutes": "分钟", - "xpack.uptime.createPackagePolicy.stepConfigure.scheduleField.number": "数字", - "xpack.uptime.createPackagePolicy.stepConfigure.scheduleField.seconds": "秒", - "xpack.uptime.createPackagePolicy.stepConfigure.scheduleField.unit": "单位", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.description": "配置向远程主机发送的有效负载。", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.requestPayload.helpText": "要发送给远程主机的有效负载字符串。", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.requestPayload.label": "请求有效负载", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.title": "请求配置", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.responseConfiguration.responseContains.helpText": "预期远程主机响应。", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.responseConfiguration.responseContains.label": "检查响应包含", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvancedOptions.responseConfiguration.description": "配置来自远程主机的预期响应。", - "xpack.uptime.createPackagePolicy.stepConfigure.tcpAdvancedOptions.responseConfiguration.title": "响应检查", - "xpack.uptime.createPackagePolicy.stepConfigure.tlsSettings.description": "配置 TLS 选项,包括验证模式、证书颁发机构和客户端证书。", - "xpack.uptime.createPackagePolicy.stepConfigure.tlsSettings.label": "TLS 设置", - "xpack.uptime.durationChart.emptyPrompt.description": "在选定时间范围内此监测从未{emphasizedText}。", - "xpack.uptime.durationChart.emptyPrompt.title": "没有持续时间数据", - "xpack.uptime.editMonitor.pageHeader.title": "编辑监测", - "xpack.uptime.editMonitorRoute.title": "编辑监测 | {baseTitle}", - "xpack.uptime.emptyState.loadingMessage": "正在加载……", - "xpack.uptime.emptyStateError.notAuthorized": "您无权查看 Uptime 数据,请联系系统管理员。", - "xpack.uptime.emptyStateError.notFoundPage": "未找到页面", - "xpack.uptime.emptyStateError.title": "错误", - "xpack.uptime.enableAlert.editAlert": "编辑告警", - "xpack.uptime.filterBar.ariaLabel": "概览页面的输入筛选条件", - "xpack.uptime.filterBar.filterAllLabel": "全部", - "xpack.uptime.filterBar.options.location.name": "位置", - "xpack.uptime.filterBar.options.portLabel": "端口", - "xpack.uptime.filterBar.options.schemeLabel": "方案", - "xpack.uptime.filterBar.options.tagsLabel": "标签", - "xpack.uptime.fleetIntegration.assets.description": "在 Uptime 中查看监测", - "xpack.uptime.fleetIntegration.assets.name": "监测", - "xpack.uptime.inspectButtonText": "检查", - "xpack.uptime.integrationLink.missingDataMessage": "未找到此集成的所需数据。", - "xpack.uptime.keyValuePairsField.deleteItem.label": "删除项目编号 {index},{key}:{value}", - "xpack.uptime.keyValuePairsField.key.ariaLabel": "钥匙", - "xpack.uptime.keyValuePairsField.key.label": "钥匙", - "xpack.uptime.keyValuePairsField.value.ariaLabel": "值", - "xpack.uptime.keyValuePairsField.value.label": "值", - "xpack.uptime.kueryBar.searchPlaceholder.kql": "使用 kql 语法搜索监测 ID、名称和类型等(例如 monitor.type: \"http\" AND tags: \"dev\")", - "xpack.uptime.kueryBar.searchPlaceholder.simple": "按监测 ID、名称或 url(例如 http://)搜索", - "xpack.uptime.locationName.helpLinkAnnotation": "添加位置", - "xpack.uptime.mappingErrorRoute.breadcrumb": "映射错误", - "xpack.uptime.mappingErrorRoute.pageHeader.title": "映射错误", - "xpack.uptime.mappingErrorRoute.title": "Synthetics | 映射错误", - "xpack.uptime.millisecond.abbreviation.label": "ms", - "xpack.uptime.ml.durationChart.exploreInMlApp": "在 ML 应用中浏览", - "xpack.uptime.ml.enableAnomalyDetectionPanel.add_job_permissions_needed": "需要权限", - "xpack.uptime.ml.enableAnomalyDetectionPanel.anomalyDetectionTitle": "异常检测", - "xpack.uptime.ml.enableAnomalyDetectionPanel.cancelLabel": "取消", - "xpack.uptime.ml.enableAnomalyDetectionPanel.createMLJobDescription": "在此处可以创建 Machine Learning 作业,以便为运行时间监测计算\n 响应持续时间的异常分数。启用后,详情页面上的监测持续时间图表\n 将显示预期边界并使用异常标注图表。您还可能\n 识别在所有地理区域的延迟增长时段。", - "xpack.uptime.ml.enableAnomalyDetectionPanel.createNewJobButtonLabel": "创建新作业", - "xpack.uptime.ml.enableAnomalyDetectionPanel.disableAnomalyAlert": "禁用异常告警", - "xpack.uptime.ml.enableAnomalyDetectionPanel.disableAnomalyDetectionTitle": "禁用异常检测", - "xpack.uptime.ml.enableAnomalyDetectionPanel.enable_or_manage_job": "您可以启用异常检测作业,或者如果此处已有作业,则可以管理该作业或告警。", - "xpack.uptime.ml.enableAnomalyDetectionPanel.enableAnomalyAlert": "启用异常告警", - "xpack.uptime.ml.enableAnomalyDetectionPanel.enableAnomalyDetectionTitle": "启用异常检测", - "xpack.uptime.ml.enableAnomalyDetectionPanel.insufficient_permissions_add_job": "您必须具有 Machine Learning 的 Kibana 权限才能使用此功能。", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreatedLazyNotificationText": "分析正等待 ML 节点变为可用。可能要花费点时间,才会将结果添加到响应时间图表。", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreatedNotificationText": "现在正在运行响应持续时间图表的分析。可能要花费点时间,才会将结果添加到响应时间图表。", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreatedNotificationText.viewJobLinkText": "查看作业", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreatedNotificationTitle": "作业已成功创建", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreationFailedNotificationText": "您当前的许可证可能不允许创建 Machine Learning 作业,或者此作业可能已存在。", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreationFailedNotificationTitle": "作业创建失败", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobDeletionConfirmLabel": "删除异常检测作业?", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobDeletionNotificationTitle": "作业已删除", - "xpack.uptime.ml.enableAnomalyDetectionPanel.jobDeletionSuccessNotificationText": "作业已成功删除", - "xpack.uptime.ml.enableAnomalyDetectionPanel.manageAnomalyDetectionTitle": "管理异常检测", - "xpack.uptime.ml.enableAnomalyDetectionPanel.manageMLJobDescription": "创建作业后,可以在 {mlJobsPageLink} 中管理作业以及查看更多详细信息。", - "xpack.uptime.ml.enableAnomalyDetectionPanel.manageMLJobDescription.mlJobsPageLinkText": "Machine Learning 作业管理页面", - "xpack.uptime.ml.enableAnomalyDetectionPanel.manageMLJobDescription.noteText": "注意:可能要过几分钟后,作业才会开始计算结果。", - "xpack.uptime.ml.enableAnomalyDetectionPanel.noPermissionsTooltip": "您需要 Uptime 的读写访问权限才能创建异常告警。", - "xpack.uptime.ml.enableAnomalyDetectionPanel.startTrial": "开始为期 14 天的免费试用", - "xpack.uptime.ml.enableAnomalyDetectionPanel.startTrialDesc": "要访问持续时间异常检测,必须订阅 Elastic 白金级许可证。", - "xpack.uptime.monitor.simpleStatusAlert.email.subject": "URL 为 {url} 的监测 {monitor} 已关闭", - "xpack.uptime.monitorCharts.durationChart.leftAxis.title": "持续时间 ({unit})", - "xpack.uptime.monitorCharts.durationChart.wrapper.label": "显示监测的 ping 持续时间(按位置分组)的图表。", - "xpack.uptime.monitorCharts.monitorDuration.titleLabel": "监测持续时间", - "xpack.uptime.monitorCharts.monitorDuration.titleLabelWithAnomaly": "监测持续时间(异常:{noOfAnomalies})", - "xpack.uptime.monitorDetails.ml.confirmAlertDeleteMessage": "确定要删除异常告警?", - "xpack.uptime.monitorDetails.ml.confirmDeleteMessage": "是否确定要删除此作业?", - "xpack.uptime.monitorDetails.ml.deleteJobWarning": "删除作业可能会非常耗时。删除将在后台进行,数据可能不会马上消失。", - "xpack.uptime.monitorDetails.ml.deleteMessage": "正在删除作业......", - "xpack.uptime.monitorDetails.statusBar.pingType.browser": "浏览器", - "xpack.uptime.monitorDetails.statusBar.pingType.http": "HTTP", - "xpack.uptime.monitorDetails.statusBar.pingType.icmp": "ICMP", - "xpack.uptime.monitorDetails.statusBar.pingType.tcp": "TCP", - "xpack.uptime.monitorDetails.title.disclaimer.description": "(公测版)", - "xpack.uptime.monitorDetails.title.disclaimer.link": "查看更多内容", - "xpack.uptime.monitorDetails.title.pingType.browser": "浏览器", - "xpack.uptime.monitorDetails.title.pingType.http": "HTTP ping", - "xpack.uptime.monitorDetails.title.pingType.icmp": "ICMP ping", - "xpack.uptime.monitorDetails.title.pingType.tcp": "TCP ping", - "xpack.uptime.monitorList.allMonitors": "所有监测", - "xpack.uptime.monitorList.anomalyColumn.label": "响应异常分数", - "xpack.uptime.monitorList.defineConnector.description": "在 {link} 中定义默认连接器以启用状态告警。", - "xpack.uptime.monitorList.defineConnector.popover.description": "以接收状态告警。", - "xpack.uptime.monitorList.disableDownAlert": "禁用状态告警", - "xpack.uptime.monitorList.downLineSeries.downLabel": "关闭检查", - "xpack.uptime.monitorList.drawer.missingLocation": "某些 Heartbeat 实例未定义位置。{link}到您的 Heartbeat 配置。", - "xpack.uptime.monitorList.drawer.mostRecentRun": "最新测试运行", - "xpack.uptime.monitorList.drawer.statusRowLocationList": "上次检查时状态为“{status}”的位置列表。", - "xpack.uptime.monitorList.drawer.url": "URL", - "xpack.uptime.monitorList.enabledAlerts.noAlert": "没有为此监测启用规则。", - "xpack.uptime.monitorList.enabledAlerts.title": "已启用规则", - "xpack.uptime.monitorList.enableDownAlert": "启用状态告警", - "xpack.uptime.monitorList.errorSummary": "错误摘要", - "xpack.uptime.monitorList.expandDrawerButton.ariaLabel": "展开 ID {id} 的监测行", - "xpack.uptime.monitorList.geoName.helpLinkAnnotation": "添加位置", - "xpack.uptime.monitorList.infraIntegrationAction.container.message": "显示容器指标", - "xpack.uptime.monitorList.infraIntegrationAction.docker.description": "在 Infrastructure UI 上查找此监测的容器 ID", - "xpack.uptime.monitorList.infraIntegrationAction.docker.tooltip": "在 Infrastructure UI 上查找容器 ID“{containerId}”", - "xpack.uptime.monitorList.infraIntegrationAction.ip.ariaLabel": "在 Infrastructure UI 上查找此监测的 IP 地址", - "xpack.uptime.monitorList.infraIntegrationAction.ip.message": "显示主机指标", - "xpack.uptime.monitorList.infraIntegrationAction.ip.tooltip": "在 Infrastructure UI 上查找 IP“{ip}”", - "xpack.uptime.monitorList.infraIntegrationAction.kubernetes.description": "在 Infrastructure UI 上查找此监测的 Pod UID", - "xpack.uptime.monitorList.infraIntegrationAction.kubernetes.message": "显示 Pod 指标", - "xpack.uptime.monitorList.infraIntegrationAction.kubernetes.tooltip": "在 Infrastructure UI 上查找 Pod UID“{podUid}”。", - "xpack.uptime.monitorList.integrationGroup.emptyMessage": "没有可用的集成应用程序", - "xpack.uptime.monitorList.invalidMonitors": "监测无效", - "xpack.uptime.monitorList.loading": "正在加载……", - "xpack.uptime.monitorList.locations.expand": "单击以查看剩余位置", - "xpack.uptime.monitorList.loggingIntegrationAction.container.id": "显示容器日志", - "xpack.uptime.monitorList.loggingIntegrationAction.container.message": "显示容器日志", - "xpack.uptime.monitorList.loggingIntegrationAction.container.tooltip": "在 Logging UI 上查找容器 ID“{containerId}”", - "xpack.uptime.monitorList.loggingIntegrationAction.ip.description": "在 Logging UI 中查找此监测的 IP 地址", - "xpack.uptime.monitorList.loggingIntegrationAction.ip.message": "显示主机日志", - "xpack.uptime.monitorList.loggingIntegrationAction.ip.tooltip": "在 Logging UI 上查找 IP“{ip}”", - "xpack.uptime.monitorList.loggingIntegrationAction.kubernetes.ariaLabel": "显示 Pod 日志", - "xpack.uptime.monitorList.loggingIntegrationAction.kubernetes.message": "显示 Pod 日志", - "xpack.uptime.monitorList.loggingIntegrationAction.kubernetes.tooltip": "在日志中查找 Pod UID“{podUid}”", - "xpack.uptime.monitorList.monitorHistoryColumnLabel": "中断历史记录", - "xpack.uptime.monitorList.monitoringStatusTitle": "监测", - "xpack.uptime.monitorList.monitorType.filter": "筛选 {type} 类型的所有监测", - "xpack.uptime.monitorList.mostRecentError.title": "最新错误 ({timestamp})", - "xpack.uptime.monitorList.nameColumnLabel": "名称", - "xpack.uptime.monitorList.noDownHistory": "在选定时间范围内此监测从未{emphasizedText}。", - "xpack.uptime.monitorList.noItemForSelectedFiltersMessage": "未找到匹配选定筛选条件的监测", - "xpack.uptime.monitorList.noItemMessage": "未找到任何运行时间监测", - "xpack.uptime.monitorList.observabilityIntegrationsColumn.apmIntegrationLink.tooltip": "单击此处可在 APM 中查找域“{domain}”或显式定义的“服务名称”。", - "xpack.uptime.monitorList.observabilityIntegrationsColumn.popoverIconButton.ariaLabel": "打开 url {monitorUrl} 的监测的集成弹出式窗口", - "xpack.uptime.monitorList.observabilityInvestigateColumn.popoverIconButton.label": "调查", - "xpack.uptime.monitorList.pageSizePopoverButtonText": "每页行数:{size}", - "xpack.uptime.monitorList.pageSizeSelect.numRowsItemMessage": "{numRows} 行", - "xpack.uptime.monitorList.redirects.description": "执行 ping 时,Heartbeat 在 {number} 次重定向后运行。", - "xpack.uptime.monitorList.redirects.openWindow": "将在新窗口中打开链接。", - "xpack.uptime.monitorList.redirects.title": "重定向", - "xpack.uptime.monitorList.redirects.title.number": "{number}", - "xpack.uptime.monitorList.refresh": "刷新", - "xpack.uptime.monitorList.statusAlert.label": "状态告警", - "xpack.uptime.monitorList.statusColumn.checkedTimestamp": "已检查 {timestamp}", - "xpack.uptime.monitorList.statusColumn.completeLabel": "已完成", - "xpack.uptime.monitorList.statusColumn.downLabel": "关闭", - "xpack.uptime.monitorList.statusColumn.error.logs": "错误日志", - "xpack.uptime.monitorList.statusColumn.error.message": "{message}。单击了解更多详情。", - "xpack.uptime.monitorList.statusColumn.error.messageLabel": "{message}。单击了解更多详情。", - "xpack.uptime.monitorList.statusColumn.failedLabel": "失败", - "xpack.uptime.monitorList.statusColumn.locStatusMessage": "在 {noLoc} 个位置", - "xpack.uptime.monitorList.statusColumn.locStatusMessage.multiple": "在 {noLoc} 个位置", - "xpack.uptime.monitorList.statusColumn.locStatusMessage.tooltip.down": "在 {locs} 关闭", - "xpack.uptime.monitorList.statusColumn.locStatusMessage.tooltip.up": "在 {locs} 运行", - "xpack.uptime.monitorList.statusColumn.upLabel": "运行", - "xpack.uptime.monitorList.statusColumnLabel": "状态", - "xpack.uptime.monitorList.table.description": "具有“状态”、“名称”、“URL”、“IP”、“中断历史记录”和“集成”列的“监测状态”表。该表当前显示 {length} 个项目。", - "xpack.uptime.monitorList.table.tags.name": "标签", - "xpack.uptime.monitorList.table.url.name": "URL", - "xpack.uptime.monitorList.tags.expand": "单击以查看剩余标签", - "xpack.uptime.monitorList.tags.filter": "筛选带 {tag} 标签的所有监测", - "xpack.uptime.monitorList.testNow.AriaLabel": "单击以立即运行测试", - "xpack.uptime.monitorList.testNow.available": "立即测试仅适用于通过监测管理添加的监测。", - "xpack.uptime.monitorList.testNow.label": "立即测试", - "xpack.uptime.monitorList.testNow.scheduled": "已计划测试", - "xpack.uptime.monitorList.testRunLogs": "测试运行日志", - "xpack.uptime.monitorList.timestamp": "时间戳", - "xpack.uptime.monitorList.tlsColumnLabel": "TLS 证书", - "xpack.uptime.monitorList.viewInDiscover": "在 Discover 中查看", - "xpack.uptime.monitorManagement.addMonitorCrumb": "添加监测", - "xpack.uptime.monitorManagement.addMonitorError": "无法加载服务位置。请稍后重试。", - "xpack.uptime.monitorManagement.addMonitorLabel": "添加监测", - "xpack.uptime.monitorManagement.addMonitorLoadingError": "加载监测管理时出错", - "xpack.uptime.monitorManagement.addMonitorLoadingLabel": "正在加载监测管理", - "xpack.uptime.monitorManagement.addMonitorServiceLocationsLoadingError": "无法加载服务位置。请稍后重试。", - "xpack.uptime.monitorManagement.apiKeysDisabledToolTip": "对此集群禁用了 API 密钥。监测管理需要使用 API 密钥才能回写 Elasticsearch 集群。要启用 API 密钥,请与管理员联系。", - "xpack.uptime.monitorManagement.callout.description.disabled": "监测管理当前处于禁用状态。要在 Elastic 托管 Synthetics 服务上运行监测,请启用监测管理。现有监测已暂停。", - "xpack.uptime.monitorManagement.callout.disabled": "已禁用监测管理", - "xpack.uptime.monitorManagement.callout.disabled.adminContact": "请联系管理员启用监测管理。", - "xpack.uptime.monitorManagement.closeButtonLabel": "关闭", - "xpack.uptime.monitorManagement.completed": "已完成", - "xpack.uptime.monitorManagement.confirmDescriptionLabel": "此操作将删除监测,但会保留收集的任何数据。此操作无法撤消。", - "xpack.uptime.monitorManagement.deleteMonitorLabel": "删除监测", - "xpack.uptime.monitorManagement.disableMonitorLabel": "禁用监测", - "xpack.uptime.monitorManagement.discardLabel": "丢弃", - "xpack.uptime.monitorManagement.duplicateNameError": "监测名称已存在。", - "xpack.uptime.monitorManagement.editMonitorCrumb": "编辑监测", - "xpack.uptime.monitorManagement.editMonitorError": "加载监测管理时出错", - "xpack.uptime.monitorManagement.editMonitorError.description": "无法加载监测管理设置。请联系支持人员。", - "xpack.uptime.monitorManagement.editMonitorErrorBody": "无法加载监测配置。请稍后重试。", - "xpack.uptime.monitorManagement.editMonitorLabel": "编辑监测", - "xpack.uptime.monitorManagement.editMonitorLoadingLabel": "正在加载监测", - "xpack.uptime.monitorManagement.emptyState.enablement": "启用监测管理以从全球托管测试地点运行轻量级检查和真正的浏览器监测。启用监测管理将生成 API 密钥,以便 Synthetics 服务回写 Elasticsearch 集群。", - "xpack.uptime.monitorManagement.emptyState.enablement.disabled.title": "已禁用监测管理", - "xpack.uptime.monitorManagement.emptyState.enablement.disabledDescription": "监测管理当前处于禁用状态。通过监测管理,您可以从全球托管测试地点运行轻量级检查和真正的浏览器监测。要启用监测管理,请与管理员联系。", - "xpack.uptime.monitorManagement.emptyState.enablement.doc": "阅读文档", - "xpack.uptime.monitorManagement.emptyState.enablement.enabled.title": "启用监测管理", - "xpack.uptime.monitorManagement.emptyState.enablement.learnMore": "希望了解详情?", - "xpack.uptime.monitorManagement.emptyState.enablement.title": "启用", - "xpack.uptime.monitorManagement.enableMonitorLabel": "启用监测", - "xpack.uptime.monitorManagement.failed": "失败", - "xpack.uptime.monitorManagement.failedRun": "无法运行步骤", - "xpack.uptime.monitorManagement.inProgress": "进行中", - "xpack.uptime.monitorManagement.label": "监测管理", - "xpack.uptime.monitorManagement.loading.label": "正在加载监测管理", - "xpack.uptime.monitorManagement.loadingSteps": "正在加载步骤......", - "xpack.uptime.monitorManagement.manageMonitorLoadingLabel": "正在加载监测管理", - "xpack.uptime.monitorManagement.manageMonitorLoadingLabel.callout.learnMore": "了解详情。", - "xpack.uptime.monitorManagement.monitorAddedSuccessMessage": "已成功添加监测。", - "xpack.uptime.monitorManagement.monitorAdvancedOptions.dataStreamConfiguration.description": "配置其他数据流选项。", - "xpack.uptime.monitorManagement.monitorAdvancedOptions.dataStreamConfiguration.title": "数据流设置", - "xpack.uptime.monitorManagement.monitorAdvancedOptions.monitorNamespaceFieldLabel": "命名空间", - "xpack.uptime.monitorManagement.monitorAdvancedOptions.namespaceHelpLabel": "更改默认命名空间。此设置将更改监测的数据流的名称。{learnMore}。", - "xpack.uptime.monitorManagement.monitorAdvancedOptions.namespaceHelpLearnMoreLabel": "了解详情", - "xpack.uptime.monitorManagement.monitorDeleteFailureMessage": "无法删除监测。请稍后重试。", - "xpack.uptime.monitorManagement.monitorDeleteLoadingMessage": "正在删除监测......", - "xpack.uptime.monitorManagement.monitorDeleteSuccessMessage": "已成功删除监测。", - "xpack.uptime.monitorManagement.monitorDisabledSuccessMessage": "已成功禁用监测 {name}。", - "xpack.uptime.monitorManagement.monitorEditedSuccessMessage": "已成功更新监测。", - "xpack.uptime.monitorManagement.monitorEnabledSuccessMessage": "已成功启用监测 {name}。", - "xpack.uptime.monitorManagement.monitorEnabledUpdateFailureMessage": "无法更新监测 {name}。", - "xpack.uptime.monitorManagement.monitorFailureMessage": "无法保存监测。请稍后重试。", - "xpack.uptime.monitorManagement.monitorList.actions": "操作", - "xpack.uptime.monitorManagement.monitorList.enabled": "已启用", - "xpack.uptime.monitorManagement.monitorList.locations": "位置", - "xpack.uptime.monitorManagement.monitorList.monitorName": "监测名称", - "xpack.uptime.monitorManagement.monitorList.monitorType": "监测类型", - "xpack.uptime.monitorManagement.monitorList.schedule": "频率(分钟)", - "xpack.uptime.monitorManagement.monitorList.tags": "标签", - "xpack.uptime.monitorManagement.monitorList.title": "监测管理列表", - "xpack.uptime.monitorManagement.monitorList.URL": "URL", - "xpack.uptime.monitorManagement.monitorLocationsLabel": "监测位置", - "xpack.uptime.monitorManagement.monitorManagementCrumb": "监测管理", - "xpack.uptime.monitorManagement.monitorNameFieldError": "监测名称必填", - "xpack.uptime.monitorManagement.monitorNameFieldLabel": "监测名称", - "xpack.uptime.monitorManagement.monitorSync.failure.content": "同步一个或多个位置的监测时遇到问题:", - "xpack.uptime.monitorManagement.monitorSync.failure.dismissLabel": "关闭", - "xpack.uptime.monitorManagement.monitorSync.failure.reasonLabel": "原因", - "xpack.uptime.monitorManagement.monitorSync.failure.statusLabel": "状态", - "xpack.uptime.monitorManagement.monitorSync.failure.title": "监测无法与 Synthetics 服务同步", - "xpack.uptime.monitorManagement.noLabel": "取消", - "xpack.uptime.monitorManagement.pageHeader.title": "管理监测", - "xpack.uptime.monitorManagement.pending": "待处理", - "xpack.uptime.monitorManagement.publicBetaDescription": "监测管理仅适用于选定的公共公测版用户。利用公共\n公测版访问权限,您能够添加 HTTP、TCP、ICMP 和浏览器检查,\n这些检查将在 Elastic 的托管 Synthetics 服务节点上运行。", - "xpack.uptime.monitorManagement.requestAccess": "请求访问权限", - "xpack.uptime.monitorManagement.reRunTest": "重新运行测试", - "xpack.uptime.monitorManagement.runTest": "运行测试", - "xpack.uptime.monitorManagement.saveMonitorLabel": "保存监测", - "xpack.uptime.monitorManagement.service.error.message": "已保存您的监测,但同步 {location} 的配置时遇到问题。我们会在稍后自动重试。如果此问题持续存在,您的监测将在 {location} 中停止运行。请联系支持人员获取帮助。", - "xpack.uptime.monitorManagement.service.error.reason": "原因:{reason}。", - "xpack.uptime.monitorManagement.service.error.status": "状态:{status}。", - "xpack.uptime.monitorManagement.service.error.title": "无法同步监测配置", - "xpack.uptime.monitorManagement.serviceLocationsValidationError": "必须至少指定一个服务位置", - "xpack.uptime.monitorManagement.stepCompleted": "已完成 {stepCount, number} 个{stepCount, plural, other {步骤}}", - "xpack.uptime.monitorManagement.syntheticsDisabled": "监测管理当前处于禁用状态。请联系管理员启用监测管理。", - "xpack.uptime.monitorManagement.syntheticsDisabledFailure": "无法禁用监测管理。请联系支持人员。", - "xpack.uptime.monitorManagement.syntheticsDisabledSuccess": "已成功禁用监测管理。", - "xpack.uptime.monitorManagement.syntheticsDisableToolTip": "禁用监测管理会立即在所有测试地点停止执行监测并阻止创建新监测。", - "xpack.uptime.monitorManagement.syntheticsEnabledFailure": "无法启用监测管理。请联系支持人员。", - "xpack.uptime.monitorManagement.syntheticsEnableLabel": "启用", - "xpack.uptime.monitorManagement.syntheticsEnableLabel.management": "启用监测管理", - "xpack.uptime.monitorManagement.syntheticsEnableSuccess": "已成功启用监测管理。", - "xpack.uptime.monitorManagement.syntheticsEnableToolTip": "启用监测管理以在全球各个地点创建轻量级、真正的浏览器监测。", - "xpack.uptime.monitorManagement.testResult": "测试结果", - "xpack.uptime.monitorManagement.timeTaken": "耗时 {timeTaken}", - "xpack.uptime.monitorManagement.updateMonitorLabel": "更新监测", - "xpack.uptime.monitorManagement.validationError": "您的监测存在错误。请在保存前修复这些错误。", - "xpack.uptime.monitorManagement.viewTestRunDetails": "查看测试结果详情", - "xpack.uptime.monitorManagement.yesLabel": "删除", - "xpack.uptime.monitorManagementRoute.title": "管理监测 | {baseTitle}", - "xpack.uptime.monitorRoute.title": "监测 | {baseTitle}", - "xpack.uptime.monitorStatusBar.durationTextAriaLabel": "监测持续时间(毫秒)", - "xpack.uptime.monitorStatusBar.healthStatusMessageAriaLabel": "监测状态", - "xpack.uptime.monitorStatusBar.loadingMessage": "正在加载……", - "xpack.uptime.monitorStatusBar.locations.oneLocStatus": "在 {loc} 位置处于 {status}", - "xpack.uptime.monitorStatusBar.locations.upStatus": "在 {loc} 位置处于 {status}", - "xpack.uptime.monitorStatusBar.monitor.availability": "总体可用性", - "xpack.uptime.monitorStatusBar.monitor.availabilityReport.availability": "可用性", - "xpack.uptime.monitorStatusBar.monitor.availabilityReport.lastCheck": "上次检查", - "xpack.uptime.monitorStatusBar.monitor.availabilityReport.location": "位置", - "xpack.uptime.monitorStatusBar.monitor.id": "监测 ID", - "xpack.uptime.monitorStatusBar.monitor.monitoringFrom": "正监测自", - "xpack.uptime.monitorStatusBar.monitor.monitoringFrom.listToMap": "更改到地图视图以按位置检查可用性。", - "xpack.uptime.monitorStatusBar.monitor.monitoringFrom.MapToList": "更改到列表视图以按位置检查可用性。", - "xpack.uptime.monitorStatusBar.monitorUrlLinkAriaLabel": "监测 URL 链接", - "xpack.uptime.monitorStatusBar.sslCertificate.title": "TLS 证书", - "xpack.uptime.monitorStatusBar.timestampFromNowTextAriaLabel": "自上次检查以来经过的时间", - "xpack.uptime.monitorStatusBar.type.ariaLabel": "监测类型", - "xpack.uptime.monitorStatusBar.type.label": "类型", - "xpack.uptime.navigateToAlertingButton.content": "管理规则", - "xpack.uptime.navigateToAlertingUi": "离开 Uptime 并前往“Alerting 管理”页面", - "xpack.uptime.noDataConfig.beatsCard.description": "主动监测站点和服务的可用性。接收告警并更快地解决问题,从而优化用户体验。", - "xpack.uptime.noDataConfig.beatsCard.title": "通过 Heartbeat 添加监测", - "xpack.uptime.noDataConfig.solutionName": "Observability", - "xpack.uptime.notFountPage.homeLinkText": "返回主页", - "xpack.uptime.openAlertContextPanel.ariaLabel": "打开规则上下文面板,以便可以选择规则类型", - "xpack.uptime.openAlertContextPanel.label": "创建规则", - "xpack.uptime.overview.alerts.disabled.failed": "无法禁用规则!", - "xpack.uptime.overview.alerts.disabled.success": "已成功禁用规则!", - "xpack.uptime.overview.alerts.enabled.failed": "无法启用规则!", - "xpack.uptime.overview.alerts.enabled.success": "已成功启用规则 ", - "xpack.uptime.overview.alerts.enabled.success.description": "此监测关闭时,将有消息发送到 {actionConnectors}。", - "xpack.uptime.overview.heading": "监测", - "xpack.uptime.overview.pageHeader.syntheticsCallout.announcementLink": "阅读公告", - "xpack.uptime.overview.pageHeader.syntheticsCallout.content": "Uptime 现在正在预览对脚本化多步骤可用性检查的支持。这意味着您可以与网页元素进行交互,并检查整个过程(例如购买或登录系统)的可用性,而不仅仅是简单的单个页面启动/关闭检查。请单击下面的内容以了解详情,如果您想率先使用这些功能,则可以下载我们的预览组合代理,并在 Uptime 中查看组合检查。", - "xpack.uptime.overview.pageHeader.syntheticsCallout.dismissButtonText": "关闭", - "xpack.uptime.overview.pageHeader.syntheticsCallout.title": "Elastic Synthetics", - "xpack.uptime.overviewPage.headerText": "概览", - "xpack.uptime.overviewPageLink.disabled.ariaLabel": "禁用的分页按钮表示在监测列表中无法进行进一步导航。", - "xpack.uptime.overviewPageLink.next.ariaLabel": "下页结果", - "xpack.uptime.overviewPageLink.prev.ariaLabel": "上页结果", - "xpack.uptime.page_header.addDataLink.label": "导航到有关如何添加 Uptime 数据的教程", - "xpack.uptime.page_header.analyzeData.label": "导航到“浏览数据”视图以可视化 Synthetics/用户数据", - "xpack.uptime.page_header.defineConnector.popover.defaultLink": "定义默认连接器", - "xpack.uptime.page_header.defineConnector.settingsLink": "设置", - "xpack.uptime.page_header.manageLink.label": "导航到 Uptime 监测管理页面", - "xpack.uptime.page_header.settingsLink": "设置", - "xpack.uptime.page_header.settingsLink.label": "导航到 Uptime 设置页面", - "xpack.uptime.pingHistogram.analyze": "分析", - "xpack.uptime.pingist.durationSecondsColumnFormatting": "{seconds} 秒", - "xpack.uptime.pingist.durationSecondsColumnFormatting.singular": "{seconds} 秒", - "xpack.uptime.pingList.checkHistoryTitle": "历史记录", - "xpack.uptime.pingList.collapseRow": "折叠", - "xpack.uptime.pingList.columns.failedStep": "失败的步骤", - "xpack.uptime.pingList.drawer.body.docsLink": "文档", - "xpack.uptime.pingList.durationMsColumnFormatting": "{millis} 毫秒", - "xpack.uptime.pingList.durationMsColumnLabel": "持续时间", - "xpack.uptime.pingList.errorColumnLabel": "错误", - "xpack.uptime.pingList.errorTypeColumnLabel": "错误类型", - "xpack.uptime.pingList.expandedRow.bodySize": "正文大小为 {bodyBytes}。", - "xpack.uptime.pingList.expandedRow.error": "错误", - "xpack.uptime.pingList.expandedRow.response_body": "响应正文", - "xpack.uptime.pingList.expandedRow.response_body.notRecorded": "正文未记录。阅读我们的{docsLink}以更多了解如何记录响应正文。", - "xpack.uptime.pingList.expandedRow.truncated": "显示前 {contentBytes} 字节。", - "xpack.uptime.pingList.expandRow": "展开", - "xpack.uptime.pingList.headers.title": "响应标头", - "xpack.uptime.pingList.ipAddressColumnLabel": "IP", - "xpack.uptime.pingList.locationNameColumnLabel": "位置", - "xpack.uptime.pingList.pingsLoadingMesssage": "正在加载历史记录......", - "xpack.uptime.pingList.pingsUnavailableMessage": "未找到历史记录", - "xpack.uptime.pingList.recencyMessage": "{fromNow}已检查", - "xpack.uptime.pingList.responseCodeColumnLabel": "响应代码", - "xpack.uptime.pingList.statusColumnLabel": "状态", - "xpack.uptime.pingList.stepDurationHeader": "步骤持续时间", - "xpack.uptime.pingList.synthetics.performanceBreakDown": "查看性能细目", - "xpack.uptime.pingList.synthetics.waterfall.filters.collapseRequestsLabel": "折叠以仅显示匹配的请求", - "xpack.uptime.pingList.synthetics.waterfall.filters.popover": "单击以打开瀑布筛选", - "xpack.uptime.pingList.timestampColumnLabel": "时间戳", - "xpack.uptime.pluginDescription": "运行时间监测", - "xpack.uptime.public.pages.mappingError.bodyDocsLink": "您可以在 {docsLink} 中了解如何解决此问题。", - "xpack.uptime.public.pages.mappingError.bodyMessage": "检测到不正确的映射!可能您忘记运行 Heartbeat {setup} 命令?", - "xpack.uptime.public.pages.mappingError.title": "Heartbeat 映射缺失", - "xpack.uptime.routes.baseTitle": "Uptime - Kibana", - "xpack.uptime.seconds.label": "秒", - "xpack.uptime.seconds.shortForm.label": "秒", - "xpack.uptime.settings.blank.error": "不能为空。", - "xpack.uptime.settings.blankNumberField.error": "必须为数字。", - "xpack.uptime.settings.cannotEditText": "您的用户当前对 Uptime 应用有“读取”权限。启用“全部”权限级别以编辑这些设置。", - "xpack.uptime.settings.cannotEditTitle": "您无权编辑设置。", - "xpack.uptime.settings.error.couldNotSave": "无法保存设置!", - "xpack.uptime.settings.heading": "Uptime 设置", - "xpack.uptime.settings.invalid.error": "值必须大于 0。", - "xpack.uptime.settings.invalid.nanError": "值必须为整数。", - "xpack.uptime.settings.noSpace.error": "索引名称不得包含空格", - "xpack.uptime.settings.saveSuccess": "设置已保存!", - "xpack.uptime.settingsBreadcrumbText": "设置", - "xpack.uptime.settingsRoute.title": "设置 | {baseTitle}", - "xpack.uptime.snapshot.donutChart.ariaLabel": "显示当前状态的饼图。{total} 个监测中有 {down} 个已关闭。", - "xpack.uptime.snapshot.monitor": "监测", - "xpack.uptime.snapshot.monitors": "监测", - "xpack.uptime.snapshot.noDataDescription": "选定的时间范围中没有 ping。", - "xpack.uptime.snapshot.noDataTitle": "没有可用的 ping 数据", - "xpack.uptime.snapshot.pingsOverTimeTitle": "时移 Ping 数", - "xpack.uptime.snapshotHistogram.description": "显示 {startTime} 到 {endTime} 运行时间时移状态的条形图。", - "xpack.uptime.snapshotHistogram.series.pings": "监测 Ping", - "xpack.uptime.snapshotHistogram.xAxisId": "Ping X 轴", - "xpack.uptime.snapshotHistogram.yAxis.title": "Ping", - "xpack.uptime.snapshotHistogram.yAxisId": "Ping Y 轴", - "xpack.uptime.sourceConfiguration.ageLimit.units.days": "天", - "xpack.uptime.sourceConfiguration.ageLimitThresholdInput.ariaLabel": "该输入控制 Kibana 显示警告之前 TLS 证书有效的最大天数。", - "xpack.uptime.sourceConfiguration.ageThresholdDefaultValue": "默认值为 {defaultValue}", - "xpack.uptime.sourceConfiguration.alertConnectors": "告警连接器", - "xpack.uptime.sourceConfiguration.alertConnectors.defaultEmail": "默认电子邮件", - "xpack.uptime.sourceConfiguration.alertDefaultForm.emailConnectorPlaceHolder": "到:电子邮件连接器的电子邮件", - "xpack.uptime.sourceConfiguration.alertDefaultForm.invalidEmail": "{val} 不是有效电子邮件。", - "xpack.uptime.sourceConfiguration.alertDefaultForm.requiredEmail": "电子邮件连接器需要目标电子邮件", - "xpack.uptime.sourceConfiguration.alertDefaultForm.selectConnector": "请选择一个或多个连接器", - "xpack.uptime.sourceConfiguration.alertDefaults": "告警默认值", - "xpack.uptime.sourceConfiguration.applySettingsButtonLabel": "应用更改", - "xpack.uptime.sourceConfiguration.certificateExpirationThresholdInput.ariaLabel": "该输入控制 Kibana 显示警告之前离 TLS 证书到期剩余的最小天数。", - "xpack.uptime.sourceConfiguration.certificateThresholdDescription": "更改显示并告警证书错误的阈值。注意:这会影响任何配置的告警。", - "xpack.uptime.sourceConfiguration.certificationSectionTitle": "证书到期", - "xpack.uptime.sourceConfiguration.defaultConnectors": "默认连接器", - "xpack.uptime.sourceConfiguration.defaultConnectors.description": "要用于发送告警的默认连接器。", - "xpack.uptime.sourceConfiguration.defaultConnectors.description.defaultEmail": "选定电子邮件告警连接器需要电子邮件设置。", - "xpack.uptime.sourceConfiguration.discardSettingsButtonLabel": "取消", - "xpack.uptime.sourceConfiguration.errorStateLabel": "到期阈值", - "xpack.uptime.sourceConfiguration.expirationThreshold": "到期/使用时间阈值", - "xpack.uptime.sourceConfiguration.expirationThresholdDefaultValue": "默认值为 {defaultValue}", - "xpack.uptime.sourceConfiguration.heartbeatIndicesDefaultValue": "默认值为 {defaultValue}", - "xpack.uptime.sourceConfiguration.heartbeatIndicesDescription": "用于匹配包含 Heartbeat 数据的索引的索引模式", - "xpack.uptime.sourceConfiguration.heartbeatIndicesLabel": "Heartbeat 索引", - "xpack.uptime.sourceConfiguration.heartbeatIndicesTitle": "Uptime 索引", - "xpack.uptime.sourceConfiguration.indicesSectionTitle": "索引", - "xpack.uptime.sourceConfiguration.warningStateLabel": "使用时间限制", - "xpack.uptime.stepDetailRoute.title": "Synthetics 详细信息 | {baseTitle}", - "xpack.uptime.stepList.collapseRow": "折叠", - "xpack.uptime.stepList.expandRow": "展开", - "xpack.uptime.stepList.stepName": "步骤名称", - "xpack.uptime.synthetics.consoleStepList.message": "此过程无法运行,记录的控制台输出如下所示:", - "xpack.uptime.synthetics.consoleStepList.title": "未执行步骤", - "xpack.uptime.synthetics.emptyJourney.message.checkGroupField": "该过程的检查组是 {codeBlock}。", - "xpack.uptime.synthetics.emptyJourney.message.footer": "没有更多可显示的信息。", - "xpack.uptime.synthetics.emptyJourney.message.heading": "此过程不包含任何步骤。", - "xpack.uptime.synthetics.emptyJourney.title": "没有此过程的任何步骤", - "xpack.uptime.synthetics.executedStep.consoleOutput.label": "控制台输出", - "xpack.uptime.synthetics.executedStep.errorHeading": "错误消息", - "xpack.uptime.synthetics.executedStep.screenshot.not": "屏幕截图", - "xpack.uptime.synthetics.executedStep.screenshot.notSucceeded": "{status} 检查的屏幕截图", - "xpack.uptime.synthetics.executedStep.screenshot.success": "上一成功检查", - "xpack.uptime.synthetics.executedStep.screenshot.successfulLink": "来自 {link} 的屏幕截图", - "xpack.uptime.synthetics.executedStep.scriptHeading.label": "在此步骤执行的脚本", - "xpack.uptime.synthetics.executedStep.stackTrace": "堆栈跟踪", - "xpack.uptime.synthetics.imageLoadingSpinner.ariaLabel": "表示图像正在加载的动画旋转图标", - "xpack.uptime.synthetics.journey.allFailedMessage": "{total} 个步骤 - 全部失败或跳过", - "xpack.uptime.synthetics.journey.allSucceededMessage": "{total} 个步骤 - 全部成功", - "xpack.uptime.synthetics.journey.loadingSteps": "正在加载步骤......", - "xpack.uptime.synthetics.journey.partialSuccessMessage": "{total} 个步骤 - {succeeded} 个成功", - "xpack.uptime.synthetics.markers.explore": "浏览", - "xpack.uptime.synthetics.markers.noFieldIcon.label": "一个图标,表示此标记没有与其关联的字段", - "xpack.uptime.synthetics.markers.openEmbeddableButton.label": "使用此图标按钮可显示该标注标记的指标。", - "xpack.uptime.synthetics.nextStepButton.ariaLabel": "下一步", - "xpack.uptime.synthetics.performanceBreakDown.label": "性能细目", - "xpack.uptime.synthetics.pingTimestamp.captionContent": "第 {stepNumber} 步,共 {totalSteps} 步", - "xpack.uptime.synthetics.prevStepButton.airaLabel": "上一步", - "xpack.uptime.synthetics.screenshot.noImageMessage": "没有可用图像", - "xpack.uptime.synthetics.screenshotDisplay.altText": "名称为“{stepName}”的步骤的屏幕截图", - "xpack.uptime.synthetics.screenshotDisplay.altTextWithoutName": "屏幕截图", - "xpack.uptime.synthetics.service.apiKey": "Synthetics 服务 API 密钥", - "xpack.uptime.synthetics.statusBadge.failedMessage": "失败", - "xpack.uptime.synthetics.statusBadge.skippedMessage": "已跳过", - "xpack.uptime.synthetics.statusBadge.succeededMessage": "成功", - "xpack.uptime.synthetics.step.duration": "{value} 秒", - "xpack.uptime.synthetics.step.durationTrend": "步骤持续时间趋势", - "xpack.uptime.synthetics.stepDetail.nextCheckButtonText": "下一检查", - "xpack.uptime.synthetics.stepDetail.noData": "找不到此步骤的数据", - "xpack.uptime.synthetics.stepDetail.previousCheckButtonText": "上一检查", - "xpack.uptime.synthetics.stepDetail.totalSteps": "第 {stepIndex} 步,共 {totalSteps} 步", - "xpack.uptime.synthetics.stepDetail.waterfall.loading": "瀑布图正在加载", - "xpack.uptime.synthetics.stepDetail.waterfallNoData": "找不到此步骤的瀑布数据", - "xpack.uptime.synthetics.stepDetail.waterfallUnsupported.description": "瀑布图无法显示。您可能正在使用较旧的组合代理版本。请检查版本并考虑升级。", - "xpack.uptime.synthetics.stepDetail.waterfallUnsupported.title": "瀑布图不可用", - "xpack.uptime.synthetics.stepList.nextCheck": "下一检查", - "xpack.uptime.synthetics.stepList.previousCheck": "上一检查", - "xpack.uptime.synthetics.thumbnail.fullSize.alt": "此过程步骤的缩略图屏幕截图较大版本。", - "xpack.uptime.synthetics.waterfall.domContentLabel": "DOM 内容已加载", - "xpack.uptime.synthetics.waterfall.fcpLabel": "首次内容绘制", - "xpack.uptime.synthetics.waterfall.filterGroup.filterScreenreaderLabel": "筛选依据", - "xpack.uptime.synthetics.waterfall.filterGroup.removeFilterScreenReaderLabel": "移除筛选依据", - "xpack.uptime.synthetics.waterfall.flyout.certificates": "证书标头", - "xpack.uptime.synthetics.waterfall.flyout.details": "详情", - "xpack.uptime.synthetics.waterfall.flyout.requestHeaders": "请求标头", - "xpack.uptime.synthetics.waterfall.flyout.responseHeaders": "响应标头", - "xpack.uptime.synthetics.waterfall.layoutShiftLabel": "布局切换", - "xpack.uptime.synthetics.waterfall.lcpLabel": "最大内容绘制", - "xpack.uptime.synthetics.waterfall.loadEventLabel": "加载事件", - "xpack.uptime.synthetics.waterfall.offsetUnit": "{offset} 毫秒", - "xpack.uptime.synthetics.waterfall.requestsHighlightedMessage": "({numHighlightedRequests}匹配筛选)", - "xpack.uptime.synthetics.waterfall.requestsTotalMessage": "{numNetworkRequests}个网络请求", - "xpack.uptime.synthetics.waterfall.requestsTotalMessage.first": "前 {count} 个", - "xpack.uptime.synthetics.waterfall.requestsTotalMessage.info": "瀑布视图最多显示 1000 个请求", - "xpack.uptime.synthetics.waterfall.resource.externalLink": "在新选项卡中打开资源", - "xpack.uptime.synthetics.waterfall.searchBox.placeholder": "筛选网络请求", - "xpack.uptime.synthetics.waterfall.sidebar.filterMatchesScreenReaderLabel": "资源匹配筛选", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.certificateExpiryDate": "失效日期", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.certificateIssueDate": "有效起始日期", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.certificateIssuer": "颁发者", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.certificateSubject": "常见名称", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.contentType": "内容类型", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.ip": "IP", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.requestStart": "请求启动", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.resourceSize": "资源大小", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.status": "状态", - "xpack.uptime.synthetics.waterfallChart.labels.metadata.transferSize": "传输大小", - "xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.font": "字体", - "xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.html": "HTML", - "xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.media": "媒体", - "xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.other": "其他", - "xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.script": "JS", - "xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.stylesheet": "CSS", - "xpack.uptime.synthetics.waterfallChart.labels.mimeTypes.xhr": "XHR", - "xpack.uptime.synthetics.waterfallChart.labels.timings.blocked": "已排队/已阻止", - "xpack.uptime.synthetics.waterfallChart.labels.timings.connect": "连接中", - "xpack.uptime.synthetics.waterfallChart.labels.timings.dns": "DNS", - "xpack.uptime.synthetics.waterfallChart.labels.timings.receive": "内容正在下载", - "xpack.uptime.synthetics.waterfallChart.labels.timings.send": "正在发送请求", - "xpack.uptime.synthetics.waterfallChart.labels.timings.ssl": "TLS", - "xpack.uptime.synthetics.waterfallChart.labels.timings.wait": "等待中 (TTFB)", - "xpack.uptime.syntheticsMonitors": "运行时间 - 监测", - "xpack.uptime.testRun.description": "请在保存前测试您的监测并验证结果", - "xpack.uptime.testRun.pushError": "无法推送监测到服务。", - "xpack.uptime.testRun.pushErrorLabel": "推送错误", - "xpack.uptime.testRun.pushing.description": "正在推送监测到服务......", - "xpack.uptime.title": "运行时间", - "xpack.uptime.toggleAlertButton.content": "监测状态规则", - "xpack.uptime.toggleAlertFlyout.ariaLabel": "打开添加规则浮出控件", - "xpack.uptime.toggleTlsAlertButton.ariaLabel": "打开 TLS 规则浮出控件", - "xpack.uptime.toggleTlsAlertButton.content": "TLS 规则", - "xpack.uptime.uptimeFeatureCatalogueTitle": "运行时间", - "xpack.uptime.uptimeSettings.index": "Uptime 设置 - 索引", - "xpack.uptime.waterfallChart.sidebar.url.https": "https", + "xpack.synthetics.addDataButtonLabel": "添加数据", + "xpack.synthetics.addMonitor.pageHeader.title": "添加监测", + "xpack.synthetics.addMonitorRoute.title": "添加监测 | {baseTitle}", + "xpack.synthetics.alertDropdown.noWritePermissions": "您需要 Uptime 的读写访问权限才能在此应用中创建告警。", + "xpack.synthetics.alerts.anomaly.criteriaExpression.ariaLabel": "显示选定监测的条件的表达式。", + "xpack.synthetics.alerts.anomaly.criteriaExpression.description": "当监测", + "xpack.synthetics.alerts.anomaly.scoreExpression.ariaLabel": "显示异常告警阈值的条件的表达式。", + "xpack.synthetics.alerts.anomaly.scoreExpression.description": "具有异常,严重性为", + "xpack.synthetics.alerts.createRulesPanel.title": "创建规则", + "xpack.synthetics.alerts.durationAnomaly": "Uptime 持续时间异常", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.anomalyStartTimestamp": "异常开始的 ISO8601 时间戳。", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.expectedResponseTime": "预期响应时间", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.monitor": "名称或 ID 的友好呈现,建议类似于 My Monitor 的名称", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.monitorId": "监测的 ID。", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.monitorUrl": "监测的 URL。", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.observerLocation": "执行 Heartbeat 检查的观察者位置。", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.severity": "异常的严重性。", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.severityScore": "异常严重性分数", + "xpack.synthetics.alerts.durationAnomaly.actionVariables.state.slowestAnomalyResponse": "在附加单位(ms、s)的异常存储桶期间最慢的响应时间。", + "xpack.synthetics.alerts.durationAnomaly.clientName": "Uptime 持续时间异常", + "xpack.synthetics.alerts.durationAnomaly.defaultActionMessage": "{anomalyStartTimestamp} 在 url {monitorUrl} 的 {monitor} 上检测到异常({severity} 级别)响应时间。异常严重性分数为 {severityScore}。\n从位置 {observerLocation} 检测到高达 {slowestAnomalyResponse} 的响应时间。预期响应时间为 {expectedResponseTime}。", + "xpack.synthetics.alerts.durationAnomaly.description": "运行时间监测持续时间异常时告警。", + "xpack.synthetics.alerts.monitorExpression.label": "移除筛选 {title}", + "xpack.synthetics.alerts.monitorStatus": "运行时间监测状态", + "xpack.synthetics.alerts.monitorStatus.actionVariables.availabilityMessage": "{interval} 可用性为 {availabilityRatio}%。小于 {expectedAvailability}% 时告警。", + "xpack.synthetics.alerts.monitorStatus.actionVariables.context.alertReasonMessage.description": "告警原因的简洁描述", + "xpack.synthetics.alerts.monitorStatus.actionVariables.context.downMonitorsWithGeo.description": "生成的摘要,显示告警已检测为“关闭”的部分或所有监测", + "xpack.synthetics.alerts.monitorStatus.actionVariables.context.message.description": "生成的消息,汇总当前关闭的监测", + "xpack.synthetics.alerts.monitorStatus.actionVariables.context.viewInAppUrl.description": "Elastic 中可用于进一步调查告警及其上下文的视图或功能的链接", + "xpack.synthetics.alerts.monitorStatus.actionVariables.down": "在过去 {interval}中失败 {count} 次。大于 {numTimes} 时告警。", + "xpack.synthetics.alerts.monitorStatus.actionVariables.downAndAvailabilityMessage": "{downMonitorsMessage} {availabilityBreachMessage}", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.currentTriggerStarted": "表示告警触发时当前触发状况开始的时间戳", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.firstCheckedAt": "表示此告警首次检查的时间戳", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.firstTriggeredAt": "表示告警首次触发的时间戳", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.isTriggered": "表示告警当前是否触发的标志", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.lastCheckedAt": "表示告警最近检查时间的时间戳", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.lastErrorMessage": "监测最新错误消息", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.lastResolvedAt": "表示此告警最近解决时间的时间戳", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.lastTriggeredAt": "表示告警最近触发时间的时间戳", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.monitor": "名称或 ID 的友好呈现,建议类似于 My Monitor 的名称", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.monitorId": "监测的 ID。", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.monitorType": "监测的类型(例如 HTTP/TCP)。", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.monitorUrl": "监测的 URL。", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.observerHostname": "执行 Heartbeat 检查的观察者主机名。", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.observerLocation": "执行 Heartbeat 检查的观察者位置。", + "xpack.synthetics.alerts.monitorStatus.actionVariables.state.statusMessage": "状态消息,例如关闭和/或低于可用性阈值(如果执行可用性检查)。", + "xpack.synthetics.alerts.monitorStatus.addFilter": "添加筛选", + "xpack.synthetics.alerts.monitorStatus.addFilter.location": "位置", + "xpack.synthetics.alerts.monitorStatus.addFilter.port": "端口", + "xpack.synthetics.alerts.monitorStatus.addFilter.tag": "标签", + "xpack.synthetics.alerts.monitorStatus.addFilter.type": "类型", + "xpack.synthetics.alerts.monitorStatus.availability.isEnabledCheckbox.label": "可用性", + "xpack.synthetics.alerts.monitorStatus.availability.threshold.anyMonitorDescription": "任何监测启动于", + "xpack.synthetics.alerts.monitorStatus.availability.threshold.ariaLabel": "指定此告警的可用性阈值", + "xpack.synthetics.alerts.monitorStatus.availability.threshold.description": "匹配的监测运行于", + "xpack.synthetics.alerts.monitorStatus.availability.threshold.input.ariaLabel": "输入用于检查此告警的可用性阈值", + "xpack.synthetics.alerts.monitorStatus.availability.threshold.value": "< {value}% 的检查", + "xpack.synthetics.alerts.monitorStatus.availability.timerangeValueField.ariaLabel": "输入告警可用性检查的单位数。", + "xpack.synthetics.alerts.monitorStatus.availability.timerangeValueField.expression": "(之内)过去", + "xpack.synthetics.alerts.monitorStatus.availability.timerangeValueField.popover.ariaLabel": "指定跟踪时间范围的可用性", + "xpack.synthetics.alerts.monitorStatus.availability.unit.headline": "选择时间范围单位", + "xpack.synthetics.alerts.monitorStatus.availability.unit.selectable": "使用此选择来设置此告警的可用性范围单位", + "xpack.synthetics.alerts.monitorStatus.clientName": "运行时间监测状态", + "xpack.synthetics.alerts.monitorStatus.defaultActionMessage": "在 {observerLocation},URL 为 {monitorUrl} 的监测 {monitorName} 是 {statusMessage} 最新错误消息是 {latestErrorMessage}", + "xpack.synthetics.alerts.monitorStatus.description": "监测关闭或超出可用性阈值时告警。", + "xpack.synthetics.alerts.monitorStatus.filterBar.ariaLabel": "允许对监测状态告警使用筛选条件的输入", + "xpack.synthetics.alerts.monitorStatus.filters.anyLocation": "任意位置", + "xpack.synthetics.alerts.monitorStatus.filters.anyPort": "任意端口", + "xpack.synthetics.alerts.monitorStatus.filters.anyTag": "任意标签", + "xpack.synthetics.alerts.monitorStatus.filters.anyType": "任意类型", + "xpack.synthetics.alerts.monitorStatus.filters.from": "自", + "xpack.synthetics.alerts.monitorStatus.filters.fromLocation": "来源位置", + "xpack.synthetics.alerts.monitorStatus.filters.location.label": "选择要应用到告警查询的位置筛选。", + "xpack.synthetics.alerts.monitorStatus.filters.of": "的", + "xpack.synthetics.alerts.monitorStatus.filters.ofType": "类型", + "xpack.synthetics.alerts.monitorStatus.filters.port.label": "选择要应用到告警查询的端口筛选。", + "xpack.synthetics.alerts.monitorStatus.filters.scheme.label": "选择要应用到告警查询的协议方案筛选。", + "xpack.synthetics.alerts.monitorStatus.filters.tag.label": "选择要应用到告警查询的标签筛选。", + "xpack.synthetics.alerts.monitorStatus.filters.using": "使用", + "xpack.synthetics.alerts.monitorStatus.filters.usingPort": "使用端口", + "xpack.synthetics.alerts.monitorStatus.filters.with": "使用", + "xpack.synthetics.alerts.monitorStatus.filters.withTag": "具有标签", + "xpack.synthetics.alerts.monitorStatus.monitorCallOut.title": "此告警将应用到大约 {snapshotCount} 个监测。", + "xpack.synthetics.alerts.monitorStatus.numTimesExpression.anyMonitors.description": "任何监测关闭 >", + "xpack.synthetics.alerts.monitorStatus.numTimesExpression.ariaLabel": "打开弹出框以输入已关闭计数", + "xpack.synthetics.alerts.monitorStatus.numTimesExpression.matchingMonitors.description": "匹配的监测关闭 >", + "xpack.synthetics.alerts.monitorStatus.numTimesField.ariaLabel": "输入触发告警的已关闭计数", + "xpack.synthetics.alerts.monitorStatus.oldAlertCallout.title": "您可能正在编辑较旧的告警,某些字段可能不自动填充。", + "xpack.synthetics.alerts.monitorStatus.recoveryMessage": "url 为 {url} 的监测 {monitor} 已恢复,状态为“运行”", + "xpack.synthetics.alerts.monitorStatus.statusEnabledCheck.label": "状态检查", + "xpack.synthetics.alerts.monitorStatus.timerangeOption.days": "天", + "xpack.synthetics.alerts.monitorStatus.timerangeOption.hours": "小时", + "xpack.synthetics.alerts.monitorStatus.timerangeOption.minutes": "分钟", + "xpack.synthetics.alerts.monitorStatus.timerangeOption.months": "个月", + "xpack.synthetics.alerts.monitorStatus.timerangeOption.seconds": "秒", + "xpack.synthetics.alerts.monitorStatus.timerangeOption.weeks": "周", + "xpack.synthetics.alerts.monitorStatus.timerangeOption.years": "年", + "xpack.synthetics.alerts.monitorStatus.timerangeSelectionHeader": "选择时间范围单位", + "xpack.synthetics.alerts.monitorStatus.timerangeUnitExpression.ariaLabel": "打开时间范围单位选择字段的弹出框", + "xpack.synthetics.alerts.monitorStatus.timerangeUnitSelectable": "告警应使用的时间范围单位的可选择字段", + "xpack.synthetics.alerts.monitorStatus.timerangeValueExpression.ariaLabel": "打开时间范围值字段的弹出框", + "xpack.synthetics.alerts.monitorStatus.timerangeValueField.ariaLabel": "输入告警范围的时间单位数目", + "xpack.synthetics.alerts.monitorStatus.timerangeValueField.expression": "之内", + "xpack.synthetics.alerts.monitorStatus.timerangeValueField.value": "上一 {value}", + "xpack.synthetics.alerts.searchPlaceholder.kql": "使用 kql 语法筛选", + "xpack.synthetics.alerts.settings.addConnector": "添加连接器", + "xpack.synthetics.alerts.timerangeUnitSelectable.daysOption.ariaLabel": "“天”时间范围选择项", + "xpack.synthetics.alerts.timerangeUnitSelectable.hoursOption.ariaLabel": "“小时”时间范围选择项", + "xpack.synthetics.alerts.timerangeUnitSelectable.minutesOption.ariaLabel": "“分钟”时间范围选择项", + "xpack.synthetics.alerts.timerangeUnitSelectable.monthsOption.ariaLabel": "“月”时间范围选择项", + "xpack.synthetics.alerts.timerangeUnitSelectable.secondsOption.ariaLabel": "“秒”时间范围选择项", + "xpack.synthetics.alerts.timerangeUnitSelectable.weeksOption.ariaLabel": "“周”时间范围选择项", + "xpack.synthetics.alerts.timerangeUnitSelectable.yearsOption.ariaLabel": "“年”时间范围选择项", + "xpack.synthetics.alerts.tls": "Uptime TLS", + "xpack.synthetics.alerts.tls.actionVariables.state.agingCommonNameAndDate": "检测到的证书的常见名称和到期日期/时间。", + "xpack.synthetics.alerts.tls.actionVariables.state.agingCount": "检测到即将过时的证书数目。", + "xpack.synthetics.alerts.tls.actionVariables.state.count": "告警执行工具检测到的证书数目", + "xpack.synthetics.alerts.tls.actionVariables.state.expiringCommonNameAndDate": "检测到的证书的常见名称和到期日期/时间", + "xpack.synthetics.alerts.tls.actionVariables.state.expiringCount": "告警检测到的即将到期证书数目。", + "xpack.synthetics.alerts.tls.ageExpression.ariaLabel": "显示将触发旧证书 TLS 告警的阈值的表达式", + "xpack.synthetics.alerts.tls.ageExpression.description": "或超过", + "xpack.synthetics.alerts.tls.ageExpression.value": "{value} 天内过期的证书", + "xpack.synthetics.alerts.tls.agingLabel": "已过旧", + "xpack.synthetics.alerts.tls.clientName": "Uptime TLS", + "xpack.synthetics.alerts.tls.criteriaExpression.ariaLabel": "显示此告警监视的监测条件的表达式", + "xpack.synthetics.alerts.tls.criteriaExpression.description": "当", + "xpack.synthetics.alerts.tls.criteriaExpression.value": "任意监测", + "xpack.synthetics.alerts.tls.defaultActionMessage": "检测到来自颁发者 {issuer} 的 TLS 证书 {commonName} 的状态为 {status}。证书 {summary}\n", + "xpack.synthetics.alerts.tls.description": "运行时间监测的 TLS 证书即将过期时告警。", + "xpack.synthetics.alerts.tls.expirationExpression.ariaLabel": "显示将触发证书过期 TLS 告警的阈值的表达式", + "xpack.synthetics.alerts.tls.expirationExpression.description": "具有将在", + "xpack.synthetics.alerts.tls.expirationExpression.value": "{value} 天内过期的证书", + "xpack.synthetics.alerts.tls.expiredLabel": "已过期", + "xpack.synthetics.alerts.tls.expiringLabel": "将到期", + "xpack.synthetics.alerts.tls.invalidLabel": "无效", + "xpack.synthetics.alerts.tls.legacy.clientName": "Uptime TLS(旧版)", + "xpack.synthetics.alerts.tls.legacy.defaultActionMessage": "检测到 {count} 个 TLS 证书即将过期或即将过时。\n{expiringConditionalOpen}\n即将过期的证书计数:{expiringCount}\n即将过期的证书:{expiringCommonNameAndDate}\n{expiringConditionalClose}\n{agingConditionalOpen}\n过时的证书计数:{agingCount}\n过时的证书:{agingCommonNameAndDate}\n{agingConditionalClose}\n", + "xpack.synthetics.alerts.tls.legacy.description": "运行时间监测的 TLS 证书即将过期时告警。未来的版本将弃用此告警。", + "xpack.synthetics.alerts.tls.settingsPageNav.text": "可以在 {settingsPageLink}上编辑这些阈值。", + "xpack.synthetics.alerts.tls.validAfterExpiredString": "已于 {relativeDate} 天前,即 {date}到期。", + "xpack.synthetics.alerts.tls.validAfterExpiringString": "将在{relativeDate} 天后,即 {date}到期。", + "xpack.synthetics.alerts.tls.validBeforeExpiredString": "自 {relativeDate} 天前,即 {date}开始生效。", + "xpack.synthetics.alerts.tls.validBeforeExpiringString": "从现在到 {date}的 {relativeDate} 天里无效。", + "xpack.synthetics.alerts.tlsLegacy": "Uptime TLS(旧版)", + "xpack.synthetics.alerts.toggleAlertFlyoutButtonText": "告警和规则", + "xpack.synthetics.alertsPopover.toggleButton.ariaLabel": "打开告警和规则上下文菜单", + "xpack.synthetics.analyzeDataButtonLabel": "浏览数据", + "xpack.synthetics.analyzeDataButtonLabel.message": "“浏览数据”允许您选择和筛选任意维度中的结果数据以及查找性能问题的原因或影响。", + "xpack.synthetics.apmIntegrationAction.description": "在 APM 中搜索此监测", + "xpack.synthetics.apmIntegrationAction.text": "显示 APM 数据", + "xpack.synthetics.availabilityLabelText": "{value} %", + "xpack.synthetics.badge.readOnly.text": "只读", + "xpack.synthetics.badge.readOnly.tooltip": "无法保存", + "xpack.synthetics.breadcrumbs.observabilityText": "Observability", + "xpack.synthetics.breadcrumbs.overviewBreadcrumbText": "运行时间", + "xpack.synthetics.certificates.heading": "TLS 证书 ({total})", + "xpack.synthetics.certificates.loading": "正在加载证书......", + "xpack.synthetics.certificates.refresh": "刷新", + "xpack.synthetics.certificatesPage.heading": "TLS 证书", + "xpack.synthetics.certificatesRoute.title": "证书 | {baseTitle}", + "xpack.synthetics.certs.expired": "已过期", + "xpack.synthetics.certs.expires": "过期", + "xpack.synthetics.certs.expireSoon": "即将过期", + "xpack.synthetics.certs.list.ageCol": "存在时间", + "xpack.synthetics.certs.list.commonName": "常见名称", + "xpack.synthetics.certs.list.copyFingerprint": "单击可复制指纹值", + "xpack.synthetics.certs.list.days": "天", + "xpack.synthetics.certs.list.empty": "找不到任何证书。注意:证书仅对 Heartbeat 7.8+ 可见", + "xpack.synthetics.certs.list.expirationDate": "指纹", + "xpack.synthetics.certs.list.issuedBy": "颁发者", + "xpack.synthetics.certs.list.monitors": "监测", + "xpack.synthetics.certs.list.status": "状态", + "xpack.synthetics.certs.list.status.old": "过旧", + "xpack.synthetics.certs.list.validUntil": "失效日期", + "xpack.synthetics.certs.ok": "确定", + "xpack.synthetics.certs.searchCerts": "搜索证书", + "xpack.synthetics.certs.status.ok.label": " 对于 {okRelativeDate}", + "xpack.synthetics.charts.mlAnnotation.header": "分数:{score}", + "xpack.synthetics.charts.mlAnnotation.severity": "严重性:{severity}", + "xpack.synthetics.controls.selectSeverity.criticalLabel": "紧急", + "xpack.synthetics.controls.selectSeverity.majorLabel": "重大", + "xpack.synthetics.controls.selectSeverity.minorLabel": "轻微", + "xpack.synthetics.controls.selectSeverity.scoreDetailsDescription": "{value} 及以上分数", + "xpack.synthetics.controls.selectSeverity.warningLabel": "警告", + "xpack.synthetics.createPackagePolicy.stepConfigure.browser.scriptRecorder.experimentalLabel": "技术预览", + "xpack.synthetics.createPackagePolicy.stepConfigure.browser.scriptRecorder.experimentalTooltip": "预览通过 Elastic Synthetics 记录器创建 Elastic Synthetics 监测脚本的最快方式", + "xpack.synthetics.createPackagePolicy.stepConfigure.browser.scriptRecorder.label": "脚本记录器", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.description": "为 Synthetics 代理提供微调的配置。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.filtering.description": "使用这些选项可将选定监测设置应用于您套件中的测试子集。仅配置的子集由此监测运行。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.filtering.title": "选择性测试", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.ignoreHttpsErrors.helpText": "将此选项设为 true 可在 Synthetics 浏览器中禁用 TLS/SSL 验证。这对于使用自签名证书的测试站点很有用。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.ignoreHttpsErrors.label": "忽略 HTTPS 错误", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersMatch.helpText": "通过此监测仅运行名称与提供的 glob 匹配的过程。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersMatch.label": "筛选匹配", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersTags.helpText": "通过此监测仅运行具有给定标签的过程。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersTags.label": "筛选标签", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.screenshots.helpText": "设置此选项以管理 Synthetics 代理捕获的屏幕截图。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.screenshots.label": "屏幕截图选项", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.syntheticsArgs.helpText": "要传递给 Synthetics 代理软件包的附加参数。取字符串列表。这在极少情况下有用,通常应不需要设置。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.syntheticsArgs.label": "Synthetics 参数", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.automatic_node_cap.message": "禁用限制时,您的监测的带宽仍然由其中运行监测的 Synthetics 节点的配置设置上限。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.automatic_node_cap.title": "自动上限", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.description": "控制监测的下载和上传速度及其延迟,以在更缓慢或更迟缓的网络上模拟应用程序的行为。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.download.error": "下载速度必须大于零。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.download.label": "下载速度", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.exceeded_throttling.message": "使用大于 Synthetics 节点带宽限制的限值时,您的监测的带宽仍然具有上限。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.exceeded_throttling.title": "您已超出 Synthetics 节点带宽限制", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.latency.error": "延迟不得为负。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.latency.label": "延迟", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.switch.description": "启用限制", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.title": "限制选项", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.upload.error": "上传速度必须大于零。", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.upload.label": "上传速度", + "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.title": "Synthetics 代理选项", + "xpack.synthetics.createPackagePolicy.stepConfigure.certificateSettings.enableSSLSettings.label": "启用 TLS 配置", + "xpack.synthetics.createPackagePolicy.stepConfigure.certificateSettings.enableZipUrlSSLSettings.label": "启用用于 Zip URL 的 TLS 配置", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificate.helpText": "用于 TLS 客户端身份验证的 PEM 格式证书。", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificate.label": "证书", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificateAuthorities.helpText": "PEM 格式自定义证书颁发机构。", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificateAuthorities.label": "证书颁发机构", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificateKey.helpText": "用于 TLS 客户端身份验证的 PEM 格式证书密钥。", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificateKey.label": "密钥", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificateKeyPassphrase.helpText": "用于 TLS 客户端身份验证的证书密钥密码。", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificateKeyPassphrase.label": "密钥密码", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.legend": "证书设置", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.tlsRole.client": "客户端", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.tlsRole.server": "服务器", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.certificate.description": "验证提供的证书是否由受信任颁发机构 (CA) 签署,但不执行任何主机名验证。", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.certificate.label": "证书", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.full.description": "验证提供的证书是否由受信任颁发机构 (CA) 签署,同时验证服务器的主机名(或 IP 地址)是否匹配证书内识别的名称。", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.full.label": "实线", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.label": "验证模式", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.none.description": "对服务器的证书不执行验证。主要用作尝试解决 TLS 错误时的临时诊断机制;强烈不建议在生产环境中使用它。", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.none.label": "无", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.strict.description": "验证提供的证书是否由受信任颁发机构 (CA) 签署,同时验证服务器的主机名(或 IP 地址)是否匹配证书内识别的名称。如果使用者备用名称为空,将返回错误。", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.strict.label": "严格", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.warning.description": "此模式禁用了许多 SSL/TLS 安全性功能,只能在谨慎考虑之后使用。", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.verificationMode.warning.title": "正在禁用 TLS", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.version.label": "支持的 TLS 协议", + "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.version.placeholder": "选择一个或多个 TLS 协议。", + "xpack.synthetics.createPackagePolicy.stepConfigure.headerField.addHeader.label": "添加标头", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions": "高级 HTTP 选项", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.indexResponseBody.helpText": "控制将 HTTP 响应正文内容索引到 ", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.indexResponseHeaders.helpText": "控制将 HTTP 响应标头索引到 ", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestBody.helpText": "请求正文内容。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.description": "配置要发送到远程主机的可选请求,包括方法、正文和标头。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.requestBody": "请求正文", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.requestHeaders": "请求标头", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.requestMethod.label": "请求方法", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestConfiguration.title": "请求配置", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestHeadersField.error": "标头密钥必须是有效的 HTTP 令牌。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestHeadersField.helpText": "要发送的额外 HTTP 标头的字典。默认情况下,客户端将设置用户代理标头以自我标识。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.requestMethod.helpText": "要使用的 HTTP 方法。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseBodyCheckNegative.helpText": "负匹配正文输出的正则表达式列表。按 enter 键添加新的表达式。如果单个表达式匹配,返回匹配失败。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseBodyCheckPositive.helpText": "匹配正文输出的正则表达式列表。按 enter 键添加新的表达式。仅单个表达式需要匹配。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseCheckNegative.label": "检查响应正文不包含", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseCheckPositive.label": "检查响应正文包含", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.checkResponseHeadersContain": "检查响应标头包含", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.description": "配置预期的 HTTP 响应。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.responseStatusCheck.error": "状态代码只能包含数字。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.responseStatusCheck.helpText": "预期状态代码列表。按 enter 键添加新的代码。4xx 和 5xx 代码默认情况下被视为关闭。其他代码被视为运行。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.responseStatusCheck.label": "检查响应状态等于", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseChecks.title": "响应检查", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfig.indexResponseBody": "索引响应正文", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfig.indexResponseHeaders": "索引响应标头", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfig.responseBodyIndexPolicy": "响应正文索引策略", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfiguration.description": "控制 HTTP 响应标头的索引。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseConfiguration.title": "响应配置", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseHeadersField.error": "标头密钥必须是有效的 HTTP 令牌。", + "xpack.synthetics.createPackagePolicy.stepConfigure.httpAdvancedOptions.responseHeadersField.helpText": "预期响应标头的列表。", + "xpack.synthetics.createPackagePolicy.stepConfigure.icmpAdvancedOptions": "高级 ICMP 选项", + "xpack.synthetics.createPackagePolicy.stepConfigure.inputVarFieldOptionalLabel": "可选", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.helpText": "此监测的 APM 服务名称。对应于 service.name ECS 字段。监测也使用 APM 的应用时设置此选项以启用 Kibana 中的 Uptime 和 APM 数据之间的集成。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.label": "APM 服务名称", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.brower.proxyURL.label": "代理 Zip URL", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.http.helpText": "用于 Zip URL 的 HTTP 代理。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.error": "“脚本”必填", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.helpText": "运行内联定义的 Synthetics 测试脚本。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.label": "内联脚本", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.params.helpText": "JSON 对象,定义您的测试所需的任何变量。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.params.label": "参数", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.scriptRecorder.closeButtonLabel": "关闭脚本浮出控件", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.scriptRecorder.mockFileName": "test_script.js", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.sourceType.label": "源类型", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.fieldLabel": "正在测试脚本", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.invalidFileError": "文件类型无效。请上传由 Elastic Synthetics 记录器生成的 .js 文件。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.label": "选择记录器生成的 .js 文件", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.parsingError": "上传文件时出错。请上传 Elastic Synthetics 记录器以内联脚本格式生成的 .js 文件。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.error": "ZIP URL 必填", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.helpText": "Synthetics 项目存储库 zip 文件的位置。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.label": "Zip URL", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.recorderLink": "下载 Elastic Synthetics 记录器", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.removeScriptLabel": "移除脚本", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.showScriptLabel": "显示脚本", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlFolder.helpText": "合成旅程文件在存储库中所在的相对目录路径。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlFolder.label": "文件夹", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlPassword.abel": "Zip URL 密码", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlPassword.helpText": "用于在 zip 终端上进行身份验证的密码。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlUsername.helpText": "用于在 zip 终端上进行身份验证的用户名。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlUsername.label": "Zip URL 用户名", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browserLabel": "浏览器(公测版)", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.enabled.helpText": "关闭此配置以禁用监测。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.enabled.label": "已启用", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.icmp.hosts": "主机", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.icmp.hosts.error": "“主机”必填", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.maxRedirects": "最大重定向数", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.maxRedirects.error": "“最大重定向数”必须不小于 0", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.maxRedirects.helpText": "要跟随的重定向总数。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorInterval": "频率", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorInterval.error": "监测频率必填", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType": "监测类型", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.description": "要创建“浏览器”监测,请确保使用 elastic-agent-complete Docker 容器,其中包含运行这些监测的依赖项。有关更多信息,请访问我们的 {link}。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.link": "Synthetics 文档", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.error": "“监测类型”必填。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.password.helpText": "用于在服务器上进行身份验证的密码。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.password.label": "密码", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyUrl.http.helpText": "HTTP 代理 URL。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyURL.http.label": "代理 URL", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyURL.label": "代理 URL", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.proxyUrl.tcp.helpText": "连接到服务器时要使用的 SOCKS5 代理的 URL。该值必须是具有 socks5:// 方案的 URL。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.resolveHostnamesLocally": "本地解析主机名", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tags.helpText": "将随监测事件一起发送的标签列表。按 enter 键添加新标签。显示在 Uptime 中并启用按标签搜索。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tags.label": "标签", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tcp.hosts": "主机:端口", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.tcp.hosts.error": "主机和端口必填", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.helpText": "允许用于测试连接并交换数据的总时间。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.label": "超时(秒)", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.lessThanIntervalError": "超时必须小于监测频率", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.timeout.moreThanZeroError": "超时必须大于或等于 0", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.URL": "URL", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.URL.error": "“URL”必填", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.username.helpText": "用于在服务器上进行身份验证的用户名。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.username.label": "用户名", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.wait.error": "“等待时间”必须不小于 0", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.wait.helpText": "如果未收到响应,在发出另一个 ICMP 回显请求之前要等待的时长。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.wait.label": "等待时间(秒)", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSectionDescription": "使用以下选项配置您的监测。", + "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSectionTitle": "监测设置", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBody.codeEditor.javascript.ariaLabel": "JavaScript 代码编辑器", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBody.codeEditor.json.ariaLabel": "JSON 代码编辑器", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBody.codeEditor.text.ariaLabel": "文本代码编辑器", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBody.codeEditor.xml.ariaLabel": "XML 代码编辑器", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBody.formField.addFormField.label": "添加表单字段", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBodyType.form": "表单", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBodyType.JSON": "JSON", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBodyType.text": "文本", + "xpack.synthetics.createPackagePolicy.stepConfigure.requestBodyType.XML": "XML", + "xpack.synthetics.createPackagePolicy.stepConfigure.responseBodyIndex.always": "始终", + "xpack.synthetics.createPackagePolicy.stepConfigure.responseBodyIndex.onError": "错误时", + "xpack.synthetics.createPackagePolicy.stepConfigure.scheduleField.minutes": "分钟", + "xpack.synthetics.createPackagePolicy.stepConfigure.scheduleField.number": "数字", + "xpack.synthetics.createPackagePolicy.stepConfigure.scheduleField.seconds": "秒", + "xpack.synthetics.createPackagePolicy.stepConfigure.scheduleField.unit": "单位", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.description": "配置向远程主机发送的有效负载。", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.requestPayload.helpText": "要发送给远程主机的有效负载字符串。", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.requestPayload.label": "请求有效负载", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.requestConfiguration.title": "请求配置", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.responseConfiguration.responseContains.helpText": "预期远程主机响应。", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvacnedSettings.responseConfiguration.responseContains.label": "检查响应包含", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvancedOptions.responseConfiguration.description": "配置来自远程主机的预期响应。", + "xpack.synthetics.createPackagePolicy.stepConfigure.tcpAdvancedOptions.responseConfiguration.title": "响应检查", + "xpack.synthetics.createPackagePolicy.stepConfigure.tlsSettings.description": "配置 TLS 选项,包括验证模式、证书颁发机构和客户端证书。", + "xpack.synthetics.createPackagePolicy.stepConfigure.tlsSettings.label": "TLS 设置", + "xpack.synthetics.durationChart.emptyPrompt.description": "在选定时间范围内此监测从未{emphasizedText}。", + "xpack.synthetics.durationChart.emptyPrompt.title": "没有持续时间数据", + "xpack.synthetics.editMonitor.pageHeader.title": "编辑监测", + "xpack.synthetics.editMonitorRoute.title": "编辑监测 | {baseTitle}", + "xpack.synthetics.emptyState.loadingMessage": "正在加载……", + "xpack.synthetics.emptyStateError.notAuthorized": "您无权查看 Uptime 数据,请联系系统管理员。", + "xpack.synthetics.emptyStateError.notFoundPage": "未找到页面", + "xpack.synthetics.emptyStateError.title": "错误", + "xpack.synthetics.enableAlert.editAlert": "编辑告警", + "xpack.synthetics.filterBar.ariaLabel": "概览页面的输入筛选条件", + "xpack.synthetics.filterBar.filterAllLabel": "全部", + "xpack.synthetics.filterBar.options.location.name": "位置", + "xpack.synthetics.filterBar.options.portLabel": "端口", + "xpack.synthetics.filterBar.options.schemeLabel": "方案", + "xpack.synthetics.filterBar.options.tagsLabel": "标签", + "xpack.synthetics.fleetIntegration.assets.description": "在 Uptime 中查看监测", + "xpack.synthetics.fleetIntegration.assets.name": "监测", + "xpack.synthetics.inspectButtonText": "检查", + "xpack.synthetics.integrationLink.missingDataMessage": "未找到此集成的所需数据。", + "xpack.synthetics.keyValuePairsField.deleteItem.label": "删除项目编号 {index},{key}:{value}", + "xpack.synthetics.keyValuePairsField.key.ariaLabel": "钥匙", + "xpack.synthetics.keyValuePairsField.key.label": "钥匙", + "xpack.synthetics.keyValuePairsField.value.ariaLabel": "值", + "xpack.synthetics.keyValuePairsField.value.label": "值", + "xpack.synthetics.kueryBar.searchPlaceholder.kql": "使用 kql 语法搜索监测 ID、名称和类型等(例如 monitor.type: \"http\" AND tags: \"dev\")", + "xpack.synthetics.kueryBar.searchPlaceholder.simple": "按监测 ID、名称或 url(例如 http://)搜索", + "xpack.synthetics.locationName.helpLinkAnnotation": "添加位置", + "xpack.synthetics.mappingErrorRoute.breadcrumb": "映射错误", + "xpack.synthetics.mappingErrorRoute.pageHeader.title": "映射错误", + "xpack.synthetics.mappingErrorRoute.title": "Synthetics | 映射错误", + "xpack.synthetics.millisecond.abbreviation.label": "ms", + "xpack.synthetics.ml.durationChart.exploreInMlApp": "在 ML 应用中浏览", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.add_job_permissions_needed": "需要权限", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.anomalyDetectionTitle": "异常检测", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.cancelLabel": "取消", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.createMLJobDescription": "在此处可以创建 Machine Learning 作业,以便为运行时间监测计算\n 响应持续时间的异常分数。启用后,详情页面上的监测持续时间图表\n 将显示预期边界并使用异常标注图表。您还可能\n 识别在所有地理区域的延迟增长时段。", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.createNewJobButtonLabel": "创建新作业", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.disableAnomalyAlert": "禁用异常告警", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.disableAnomalyDetectionTitle": "禁用异常检测", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.enable_or_manage_job": "您可以启用异常检测作业,或者如果此处已有作业,则可以管理该作业或告警。", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.enableAnomalyAlert": "启用异常告警", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.enableAnomalyDetectionTitle": "启用异常检测", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.insufficient_permissions_add_job": "您必须具有 Machine Learning 的 Kibana 权限才能使用此功能。", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreatedLazyNotificationText": "分析正等待 ML 节点变为可用。可能要花费点时间,才会将结果添加到响应时间图表。", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreatedNotificationText": "现在正在运行响应持续时间图表的分析。可能要花费点时间,才会将结果添加到响应时间图表。", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreatedNotificationText.viewJobLinkText": "查看作业", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreatedNotificationTitle": "作业已成功创建", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreationFailedNotificationText": "您当前的许可证可能不允许创建 Machine Learning 作业,或者此作业可能已存在。", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobCreationFailedNotificationTitle": "作业创建失败", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobDeletionConfirmLabel": "删除异常检测作业?", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobDeletionNotificationTitle": "作业已删除", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.jobDeletionSuccessNotificationText": "作业已成功删除", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.manageAnomalyDetectionTitle": "管理异常检测", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.manageMLJobDescription": "创建作业后,可以在 {mlJobsPageLink} 中管理作业以及查看更多详细信息。", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.manageMLJobDescription.mlJobsPageLinkText": "Machine Learning 作业管理页面", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.manageMLJobDescription.noteText": "注意:可能要过几分钟后,作业才会开始计算结果。", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.noPermissionsTooltip": "您需要 Uptime 的读写访问权限才能创建异常告警。", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.startTrial": "开始为期 14 天的免费试用", + "xpack.synthetics.ml.enableAnomalyDetectionPanel.startTrialDesc": "要访问持续时间异常检测,必须订阅 Elastic 白金级许可证。", + "xpack.synthetics.monitor.simpleStatusAlert.email.subject": "URL 为 {url} 的监测 {monitor} 已关闭", + "xpack.synthetics.monitorCharts.durationChart.leftAxis.title": "持续时间 ({unit})", + "xpack.synthetics.monitorCharts.durationChart.wrapper.label": "显示监测的 ping 持续时间(按位置分组)的图表。", + "xpack.synthetics.monitorCharts.monitorDuration.titleLabel": "监测持续时间", + "xpack.synthetics.monitorCharts.monitorDuration.titleLabelWithAnomaly": "监测持续时间(异常:{noOfAnomalies})", + "xpack.synthetics.monitorDetails.ml.confirmAlertDeleteMessage": "确定要删除异常告警?", + "xpack.synthetics.monitorDetails.ml.confirmDeleteMessage": "是否确定要删除此作业?", + "xpack.synthetics.monitorDetails.ml.deleteJobWarning": "删除作业可能会非常耗时。删除将在后台进行,数据可能不会马上消失。", + "xpack.synthetics.monitorDetails.ml.deleteMessage": "正在删除作业......", + "xpack.synthetics.monitorDetails.statusBar.pingType.browser": "浏览器", + "xpack.synthetics.monitorDetails.statusBar.pingType.http": "HTTP", + "xpack.synthetics.monitorDetails.statusBar.pingType.icmp": "ICMP", + "xpack.synthetics.monitorDetails.statusBar.pingType.tcp": "TCP", + "xpack.synthetics.monitorDetails.title.disclaimer.description": "(公测版)", + "xpack.synthetics.monitorDetails.title.disclaimer.link": "查看更多内容", + "xpack.synthetics.monitorDetails.title.pingType.browser": "浏览器", + "xpack.synthetics.monitorDetails.title.pingType.http": "HTTP ping", + "xpack.synthetics.monitorDetails.title.pingType.icmp": "ICMP ping", + "xpack.synthetics.monitorDetails.title.pingType.tcp": "TCP ping", + "xpack.synthetics.monitorList.allMonitors": "所有监测", + "xpack.synthetics.monitorList.anomalyColumn.label": "响应异常分数", + "xpack.synthetics.monitorList.defineConnector.description": "在 {link} 中定义默认连接器以启用状态告警。", + "xpack.synthetics.monitorList.defineConnector.popover.description": "以接收状态告警。", + "xpack.synthetics.monitorList.disableDownAlert": "禁用状态告警", + "xpack.synthetics.monitorList.downLineSeries.downLabel": "关闭检查", + "xpack.synthetics.monitorList.drawer.missingLocation": "某些 Heartbeat 实例未定义位置。{link}到您的 Heartbeat 配置。", + "xpack.synthetics.monitorList.drawer.mostRecentRun": "最新测试运行", + "xpack.synthetics.monitorList.drawer.statusRowLocationList": "上次检查时状态为“{status}”的位置列表。", + "xpack.synthetics.monitorList.drawer.url": "URL", + "xpack.synthetics.monitorList.enabledAlerts.noAlert": "没有为此监测启用规则。", + "xpack.synthetics.monitorList.enabledAlerts.title": "已启用规则", + "xpack.synthetics.monitorList.enableDownAlert": "启用状态告警", + "xpack.synthetics.monitorList.errorSummary": "错误摘要", + "xpack.synthetics.monitorList.expandDrawerButton.ariaLabel": "展开 ID {id} 的监测行", + "xpack.synthetics.monitorList.geoName.helpLinkAnnotation": "添加位置", + "xpack.synthetics.monitorList.infraIntegrationAction.container.message": "显示容器指标", + "xpack.synthetics.monitorList.infraIntegrationAction.docker.description": "在 Infrastructure UI 上查找此监测的容器 ID", + "xpack.synthetics.monitorList.infraIntegrationAction.docker.tooltip": "在 Infrastructure UI 上查找容器 ID“{containerId}”", + "xpack.synthetics.monitorList.infraIntegrationAction.ip.ariaLabel": "在 Infrastructure UI 上查找此监测的 IP 地址", + "xpack.synthetics.monitorList.infraIntegrationAction.ip.message": "显示主机指标", + "xpack.synthetics.monitorList.infraIntegrationAction.ip.tooltip": "在 Infrastructure UI 上查找 IP“{ip}”", + "xpack.synthetics.monitorList.infraIntegrationAction.kubernetes.description": "在 Infrastructure UI 上查找此监测的 Pod UID", + "xpack.synthetics.monitorList.infraIntegrationAction.kubernetes.message": "显示 Pod 指标", + "xpack.synthetics.monitorList.infraIntegrationAction.kubernetes.tooltip": "在 Infrastructure UI 上查找 Pod UID“{podUid}”。", + "xpack.synthetics.monitorList.integrationGroup.emptyMessage": "没有可用的集成应用程序", + "xpack.synthetics.monitorList.invalidMonitors": "监测无效", + "xpack.synthetics.monitorList.loading": "正在加载……", + "xpack.synthetics.monitorList.locations.expand": "单击以查看剩余位置", + "xpack.synthetics.monitorList.loggingIntegrationAction.container.id": "显示容器日志", + "xpack.synthetics.monitorList.loggingIntegrationAction.container.message": "显示容器日志", + "xpack.synthetics.monitorList.loggingIntegrationAction.container.tooltip": "在 Logging UI 上查找容器 ID“{containerId}”", + "xpack.synthetics.monitorList.loggingIntegrationAction.ip.description": "在 Logging UI 中查找此监测的 IP 地址", + "xpack.synthetics.monitorList.loggingIntegrationAction.ip.message": "显示主机日志", + "xpack.synthetics.monitorList.loggingIntegrationAction.ip.tooltip": "在 Logging UI 上查找 IP“{ip}”", + "xpack.synthetics.monitorList.loggingIntegrationAction.kubernetes.ariaLabel": "显示 Pod 日志", + "xpack.synthetics.monitorList.loggingIntegrationAction.kubernetes.message": "显示 Pod 日志", + "xpack.synthetics.monitorList.loggingIntegrationAction.kubernetes.tooltip": "在日志中查找 Pod UID“{podUid}”", + "xpack.synthetics.monitorList.monitorHistoryColumnLabel": "中断历史记录", + "xpack.synthetics.monitorList.monitoringStatusTitle": "监测", + "xpack.synthetics.monitorList.monitorType.filter": "筛选 {type} 类型的所有监测", + "xpack.synthetics.monitorList.mostRecentError.title": "最新错误 ({timestamp})", + "xpack.synthetics.monitorList.nameColumnLabel": "名称", + "xpack.synthetics.monitorList.noDownHistory": "在选定时间范围内此监测从未{emphasizedText}。", + "xpack.synthetics.monitorList.noItemForSelectedFiltersMessage": "未找到匹配选定筛选条件的监测", + "xpack.synthetics.monitorList.noItemMessage": "未找到任何运行时间监测", + "xpack.synthetics.monitorList.observabilityIntegrationsColumn.apmIntegrationLink.tooltip": "单击此处可在 APM 中查找域“{domain}”或显式定义的“服务名称”。", + "xpack.synthetics.monitorList.observabilityIntegrationsColumn.popoverIconButton.ariaLabel": "打开 url {monitorUrl} 的监测的集成弹出式窗口", + "xpack.synthetics.monitorList.observabilityInvestigateColumn.popoverIconButton.label": "调查", + "xpack.synthetics.monitorList.pageSizePopoverButtonText": "每页行数:{size}", + "xpack.synthetics.monitorList.pageSizeSelect.numRowsItemMessage": "{numRows} 行", + "xpack.synthetics.monitorList.redirects.description": "执行 ping 时,Heartbeat 在 {number} 次重定向后运行。", + "xpack.synthetics.monitorList.redirects.openWindow": "将在新窗口中打开链接。", + "xpack.synthetics.monitorList.redirects.title": "重定向", + "xpack.synthetics.monitorList.redirects.title.number": "{number}", + "xpack.synthetics.monitorList.refresh": "刷新", + "xpack.synthetics.monitorList.statusAlert.label": "状态告警", + "xpack.synthetics.monitorList.statusColumn.checkedTimestamp": "已检查 {timestamp}", + "xpack.synthetics.monitorList.statusColumn.completeLabel": "已完成", + "xpack.synthetics.monitorList.statusColumn.downLabel": "关闭", + "xpack.synthetics.monitorList.statusColumn.error.logs": "错误日志", + "xpack.synthetics.monitorList.statusColumn.error.message": "{message}。单击了解更多详情。", + "xpack.synthetics.monitorList.statusColumn.error.messageLabel": "{message}。单击了解更多详情。", + "xpack.synthetics.monitorList.statusColumn.failedLabel": "失败", + "xpack.synthetics.monitorList.statusColumn.locStatusMessage": "在 {noLoc} 个位置", + "xpack.synthetics.monitorList.statusColumn.locStatusMessage.multiple": "在 {noLoc} 个位置", + "xpack.synthetics.monitorList.statusColumn.locStatusMessage.tooltip.down": "在 {locs} 关闭", + "xpack.synthetics.monitorList.statusColumn.locStatusMessage.tooltip.up": "在 {locs} 运行", + "xpack.synthetics.monitorList.statusColumn.upLabel": "运行", + "xpack.synthetics.monitorList.statusColumnLabel": "状态", + "xpack.synthetics.monitorList.table.description": "具有“状态”、“名称”、“URL”、“IP”、“中断历史记录”和“集成”列的“监测状态”表。该表当前显示 {length} 个项目。", + "xpack.synthetics.monitorList.table.tags.name": "标签", + "xpack.synthetics.monitorList.table.url.name": "URL", + "xpack.synthetics.monitorList.tags.expand": "单击以查看剩余标签", + "xpack.synthetics.monitorList.tags.filter": "筛选带 {tag} 标签的所有监测", + "xpack.synthetics.monitorList.testNow.AriaLabel": "单击以立即运行测试", + "xpack.synthetics.monitorList.testNow.available": "立即测试仅适用于通过监测管理添加的监测。", + "xpack.synthetics.monitorList.testNow.label": "立即测试", + "xpack.synthetics.monitorList.testNow.scheduled": "已计划测试", + "xpack.synthetics.monitorList.testRunLogs": "测试运行日志", + "xpack.synthetics.monitorList.timestamp": "时间戳", + "xpack.synthetics.monitorList.tlsColumnLabel": "TLS 证书", + "xpack.synthetics.monitorList.viewInDiscover": "在 Discover 中查看", + "xpack.synthetics.monitorManagement.addMonitorCrumb": "添加监测", + "xpack.synthetics.monitorManagement.addMonitorError": "无法加载服务位置。请稍后重试。", + "xpack.synthetics.monitorManagement.addMonitorLabel": "添加监测", + "xpack.synthetics.monitorManagement.addMonitorLoadingError": "加载监测管理时出错", + "xpack.synthetics.monitorManagement.addMonitorLoadingLabel": "正在加载监测管理", + "xpack.synthetics.monitorManagement.addMonitorServiceLocationsLoadingError": "无法加载服务位置。请稍后重试。", + "xpack.synthetics.monitorManagement.apiKeysDisabledToolTip": "对此集群禁用了 API 密钥。监测管理需要使用 API 密钥才能回写 Elasticsearch 集群。要启用 API 密钥,请与管理员联系。", + "xpack.synthetics.monitorManagement.callout.description.disabled": "监测管理当前处于禁用状态。要在 Elastic 托管 Synthetics 服务上运行监测,请启用监测管理。现有监测已暂停。", + "xpack.synthetics.monitorManagement.callout.disabled": "已禁用监测管理", + "xpack.synthetics.monitorManagement.callout.disabled.adminContact": "请联系管理员启用监测管理。", + "xpack.synthetics.monitorManagement.closeButtonLabel": "关闭", + "xpack.synthetics.monitorManagement.completed": "已完成", + "xpack.synthetics.monitorManagement.confirmDescriptionLabel": "此操作将删除监测,但会保留收集的任何数据。此操作无法撤消。", + "xpack.synthetics.monitorManagement.deleteMonitorLabel": "删除监测", + "xpack.synthetics.monitorManagement.disableMonitorLabel": "禁用监测", + "xpack.synthetics.monitorManagement.discardLabel": "丢弃", + "xpack.synthetics.monitorManagement.duplicateNameError": "监测名称已存在。", + "xpack.synthetics.monitorManagement.editMonitorCrumb": "编辑监测", + "xpack.synthetics.monitorManagement.editMonitorError": "加载监测管理时出错", + "xpack.synthetics.monitorManagement.editMonitorError.description": "无法加载监测管理设置。请联系支持人员。", + "xpack.synthetics.monitorManagement.editMonitorErrorBody": "无法加载监测配置。请稍后重试。", + "xpack.synthetics.monitorManagement.editMonitorLabel": "编辑监测", + "xpack.synthetics.monitorManagement.editMonitorLoadingLabel": "正在加载监测", + "xpack.synthetics.monitorManagement.emptyState.enablement": "启用监测管理以从全球托管测试地点运行轻量级检查和真正的浏览器监测。启用监测管理将生成 API 密钥,以便 Synthetics 服务回写 Elasticsearch 集群。", + "xpack.synthetics.monitorManagement.emptyState.enablement.disabled.title": "已禁用监测管理", + "xpack.synthetics.monitorManagement.emptyState.enablement.disabledDescription": "监测管理当前处于禁用状态。通过监测管理,您可以从全球托管测试地点运行轻量级检查和真正的浏览器监测。要启用监测管理,请与管理员联系。", + "xpack.synthetics.monitorManagement.emptyState.enablement.doc": "阅读文档", + "xpack.synthetics.monitorManagement.emptyState.enablement.enabled.title": "启用监测管理", + "xpack.synthetics.monitorManagement.emptyState.enablement.learnMore": "希望了解详情?", + "xpack.synthetics.monitorManagement.emptyState.enablement.title": "启用", + "xpack.synthetics.monitorManagement.enableMonitorLabel": "启用监测", + "xpack.synthetics.monitorManagement.failed": "失败", + "xpack.synthetics.monitorManagement.failedRun": "无法运行步骤", + "xpack.synthetics.monitorManagement.inProgress": "进行中", + "xpack.synthetics.monitorManagement.label": "监测管理", + "xpack.synthetics.monitorManagement.loading.label": "正在加载监测管理", + "xpack.synthetics.monitorManagement.loadingSteps": "正在加载步骤......", + "xpack.synthetics.monitorManagement.manageMonitorLoadingLabel": "正在加载监测管理", + "xpack.synthetics.monitorManagement.manageMonitorLoadingLabel.callout.learnMore": "了解详情。", + "xpack.synthetics.monitorManagement.monitorAddedSuccessMessage": "已成功添加监测。", + "xpack.synthetics.monitorManagement.monitorAdvancedOptions.dataStreamConfiguration.description": "配置其他数据流选项。", + "xpack.synthetics.monitorManagement.monitorAdvancedOptions.dataStreamConfiguration.title": "数据流设置", + "xpack.synthetics.monitorManagement.monitorAdvancedOptions.monitorNamespaceFieldLabel": "命名空间", + "xpack.synthetics.monitorManagement.monitorAdvancedOptions.namespaceHelpLabel": "更改默认命名空间。此设置将更改监测的数据流的名称。{learnMore}。", + "xpack.synthetics.monitorManagement.monitorAdvancedOptions.namespaceHelpLearnMoreLabel": "了解详情", + "xpack.synthetics.monitorManagement.monitorDeleteFailureMessage": "无法删除监测。请稍后重试。", + "xpack.synthetics.monitorManagement.monitorDeleteLoadingMessage": "正在删除监测......", + "xpack.synthetics.monitorManagement.monitorDeleteSuccessMessage": "已成功删除监测。", + "xpack.synthetics.monitorManagement.monitorDisabledSuccessMessage": "已成功禁用监测 {name}。", + "xpack.synthetics.monitorManagement.monitorEditedSuccessMessage": "已成功更新监测。", + "xpack.synthetics.monitorManagement.monitorEnabledSuccessMessage": "已成功启用监测 {name}。", + "xpack.synthetics.monitorManagement.monitorEnabledUpdateFailureMessage": "无法更新监测 {name}。", + "xpack.synthetics.monitorManagement.monitorFailureMessage": "无法保存监测。请稍后重试。", + "xpack.synthetics.monitorManagement.monitorList.actions": "操作", + "xpack.synthetics.monitorManagement.monitorList.enabled": "已启用", + "xpack.synthetics.monitorManagement.monitorList.locations": "位置", + "xpack.synthetics.monitorManagement.monitorList.monitorName": "监测名称", + "xpack.synthetics.monitorManagement.monitorList.monitorType": "监测类型", + "xpack.synthetics.monitorManagement.monitorList.schedule": "频率(分钟)", + "xpack.synthetics.monitorManagement.monitorList.tags": "标签", + "xpack.synthetics.monitorManagement.monitorList.title": "监测管理列表", + "xpack.synthetics.monitorManagement.monitorList.URL": "URL", + "xpack.synthetics.monitorManagement.monitorLocationsLabel": "监测位置", + "xpack.synthetics.monitorManagement.monitorManagementCrumb": "监测管理", + "xpack.synthetics.monitorManagement.monitorNameFieldError": "监测名称必填", + "xpack.synthetics.monitorManagement.monitorNameFieldLabel": "监测名称", + "xpack.synthetics.monitorManagement.monitorSync.failure.content": "同步一个或多个位置的监测时遇到问题:", + "xpack.synthetics.monitorManagement.monitorSync.failure.dismissLabel": "关闭", + "xpack.synthetics.monitorManagement.monitorSync.failure.reasonLabel": "原因", + "xpack.synthetics.monitorManagement.monitorSync.failure.statusLabel": "状态", + "xpack.synthetics.monitorManagement.monitorSync.failure.title": "监测无法与 Synthetics 服务同步", + "xpack.synthetics.monitorManagement.noLabel": "取消", + "xpack.synthetics.monitorManagement.pageHeader.title": "管理监测", + "xpack.synthetics.monitorManagement.pending": "待处理", + "xpack.synthetics.monitorManagement.publicBetaDescription": "监测管理仅适用于选定的公共公测版用户。利用公共\n公测版访问权限,您能够添加 HTTP、TCP、ICMP 和浏览器检查,\n这些检查将在 Elastic 的托管 Synthetics 服务节点上运行。", + "xpack.synthetics.monitorManagement.requestAccess": "请求访问权限", + "xpack.synthetics.monitorManagement.reRunTest": "重新运行测试", + "xpack.synthetics.monitorManagement.runTest": "运行测试", + "xpack.synthetics.monitorManagement.saveMonitorLabel": "保存监测", + "xpack.synthetics.monitorManagement.service.error.message": "已保存您的监测,但同步 {location} 的配置时遇到问题。我们会在稍后自动重试。如果此问题持续存在,您的监测将在 {location} 中停止运行。请联系支持人员获取帮助。", + "xpack.synthetics.monitorManagement.service.error.reason": "原因:{reason}。", + "xpack.synthetics.monitorManagement.service.error.status": "状态:{status}。", + "xpack.synthetics.monitorManagement.service.error.title": "无法同步监测配置", + "xpack.synthetics.monitorManagement.serviceLocationsValidationError": "必须至少指定一个服务位置", + "xpack.synthetics.monitorManagement.stepCompleted": "已完成 {stepCount, number} 个{stepCount, plural, other {步骤}}", + "xpack.synthetics.monitorManagement.syntheticsDisabled": "监测管理当前处于禁用状态。请联系管理员启用监测管理。", + "xpack.synthetics.monitorManagement.syntheticsDisabledFailure": "无法禁用监测管理。请联系支持人员。", + "xpack.synthetics.monitorManagement.syntheticsDisabledSuccess": "已成功禁用监测管理。", + "xpack.synthetics.monitorManagement.syntheticsDisableToolTip": "禁用监测管理会立即在所有测试地点停止执行监测并阻止创建新监测。", + "xpack.synthetics.monitorManagement.syntheticsEnabledFailure": "无法启用监测管理。请联系支持人员。", + "xpack.synthetics.monitorManagement.syntheticsEnableLabel": "启用", + "xpack.synthetics.monitorManagement.syntheticsEnableLabel.management": "启用监测管理", + "xpack.synthetics.monitorManagement.syntheticsEnableSuccess": "已成功启用监测管理。", + "xpack.synthetics.monitorManagement.syntheticsEnableToolTip": "启用监测管理以在全球各个地点创建轻量级、真正的浏览器监测。", + "xpack.synthetics.monitorManagement.testResult": "测试结果", + "xpack.synthetics.monitorManagement.timeTaken": "耗时 {timeTaken}", + "xpack.synthetics.monitorManagement.updateMonitorLabel": "更新监测", + "xpack.synthetics.monitorManagement.validationError": "您的监测存在错误。请在保存前修复这些错误。", + "xpack.synthetics.monitorManagement.viewTestRunDetails": "查看测试结果详情", + "xpack.synthetics.monitorManagement.yesLabel": "删除", + "xpack.synthetics.monitorManagementRoute.title": "管理监测 | {baseTitle}", + "xpack.synthetics.monitorRoute.title": "监测 | {baseTitle}", + "xpack.synthetics.monitorStatusBar.durationTextAriaLabel": "监测持续时间(毫秒)", + "xpack.synthetics.monitorStatusBar.healthStatusMessageAriaLabel": "监测状态", + "xpack.synthetics.monitorStatusBar.loadingMessage": "正在加载……", + "xpack.synthetics.monitorStatusBar.locations.oneLocStatus": "在 {loc} 位置处于 {status}", + "xpack.synthetics.monitorStatusBar.locations.upStatus": "在 {loc} 位置处于 {status}", + "xpack.synthetics.monitorStatusBar.monitor.availability": "总体可用性", + "xpack.synthetics.monitorStatusBar.monitor.availabilityReport.availability": "可用性", + "xpack.synthetics.monitorStatusBar.monitor.availabilityReport.lastCheck": "上次检查", + "xpack.synthetics.monitorStatusBar.monitor.availabilityReport.location": "位置", + "xpack.synthetics.monitorStatusBar.monitor.id": "监测 ID", + "xpack.synthetics.monitorStatusBar.monitor.monitoringFrom": "正监测自", + "xpack.synthetics.monitorStatusBar.monitor.monitoringFrom.listToMap": "更改到地图视图以按位置检查可用性。", + "xpack.synthetics.monitorStatusBar.monitor.monitoringFrom.MapToList": "更改到列表视图以按位置检查可用性。", + "xpack.synthetics.monitorStatusBar.monitorUrlLinkAriaLabel": "监测 URL 链接", + "xpack.synthetics.monitorStatusBar.sslCertificate.title": "TLS 证书", + "xpack.synthetics.monitorStatusBar.timestampFromNowTextAriaLabel": "自上次检查以来经过的时间", + "xpack.synthetics.monitorStatusBar.type.ariaLabel": "监测类型", + "xpack.synthetics.monitorStatusBar.type.label": "类型", + "xpack.synthetics.navigateToAlertingButton.content": "管理规则", + "xpack.synthetics.navigateToAlertingUi": "离开 Uptime 并前往“Alerting 管理”页面", + "xpack.synthetics.noDataConfig.beatsCard.description": "主动监测站点和服务的可用性。接收告警并更快地解决问题,从而优化用户体验。", + "xpack.synthetics.noDataConfig.beatsCard.title": "通过 Heartbeat 添加监测", + "xpack.synthetics.noDataConfig.solutionName": "Observability", + "xpack.synthetics.notFountPage.homeLinkText": "返回主页", + "xpack.synthetics.openAlertContextPanel.ariaLabel": "打开规则上下文面板,以便可以选择规则类型", + "xpack.synthetics.openAlertContextPanel.label": "创建规则", + "xpack.synthetics.overview.alerts.disabled.failed": "无法禁用规则!", + "xpack.synthetics.overview.alerts.disabled.success": "已成功禁用规则!", + "xpack.synthetics.overview.alerts.enabled.failed": "无法启用规则!", + "xpack.synthetics.overview.alerts.enabled.success": "已成功启用规则 ", + "xpack.synthetics.overview.alerts.enabled.success.description": "此监测关闭时,将有消息发送到 {actionConnectors}。", + "xpack.synthetics.overview.heading": "监测", + "xpack.synthetics.overview.pageHeader.syntheticsCallout.announcementLink": "阅读公告", + "xpack.synthetics.overview.pageHeader.syntheticsCallout.content": "Uptime 现在正在预览对脚本化多步骤可用性检查的支持。这意味着您可以与网页元素进行交互,并检查整个过程(例如购买或登录系统)的可用性,而不仅仅是简单的单个页面启动/关闭检查。请单击下面的内容以了解详情,如果您想率先使用这些功能,则可以下载我们的预览组合代理,并在 Uptime 中查看组合检查。", + "xpack.synthetics.overview.pageHeader.syntheticsCallout.dismissButtonText": "关闭", + "xpack.synthetics.overview.pageHeader.syntheticsCallout.title": "Elastic Synthetics", + "xpack.synthetics.overviewPage.headerText": "概览", + "xpack.synthetics.overviewPageLink.disabled.ariaLabel": "禁用的分页按钮表示在监测列表中无法进行进一步导航。", + "xpack.synthetics.overviewPageLink.next.ariaLabel": "下页结果", + "xpack.synthetics.overviewPageLink.prev.ariaLabel": "上页结果", + "xpack.synthetics.page_header.addDataLink.label": "导航到有关如何添加 Uptime 数据的教程", + "xpack.synthetics.page_header.analyzeData.label": "导航到“浏览数据”视图以可视化 Synthetics/用户数据", + "xpack.synthetics.page_header.defineConnector.popover.defaultLink": "定义默认连接器", + "xpack.synthetics.page_header.defineConnector.settingsLink": "设置", + "xpack.synthetics.page_header.manageLink.label": "导航到 Uptime 监测管理页面", + "xpack.synthetics.page_header.settingsLink": "设置", + "xpack.synthetics.page_header.settingsLink.label": "导航到 Uptime 设置页面", + "xpack.synthetics.pingHistogram.analyze": "分析", + "xpack.synthetics.pingist.durationSecondsColumnFormatting": "{seconds} 秒", + "xpack.synthetics.pingist.durationSecondsColumnFormatting.singular": "{seconds} 秒", + "xpack.synthetics.pingList.checkHistoryTitle": "历史记录", + "xpack.synthetics.pingList.collapseRow": "折叠", + "xpack.synthetics.pingList.columns.failedStep": "失败的步骤", + "xpack.synthetics.pingList.drawer.body.docsLink": "文档", + "xpack.synthetics.pingList.durationMsColumnFormatting": "{millis} 毫秒", + "xpack.synthetics.pingList.durationMsColumnLabel": "持续时间", + "xpack.synthetics.pingList.errorColumnLabel": "错误", + "xpack.synthetics.pingList.errorTypeColumnLabel": "错误类型", + "xpack.synthetics.pingList.expandedRow.bodySize": "正文大小为 {bodyBytes}。", + "xpack.synthetics.pingList.expandedRow.error": "错误", + "xpack.synthetics.pingList.expandedRow.response_body": "响应正文", + "xpack.synthetics.pingList.expandedRow.response_body.notRecorded": "正文未记录。阅读我们的{docsLink}以更多了解如何记录响应正文。", + "xpack.synthetics.pingList.expandedRow.truncated": "显示前 {contentBytes} 字节。", + "xpack.synthetics.pingList.expandRow": "展开", + "xpack.synthetics.pingList.headers.title": "响应标头", + "xpack.synthetics.pingList.ipAddressColumnLabel": "IP", + "xpack.synthetics.pingList.locationNameColumnLabel": "位置", + "xpack.synthetics.pingList.pingsLoadingMesssage": "正在加载历史记录......", + "xpack.synthetics.pingList.pingsUnavailableMessage": "未找到历史记录", + "xpack.synthetics.pingList.recencyMessage": "{fromNow}已检查", + "xpack.synthetics.pingList.responseCodeColumnLabel": "响应代码", + "xpack.synthetics.pingList.statusColumnLabel": "状态", + "xpack.synthetics.pingList.stepDurationHeader": "步骤持续时间", + "xpack.synthetics.pingList.synthetics.performanceBreakDown": "查看性能细目", + "xpack.synthetics.pingList.synthetics.waterfall.filters.collapseRequestsLabel": "折叠以仅显示匹配的请求", + "xpack.synthetics.pingList.synthetics.waterfall.filters.popover": "单击以打开瀑布筛选", + "xpack.synthetics.pingList.timestampColumnLabel": "时间戳", + "xpack.synthetics.pluginDescription": "运行时间监测", + "xpack.synthetics.public.pages.mappingError.bodyDocsLink": "您可以在 {docsLink} 中了解如何解决此问题。", + "xpack.synthetics.public.pages.mappingError.bodyMessage": "检测到不正确的映射!可能您忘记运行 Heartbeat {setup} 命令?", + "xpack.synthetics.public.pages.mappingError.title": "Heartbeat 映射缺失", + "xpack.synthetics.routes.baseTitle": "Uptime - Kibana", + "xpack.synthetics.seconds.label": "秒", + "xpack.synthetics.seconds.shortForm.label": "秒", + "xpack.synthetics.settings.blank.error": "不能为空。", + "xpack.synthetics.settings.blankNumberField.error": "必须为数字。", + "xpack.synthetics.settings.cannotEditText": "您的用户当前对 Uptime 应用有“读取”权限。启用“全部”权限级别以编辑这些设置。", + "xpack.synthetics.settings.cannotEditTitle": "您无权编辑设置。", + "xpack.synthetics.settings.error.couldNotSave": "无法保存设置!", + "xpack.synthetics.settings.heading": "Uptime 设置", + "xpack.synthetics.settings.invalid.error": "值必须大于 0。", + "xpack.synthetics.settings.invalid.nanError": "值必须为整数。", + "xpack.synthetics.settings.noSpace.error": "索引名称不得包含空格", + "xpack.synthetics.settings.saveSuccess": "设置已保存!", + "xpack.synthetics.settingsBreadcrumbText": "设置", + "xpack.synthetics.settingsRoute.title": "设置 | {baseTitle}", + "xpack.synthetics.snapshot.donutChart.ariaLabel": "显示当前状态的饼图。{total} 个监测中有 {down} 个已关闭。", + "xpack.synthetics.snapshot.monitor": "监测", + "xpack.synthetics.snapshot.monitors": "监测", + "xpack.synthetics.snapshot.noDataDescription": "选定的时间范围中没有 ping。", + "xpack.synthetics.snapshot.noDataTitle": "没有可用的 ping 数据", + "xpack.synthetics.snapshot.pingsOverTimeTitle": "时移 Ping 数", + "xpack.synthetics.snapshotHistogram.description": "显示 {startTime} 到 {endTime} 运行时间时移状态的条形图。", + "xpack.synthetics.snapshotHistogram.series.pings": "监测 Ping", + "xpack.synthetics.snapshotHistogram.xAxisId": "Ping X 轴", + "xpack.synthetics.snapshotHistogram.yAxis.title": "Ping", + "xpack.synthetics.snapshotHistogram.yAxisId": "Ping Y 轴", + "xpack.synthetics.sourceConfiguration.ageLimit.units.days": "天", + "xpack.synthetics.sourceConfiguration.ageLimitThresholdInput.ariaLabel": "该输入控制 Kibana 显示警告之前 TLS 证书有效的最大天数。", + "xpack.synthetics.sourceConfiguration.ageThresholdDefaultValue": "默认值为 {defaultValue}", + "xpack.synthetics.sourceConfiguration.alertConnectors": "告警连接器", + "xpack.synthetics.sourceConfiguration.alertConnectors.defaultEmail": "默认电子邮件", + "xpack.synthetics.sourceConfiguration.alertDefaultForm.emailConnectorPlaceHolder": "到:电子邮件连接器的电子邮件", + "xpack.synthetics.sourceConfiguration.alertDefaultForm.invalidEmail": "{val} 不是有效电子邮件。", + "xpack.synthetics.sourceConfiguration.alertDefaultForm.requiredEmail": "电子邮件连接器需要目标电子邮件", + "xpack.synthetics.sourceConfiguration.alertDefaultForm.selectConnector": "请选择一个或多个连接器", + "xpack.synthetics.sourceConfiguration.alertDefaults": "告警默认值", + "xpack.synthetics.sourceConfiguration.applySettingsButtonLabel": "应用更改", + "xpack.synthetics.sourceConfiguration.certificateExpirationThresholdInput.ariaLabel": "该输入控制 Kibana 显示警告之前离 TLS 证书到期剩余的最小天数。", + "xpack.synthetics.sourceConfiguration.certificateThresholdDescription": "更改显示并告警证书错误的阈值。注意:这会影响任何配置的告警。", + "xpack.synthetics.sourceConfiguration.certificationSectionTitle": "证书到期", + "xpack.synthetics.sourceConfiguration.defaultConnectors": "默认连接器", + "xpack.synthetics.sourceConfiguration.defaultConnectors.description": "要用于发送告警的默认连接器。", + "xpack.synthetics.sourceConfiguration.defaultConnectors.description.defaultEmail": "选定电子邮件告警连接器需要电子邮件设置。", + "xpack.synthetics.sourceConfiguration.discardSettingsButtonLabel": "取消", + "xpack.synthetics.sourceConfiguration.errorStateLabel": "到期阈值", + "xpack.synthetics.sourceConfiguration.expirationThreshold": "到期/使用时间阈值", + "xpack.synthetics.sourceConfiguration.expirationThresholdDefaultValue": "默认值为 {defaultValue}", + "xpack.synthetics.sourceConfiguration.heartbeatIndicesDefaultValue": "默认值为 {defaultValue}", + "xpack.synthetics.sourceConfiguration.heartbeatIndicesDescription": "用于匹配包含 Heartbeat 数据的索引的索引模式", + "xpack.synthetics.sourceConfiguration.heartbeatIndicesLabel": "Heartbeat 索引", + "xpack.synthetics.sourceConfiguration.heartbeatIndicesTitle": "Uptime 索引", + "xpack.synthetics.sourceConfiguration.indicesSectionTitle": "索引", + "xpack.synthetics.sourceConfiguration.warningStateLabel": "使用时间限制", + "xpack.synthetics.stepDetailRoute.title": "Synthetics 详细信息 | {baseTitle}", + "xpack.synthetics.stepList.collapseRow": "折叠", + "xpack.synthetics.stepList.expandRow": "展开", + "xpack.synthetics.stepList.stepName": "步骤名称", + "xpack.synthetics.synthetics.consoleStepList.message": "此过程无法运行,记录的控制台输出如下所示:", + "xpack.synthetics.synthetics.consoleStepList.title": "未执行步骤", + "xpack.synthetics.synthetics.emptyJourney.message.checkGroupField": "该过程的检查组是 {codeBlock}。", + "xpack.synthetics.synthetics.emptyJourney.message.footer": "没有更多可显示的信息。", + "xpack.synthetics.synthetics.emptyJourney.message.heading": "此过程不包含任何步骤。", + "xpack.synthetics.synthetics.emptyJourney.title": "没有此过程的任何步骤", + "xpack.synthetics.synthetics.executedStep.consoleOutput.label": "控制台输出", + "xpack.synthetics.synthetics.executedStep.errorHeading": "错误消息", + "xpack.synthetics.synthetics.executedStep.screenshot.not": "屏幕截图", + "xpack.synthetics.synthetics.executedStep.screenshot.notSucceeded": "{status} 检查的屏幕截图", + "xpack.synthetics.synthetics.executedStep.screenshot.success": "上一成功检查", + "xpack.synthetics.synthetics.executedStep.screenshot.successfulLink": "来自 {link} 的屏幕截图", + "xpack.synthetics.synthetics.executedStep.scriptHeading.label": "在此步骤执行的脚本", + "xpack.synthetics.synthetics.executedStep.stackTrace": "堆栈跟踪", + "xpack.synthetics.synthetics.imageLoadingSpinner.ariaLabel": "表示图像正在加载的动画旋转图标", + "xpack.synthetics.synthetics.journey.allFailedMessage": "{total} 个步骤 - 全部失败或跳过", + "xpack.synthetics.synthetics.journey.allSucceededMessage": "{total} 个步骤 - 全部成功", + "xpack.synthetics.synthetics.journey.loadingSteps": "正在加载步骤......", + "xpack.synthetics.synthetics.journey.partialSuccessMessage": "{total} 个步骤 - {succeeded} 个成功", + "xpack.synthetics.synthetics.markers.explore": "浏览", + "xpack.synthetics.synthetics.markers.noFieldIcon.label": "一个图标,表示此标记没有与其关联的字段", + "xpack.synthetics.synthetics.markers.openEmbeddableButton.label": "使用此图标按钮可显示该标注标记的指标。", + "xpack.synthetics.synthetics.nextStepButton.ariaLabel": "下一步", + "xpack.synthetics.synthetics.performanceBreakDown.label": "性能细目", + "xpack.synthetics.synthetics.pingTimestamp.captionContent": "第 {stepNumber} 步,共 {totalSteps} 步", + "xpack.synthetics.synthetics.prevStepButton.airaLabel": "上一步", + "xpack.synthetics.synthetics.screenshot.noImageMessage": "没有可用图像", + "xpack.synthetics.synthetics.screenshotDisplay.altText": "名称为“{stepName}”的步骤的屏幕截图", + "xpack.synthetics.synthetics.screenshotDisplay.altTextWithoutName": "屏幕截图", + "xpack.synthetics.synthetics.service.apiKey": "Synthetics 服务 API 密钥", + "xpack.synthetics.synthetics.statusBadge.failedMessage": "失败", + "xpack.synthetics.synthetics.statusBadge.skippedMessage": "已跳过", + "xpack.synthetics.synthetics.statusBadge.succeededMessage": "成功", + "xpack.synthetics.synthetics.step.duration": "{value} 秒", + "xpack.synthetics.synthetics.step.durationTrend": "步骤持续时间趋势", + "xpack.synthetics.synthetics.stepDetail.nextCheckButtonText": "下一检查", + "xpack.synthetics.synthetics.stepDetail.noData": "找不到此步骤的数据", + "xpack.synthetics.synthetics.stepDetail.previousCheckButtonText": "上一检查", + "xpack.synthetics.synthetics.stepDetail.totalSteps": "第 {stepIndex} 步,共 {totalSteps} 步", + "xpack.synthetics.synthetics.stepDetail.waterfall.loading": "瀑布图正在加载", + "xpack.synthetics.synthetics.stepDetail.waterfallNoData": "找不到此步骤的瀑布数据", + "xpack.synthetics.synthetics.stepDetail.waterfallUnsupported.description": "瀑布图无法显示。您可能正在使用较旧的组合代理版本。请检查版本并考虑升级。", + "xpack.synthetics.synthetics.stepDetail.waterfallUnsupported.title": "瀑布图不可用", + "xpack.synthetics.synthetics.stepList.nextCheck": "下一检查", + "xpack.synthetics.synthetics.stepList.previousCheck": "上一检查", + "xpack.synthetics.synthetics.thumbnail.fullSize.alt": "此过程步骤的缩略图屏幕截图较大版本。", + "xpack.synthetics.synthetics.waterfall.domContentLabel": "DOM 内容已加载", + "xpack.synthetics.synthetics.waterfall.fcpLabel": "首次内容绘制", + "xpack.synthetics.synthetics.waterfall.filterGroup.filterScreenreaderLabel": "筛选依据", + "xpack.synthetics.synthetics.waterfall.filterGroup.removeFilterScreenReaderLabel": "移除筛选依据", + "xpack.synthetics.synthetics.waterfall.flyout.certificates": "证书标头", + "xpack.synthetics.synthetics.waterfall.flyout.details": "详情", + "xpack.synthetics.synthetics.waterfall.flyout.requestHeaders": "请求标头", + "xpack.synthetics.synthetics.waterfall.flyout.responseHeaders": "响应标头", + "xpack.synthetics.synthetics.waterfall.layoutShiftLabel": "布局切换", + "xpack.synthetics.synthetics.waterfall.lcpLabel": "最大内容绘制", + "xpack.synthetics.synthetics.waterfall.loadEventLabel": "加载事件", + "xpack.synthetics.synthetics.waterfall.offsetUnit": "{offset} 毫秒", + "xpack.synthetics.synthetics.waterfall.requestsHighlightedMessage": "({numHighlightedRequests}匹配筛选)", + "xpack.synthetics.synthetics.waterfall.requestsTotalMessage": "{numNetworkRequests}个网络请求", + "xpack.synthetics.synthetics.waterfall.requestsTotalMessage.first": "前 {count} 个", + "xpack.synthetics.synthetics.waterfall.requestsTotalMessage.info": "瀑布视图最多显示 1000 个请求", + "xpack.synthetics.synthetics.waterfall.resource.externalLink": "在新选项卡中打开资源", + "xpack.synthetics.synthetics.waterfall.searchBox.placeholder": "筛选网络请求", + "xpack.synthetics.synthetics.waterfall.sidebar.filterMatchesScreenReaderLabel": "资源匹配筛选", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.certificateExpiryDate": "失效日期", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.certificateIssueDate": "有效起始日期", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.certificateIssuer": "颁发者", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.certificateSubject": "常见名称", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.contentType": "内容类型", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.ip": "IP", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.requestStart": "请求启动", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.resourceSize": "资源大小", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.status": "状态", + "xpack.synthetics.synthetics.waterfallChart.labels.metadata.transferSize": "传输大小", + "xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.font": "字体", + "xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.html": "HTML", + "xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.media": "媒体", + "xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.other": "其他", + "xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.script": "JS", + "xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.stylesheet": "CSS", + "xpack.synthetics.synthetics.waterfallChart.labels.mimeTypes.xhr": "XHR", + "xpack.synthetics.synthetics.waterfallChart.labels.timings.blocked": "已排队/已阻止", + "xpack.synthetics.synthetics.waterfallChart.labels.timings.connect": "连接中", + "xpack.synthetics.synthetics.waterfallChart.labels.timings.dns": "DNS", + "xpack.synthetics.synthetics.waterfallChart.labels.timings.receive": "内容正在下载", + "xpack.synthetics.synthetics.waterfallChart.labels.timings.send": "正在发送请求", + "xpack.synthetics.synthetics.waterfallChart.labels.timings.ssl": "TLS", + "xpack.synthetics.synthetics.waterfallChart.labels.timings.wait": "等待中 (TTFB)", + "xpack.synthetics.syntheticsMonitors": "运行时间 - 监测", + "xpack.synthetics.testRun.description": "请在保存前测试您的监测并验证结果", + "xpack.synthetics.testRun.pushError": "无法推送监测到服务。", + "xpack.synthetics.testRun.pushErrorLabel": "推送错误", + "xpack.synthetics.testRun.pushing.description": "正在推送监测到服务......", + "xpack.synthetics.title": "运行时间", + "xpack.synthetics.toggleAlertButton.content": "监测状态规则", + "xpack.synthetics.toggleAlertFlyout.ariaLabel": "打开添加规则浮出控件", + "xpack.synthetics.toggleTlsAlertButton.ariaLabel": "打开 TLS 规则浮出控件", + "xpack.synthetics.toggleTlsAlertButton.content": "TLS 规则", + "xpack.synthetics.uptimeFeatureCatalogueTitle": "运行时间", + "xpack.synthetics.uptimeSettings.index": "Uptime 设置 - 索引", + "xpack.synthetics.waterfallChart.sidebar.url.https": "https", "xpack.urlDrilldown.click.event.key.documentation": "已点击数据点背后的字段名称。", "xpack.urlDrilldown.click.event.key.title": "已点击字段的名称。", "xpack.urlDrilldown.click.event.negate.documentation": "布尔值,表示已点击数据点是否导致负筛选。", @@ -31336,6 +31230,138 @@ "xpack.watcher.watchActions.webhook.portIsRequiredValidationMessage": "Webhook 端口必填。", "xpack.watcher.watchActions.webhook.usernameIsRequiredIfPasswordValidationMessage": "“用户名”必填。", "xpack.watcher.watchEdit.thresholdWatchExpression.aggType.fieldIsRequiredValidationMessage": "此字段必填。", - "xpack.watcher.watcherDescription": "通过创建、管理和监测警报来检测数据中的更改。" + "xpack.watcher.watcherDescription": "通过创建、管理和监测警报来检测数据中的更改。", + "unifiedSearch.search.searchBar.savedQueryDescriptionLabelText": "描述", + "unifiedSearch.search.searchBar.savedQueryDescriptionText": "保存想要再次使用的查询文本和筛选。", + "unifiedSearch.search.searchBar.savedQueryForm.titleConflictText": "标题与现有已保存查询有冲突", + "unifiedSearch.search.searchBar.savedQueryFormCancelButtonText": "取消", + "unifiedSearch.search.searchBar.savedQueryFormSaveButtonText": "保存", + "unifiedSearch.search.searchBar.savedQueryFormTitle": "保存查询", + "unifiedSearch.search.searchBar.savedQueryIncludeFiltersLabelText": "包括筛选", + "unifiedSearch.search.searchBar.savedQueryIncludeTimeFilterLabelText": "包括时间筛选", + "unifiedSearch.search.searchBar.savedQueryNameHelpText": "名称必填,其中不能包含前导或尾随空格,并且必须唯一。", + "unifiedSearch.search.searchBar.savedQueryNameLabelText": "名称", + "unifiedSearch.search.searchBar.savedQueryNoSavedQueriesText": "没有已保存查询。", + "unifiedSearch.search.searchBar.savedQueryPopoverButtonText": "查看已保存查询", + "unifiedSearch.search.searchBar.savedQueryPopoverClearButtonAriaLabel": "清除当前已保存查询", + "unifiedSearch.search.searchBar.savedQueryPopoverClearButtonText": "清除", + "unifiedSearch.search.searchBar.savedQueryPopoverConfirmDeletionCancelButtonText": "取消", + "unifiedSearch.search.searchBar.savedQueryPopoverConfirmDeletionConfirmButtonText": "删除", + "unifiedSearch.search.searchBar.savedQueryPopoverConfirmDeletionTitle": "删除“{savedQueryName}”?", + "unifiedSearch.search.searchBar.savedQueryPopoverDeleteButtonAriaLabel": "删除已保存查询 {savedQueryName}", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveAsNewButtonAriaLabel": "另存为新的已保存查询", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveAsNewButtonText": "另存为新的", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveButtonAriaLabel": "保存新的已保存查询", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveButtonText": "保存当前查询", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveChangesButtonAriaLabel": "将更改保存到 {title}", + "unifiedSearch.search.searchBar.savedQueryPopoverSaveChangesButtonText": "保存更改", + "unifiedSearch.search.searchBar.savedQueryPopoverSavedQueryListItemButtonAriaLabel": "已保存查询按钮 {savedQueryName}", + "unifiedSearch.search.searchBar.savedQueryPopoverSavedQueryListItemDescriptionAriaLabel": "{savedQueryName} 描述", + "unifiedSearch.search.searchBar.savedQueryPopoverSavedQueryListItemSelectedButtonAriaLabel": "已保存查询按钮已选择 {savedQueryName}。按下可清除任何更改。", + "unifiedSearch.search.searchBar.savedQueryPopoverTitleText": "已保存查询", + "unifiedSearch.noDataPopover.content": "此时间范围不包含任何数据。增大或调整时间范围,以查看更多的字段并创建图表。", + "unifiedSearch.noDataPopover.dismissAction": "不再显示", + "unifiedSearch.noDataPopover.subtitle": "提示", + "unifiedSearch.noDataPopover.title": "空数据集", + "unifiedSearch.query.queryBar.clearInputLabel": "清除输入", + "unifiedSearch.query.queryBar.comboboxAriaLabel": "搜索并筛选 {pageType} 页面", + "unifiedSearch.query.queryBar.kqlFullLanguageName": "Kibana 查询语言", + "unifiedSearch.query.queryBar.kqlLanguageName": "KQL", + "unifiedSearch.query.queryBar.KQLNestedQuerySyntaxInfoDocLinkText": "文档", + "unifiedSearch.query.queryBar.KQLNestedQuerySyntaxInfoOptOutText": "不再显示", + "unifiedSearch.query.queryBar.KQLNestedQuerySyntaxInfoText": "似乎您正在查询嵌套字段。您可以使用不同的方式构造嵌套查询的 KQL 语法,具体取决于您想要的结果。详细了解我们的 {link}。", + "unifiedSearch.query.queryBar.KQLNestedQuerySyntaxInfoTitle": "KQL 嵌套查询语法", + "unifiedSearch.query.queryBar.kqlOffLabel": "关闭", + "unifiedSearch.query.queryBar.kqlOnLabel": "开启", + "unifiedSearch.query.queryBar.languageSwitcher.toText": "切换到 Kibana 查询语言以进行搜索", + "unifiedSearch.query.queryBar.luceneLanguageName": "Lucene", + "unifiedSearch.query.queryBar.searchInputAriaLabel": "开始键入内容,以搜索并筛选 {pageType} 页面", + "unifiedSearch.query.queryBar.searchInputPlaceholder": "搜索", + "unifiedSearch.query.queryBar.syntaxOptionsDescription": "{docsLink} (KQL) 提供简化查询语法并支持脚本字段。KQL 还提供自动完成功能。如果关闭 KQL,{nonKqlModeHelpText}", + "unifiedSearch.query.queryBar.syntaxOptionsDescription.nonKqlModeHelpText": "Kibana 使用 Lucene。", + "unifiedSearch.search.unableToGetSavedQueryToastTitle": "无法加载已保存查询 {savedQueryId}", + "unifiedSearch.query.queryBar.syntaxOptionsTitle": "语法选项", + "unifiedSearch.filter.applyFilterActionTitle": "将筛选应用于当前视图", + "unifiedSearch.filter.applyFilters.popupHeader": "选择要应用的筛选", + "unifiedSearch.filter.applyFiltersPopup.cancelButtonLabel": "取消", + "unifiedSearch.filter.applyFiltersPopup.saveButtonLabel": "应用", + "unifiedSearch.filter.filterBar.addFilterButtonLabel": "添加筛选", + "unifiedSearch.filter.filterBar.deleteFilterButtonLabel": "删除", + "unifiedSearch.filter.filterBar.disabledFilterPrefix": "已禁用", + "unifiedSearch.filter.filterBar.disableFilterButtonLabel": "暂时禁用", + "unifiedSearch.filter.filterBar.editFilterButtonLabel": "编辑筛选", + "unifiedSearch.filter.filterBar.enableFilterButtonLabel": "重新启用", + "unifiedSearch.filter.filterBar.excludeFilterButtonLabel": "排除结果", + "unifiedSearch.filter.filterBar.filterItemBadgeAriaLabel": "筛选操作", + "unifiedSearch.filter.filterBar.filterItemBadgeIconAriaLabel": "删除 {filter}", + "unifiedSearch.filter.filterBar.includeFilterButtonLabel": "包括结果", + "unifiedSearch.filter.filterBar.indexPatternSelectPlaceholder": "选择索引模式", + "unifiedSearch.filter.filterBar.labelErrorInfo": "找不到索引模式 {indexPattern}", + "unifiedSearch.filter.filterBar.labelErrorText": "错误", + "unifiedSearch.filter.filterBar.labelWarningInfo": "当前视图中不存在字段 {fieldName}", + "unifiedSearch.filter.filterBar.labelWarningText": "警告", + "unifiedSearch.filter.filterBar.moreFilterActionsMessage": "筛选:{innerText}。选择以获取更多筛选操作。", + "unifiedSearch.filter.filterBar.negatedFilterPrefix": "非 ", + "unifiedSearch.filter.filterBar.pinFilterButtonLabel": "在所有应用上固定", + "unifiedSearch.filter.filterBar.pinnedFilterPrefix": "已置顶", + "unifiedSearch.filter.filterBar.unpinFilterButtonLabel": "取消固定", + "unifiedSearch.filter.filterEditor.cancelButtonLabel": "取消", + "unifiedSearch.filter.filterEditor.createCustomLabelInputLabel": "定制标签", + "unifiedSearch.filter.filterEditor.createCustomLabelSwitchLabel": "创建定制标签?", + "unifiedSearch.filter.filterEditor.doesNotExistOperatorOptionLabel": "不存在", + "unifiedSearch.filter.filterEditor.editFilterPopupTitle": "编辑筛选", + "unifiedSearch.filter.filterEditor.editFilterValuesButtonLabel": "编辑筛选值", + "unifiedSearch.filter.filterEditor.editQueryDslButtonLabel": "编辑为查询 DSL", + "unifiedSearch.filter.filterEditor.existsOperatorOptionLabel": "存在", + "unifiedSearch.filter.filterEditor.falseOptionLabel": "false", + "unifiedSearch.filter.filterEditor.fieldSelectLabel": "字段", + "unifiedSearch.filter.filterEditor.fieldSelectPlaceholder": "首先选择字段", + "unifiedSearch.filter.filterEditor.indexPatternSelectLabel": "索引模式", + "unifiedSearch.filter.filterEditor.isBetweenOperatorOptionLabel": "介于", + "unifiedSearch.filter.filterEditor.isNotBetweenOperatorOptionLabel": "不介于", + "unifiedSearch.filter.filterEditor.isNotOneOfOperatorOptionLabel": "不属于", + "unifiedSearch.filter.filterEditor.isNotOperatorOptionLabel": "不是", + "unifiedSearch.filter.filterEditor.isOneOfOperatorOptionLabel": "属于", + "unifiedSearch.filter.filterEditor.isOperatorOptionLabel": "是", + "unifiedSearch.filter.filterEditor.operatorSelectLabel": "运算符", + "unifiedSearch.filter.filterEditor.operatorSelectPlaceholderSelect": "选择", + "unifiedSearch.filter.filterEditor.operatorSelectPlaceholderWaiting": "正在等候", + "unifiedSearch.filter.filterEditor.queryDslAriaLabel": "Elasticsearch 查询 DSL 编辑器", + "unifiedSearch.filter.filterEditor.queryDslLabel": "Elasticsearch 查询 DSL", + "unifiedSearch.filter.filterEditor.rangeEndInputPlaceholder": "范围结束", + "unifiedSearch.filter.filterEditor.rangeInputLabel": "范围", + "unifiedSearch.filter.filterEditor.rangeStartInputPlaceholder": "范围开始", + "unifiedSearch.filter.filterEditor.saveButtonLabel": "保存", + "unifiedSearch.filter.filterEditor.trueOptionLabel": "true", + "unifiedSearch.filter.filterEditor.valueInputLabel": "值", + "unifiedSearch.filter.filterEditor.valueInputPlaceholder": "输入值", + "unifiedSearch.filter.filterEditor.valueSelectPlaceholder": "选择值", + "unifiedSearch.filter.filterEditor.valuesSelectLabel": "值", + "unifiedSearch.filter.filterEditor.valuesSelectPlaceholder": "选择值", + "unifiedSearch.filter.options.changeAllFiltersButtonLabel": "更改所有筛选", + "unifiedSearch.filter.options.deleteAllFiltersButtonLabel": "全部删除", + "unifiedSearch.filter.options.disableAllFiltersButtonLabel": "全部禁用", + "unifiedSearch.filter.options.enableAllFiltersButtonLabel": "全部启用", + "unifiedSearch.filter.options.invertDisabledFiltersButtonLabel": "反向已启用/已禁用", + "unifiedSearch.filter.options.invertNegatedFiltersButtonLabel": "反向包括", + "unifiedSearch.filter.options.pinAllFiltersButtonLabel": "全部固定", + "unifiedSearch.filter.options.unpinAllFiltersButtonLabel": "全部取消固定", + "unifiedSearch.filter.searchBar.changeAllFiltersTitle": "更改所有筛选", + "unifiedSearch.kueryAutocomplete.andOperatorDescription": "需要{bothArguments}为 true", + "unifiedSearch.kueryAutocomplete.andOperatorDescription.bothArgumentsText": "两个参数都", + "unifiedSearch.kueryAutocomplete.equalOperatorDescription": "{equals}某一值", + "unifiedSearch.kueryAutocomplete.equalOperatorDescription.equalsText": "等于", + "unifiedSearch.kueryAutocomplete.existOperatorDescription": "以任意形式{exists}", + "unifiedSearch.kueryAutocomplete.existOperatorDescription.existsText": "存在", + "unifiedSearch.kueryAutocomplete.greaterThanOperatorDescription": "{greaterThan}某一值", + "unifiedSearch.kueryAutocomplete.greaterThanOperatorDescription.greaterThanText": "大于", + "unifiedSearch.kueryAutocomplete.greaterThanOrEqualOperatorDescription": "{greaterThanOrEqualTo}某一值", + "unifiedSearch.kueryAutocomplete.greaterThanOrEqualOperatorDescription.greaterThanOrEqualToText": "大于或等于", + "unifiedSearch.kueryAutocomplete.lessThanOperatorDescription": "{lessThan}某一值", + "unifiedSearch.kueryAutocomplete.lessThanOperatorDescription.lessThanText": "小于", + "unifiedSearch.kueryAutocomplete.lessThanOrEqualOperatorDescription": "{lessThanOrEqualTo}某一值", + "unifiedSearch.kueryAutocomplete.lessThanOrEqualOperatorDescription.lessThanOrEqualToText": "小于或等于", + "unifiedSearch.kueryAutocomplete.orOperatorDescription": "需要{oneOrMoreArguments}为 true", + "unifiedSearch.kueryAutocomplete.orOperatorDescription.oneOrMoreArgumentsText": "一个或多个参数" } } diff --git a/x-pack/plugins/triggers_actions_ui/README.md b/x-pack/plugins/triggers_actions_ui/README.md index f4a1f79da1546..7fde1f1512302 100644 --- a/x-pack/plugins/triggers_actions_ui/README.md +++ b/x-pack/plugins/triggers_actions_ui/README.md @@ -252,7 +252,8 @@ Each alert type should be defined as `RuleTypeModel` object with the these prope |iconClass|Icon of the alert type that will be displayed on the select card in the UI.| |validate|Validation function for the alert params.| |ruleParamsExpression| A lazy loaded React component for building UI of the current alert type params.| -|defaultActionMessage|Optional property for providing default message for all added actions with `message` property.| +|defaultActionMessage|Optional property for providing default messages for all added actions, excluding the Recovery action group, with `message` property. | +|defaultRecoveryMessage|Optional property for providing a default message for all added actions with `message` property for the Recovery action group.| |requiresAppContext|Define if alert type is enabled for create and edit in the alerting management UI.| IMPORTANT: The current UI supports a single action group only. diff --git a/x-pack/plugins/triggers_actions_ui/common/experimental_features.ts b/x-pack/plugins/triggers_actions_ui/common/experimental_features.ts index 21835a5977216..0a0b8cdeab208 100644 --- a/x-pack/plugins/triggers_actions_ui/common/experimental_features.ts +++ b/x-pack/plugins/triggers_actions_ui/common/experimental_features.ts @@ -15,6 +15,7 @@ export const allowedExperimentalValues = Object.freeze({ rulesListDatagrid: true, internalAlertsTable: false, internalShareableComponentsSandbox: false, + ruleStatusFilter: false, rulesDetailLogs: true, }); diff --git a/x-pack/plugins/triggers_actions_ui/kibana.json b/x-pack/plugins/triggers_actions_ui/kibana.json index 4be95ed2db91d..a872ad6fab5c0 100644 --- a/x-pack/plugins/triggers_actions_ui/kibana.json +++ b/x-pack/plugins/triggers_actions_ui/kibana.json @@ -7,9 +7,9 @@ "version": "kibana", "server": true, "ui": true, - "optionalPlugins": ["alerting", "cloud", "features", "home", "spaces"], - "requiredPlugins": ["management", "charts", "data", "kibanaReact", "kibanaUtils", "savedObjects", "unifiedSearch", "dataViews"], + "optionalPlugins": ["cloud", "features", "home", "spaces"], + "requiredPlugins": ["management", "charts", "data", "kibanaReact", "kibanaUtils", "savedObjects", "unifiedSearch", "dataViews", "alerting", "actions"], "configPath": ["xpack", "trigger_actions_ui"], "extraPublicDirs": ["public/common", "public/common/constants"], - "requiredBundles": ["alerting", "esUiShared", "kibanaReact", "kibanaUtils"] + "requiredBundles": ["alerting", "esUiShared", "kibanaReact", "kibanaUtils", "actions"] } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email.test.tsx index f91ef64ca28a3..31ff85a20ed3b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email.test.tsx @@ -10,13 +10,44 @@ import { registerBuiltInActionTypes } from '..'; import { ActionTypeModel } from '../../../../types'; import { EmailActionConnector } from '../types'; import { getEmailServices } from './email'; +import { + ValidatedEmail, + InvalidEmailReason, + ValidateEmailAddressesOptions, + MustacheInEmailRegExp, +} from '@kbn/actions-plugin/common'; const ACTION_TYPE_ID = '.email'; let actionTypeModel: ActionTypeModel; +const RegistrationServices = { + validateEmailAddresses: validateEmails, +}; + +// stub for the real validator +function validateEmails( + addresses: string[], + options?: ValidateEmailAddressesOptions +): ValidatedEmail[] { + return addresses.map((address) => { + if (address.includes('invalid')) + return { address, valid: false, reason: InvalidEmailReason.invalid }; + else if (address.includes('notallowed')) + return { address, valid: false, reason: InvalidEmailReason.notAllowed }; + else if (options?.treatMustacheTemplatesAsValid) return { address, valid: true }; + else if (address.match(MustacheInEmailRegExp)) + return { address, valid: false, reason: InvalidEmailReason.invalid }; + else return { address, valid: true }; + }); +} + +beforeEach(() => { + jest.resetAllMocks(); +}); + beforeAll(() => { const actionTypeRegistry = new TypeRegistry(); - registerBuiltInActionTypes({ actionTypeRegistry }); + registerBuiltInActionTypes({ actionTypeRegistry, services: RegistrationServices }); const getResult = actionTypeRegistry.get(ACTION_TYPE_ID); if (getResult !== null) { actionTypeModel = getResult; @@ -54,6 +85,7 @@ describe('connector validation', () => { actionTypeId: '.email', name: 'email', isPreconfigured: false, + isDeprecated: false, config: { from: 'test@test.com', port: 2323, @@ -95,6 +127,7 @@ describe('connector validation', () => { id: 'test', actionTypeId: '.email', isPreconfigured: false, + isDeprecated: false, name: 'email', config: { from: 'test@test.com', @@ -136,7 +169,7 @@ describe('connector validation', () => { actionTypeId: '.email', name: 'email', config: { - from: 'test@test.com', + from: 'test@notallowed.com', hasAuth: true, service: 'other', }, @@ -145,7 +178,7 @@ describe('connector validation', () => { expect(await actionTypeModel.validateConnector(actionConnector)).toEqual({ config: { errors: { - from: [], + from: ['Email address test@notallowed.com is not allowed.'], port: ['Port is required.'], host: ['Host is required.'], service: [], @@ -161,7 +194,13 @@ describe('connector validation', () => { }, }, }); + + // also check that mustache is not valid + actionConnector.config.from = '{{mustached}}'; + const validation = await actionTypeModel.validateConnector(actionConnector); + expect(validation?.config?.errors?.from).toEqual(['Email address {{mustached}} is not valid.']); }); + test('connector validation fails when user specified but not password', async () => { const actionConnector = { secrets: { @@ -172,6 +211,7 @@ describe('connector validation', () => { id: 'test', actionTypeId: '.email', isPreconfigured: false, + isDeprecated: false, name: 'email', config: { from: 'test@test.com', @@ -213,6 +253,7 @@ describe('connector validation', () => { id: 'test', actionTypeId: '.email', isPreconfigured: false, + isDeprecated: false, name: 'email', config: { from: 'test@test.com', @@ -253,6 +294,7 @@ describe('connector validation', () => { id: 'test', actionTypeId: '.email', isPreconfigured: false, + isDeprecated: false, name: 'email', config: { from: 'test@test.com', @@ -296,6 +338,7 @@ describe('connector validation', () => { actionTypeId: '.email', name: 'email', isPreconfigured: false, + isDeprecated: false, config: { from: 'test@test.com', hasAuth: true, @@ -330,6 +373,7 @@ describe('action params validation', () => { const actionParams = { to: [], cc: ['test1@test.com'], + bcc: ['mustache {{\n}} template'], message: 'message {test}', subject: 'test', }; @@ -347,15 +391,17 @@ describe('action params validation', () => { test('action params validation fails when action params is not valid', async () => { const actionParams = { - to: ['test@test.com'], + to: ['invalid.com'], + cc: ['bob@notallowed.com'], + bcc: ['another-invalid.com'], subject: 'test', }; expect(await actionTypeModel.validateParams(actionParams)).toEqual({ errors: { - to: [], - cc: [], - bcc: [], + to: ['Email address invalid.com is not valid.'], + cc: ['Email address bob@notallowed.com is not allowed.'], + bcc: ['Email address another-invalid.com is not valid.'], message: ['Message is required.'], subject: [], }, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email.tsx index c5da19c305268..0add2396a74d0 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email.tsx @@ -5,16 +5,18 @@ * 2.0. */ +import { uniq } from 'lodash'; import { lazy } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiSelectOption } from '@elastic/eui'; -import { AdditionalEmailServices } from '@kbn/actions-plugin/common'; +import { AdditionalEmailServices, InvalidEmailReason } from '@kbn/actions-plugin/common'; import { ActionTypeModel, ConnectorValidationResult, GenericValidationResult, } from '../../../../types'; import { EmailActionParams, EmailConfig, EmailSecrets, EmailActionConnector } from '../types'; +import { RegistrationServices } from '..'; const emailServices: EuiSelectOption[] = [ { @@ -79,8 +81,9 @@ export function getEmailServices(isCloudEnabled: boolean) { : emailServices.filter((service) => service.value !== 'elastic_cloud'); } -export function getActionType(): ActionTypeModel { - const mailformat = /^[^@\s]+@[^@\s]+$/; +export function getActionType( + services: RegistrationServices +): ActionTypeModel { return { id: '.email', iconClass: 'email', @@ -122,9 +125,15 @@ export function getActionType(): ActionTypeModel(), }; const validationResult = { errors }; - if ( - (!(actionParams.to instanceof Array) || actionParams.to.length === 0) && - (!(actionParams.cc instanceof Array) || actionParams.cc.length === 0) && - (!(actionParams.bcc instanceof Array) || actionParams.bcc.length === 0) - ) { - const errorText = translations.TO_CC_REQUIRED; - errors.to.push(errorText); - errors.cc.push(errorText); - errors.bcc.push(errorText); - } + if (!actionParams.message?.length) { errors.message.push(translations.MESSAGE_REQUIRED); } if (!actionParams.subject?.length) { errors.subject.push(translations.SUBJECT_REQUIRED); } + + const toEmails = getToFields(actionParams); + const ccEmails = getCcFields(actionParams); + const bccEmails = getBccFields(actionParams); + + if (toEmails.length === 0 && ccEmails.length === 0 && bccEmails.length === 0) { + const errorText = translations.TO_CC_REQUIRED; + errors.to.push(errorText); + errors.cc.push(errorText); + errors.bcc.push(errorText); + } + + const allEmails = uniq(toEmails.concat(ccEmails).concat(bccEmails)); + const validatedEmails = services.validateEmailAddresses(allEmails, { + treatMustacheTemplatesAsValid: true, + }); + + const toEmailSet = new Set(toEmails); + const ccEmailSet = new Set(ccEmails); + const bccEmailSet = new Set(bccEmails); + + for (const validated of validatedEmails) { + if (!validated.valid) { + const email = validated.address; + const message = + validated.reason === InvalidEmailReason.notAllowed + ? translations.getNotAllowedEmailAddress(email) + : translations.getInvalidEmailAddress(email); + + if (toEmailSet.has(email)) errors.to.push(message); + if (ccEmailSet.has(email)) errors.cc.push(message); + if (bccEmailSet.has(email)) errors.bcc.push(message); + } + } + return validationResult; }, actionConnectorFields: lazy(() => import('./email_connector')), actionParamsFields: lazy(() => import('./email_params')), }; } + +function getToFields(actionParams: EmailActionParams): string[] { + if (!(actionParams.to instanceof Array)) return []; + return actionParams.to; +} + +function getCcFields(actionParams: EmailActionParams): string[] { + if (!(actionParams.cc instanceof Array)) return []; + return actionParams.cc; +} + +function getBccFields(actionParams: EmailActionParams): string[] { + if (!(actionParams.bcc instanceof Array)) return []; + return actionParams.bcc; +} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/translations.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/translations.ts index 38e16f6046184..e1bee12d98993 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/translations.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/translations.ts @@ -104,3 +104,20 @@ export const SUBJECT_REQUIRED = i18n.translate( defaultMessage: 'Subject is required.', } ); + +export function getInvalidEmailAddress(email: string) { + return i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.error.invalidEmail', + { + defaultMessage: 'Email address {email} is not valid.', + values: { email }, + } + ); +} + +export function getNotAllowedEmailAddress(email: string) { + return i18n.translate('xpack.triggersActionsUI.components.builtinActionTypes.error.notAllowed', { + defaultMessage: 'Email address {email} is not allowed.', + values: { email }, + }); +} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index.test.tsx index 4097adb7b067f..42dc8a16a8b19 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index.test.tsx @@ -9,13 +9,14 @@ import { TypeRegistry } from '../../../type_registry'; import { registerBuiltInActionTypes } from '..'; import { ActionTypeModel } from '../../../../types'; import { EsIndexActionConnector } from '../types'; +import { registrationServicesMock } from '../../../../mocks'; const ACTION_TYPE_ID = '.index'; let actionTypeModel: ActionTypeModel; beforeAll(() => { const actionTypeRegistry = new TypeRegistry(); - registerBuiltInActionTypes({ actionTypeRegistry }); + registerBuiltInActionTypes({ actionTypeRegistry, services: registrationServicesMock }); const getResult = actionTypeRegistry.get(ACTION_TYPE_ID); if (getResult !== null) { actionTypeModel = getResult; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index_params.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index_params.test.tsx index 6125255b3a52a..910627b0c851b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index_params.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index_params.test.tsx @@ -33,6 +33,7 @@ const actionConnector = { }, id: 'es index connector', isPreconfigured: false, + isDeprecated: false, name: 'test name', secrets: {}, }; @@ -44,6 +45,7 @@ const preconfiguredActionConnector = { }, id: AlertHistoryEsIndexConnectorId, isPreconfigured: true, + isDeprecated: false, name: 'Alert history Elasticsearch index', secrets: {}, }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/index.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/index.ts index 6817631e2150a..e2089221b4d60 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/index.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { ValidatedEmail, ValidateEmailAddressesOptions } from '@kbn/actions-plugin/common'; import { getServerLogActionType } from './server_log'; import { getSlackActionType } from './slack'; import { getEmailActionType } from './email'; @@ -24,14 +25,23 @@ import { getJiraActionType } from './jira'; import { getResilientActionType } from './resilient'; import { getTeamsActionType } from './teams'; +export interface RegistrationServices { + validateEmailAddresses: ( + addresses: string[], + options?: ValidateEmailAddressesOptions + ) => ValidatedEmail[]; +} + export function registerBuiltInActionTypes({ actionTypeRegistry, + services, }: { actionTypeRegistry: TypeRegistry; + services: RegistrationServices; }) { actionTypeRegistry.register(getServerLogActionType()); actionTypeRegistry.register(getSlackActionType()); - actionTypeRegistry.register(getEmailActionType()); + actionTypeRegistry.register(getEmailActionType(services)); actionTypeRegistry.register(getIndexActionType()); actionTypeRegistry.register(getPagerDutyActionType()); actionTypeRegistry.register(getSwimlaneActionType()); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira.test.tsx index 425bcf651f104..3bb023b135c40 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira.test.tsx @@ -9,13 +9,14 @@ import { TypeRegistry } from '../../../type_registry'; import { registerBuiltInActionTypes } from '..'; import { ActionTypeModel } from '../../../../types'; import { JiraActionConnector } from './types'; +import { registrationServicesMock } from '../../../../mocks'; const ACTION_TYPE_ID = '.jira'; let actionTypeModel: ActionTypeModel; beforeAll(() => { const actionTypeRegistry = new TypeRegistry(); - registerBuiltInActionTypes({ actionTypeRegistry }); + registerBuiltInActionTypes({ actionTypeRegistry, services: registrationServicesMock }); const getResult = actionTypeRegistry.get(ACTION_TYPE_ID); if (getResult !== null) { actionTypeModel = getResult; @@ -39,6 +40,7 @@ describe('jira connector validation', () => { actionTypeId: '.jira', name: 'jira', isPreconfigured: false, + isDeprecated: false, config: { apiUrl: 'https://siem-kibana.atlassian.net', projectKey: 'CK', diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_connectors.test.tsx index 1c8c58c7c4a16..22d154373ea66 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_connectors.test.tsx @@ -21,6 +21,7 @@ describe('JiraActionConnectorFields renders', () => { id: 'test', actionTypeId: '.jira', isPreconfigured: false, + isDeprecated: false, name: 'jira', config: { apiUrl: 'https://test/', @@ -62,6 +63,7 @@ describe('JiraActionConnectorFields renders', () => { id: 'test', actionTypeId: '.jira', isPreconfigured: false, + isDeprecated: false, name: 'jira', config: { apiUrl: 'https://test/', @@ -98,6 +100,7 @@ describe('JiraActionConnectorFields renders', () => { const actionConnector = { actionTypeId: '.jira', isPreconfigured: false, + isDeprecated: false, secrets: {}, config: {}, } as JiraActionConnector; @@ -120,6 +123,7 @@ describe('JiraActionConnectorFields renders', () => { const actionConnector = { actionTypeId: '.jira', isPreconfigured: false, + isDeprecated: false, isMissingSecrets: true, secrets: {}, config: {}, @@ -147,6 +151,7 @@ describe('JiraActionConnectorFields renders', () => { id: 'test', actionTypeId: '.jira', isPreconfigured: false, + isDeprecated: false, name: 'jira', config: { apiUrl: 'https://test/', diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_params.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_params.test.tsx index 6c39236b3ff98..16581008c9e6a 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_params.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_params.test.tsx @@ -44,6 +44,7 @@ const connector: ActionConnector = { actionTypeId: '.test', name: 'Test', isPreconfigured: false, + isDeprecated: false, }; const editAction = jest.fn(); const defaultProps = { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty/pagerduty.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty/pagerduty.test.tsx index 10bf1a45806e8..a8274729506af 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty/pagerduty.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty/pagerduty.test.tsx @@ -9,13 +9,14 @@ import { TypeRegistry } from '../../../type_registry'; import { registerBuiltInActionTypes } from '..'; import { ActionTypeModel } from '../../../../types'; import { PagerDutyActionConnector } from '../types'; +import { registrationServicesMock } from '../../../../mocks'; const ACTION_TYPE_ID = '.pagerduty'; let actionTypeModel: ActionTypeModel; beforeAll(() => { const actionTypeRegistry = new TypeRegistry(); - registerBuiltInActionTypes({ actionTypeRegistry }); + registerBuiltInActionTypes({ actionTypeRegistry, services: registrationServicesMock }); const getResult = actionTypeRegistry.get(ACTION_TYPE_ID); if (getResult !== null) { actionTypeModel = getResult; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/resilient/resilient.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/resilient/resilient.test.tsx index 89b4b6ee668db..209606913dce6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/resilient/resilient.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/resilient/resilient.test.tsx @@ -9,13 +9,14 @@ import { TypeRegistry } from '../../../type_registry'; import { registerBuiltInActionTypes } from '..'; import { ActionTypeModel } from '../../../../types'; import { ResilientActionConnector } from './types'; +import { registrationServicesMock } from '../../../../mocks'; const ACTION_TYPE_ID = '.resilient'; let actionTypeModel: ActionTypeModel; beforeAll(() => { const actionTypeRegistry = new TypeRegistry(); - registerBuiltInActionTypes({ actionTypeRegistry }); + registerBuiltInActionTypes({ actionTypeRegistry, services: registrationServicesMock }); const getResult = actionTypeRegistry.get(ACTION_TYPE_ID); if (getResult !== null) { actionTypeModel = getResult; @@ -38,6 +39,7 @@ describe('resilient connector validation', () => { id: 'test', actionTypeId: '.resilient', isPreconfigured: false, + isDeprecated: false, name: 'resilient', config: { apiUrl: 'https://test/', diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/resilient/resilient_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/resilient/resilient_connectors.test.tsx index 13459888ac365..7db5cc113fcb9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/resilient/resilient_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/resilient/resilient_connectors.test.tsx @@ -21,6 +21,7 @@ describe('ResilientActionConnectorFields renders', () => { id: 'test', actionTypeId: '.resilient', isPreconfigured: false, + isDeprecated: false, name: 'resilient', config: { apiUrl: 'https://test/', @@ -62,6 +63,7 @@ describe('ResilientActionConnectorFields renders', () => { id: 'test', actionTypeId: '.resilient', isPreconfigured: false, + isDeprecated: false, name: 'resilient', config: { apiUrl: 'https://test/', @@ -99,6 +101,7 @@ describe('ResilientActionConnectorFields renders', () => { const actionConnector = { actionTypeId: '.resilient', isPreconfigured: false, + isDeprecated: false, config: {}, secrets: {}, } as ResilientActionConnector; @@ -121,6 +124,7 @@ describe('ResilientActionConnectorFields renders', () => { const actionConnector = { actionTypeId: '.resilient', isPreconfigured: false, + isDeprecated: false, config: {}, secrets: {}, isMissingSecrets: true, @@ -148,6 +152,7 @@ describe('ResilientActionConnectorFields renders', () => { id: 'test', actionTypeId: '.resilient', isPreconfigured: false, + isDeprecated: false, name: 'resilient', config: { apiUrl: 'https://test/', diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/resilient/resilient_params.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/resilient/resilient_params.test.tsx index 247e968d08fc6..09ae6fe002d41 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/resilient/resilient_params.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/resilient/resilient_params.test.tsx @@ -39,6 +39,7 @@ const connector = { actionTypeId: '.test', name: 'Test', isPreconfigured: false, + isDeprecated: false, }; const editAction = jest.fn(); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/server_log/server_log.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/server_log/server_log.test.tsx index e91f76d94d2fb..012a233973012 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/server_log/server_log.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/server_log/server_log.test.tsx @@ -8,13 +8,14 @@ import { TypeRegistry } from '../../../type_registry'; import { registerBuiltInActionTypes } from '..'; import { ActionTypeModel, UserConfiguredActionConnector } from '../../../../types'; +import { registrationServicesMock } from '../../../../mocks'; const ACTION_TYPE_ID = '.server-log'; let actionTypeModel: ActionTypeModel; beforeAll(() => { const actionTypeRegistry = new TypeRegistry(); - registerBuiltInActionTypes({ actionTypeRegistry }); + registerBuiltInActionTypes({ actionTypeRegistry, services: registrationServicesMock }); const getResult = actionTypeRegistry.get(ACTION_TYPE_ID); if (getResult !== null) { actionTypeModel = getResult; @@ -37,6 +38,7 @@ describe('server-log connector validation', () => { name: 'server-log', config: {}, isPreconfigured: false, + isDeprecated: false, }; expect(await actionTypeModel.validateConnector(actionConnector)).toEqual({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/api.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/api.ts index dad3e3e0d0170..a9e8b8f544d42 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/api.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/api.ts @@ -7,9 +7,7 @@ import { HttpSetup } from '@kbn/core/public'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { snExternalServiceConfig } from '@kbn/actions-plugin/server/builtin_action_types/servicenow/config'; -import { ActionTypeExecutorResult } from '@kbn/actions-plugin/common'; +import { ActionTypeExecutorResult, snExternalServiceConfig } from '@kbn/actions-plugin/common'; import { BASE_ACTION_API_PATH } from '../../../constants'; import { API_INFO_ERROR } from './translations'; import { AppInfo, RESTApiError } from './types'; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.test.ts index 912b308d8d79c..d76cb5ddb5725 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.test.ts @@ -22,9 +22,14 @@ const deprecatedConnector: ActionConnector = { actionTypeId: '.servicenow', name: 'Test', isPreconfigured: false, + isDeprecated: true, }; -const validConnector = { ...deprecatedConnector, config: { usesTableApi: false } }; +const validConnector = { + ...deprecatedConnector, + config: { usesTableApi: false }, + isDeprecated: false, +}; describe('helpers', () => { describe('isRESTApiError', () => { @@ -69,21 +74,21 @@ describe('helpers', () => { }); describe('getConnectorDescriptiveTitle', () => { - it('adds deprecated to the connector name when the connector usesTableApi', () => { + it('adds deprecated to the connector name when the connector is deprectaed', () => { expect(getConnectorDescriptiveTitle(deprecatedConnector)).toEqual('Test (deprecated)'); }); - it('does not add deprecated when the connector has usesTableApi:false', () => { + it('does not add deprecated when the connector is not deprectaed', () => { expect(getConnectorDescriptiveTitle(validConnector)).toEqual('Test'); }); }); describe('getSelectedConnectorIcon', () => { - it('returns undefined when the connector has usesTableApi:false', () => { + it('returns undefined when the connector is not deprectaed', () => { expect(getSelectedConnectorIcon(validConnector)).toBeUndefined(); }); - it('returns a component when the connector has usesTableApi:true', () => { + it('returns a component when the connector is deprectaed', () => { expect(getSelectedConnectorIcon(deprecatedConnector)).toBeDefined(); }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.ts index 610759a569fd3..49ae38c12947f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.ts @@ -9,10 +9,7 @@ import { lazy, ComponentType } from 'react'; import { EuiSelectOption } from '@elastic/eui'; import { AppInfo, Choice, RESTApiError } from './types'; import { ActionConnector, IErrorObject } from '../../../../types'; -import { - deprecatedMessage, - checkConnectorIsDeprecated, -} from '../../../../common/connectors_selection'; +import { deprecatedMessage } from '../../../../common/connectors_selection'; export const DEFAULT_CORRELATION_ID = '{{rule.id}}:{{alert.id}}'; @@ -30,7 +27,7 @@ export const isFieldInvalid = ( export const getConnectorDescriptiveTitle = (connector: ActionConnector) => { let title = connector.name; - if (checkConnectorIsDeprecated(connector)) { + if (connector.isDeprecated) { title += ` ${deprecatedMessage}`; } @@ -40,7 +37,7 @@ export const getConnectorDescriptiveTitle = (connector: ActionConnector) => { export const getSelectedConnectorIcon = ( actionConnector: ActionConnector ): React.LazyExoticComponent> | undefined => { - if (checkConnectorIsDeprecated(actionConnector)) { + if (actionConnector.isDeprecated) { return lazy(() => import('./servicenow_selection_row')); } }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx index 0e6eb4d8ff0f2..9a634170fa793 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx @@ -9,6 +9,7 @@ import { TypeRegistry } from '../../../type_registry'; import { registerBuiltInActionTypes } from '..'; import { ActionTypeModel } from '../../../../types'; import { ServiceNowActionConnector } from './types'; +import { registrationServicesMock } from '../../../../mocks'; const SERVICENOW_ITSM_ACTION_TYPE_ID = '.servicenow'; const SERVICENOW_SIR_ACTION_TYPE_ID = '.servicenow-sir'; @@ -17,7 +18,7 @@ let actionTypeRegistry: TypeRegistry; beforeAll(() => { actionTypeRegistry = new TypeRegistry(); - registerBuiltInActionTypes({ actionTypeRegistry }); + registerBuiltInActionTypes({ actionTypeRegistry, services: registrationServicesMock }); }); describe('actionTypeRegistry.get() works', () => { @@ -50,6 +51,7 @@ describe('servicenow connector validation', () => { actionTypeId: id, name: 'ServiceNow', isPreconfigured: false, + isDeprecated: false, config: { apiUrl: 'https://dev94428.service-now.com/', usesTableApi: false, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx index 786c84942e08f..315ac6db4ad92 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx @@ -33,6 +33,7 @@ describe('ServiceNowActionConnectorFields renders', () => { id: 'test', actionTypeId: '.servicenow', isPreconfigured: false, + isDeprecated: true, name: 'SN', config: { apiUrl: 'https://test/', @@ -42,6 +43,7 @@ describe('ServiceNowActionConnectorFields renders', () => { const usesImportSetApiConnector = { ...usesTableApiConnector, + isDeprecated: false, config: { ...usesTableApiConnector.config, usesTableApi: false, @@ -94,6 +96,7 @@ describe('ServiceNowActionConnectorFields renders', () => { const actionConnector = { actionTypeId: '.servicenow', isPreconfigured: false, + isDeprecated: false, config: {}, secrets: {}, } as ServiceNowActionConnector; @@ -117,6 +120,7 @@ describe('ServiceNowActionConnectorFields renders', () => { const actionConnector = { actionTypeId: '.servicenow', isPreconfigured: false, + isDeprecated: false, isMissingSecrets: true, config: {}, secrets: {}, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx index a12d43c35369e..22afcd5255e44 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx @@ -8,8 +8,7 @@ import React, { useCallback, useEffect, useState } from 'react'; import { EuiSpacer } from '@elastic/eui'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { snExternalServiceConfig } from '@kbn/actions-plugin/server/builtin_action_types/servicenow/config'; +import { snExternalServiceConfig } from '@kbn/actions-plugin/common'; import { ActionConnectorFieldsProps } from '../../../../types'; import * as i18n from './translations'; @@ -23,7 +22,6 @@ import { InstallationCallout } from './installation_callout'; import { UpdateConnector } from './update_connector'; import { updateActionConnector } from '../../../lib/action_connector_api'; import { Credentials } from './credentials'; -import { checkConnectorIsDeprecated } from '../../../../common/connectors_selection'; // eslint-disable-next-line import/no-default-export export { ServiceNowConnectorFields as default }; @@ -46,7 +44,7 @@ const ServiceNowConnectorFields: React.FC< } = useKibana().services; const { apiUrl, usesTableApi } = action.config; const { username, password } = action.secrets; - const requiresNewApplication = !checkConnectorIsDeprecated(action); + const requiresNewApplication = !action.isDeprecated; const [showUpdateConnector, setShowUpdateConnector] = useState(false); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itom_params.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itom_params.test.tsx index ef934d4ebacd7..d17c77da1f820 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itom_params.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itom_params.test.tsx @@ -41,6 +41,7 @@ const connector: ActionConnector = { actionTypeId: '.test', name: 'Test', isPreconfigured: false, + isDeprecated: false, }; const editAction = jest.fn(); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itsm_params.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itsm_params.test.tsx index cdbfad469b68d..f8375a5aaeb6e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itsm_params.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itsm_params.test.tsx @@ -46,6 +46,7 @@ const connector: ActionConnector = { actionTypeId: '.test', name: 'Test', isPreconfigured: false, + isDeprecated: false, }; const editAction = jest.fn(); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itsm_params.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itsm_params.tsx index 6c3c9528e5b19..3bae1c3b858d6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itsm_params.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itsm_params.tsx @@ -26,7 +26,6 @@ import { useGetChoices } from './use_get_choices'; import { choicesToEuiOptions, DEFAULT_CORRELATION_ID } from './helpers'; import * as i18n from './translations'; -import { checkConnectorIsDeprecated } from '../../../../common/connectors_selection'; const useGetChoicesFields = ['urgency', 'severity', 'impact', 'category', 'subcategory']; const defaultFields: Fields = { @@ -47,7 +46,7 @@ const ServiceNowParamsFields: React.FunctionComponent< notifications: { toasts }, } = useKibana().services; - const isDeprecatedActionConnector = checkConnectorIsDeprecated(actionConnector); + const isDeprecatedActionConnector = actionConnector?.isDeprecated; const actionConnectorRef = useRef(actionConnector?.id ?? ''); const { incident, comments } = useMemo( diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_sir_params.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_sir_params.test.tsx index 0a426aeade4c0..9f15cb07f92e1 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_sir_params.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_sir_params.test.tsx @@ -48,6 +48,7 @@ const connector: ActionConnector = { actionTypeId: '.test', name: 'Test', isPreconfigured: false, + isDeprecated: false, }; const editAction = jest.fn(); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_sir_params.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_sir_params.tsx index daeaea1c86137..a341dca3f255a 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_sir_params.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_sir_params.tsx @@ -27,7 +27,6 @@ import { useGetChoices } from './use_get_choices'; import { ServiceNowSIRActionParams, Fields, Choice } from './types'; import { choicesToEuiOptions, DEFAULT_CORRELATION_ID } from './helpers'; import { DeprecatedCallout } from './deprecated_callout'; -import { checkConnectorIsDeprecated } from '../../../../common/connectors_selection'; const useGetChoicesFields = ['category', 'subcategory', 'priority']; const defaultFields: Fields = { @@ -45,7 +44,7 @@ const ServiceNowSIRParamsFields: React.FunctionComponent< notifications: { toasts }, } = useKibana().services; - const isDeprecatedActionConnector = checkConnectorIsDeprecated(actionConnector); + const isDeprecatedActionConnector = actionConnector?.isDeprecated; const actionConnectorRef = useRef(actionConnector?.id ?? ''); const { incident, comments } = useMemo( diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/update_connector.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/update_connector.test.tsx index 00cce14906e82..0c7bc3b938ef8 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/update_connector.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/update_connector.test.tsx @@ -19,6 +19,7 @@ const actionConnector: ServiceNowActionConnector = { id: 'test', actionTypeId: '.servicenow', isPreconfigured: false, + isDeprecated: false, name: 'servicenow', config: { apiUrl: 'https://test/', diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/update_connector.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/update_connector.tsx index 732aeed6313ac..de5cf4df5731a 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/update_connector.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/update_connector.tsx @@ -21,8 +21,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { snExternalServiceConfig } from '@kbn/actions-plugin/server/builtin_action_types/servicenow/config'; +import { snExternalServiceConfig } from '@kbn/actions-plugin/common'; import { ActionConnectorFieldsProps } from '../../../../types'; import { ServiceNowActionConnector } from './types'; import { CredentialsApiUrl } from './credentials_api_url'; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/use_choices.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/use_choices.test.tsx index 175a80c63d4b7..22839c03d3bb7 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/use_choices.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/use_choices.test.tsx @@ -27,6 +27,7 @@ const actionConnector = { actionTypeId: '.servicenow', name: 'ServiceNow ITSM', isPreconfigured: false, + isDeprecated: false, config: { apiUrl: 'https://dev94428.service-now.com/', }, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/use_get_app_info.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/use_get_app_info.test.tsx index f842f6863676a..1e496e66c373b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/use_get_app_info.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/use_get_app_info.test.tsx @@ -32,6 +32,7 @@ const actionConnector = { actionTypeId: '.servicenow', name: 'ServiceNow ITSM', isPreconfigured: false, + isDeprecated: false, config: { apiUrl: 'https://test.service-now.com/', usesTableApi: false, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/use_get_choices.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/use_get_choices.test.tsx index ecbc9512a4d3a..06956e6402300 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/use_get_choices.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/use_get_choices.test.tsx @@ -28,6 +28,7 @@ const actionConnector = { actionTypeId: '.servicenow', name: 'ServiceNow ITSM', isPreconfigured: false, + isDeprecated: false, config: { apiUrl: 'https://dev94428.service-now.com/', }, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack.test.tsx index 95ce25a03349e..76a23ab94d972 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack.test.tsx @@ -9,13 +9,14 @@ import { TypeRegistry } from '../../../type_registry'; import { registerBuiltInActionTypes } from '..'; import { ActionTypeModel } from '../../../../types'; import { SlackActionConnector } from '../types'; +import { registrationServicesMock } from '../../../../mocks'; const ACTION_TYPE_ID = '.slack'; let actionTypeModel: ActionTypeModel; beforeAll(async () => { const actionTypeRegistry = new TypeRegistry(); - registerBuiltInActionTypes({ actionTypeRegistry }); + registerBuiltInActionTypes({ actionTypeRegistry, services: registrationServicesMock }); const getResult = actionTypeRegistry.get(ACTION_TYPE_ID); if (getResult !== null) { actionTypeModel = getResult; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/swimlane/swimlane.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/swimlane/swimlane.test.tsx index 5d69af2d08779..45d68c8ab39e8 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/swimlane/swimlane.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/swimlane/swimlane.test.tsx @@ -9,13 +9,14 @@ import { TypeRegistry } from '../../../type_registry'; import { registerBuiltInActionTypes } from '..'; import { ActionTypeModel } from '../../../../types'; import { SwimlaneActionConnector } from './types'; +import { registrationServicesMock } from '../../../../mocks'; const ACTION_TYPE_ID = '.swimlane'; let actionTypeModel: ActionTypeModel; beforeAll(() => { const actionTypeRegistry = new TypeRegistry(); - registerBuiltInActionTypes({ actionTypeRegistry }); + registerBuiltInActionTypes({ actionTypeRegistry, services: registrationServicesMock }); const getResult = actionTypeRegistry.get(ACTION_TYPE_ID); if (getResult !== null) { actionTypeModel = getResult; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/swimlane/swimlane_params.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/swimlane/swimlane_params.test.tsx index 03f20546b1003..302e5c80af15c 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/swimlane/swimlane_params.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/swimlane/swimlane_params.test.tsx @@ -36,6 +36,7 @@ describe('SwimlaneParamsFields renders', () => { actionTypeId: '.test', name: 'Test', isPreconfigured: false, + isDeprecated: false, }; const defaultProps = { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/swimlane/use_get_application.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/swimlane/use_get_application.test.tsx index 4744c4d22fdc9..fc0ae22efe377 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/swimlane/use_get_application.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/swimlane/use_get_application.test.tsx @@ -24,6 +24,7 @@ const action = { actionTypeId: '.swimlane', name: 'Swimlane', isPreconfigured: false, + isDeprecated: false, config: { apiUrl: 'https://test.swimlane.com/', appId: 'bcq16kdTbz5jlwM6h', diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/teams/teams.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/teams/teams.test.tsx index da0a67fe79a20..8590433f39cc0 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/teams/teams.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/teams/teams.test.tsx @@ -9,13 +9,14 @@ import { TypeRegistry } from '../../../type_registry'; import { registerBuiltInActionTypes } from '..'; import { ActionTypeModel } from '../../../../types'; import { TeamsActionConnector } from '../types'; +import { registrationServicesMock } from '../../../../mocks'; const ACTION_TYPE_ID = '.teams'; let actionTypeModel: ActionTypeModel; beforeAll(async () => { const actionTypeRegistry = new TypeRegistry(); - registerBuiltInActionTypes({ actionTypeRegistry }); + registerBuiltInActionTypes({ actionTypeRegistry, services: registrationServicesMock }); const getResult = actionTypeRegistry.get(ACTION_TYPE_ID); if (getResult !== null) { actionTypeModel = getResult; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook.test.tsx index 8a17b1c0b206a..771786157ed4c 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook.test.tsx @@ -9,13 +9,14 @@ import { TypeRegistry } from '../../../type_registry'; import { registerBuiltInActionTypes } from '..'; import { ActionTypeModel } from '../../../../types'; import { WebhookActionConnector } from '../types'; +import { registrationServicesMock } from '../../../../mocks'; const ACTION_TYPE_ID = '.webhook'; let actionTypeModel: ActionTypeModel; beforeAll(() => { const actionTypeRegistry = new TypeRegistry(); - registerBuiltInActionTypes({ actionTypeRegistry }); + registerBuiltInActionTypes({ actionTypeRegistry, services: registrationServicesMock }); const getResult = actionTypeRegistry.get(ACTION_TYPE_ID); if (getResult !== null) { actionTypeModel = getResult; @@ -40,6 +41,7 @@ describe('webhook connector validation', () => { actionTypeId: '.webhook', name: 'webhook', isPreconfigured: false, + isDeprecated: false, config: { method: 'PUT', url: 'http://test.com', @@ -74,6 +76,7 @@ describe('webhook connector validation', () => { actionTypeId: '.webhook', name: 'webhook', isPreconfigured: false, + isDeprecated: false, config: { method: 'PUT', url: 'http://test.com', diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.test.tsx index 2579d8dd1a93b..533d6d9a9b605 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.test.tsx @@ -20,6 +20,7 @@ describe('WebhookActionConnectorFields renders', () => { id: 'test', actionTypeId: '.webhook', isPreconfigured: false, + isDeprecated: false, name: 'webhook', config: { method: 'PUT', @@ -53,6 +54,7 @@ describe('WebhookActionConnectorFields renders', () => { secrets: {}, actionTypeId: '.webhook', isPreconfigured: false, + isDeprecated: false, config: { hasAuth: true, }, @@ -81,6 +83,7 @@ describe('WebhookActionConnectorFields renders', () => { id: 'test', actionTypeId: '.webhook', isPreconfigured: false, + isDeprecated: false, name: 'webhook', config: { method: 'PUT', @@ -113,6 +116,7 @@ describe('WebhookActionConnectorFields renders', () => { id: 'test', actionTypeId: '.webhook', isPreconfigured: false, + isDeprecated: false, isMissingSecrets: true, name: 'webhook', config: { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/xmatters/xmatters.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/xmatters/xmatters.test.tsx index 93d8c6f5d39db..7e9dbc4cf885a 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/xmatters/xmatters.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/xmatters/xmatters.test.tsx @@ -9,13 +9,14 @@ import { TypeRegistry } from '../../../type_registry'; import { registerBuiltInActionTypes } from '..'; import { ActionTypeModel } from '../../../../types'; import { XmattersActionConnector } from '../types'; +import { registrationServicesMock } from '../../../../mocks'; const ACTION_TYPE_ID = '.xmatters'; let actionTypeModel: ActionTypeModel; beforeAll(() => { const actionTypeRegistry = new TypeRegistry(); - registerBuiltInActionTypes({ actionTypeRegistry }); + registerBuiltInActionTypes({ actionTypeRegistry, services: registrationServicesMock }); const getResult = actionTypeRegistry.get(ACTION_TYPE_ID); if (getResult !== null) { actionTypeModel = getResult; @@ -40,6 +41,7 @@ describe('xmatters connector validation', () => { actionTypeId: '.xmatters', name: 'xmatters', isPreconfigured: false, + isDeprecated: false, config: { configUrl: 'http://test.com', usesBasic: true, @@ -73,6 +75,7 @@ describe('xmatters connector validation', () => { actionTypeId: '.xmatters', name: 'xmatters', isPreconfigured: false, + isDeprecated: false, config: { usesBasic: false, }, @@ -105,6 +108,8 @@ describe('xmatters connector validation', () => { config: { usesBasic: true, }, + isPreconfigured: false, + isDeprecated: false, } as XmattersActionConnector; expect(await actionTypeModel.validateConnector(actionConnector)).toEqual({ @@ -136,6 +141,8 @@ describe('xmatters connector validation', () => { configUrl: 'invalid.url', usesBasic: true, }, + isPreconfigured: false, + isDeprecated: false, } as XmattersActionConnector; expect(await actionTypeModel.validateConnector(actionConnector)).toEqual({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/xmatters/xmatters_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/xmatters/xmatters_connectors.test.tsx index a96e2bf679240..7da6cfe0a4a37 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/xmatters/xmatters_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/xmatters/xmatters_connectors.test.tsx @@ -20,6 +20,7 @@ describe('XmattersActionConnectorFields renders', () => { id: 'test', actionTypeId: '.xmatters', isPreconfigured: false, + isDeprecated: false, name: 'xmatters', config: { configUrl: 'http:\\test', @@ -51,6 +52,7 @@ describe('XmattersActionConnectorFields renders', () => { id: 'test', actionTypeId: '.xmatters', isPreconfigured: false, + isDeprecated: false, name: 'xmatters', config: { configUrl: 'http:\\test', @@ -81,6 +83,7 @@ describe('XmattersActionConnectorFields renders', () => { id: 'test', actionTypeId: '.xmatters', isPreconfigured: false, + isDeprecated: false, name: 'xmatters', config: { usesBasic: false, @@ -107,6 +110,7 @@ describe('XmattersActionConnectorFields renders', () => { secrets: {}, actionTypeId: '.xmatters', isPreconfigured: false, + isDeprecated: false, config: { usesBasic: true, }, @@ -135,6 +139,7 @@ describe('XmattersActionConnectorFields renders', () => { id: 'test', actionTypeId: '.xmatters', isPreconfigured: false, + isDeprecated: false, name: 'xmatters', config: { configUrl: 'http:\\test', @@ -165,6 +170,7 @@ describe('XmattersActionConnectorFields renders', () => { id: 'test', actionTypeId: '.xmatters', isPreconfigured: false, + isDeprecated: false, isMissingSecrets: true, name: 'xmatters', config: { @@ -194,6 +200,7 @@ describe('XmattersActionConnectorFields renders', () => { id: 'test', actionTypeId: '.xmatters', isPreconfigured: false, + isDeprecated: false, name: 'xmatters', config: { usesBasic: false, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/internal/shareable_components_sandbox/rule_status_filter_sandbox.tsx b/x-pack/plugins/triggers_actions_ui/public/application/internal/shareable_components_sandbox/rule_status_filter_sandbox.tsx new file mode 100644 index 0000000000000..99ddd8daf16ac --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/internal/shareable_components_sandbox/rule_status_filter_sandbox.tsx @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useState } from 'react'; +import { RuleStatusFilterProps } from '../../../types'; +import { getRuleStatusFilterLazy } from '../../../common/get_rule_status_filter'; + +export const RuleStatusFilterSandbox = () => { + const [selectedStatuses, setSelectedStatuses] = useState< + RuleStatusFilterProps['selectedStatuses'] + >([]); + + return ( +
+ {getRuleStatusFilterLazy({ + selectedStatuses, + onChange: setSelectedStatuses, + })} +
Selected states: {JSON.stringify(selectedStatuses)}
+
+ ); +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/internal/shareable_components_sandbox/rule_tag_badge_sandbox.tsx b/x-pack/plugins/triggers_actions_ui/public/application/internal/shareable_components_sandbox/rule_tag_badge_sandbox.tsx new file mode 100644 index 0000000000000..097fb00969d27 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/internal/shareable_components_sandbox/rule_tag_badge_sandbox.tsx @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/** + * Note: This exists only temporarily as we refactor to remove the sandboxes + * to its own plugin. Ideally we do not want to use an internal page within + * the triggers_actions_ui plugin + */ + +import React, { useState } from 'react'; +import { getRuleTagBadgeLazy } from '../../../common/get_rule_tag_badge'; + +const tags = ['tag1', 'tag2', 'tag3', 'tag4']; + +export const RuleTagBadgeSandbox = () => { + const [isOpen, setIsOpen] = useState(false); + + return ( +
+ {getRuleTagBadgeLazy({ + isOpen, + tags, + onClick: () => setIsOpen(true), + onClose: () => setIsOpen(false), + })} +
+ ); +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/internal/shareable_components_sandbox/shareable_components_sandbox.tsx b/x-pack/plugins/triggers_actions_ui/public/application/internal/shareable_components_sandbox/shareable_components_sandbox.tsx index 97366832bda0e..bedcbb03045a5 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/internal/shareable_components_sandbox/shareable_components_sandbox.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/internal/shareable_components_sandbox/shareable_components_sandbox.tsx @@ -7,11 +7,15 @@ import React from 'react'; import { RuleStatusDropdownSandbox } from './rule_status_dropdown_sandbox'; +import { RuleStatusFilterSandbox } from './rule_status_filter_sandbox'; +import { RuleTagBadgeSandbox } from './rule_tag_badge_sandbox'; export const InternalShareableComponentsSandbox: React.FC<{}> = () => { return ( <> + + ); }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connectors.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connectors.ts index fbef1521b2024..c08232ca5eea5 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connectors.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connectors.ts @@ -22,12 +22,14 @@ const transformConnector: RewriteRequestCase< > = ({ connector_type_id: actionTypeId, is_preconfigured: isPreconfigured, + is_deprecated: isDeprecated, referenced_by_count: referencedByCount, is_missing_secrets: isMissingSecrets, ...res }) => ({ actionTypeId, isPreconfigured, + isDeprecated, referencedByCount, isMissingSecrets, ...res, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/create.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/create.test.ts index 42588610e036b..a2ed111daa2be 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/create.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/create.test.ts @@ -18,6 +18,7 @@ describe('createActionConnector', () => { const apiResponse = { connector_type_id: 'test', is_preconfigured: false, + is_deprecated: false, name: 'My test', config: {}, secrets: {}, @@ -28,6 +29,7 @@ describe('createActionConnector', () => { const connector: ActionConnectorWithoutId<{}, {}> = { actionTypeId: 'test', isPreconfigured: false, + isDeprecated: false, name: 'My test', config: {}, secrets: {}, @@ -40,7 +42,7 @@ describe('createActionConnector', () => { Array [ "/api/actions/connector", Object { - "body": "{\\"name\\":\\"My test\\",\\"config\\":{},\\"secrets\\":{},\\"connector_type_id\\":\\"test\\",\\"is_preconfigured\\":false}", + "body": "{\\"name\\":\\"My test\\",\\"config\\":{},\\"secrets\\":{},\\"connector_type_id\\":\\"test\\",\\"is_preconfigured\\":false,\\"is_deprecated\\":false}", }, ] `); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/create.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/create.ts index 2799848909446..9227c4747c84a 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/create.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/create.ts @@ -15,10 +15,11 @@ import type { const rewriteBodyRequest: RewriteResponseCase< Omit -> = ({ actionTypeId, isPreconfigured, ...res }) => ({ +> = ({ actionTypeId, isPreconfigured, isDeprecated, ...res }) => ({ ...res, connector_type_id: actionTypeId, is_preconfigured: isPreconfigured, + is_deprecated: isDeprecated, }); const rewriteBodyRes: RewriteRequestCase< @@ -26,12 +27,14 @@ const rewriteBodyRes: RewriteRequestCase< > = ({ connector_type_id: actionTypeId, is_preconfigured: isPreconfigured, + is_deprecated: isDeprecated, is_missing_secrets: isMissingSecrets, ...res }) => ({ ...res, actionTypeId, isPreconfigured, + isDeprecated, isMissingSecrets, }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.test.ts index 90c0d3adb9235..957f682d1fd6c 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.test.ts @@ -19,6 +19,7 @@ describe('updateActionConnector', () => { const apiResponse = { connector_type_id: 'te/st', is_preconfigured: false, + is_deprecated: false, name: 'My test', config: {}, secrets: {}, @@ -29,6 +30,7 @@ describe('updateActionConnector', () => { const connector: ActionConnectorWithoutId<{}, {}> = { actionTypeId: 'te/st', isPreconfigured: false, + isDeprecated: false, name: 'My test', config: {}, secrets: {}, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.ts index 18f4bdd60ad27..34aa1e127ad95 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.ts @@ -18,12 +18,14 @@ const rewriteBodyRes: RewriteRequestCase< > = ({ connector_type_id: actionTypeId, is_preconfigured: isPreconfigured, + is_deprecated: isDeprecated, is_missing_secrets: isMissingSecrets, ...res }) => ({ ...res, actionTypeId, isPreconfigured, + isDeprecated, isMissingSecrets, }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.test.tsx index 6b115abc590cc..93aade03b22b2 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.test.tsx @@ -99,6 +99,7 @@ describe('checkActionFormActionTypeEnabled', () => { actionTypeId: '1', id: 'test1', isPreconfigured: true, + isDeprecated: true, name: 'test', referencedByCount: 0, }, @@ -106,6 +107,7 @@ describe('checkActionFormActionTypeEnabled', () => { actionTypeId: '2', id: 'test2', isPreconfigured: true, + isDeprecated: true, name: 'test', referencedByCount: 0, }, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate.test.ts index 46653e5bc3911..ab8f1b565c888 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate.test.ts @@ -209,4 +209,84 @@ describe('loadRuleAggregations', () => { ] `); }); + + test('should call aggregate API with ruleStatusesFilter', async () => { + const resolvedValue = { + rule_execution_status: { + ok: 4, + active: 2, + error: 1, + pending: 1, + unknown: 0, + }, + }; + http.get.mockResolvedValue(resolvedValue); + + let result = await loadRuleAggregations({ + http, + ruleStatusesFilter: ['enabled'], + }); + + expect(result).toEqual({ + ruleExecutionStatus: { + ok: 4, + active: 2, + error: 1, + pending: 1, + unknown: 0, + }, + }); + + expect(http.get.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_aggregate", + Object { + "query": Object { + "default_search_operator": "AND", + "filter": "alert.attributes.enabled:(true) and not (alert.attributes.muteAll:true OR alert.attributes.snoozeEndTime > now)", + "search": undefined, + "search_fields": undefined, + }, + }, + ] + `); + + result = await loadRuleAggregations({ + http, + ruleStatusesFilter: ['enabled', 'snoozed'], + }); + + expect(http.get.mock.calls[1]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_aggregate", + Object { + "query": Object { + "default_search_operator": "AND", + "filter": "alert.attributes.enabled:(true) or (alert.attributes.muteAll:true OR alert.attributes.snoozeEndTime > now)", + "search": undefined, + "search_fields": undefined, + }, + }, + ] + `); + + result = await loadRuleAggregations({ + http, + ruleStatusesFilter: ['enabled', 'disabled', 'snoozed'], + }); + + expect(http.get.mock.calls[1]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_aggregate", + Object { + "query": Object { + "default_search_operator": "AND", + "filter": "alert.attributes.enabled:(true) or (alert.attributes.muteAll:true OR alert.attributes.snoozeEndTime > now)", + "search": undefined, + "search_fields": undefined, + }, + }, + ] + `); + }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate.ts index c7bcd438ef697..9548445d0df9c 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate.ts @@ -6,7 +6,7 @@ */ import { HttpSetup } from '@kbn/core/public'; import { AsApiContract, RewriteRequestCase } from '@kbn/actions-plugin/common'; -import { RuleAggregations } from '../../../types'; +import { RuleAggregations, RuleStatus } from '../../../types'; import { INTERNAL_BASE_ALERTING_API_PATH } from '../../constants'; import { mapFiltersToKql } from './map_filters_to_kql'; @@ -29,15 +29,22 @@ export async function loadRuleAggregations({ searchText, typesFilter, actionTypesFilter, + ruleExecutionStatusesFilter, ruleStatusesFilter, }: { http: HttpSetup; searchText?: string; typesFilter?: string[]; actionTypesFilter?: string[]; - ruleStatusesFilter?: string[]; + ruleExecutionStatusesFilter?: string[]; + ruleStatusesFilter?: RuleStatus[]; }): Promise { - const filters = mapFiltersToKql({ typesFilter, actionTypesFilter, ruleStatusesFilter }); + const filters = mapFiltersToKql({ + typesFilter, + actionTypesFilter, + ruleExecutionStatusesFilter, + ruleStatusesFilter, + }); const res = await http.get>( `${INTERNAL_BASE_ALERTING_API_PATH}/rules/_aggregate`, { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/map_filters_to_kql.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/map_filters_to_kql.test.ts index e1dd14a7a9fde..df762d05e0eff 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/map_filters_to_kql.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/map_filters_to_kql.test.ts @@ -32,14 +32,62 @@ describe('mapFiltersToKql', () => { ]); }); - test('should handle ruleStatusesFilter', () => { + test('should handle ruleExecutionStatusesFilter', () => { expect( mapFiltersToKql({ - ruleStatusesFilter: ['alert', 'statuses', 'filter'], + ruleExecutionStatusesFilter: ['alert', 'statuses', 'filter'], }) ).toEqual(['alert.attributes.executionStatus.status:(alert or statuses or filter)']); }); + test('should handle ruleStatusesFilter', () => { + expect( + mapFiltersToKql({ + ruleStatusesFilter: ['enabled'], + }) + ).toEqual([ + 'alert.attributes.enabled:(true) and not (alert.attributes.muteAll:true OR alert.attributes.snoozeEndTime > now)', + ]); + + expect( + mapFiltersToKql({ + ruleStatusesFilter: ['disabled'], + }) + ).toEqual([ + 'alert.attributes.enabled:(false) and not (alert.attributes.muteAll:true OR alert.attributes.snoozeEndTime > now)', + ]); + + expect( + mapFiltersToKql({ + ruleStatusesFilter: ['snoozed'], + }) + ).toEqual(['(alert.attributes.muteAll:true OR alert.attributes.snoozeEndTime > now)']); + + expect( + mapFiltersToKql({ + ruleStatusesFilter: ['enabled', 'snoozed'], + }) + ).toEqual([ + 'alert.attributes.enabled:(true) or (alert.attributes.muteAll:true OR alert.attributes.snoozeEndTime > now)', + ]); + + expect( + mapFiltersToKql({ + ruleStatusesFilter: ['disabled', 'snoozed'], + }) + ).toEqual([ + 'alert.attributes.enabled:(false) or (alert.attributes.muteAll:true OR alert.attributes.snoozeEndTime > now)', + ]); + + expect( + mapFiltersToKql({ + ruleStatusesFilter: ['enabled', 'disabled', 'snoozed'], + }) + ).toEqual([ + 'alert.attributes.enabled:(true or false) or (alert.attributes.muteAll:true OR alert.attributes.snoozeEndTime > now)', + ]); + }); + test('should handle typesFilter and actionTypesFilter', () => { expect( mapFiltersToKql({ @@ -52,12 +100,12 @@ describe('mapFiltersToKql', () => { ]); }); - test('should handle typesFilter, actionTypesFilter and ruleStatusesFilter', () => { + test('should handle typesFilter, actionTypesFilter and ruleExecutionStatusesFilter', () => { expect( mapFiltersToKql({ typesFilter: ['type', 'filter'], actionTypesFilter: ['action', 'types', 'filter'], - ruleStatusesFilter: ['alert', 'statuses', 'filter'], + ruleExecutionStatusesFilter: ['alert', 'statuses', 'filter'], }) ).toEqual([ 'alert.attributes.alertTypeId:(type or filter)', diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/map_filters_to_kql.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/map_filters_to_kql.ts index d7b22a7a4aee4..0e64f5500454f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/map_filters_to_kql.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/map_filters_to_kql.ts @@ -5,16 +5,34 @@ * 2.0. */ +import { RuleStatus } from '../../../types'; + +const getEnablementFilter = (ruleStatusFilter: RuleStatus[] = []) => { + const enablementFilters = ruleStatusFilter.reduce((result, filter) => { + if (filter === 'enabled') { + return [...result, 'true']; + } + if (filter === 'disabled') { + return [...result, 'false']; + } + return result; + }, []); + return `alert.attributes.enabled:(${enablementFilters.join(' or ')})`; +}; + export const mapFiltersToKql = ({ typesFilter, actionTypesFilter, + ruleExecutionStatusesFilter, ruleStatusesFilter, }: { typesFilter?: string[]; actionTypesFilter?: string[]; - ruleStatusesFilter?: string[]; + ruleExecutionStatusesFilter?: string[]; + ruleStatusesFilter?: RuleStatus[]; }): string[] => { const filters = []; + if (typesFilter && typesFilter.length) { filters.push(`alert.attributes.alertTypeId:(${typesFilter.join(' or ')})`); } @@ -29,8 +47,27 @@ export const mapFiltersToKql = ({ ].join('') ); } + if (ruleExecutionStatusesFilter && ruleExecutionStatusesFilter.length) { + filters.push( + `alert.attributes.executionStatus.status:(${ruleExecutionStatusesFilter.join(' or ')})` + ); + } + if (ruleStatusesFilter && ruleStatusesFilter.length) { - filters.push(`alert.attributes.executionStatus.status:(${ruleStatusesFilter.join(' or ')})`); + const enablementFilter = getEnablementFilter(ruleStatusesFilter); + const snoozedFilter = `(alert.attributes.muteAll:true OR alert.attributes.snoozeEndTime > now)`; + const hasEnablement = + ruleStatusesFilter.includes('enabled') || ruleStatusesFilter.includes('disabled'); + const hasSnoozed = ruleStatusesFilter.includes('snoozed'); + + if (hasEnablement && !hasSnoozed) { + filters.push(`${enablementFilter} and not ${snoozedFilter}`); + } else if (!hasEnablement && hasSnoozed) { + filters.push(snoozedFilter); + } else { + filters.push(`${enablementFilter} or ${snoozedFilter}`); + } } + return filters; }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules.test.ts index 5f6c6e938a0a7..8adc92738b7c6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules.test.ts @@ -239,4 +239,101 @@ describe('loadRules', () => { ] `); }); + + test('should call find API with ruleStatusesilter', async () => { + const resolvedValue = { + page: 1, + per_page: 10, + total: 0, + data: [], + }; + http.get.mockResolvedValue(resolvedValue); + + let result = await loadRules({ + http, + ruleStatusesFilter: ['enabled', 'snoozed'], + page: { index: 0, size: 10 }, + }); + expect(result).toEqual({ + page: 1, + perPage: 10, + total: 0, + data: [], + }); + expect(http.get.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_find", + Object { + "query": Object { + "default_search_operator": "AND", + "filter": "alert.attributes.enabled:(true) or (alert.attributes.muteAll:true OR alert.attributes.snoozeEndTime > now)", + "page": 1, + "per_page": 10, + "search": undefined, + "search_fields": undefined, + "sort_field": "name", + "sort_order": "asc", + }, + }, + ] + `); + + result = await loadRules({ + http, + ruleStatusesFilter: ['disabled'], + page: { index: 0, size: 10 }, + }); + expect(result).toEqual({ + page: 1, + perPage: 10, + total: 0, + data: [], + }); + expect(http.get.mock.calls[1]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_find", + Object { + "query": Object { + "default_search_operator": "AND", + "filter": "alert.attributes.enabled:(false) and not (alert.attributes.muteAll:true OR alert.attributes.snoozeEndTime > now)", + "page": 1, + "per_page": 10, + "search": undefined, + "search_fields": undefined, + "sort_field": "name", + "sort_order": "asc", + }, + }, + ] + `); + + result = await loadRules({ + http, + ruleStatusesFilter: ['enabled', 'disabled', 'snoozed'], + page: { index: 0, size: 10 }, + }); + expect(result).toEqual({ + page: 1, + perPage: 10, + total: 0, + data: [], + }); + expect(http.get.mock.calls[2]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_find", + Object { + "query": Object { + "default_search_operator": "AND", + "filter": "alert.attributes.enabled:(true or false) or (alert.attributes.muteAll:true OR alert.attributes.snoozeEndTime > now)", + "page": 1, + "per_page": 10, + "search": undefined, + "search_fields": undefined, + "sort_field": "name", + "sort_order": "asc", + }, + }, + ] + `); + }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules.ts index 52ba09a5c0adf..bdbdcf2f094b2 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules.ts @@ -7,7 +7,7 @@ import { HttpSetup } from '@kbn/core/public'; import { AsApiContract } from '@kbn/actions-plugin/common'; import { INTERNAL_BASE_ALERTING_API_PATH } from '../../constants'; -import { Rule, Pagination, Sorting } from '../../../types'; +import { Rule, Pagination, Sorting, RuleStatus } from '../../../types'; import { mapFiltersToKql } from './map_filters_to_kql'; import { transformRule } from './common_transformations'; @@ -21,6 +21,7 @@ export async function loadRules({ searchText, typesFilter, actionTypesFilter, + ruleExecutionStatusesFilter, ruleStatusesFilter, sort = { field: 'name', direction: 'asc' }, }: { @@ -29,7 +30,8 @@ export async function loadRules({ searchText?: string; typesFilter?: string[]; actionTypesFilter?: string[]; - ruleStatusesFilter?: string[]; + ruleExecutionStatusesFilter?: string[]; + ruleStatusesFilter?: RuleStatus[]; sort?: Sorting; }): Promise<{ page: number; @@ -37,7 +39,12 @@ export async function loadRules({ total: number; data: Rule[]; }> { - const filters = mapFiltersToKql({ typesFilter, actionTypesFilter, ruleStatusesFilter }); + const filters = mapFiltersToKql({ + typesFilter, + actionTypesFilter, + ruleExecutionStatusesFilter, + ruleStatusesFilter, + }); const res = await http.get< AsApiContract<{ page: number; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts index 162cb222b78fe..6587fc669b97e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts @@ -112,6 +112,7 @@ describe('getConnectorWithInvalidatedFields', () => { name: 'slack', config: {}, isPreconfigured: false, + isDeprecated: false, }; const secretsErrors = { webhookUrl: ['Webhook URL is required.'] }; const configErrors = {}; @@ -128,6 +129,7 @@ describe('getConnectorWithInvalidatedFields', () => { name: 'jira', config: {} as any, isPreconfigured: false, + isDeprecated: false, }; const secretsErrors = {}; const configErrors = { apiUrl: ['apiUrl is required'] }; @@ -146,6 +148,7 @@ describe('getConnectorWithInvalidatedFields', () => { name: 'slack', config: {}, isPreconfigured: false, + isDeprecated: false, }; const secretsErrors = { webhookUrl: ['Webhook URL must start with https://.'] }; const configErrors = {}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx index 4addfc3833aab..b86a3952eb0a6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx @@ -41,6 +41,7 @@ describe('action_connector_form', () => { config: {}, secrets: {}, isPreconfigured: false, + isDeprecated: false, }; const wrapper = mountWithIntl( { name: 'Test connector', config: {}, isPreconfigured: false, + isDeprecated: false, }, { secrets: {}, @@ -142,6 +143,7 @@ describe('action_form', () => { name: 'Test connector 2', config: {}, isPreconfigured: true, + isDeprecated: false, }, { secrets: {}, @@ -151,6 +153,7 @@ describe('action_form', () => { name: 'Preconfigured Only', config: {}, isPreconfigured: true, + isDeprecated: false, }, { secrets: {}, @@ -160,6 +163,7 @@ describe('action_form', () => { name: 'Regular connector', config: {}, isPreconfigured: false, + isDeprecated: false, }, { secrets: {}, @@ -169,6 +173,7 @@ describe('action_form', () => { name: 'Non consumer connector', config: {}, isPreconfigured: false, + isDeprecated: false, }, { secrets: {}, @@ -178,6 +183,7 @@ describe('action_form', () => { name: 'Connector with disabled action group', config: {}, isPreconfigured: false, + isDeprecated: false, }, { secrets: null, @@ -187,6 +193,7 @@ describe('action_form', () => { name: 'Connector with disabled action group', config: {}, isPreconfigured: false, + isDeprecated: false, }, ]; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx index 484f6698a8b29..7b89d720eabe3 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx @@ -154,6 +154,7 @@ function getActionTypeForm( }, id: 'test', isPreconfigured: false, + isDeprecated: false, name: 'test name', secrets: {}, }; @@ -176,6 +177,7 @@ function getActionTypeForm( }, id: 'test', isPreconfigured: false, + isDeprecated: false, name: 'test name', secrets: {}, }, @@ -184,6 +186,7 @@ function getActionTypeForm( name: 'Server log', actionTypeId: '.server-log', isPreconfigured: false, + isDeprecated: false, config: {}, secrets: {}, }, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.test.tsx index 524b848dbb275..e01d325ba3ef5 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.test.tsx @@ -43,6 +43,7 @@ describe('connector_edit_flyout', () => { actionType: 'test-action-type-name', name: 'action-connector', isPreconfigured: false, + isDeprecated: false, referencedByCount: 0, config: {}, }; @@ -87,6 +88,7 @@ describe('connector_edit_flyout', () => { actionType: 'test-action-type-name', name: 'preconfigured-connector', isPreconfigured: true, + isDeprecated: false, referencedByCount: 0, config: {}, }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_reducer.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_reducer.test.ts index ab9ff5bfa9ffe..bc23b87176598 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_reducer.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_reducer.test.ts @@ -21,6 +21,7 @@ describe('connector reducer', () => { name: 'action-connector', referencedByCount: 0, isPreconfigured: false, + isDeprecated: false, config: {}, }; }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connectors_selection.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connectors_selection.test.tsx index 3bef8e19abff1..b56e245633ece 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connectors_selection.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connectors_selection.test.tsx @@ -66,6 +66,7 @@ describe('connectors_selection', () => { }, id: 'testId', isPreconfigured: false, + isDeprecated: false, name: 'test pagerduty', secrets: {}, }, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx index 4b51c9b306a75..9d6e464f25dd3 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx @@ -105,6 +105,7 @@ describe('actions_connectors_list component with items', () => { actionTypeId: 'test', description: 'My test', isPreconfigured: false, + isDeprecated: false, referencedByCount: 1, config: {}, }, @@ -114,6 +115,7 @@ describe('actions_connectors_list component with items', () => { description: 'My test 2', referencedByCount: 1, isPreconfigured: false, + isDeprecated: false, config: {}, }, { @@ -123,6 +125,7 @@ describe('actions_connectors_list component with items', () => { isMissingSecrets: true, referencedByCount: 1, isPreconfigured: true, + isDeprecated: false, config: {}, }, { @@ -131,6 +134,7 @@ describe('actions_connectors_list component with items', () => { description: 'My invalid connector type', referencedByCount: 1, isPreconfigured: false, + isDeprecated: false, config: {}, }, ] @@ -237,6 +241,7 @@ describe('actions_connectors_list component with items', () => { secrets: {}, description: `My test ${index}`, isPreconfigured: false, + isDeprecated: false, referencedByCount: 1, config: {}, })) @@ -472,6 +477,7 @@ describe('actions_connectors_list component with deprecated connectors', () => { description: 'My test', referencedByCount: 1, config: { usesTableApi: true }, + isDeprecated: true, }, { id: '2', @@ -479,6 +485,7 @@ describe('actions_connectors_list component with deprecated connectors', () => { description: 'My test 2', referencedByCount: 1, config: { usesTableApi: true }, + isDeprecated: true, }, ]); loadActionTypes.mockResolvedValueOnce([ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx index 80d1839b231df..a1867bb6362b8 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx @@ -50,7 +50,6 @@ import ConnectorAddFlyout from '../../action_connector_form/connector_add_flyout import { connectorDeprecatedMessage, deprecatedMessage, - checkConnectorIsDeprecated, } from '../../../../common/connectors_selection'; const ConnectorIconTipWithSpacing = withTheme(({ theme }: { theme: EuiTheme }) => { @@ -203,7 +202,7 @@ const ActionsConnectorsList: React.FunctionComponent = () => { * TODO: Remove when connectors can provide their own UX message. * Issue: https://github.com/elastic/kibana/issues/114507 */ - const showDeprecatedTooltip = checkConnectorIsDeprecated(item); + const showDeprecatedTooltip = item.isDeprecated; const name = getConnectorName(value, item); const link = ( @@ -490,7 +489,7 @@ function getActionsCountByActionType(actions: ActionConnector[], actionTypeId: s } function getConnectorName(name: string, connector: ActionConnector): string { - return checkConnectorIsDeprecated(connector) ? `${name} ${deprecatedMessage}` : name; + return connector.isDeprecated ? `${name} ${deprecatedMessage}` : name; } const DeleteOperation: React.FunctionComponent<{ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_flyout/alerts_flyout.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_flyout/alerts_flyout.test.tsx new file mode 100644 index 0000000000000..cbb2ad745a3b2 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_flyout/alerts_flyout.test.tsx @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import { mountWithIntl, nextTick } from '@kbn/test-jest-helpers'; +import { act } from 'react-dom/test-utils'; +import { AlertsFlyout } from './alerts_flyout'; +import { AlertsField } from '../../../../types'; + +const onClose = jest.fn(); +const onPaginateNext = jest.fn(); +const onPaginatePrevious = jest.fn(); +const props = { + alert: { + [AlertsField.name]: ['one'], + [AlertsField.reason]: ['two'], + }, + onClose, + onPaginateNext, + onPaginatePrevious, +}; + +describe('AlertsFlyout', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should render high level details from the alert', async () => { + const wrapper = mountWithIntl(); + await act(async () => { + await nextTick(); + wrapper.update(); + }); + expect(wrapper.find('[data-test-subj="alertsFlyoutTitle"]').first().text()).toBe('one'); + expect(wrapper.find('[data-test-subj="alertsFlyoutReason"]').first().text()).toBe('two'); + }); + + it('should allow pagination', async () => { + const wrapper = mountWithIntl(); + await act(async () => { + await nextTick(); + wrapper.update(); + }); + wrapper.find('[data-test-subj="alertsFlyoutPaginatePrevious"]').first().simulate('click'); + expect(onPaginatePrevious).toHaveBeenCalled(); + wrapper.find('[data-test-subj="alertsFlyoutPaginateNext"]').first().simulate('click'); + expect(onPaginateNext).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_flyout/alerts_flyout.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_flyout/alerts_flyout.tsx new file mode 100644 index 0000000000000..51174ca7b9a80 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_flyout/alerts_flyout.tsx @@ -0,0 +1,95 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import { get } from 'lodash'; +import { i18n } from '@kbn/i18n'; +import { + EuiFlyout, + EuiFlyoutBody, + EuiFlyoutHeader, + EuiSpacer, + EuiTitle, + EuiText, + EuiHorizontalRule, + EuiFlyoutFooter, + EuiFlexGroup, + EuiFlexItem, + EuiButton, +} from '@elastic/eui'; +import { AlertsField, AlertsData } from '../../../../types'; + +const REASON_LABEL = i18n.translate( + 'xpack.triggersActionsUI.sections.alertsTable.alertsFlyout.reason', + { + defaultMessage: 'Reason', + } +); + +const NEXT_LABEL = i18n.translate( + 'xpack.triggersActionsUI.sections.alertsTable.alertsFlyout.next', + { + defaultMessage: 'Next', + } +); +const PREVIOUS_LABEL = i18n.translate( + 'xpack.triggersActionsUI.sections.alertsTable.alertsFlyout.previous', + { + defaultMessage: 'Previous', + } +); + +interface AlertsFlyoutProps { + alert: AlertsData; + onClose: () => void; + onPaginateNext: () => void; + onPaginatePrevious: () => void; +} +export const AlertsFlyout: React.FunctionComponent = ({ + alert, + onClose, + onPaginateNext, + onPaginatePrevious, +}: AlertsFlyoutProps) => { + return ( + + + +

{get(alert, AlertsField.name)}

+
+
+ + +

{REASON_LABEL}

+
+ + + {get(alert, AlertsField.reason)} + + + +
+ + + + + {PREVIOUS_LABEL} + + + + + {NEXT_LABEL} + + + + +
+ ); +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_flyout/index.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_flyout/index.ts new file mode 100644 index 0000000000000..f1f90cc602c58 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_flyout/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { AlertsFlyout } from './alerts_flyout'; +// eslint-disable-next-line import/no-default-export +export default AlertsFlyout; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_page/alerts_page.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_page/alerts_page.tsx index 5d961eaba2455..64f89a570d8b4 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_page/alerts_page.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_page/alerts_page.tsx @@ -7,7 +7,6 @@ import React, { useState, useCallback, useEffect } from 'react'; import { get } from 'lodash'; import { - EuiDataGridCellValueElementProps, EuiDataGridControlColumn, EuiFlexItem, EuiFlexGroup, @@ -25,7 +24,7 @@ import { AbortError } from '@kbn/kibana-utils-plugin/common'; import { PLUGIN_ID } from '../../../../common/constants'; import { AlertsTable } from '../alerts_table'; import { useKibana } from '../../../../common/lib/kibana'; -import { AlertsData } from '../../../../types'; +import { AlertsData, RenderCellValueProps } from '../../../../types'; const consumers = [ AlertConsumers.APM, @@ -142,18 +141,16 @@ const AlertsPage: React.FunctionComponent = () => { deletedEventIds: [], disabledCellActions: [], pageSize: defaultPagination.pageSize, - pageSizeOptions: [2, 5, 10, 20, 50, 100], + pageSizeOptions: [1, 2, 5, 10, 20, 50, 100], leadingControlColumns: [], - renderCellValue: (rcvProps: EuiDataGridCellValueElementProps) => { - const { columnId, visibleRowIndex } = rcvProps as EuiDataGridCellValueElementProps & { - visibleRowIndex: number; - }; - const value = (get(alerts[visibleRowIndex], columnId) ?? [])[0]; + renderCellValue: ({ alert, field }: RenderCellValueProps) => { + const value = get(alert, field, [])[0]; return value ?? 'N/A'; }, showCheckboxes, trailingControlColumns: [], useFetchAlertsData, + alerts, 'data-test-subj': 'internalAlertsPage', }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.scss b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.scss new file mode 100644 index 0000000000000..fa62ba0307bf0 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.scss @@ -0,0 +1,3 @@ +.alertsTableActiveRow { + background-color: tintOrShade($euiColorLightShade, 50%, 0); +} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.test.tsx index 89171f5e06e8d..6aa3c17220668 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { AlertConsumers } from '@kbn/rule-data-utils'; import { AlertsTable } from './alerts_table'; -import { AlertsData } from '../../../types'; +import { AlertsData, AlertsField } from '../../../types'; import { PLUGIN_ID } from '../../../common/constants'; import { useKibana } from '../../../common/lib/kibana'; import { render } from '@testing-library/react'; @@ -50,12 +50,12 @@ describe('AlertsTable', () => { const alerts: AlertsData[] = [ { - field1: ['one'], - field2: ['two'], + [AlertsField.name]: ['one'], + [AlertsField.reason]: ['two'], }, { - field1: ['three'], - field2: ['four'], + [AlertsField.name]: ['three'], + [AlertsField.reason]: ['four'], }, ]; @@ -83,13 +83,14 @@ describe('AlertsTable', () => { deletedEventIds: [], disabledCellActions: [], pageSize: 1, - pageSizeOptions: [1, 2, 5, 10, 20, 50, 100], + pageSizeOptions: [1, 10, 20, 50, 100], leadingControlColumns: [], renderCellValue: jest.fn().mockImplementation((props) => { return `${props.colIndex}:${props.rowIndex}`; }), showCheckboxes: false, trailingControlColumns: [], + alerts, useFetchAlertsData, 'data-test-subj': 'testTable', }; @@ -115,6 +116,73 @@ describe('AlertsTable', () => { userEvent.click(renderResult.getByTestId('pagination-button-1')); expect(fetchAlertsData.onPageChange).toHaveBeenCalledWith({ pageIndex: 1, pageSize: 1 }); }); + + describe('flyout', () => { + it('should show a flyout when selecting an alert', async () => { + const wrapper = render( + + ); + userEvent.click(wrapper.queryByTestId('expandColumnCellOpenFlyoutButton-0')!); + + const result = await wrapper.findAllByTestId('alertsFlyout'); + expect(result.length).toBe(1); + + expect(wrapper.queryByTestId('alertsFlyoutTitle')?.textContent).toBe('one'); + expect(wrapper.queryByTestId('alertsFlyoutReason')?.textContent).toBe('two'); + + // Should paginate too + userEvent.click(wrapper.queryAllByTestId('alertsFlyoutPaginateNext')[0]); + expect(wrapper.queryByTestId('alertsFlyoutTitle')?.textContent).toBe('three'); + expect(wrapper.queryByTestId('alertsFlyoutReason')?.textContent).toBe('four'); + + userEvent.click(wrapper.queryAllByTestId('alertsFlyoutPaginatePrevious')[0]); + expect(wrapper.queryByTestId('alertsFlyoutTitle')?.textContent).toBe('one'); + expect(wrapper.queryByTestId('alertsFlyoutReason')?.textContent).toBe('two'); + }); + + it('should refetch data if flyout pagination exceeds the current page', async () => { + const wrapper = render(); + + userEvent.click(wrapper.queryByTestId('expandColumnCellOpenFlyoutButton-0')!); + const result = await wrapper.findAllByTestId('alertsFlyout'); + expect(result.length).toBe(1); + + userEvent.click(wrapper.queryAllByTestId('alertsFlyoutPaginateNext')[0]); + expect(fetchAlertsData.onPageChange).toHaveBeenCalledWith({ pageIndex: 1, pageSize: 1 }); + + userEvent.click(wrapper.queryAllByTestId('alertsFlyoutPaginatePrevious')[0]); + expect(fetchAlertsData.onPageChange).toHaveBeenCalledWith({ pageIndex: 0, pageSize: 1 }); + }); + }); + + describe('leading control columns', () => { + it('should return at least the flyout action control', async () => { + const wrapper = render(); + expect(wrapper.getByTestId('expandColumnHeaderLabel').textContent).toBe('Actions'); + }); + + it('should render other leading controls', () => { + const customTableProps = { + ...tableProps, + leadingControlColumns: [ + { + id: 'selection', + width: 67, + headerCellRender: () => Test header, + rowCellRender: () =>

Test cell

, + }, + ], + }; + const wrapper = render(); + expect(wrapper.queryByTestId('testHeader')).not.toBe(null); + expect(wrapper.queryByTestId('testCell')).not.toBe(null); + }); + }); }); describe('Alerts table configuration registry', () => { @@ -127,7 +195,7 @@ describe('AlertsTable', () => { it('should render an empty error state when the plugin id owner is not registered', async () => { const props = { ...tableProps, configurationId: 'none' }; const result = render(); - expect(result.getByTestId('alerts-table-no-configuration')).toBeTruthy(); + expect(result.getByTestId('alertsTableNoConfiguration')).toBeTruthy(); }); }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx index 4b0a7ef6e0e16..da05b4c175bdd 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx @@ -4,12 +4,33 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React, { useState } from 'react'; -import { EuiDataGrid, EuiEmptyPrompt } from '@elastic/eui'; + +import React, { useState, Suspense, lazy, useCallback, useMemo, useEffect } from 'react'; +import { + EuiDataGrid, + EuiEmptyPrompt, + EuiDataGridCellValueElementProps, + EuiDataGridCellValueProps, + EuiFlexGroup, + EuiFlexItem, + EuiToolTip, + EuiButtonIcon, + EuiDataGridStyle, +} from '@elastic/eui'; import { useSorting, usePagination } from './hooks'; -import { AlertsTableProps } from '../../../types'; +import { AlertsTableProps, AlertsField } from '../../../types'; import { useKibana } from '../../../common/lib/kibana'; -import { ALERTS_TABLE_CONF_ERROR_MESSAGE, ALERTS_TABLE_CONF_ERROR_TITLE } from './translations'; +import { + ALERTS_TABLE_CONF_ERROR_MESSAGE, + ALERTS_TABLE_CONF_ERROR_TITLE, + ALERTS_TABLE_CONTROL_COLUMNS_ACTIONS_LABEL, + ALERTS_TABLE_CONTROL_COLUMNS_VIEW_DETAILS_LABEL, +} from './translations'; +import './alerts_table.scss'; + +export const ACTIVE_ROW_CLASS = 'alertsTableActiveRow'; + +const AlertsFlyout = lazy(() => import('./alerts_flyout')); const emptyConfiguration = { id: '', @@ -17,17 +38,26 @@ const emptyConfiguration = { }; const AlertsTable: React.FunctionComponent = (props: AlertsTableProps) => { + const [rowClasses, setRowClasses] = useState({}); const { activePage, alertsCount, onPageChange, onSortChange } = props.useFetchAlertsData(); const { sortingColumns, onSort } = useSorting(onSortChange); - const { pagination, onChangePageSize, onChangePageIndex } = usePagination({ + const { + pagination, + onChangePageSize, + onChangePageIndex, + onPaginateFlyoutNext, + onPaginateFlyoutPrevious, + flyoutAlertIndex, + setFlyoutAlertIndex, + } = usePagination({ onPageChange, pageIndex: activePage, pageSize: props.pageSize, + alertsCount, }); const alertsTableConfigurationRegistry = useKibana().services.alertsTableConfigurationRegistry; const hasAlertsTableConfiguration = alertsTableConfigurationRegistry.has(props.configurationId); - const alertsTableConfiguration = hasAlertsTableConfiguration ? alertsTableConfigurationRegistry.get(props.configurationId) : emptyConfiguration; @@ -36,15 +66,86 @@ const AlertsTable: React.FunctionComponent = (props: AlertsTab alertsTableConfiguration.columns.map(({ id }) => id) ); + const leadingControlColumns = useMemo(() => { + return [ + { + id: 'expandColumn', + width: 50, + headerCellRender: () => { + return ( + + {ALERTS_TABLE_CONTROL_COLUMNS_ACTIONS_LABEL} + + ); + }, + rowCellRender: (cveProps: EuiDataGridCellValueElementProps) => { + const { visibleRowIndex } = cveProps as EuiDataGridCellValueElementProps & { + visibleRowIndex: number; + }; + return ( + + + + { + setFlyoutAlertIndex(visibleRowIndex); + }} + data-test-subj={`expandColumnCellOpenFlyoutButton-${visibleRowIndex}`} + aria-label={ALERTS_TABLE_CONTROL_COLUMNS_VIEW_DETAILS_LABEL} + /> + + + + ); + }, + }, + ...props.leadingControlColumns, + ]; + }, [props.leadingControlColumns, setFlyoutAlertIndex]); + + useEffect(() => { + // Row classes do not deal with visible row indices so we need to handle page offset + const rowIndex = flyoutAlertIndex + pagination.pageIndex * pagination.pageSize; + setRowClasses({ + [rowIndex]: ACTIVE_ROW_CLASS, + }); + }, [flyoutAlertIndex, pagination.pageIndex, pagination.pageSize]); + + const handleFlyoutClose = useCallback(() => setFlyoutAlertIndex(-1), [setFlyoutAlertIndex]); + return hasAlertsTableConfiguration ? (
+ {flyoutAlertIndex > -1 && ( + + + + )} { + const rcvProps = improper as EuiDataGridCellValueElementProps & EuiDataGridCellValueProps; + const alert = props.alerts[rcvProps.visibleRowIndex]; + return props.renderCellValue({ + ...rcvProps, + alert, + field: rcvProps.columnId as AlertsField, + }); + }} + gridStyle={{ rowClasses }} sorting={{ columns: sortingColumns, onSort }} pagination={{ ...pagination, @@ -56,7 +157,7 @@ const AlertsTable: React.FunctionComponent = (props: AlertsTab
) : ( {ALERTS_TABLE_CONF_ERROR_TITLE}

} body={

{ALERTS_TABLE_CONF_ERROR_MESSAGE}

} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_pagination.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_pagination.test.ts index 8b8ff68f106c2..6073d907f161d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_pagination.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_pagination.test.ts @@ -11,20 +11,25 @@ describe('usePagination', () => { const onPageChange = jest.fn(); const pageIndex = 0; const pageSize = 10; + const alertsCount = 5; beforeEach(() => { onPageChange.mockClear(); }); it('should return the pagination information and callback functions', () => { - const { result } = renderHook(() => usePagination({ onPageChange, pageIndex, pageSize })); + const { result } = renderHook(() => + usePagination({ onPageChange, pageIndex, pageSize, alertsCount }) + ); expect(result.current.pagination).toStrictEqual({ pageIndex, pageSize }); expect(result.current.onChangePageSize).toBeDefined(); expect(result.current.onChangePageIndex).toBeDefined(); }); it('should change the pagination when `onChangePageSize` is called', () => { - const { result } = renderHook(() => usePagination({ onPageChange, pageIndex, pageSize })); + const { result } = renderHook(() => + usePagination({ onPageChange, pageIndex, pageSize, alertsCount }) + ); act(() => { result.current.onChangePageSize(20); @@ -34,7 +39,9 @@ describe('usePagination', () => { }); it('should change the pagination when `onChangePageIndex` is called', () => { - const { result } = renderHook(() => usePagination({ onPageChange, pageIndex, pageSize })); + const { result } = renderHook(() => + usePagination({ onPageChange, pageIndex, pageSize, alertsCount }) + ); act(() => { result.current.onChangePageIndex(1); @@ -42,4 +49,66 @@ describe('usePagination', () => { expect(result.current.pagination).toStrictEqual({ pageIndex: 1, pageSize }); }); + + it('should paginate the alert flyout', () => { + const { result } = renderHook(() => + usePagination({ onPageChange, pageIndex, pageSize, alertsCount }) + ); + + expect(result.current.flyoutAlertIndex).toBe(-1); + + act(() => { + result.current.onPaginateFlyoutNext(); + }); + + expect(result.current.flyoutAlertIndex).toBe(0); + + act(() => { + result.current.onPaginateFlyoutNext(); + }); + + expect(result.current.flyoutAlertIndex).toBe(1); + + act(() => { + result.current.onPaginateFlyoutPrevious(); + }); + + expect(result.current.flyoutAlertIndex).toBe(0); + }); + + it('should paginate the flyout when we need to change the page index', () => { + const { result } = renderHook(() => + usePagination({ onPageChange, pageIndex: 0, pageSize: 1, alertsCount }) + ); + + act(() => { + result.current.onPaginateFlyoutPrevious(); + }); + + // It should reset to the first alert in the table + expect(result.current.flyoutAlertIndex).toBe(0); + + // It should go to the last page + expect(result.current.pagination).toStrictEqual({ pageIndex: 4, pageSize: 1 }); + + act(() => { + result.current.onPaginateFlyoutNext(); + }); + + // It should reset to the first alert in the table + expect(result.current.flyoutAlertIndex).toBe(0); + + // It should go to the first page + expect(result.current.pagination).toStrictEqual({ pageIndex: 0, pageSize: 1 }); + + act(() => { + result.current.onPaginateFlyoutNext(); + }); + + // It should reset to the first alert in the table + expect(result.current.flyoutAlertIndex).toBe(0); + + // It should go to the second page + expect(result.current.pagination).toStrictEqual({ pageIndex: 1, pageSize: 1 }); + }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_pagination.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_pagination.ts index 7c78636559d38..484775d9877dd 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_pagination.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_pagination.ts @@ -9,13 +9,15 @@ import { RuleRegistrySearchRequestPagination } from '@kbn/rule-registry-plugin/c type PaginationProps = RuleRegistrySearchRequestPagination & { onPageChange: (pagination: RuleRegistrySearchRequestPagination) => void; + alertsCount: number; }; -export function usePagination({ onPageChange, pageIndex, pageSize }: PaginationProps) { +export function usePagination({ onPageChange, pageIndex, pageSize, alertsCount }: PaginationProps) { const [pagination, setPagination] = useState({ pageIndex, pageSize, }); + const [flyoutAlertIndex, setFlyoutAlertIndex] = useState(-1); const onChangePageSize = useCallback( (_pageSize) => { setPagination((state) => ({ @@ -34,5 +36,42 @@ export function usePagination({ onPageChange, pageIndex, pageSize }: PaginationP }, [setPagination, onPageChange, pagination.pageSize] ); - return { pagination, onChangePageSize, onChangePageIndex }; + + const paginateFlyout = useCallback( + (newFlyoutAlertIndex: number) => { + const lastPage = Math.floor(alertsCount / pagination.pageSize) - 1; + if (newFlyoutAlertIndex < 0) { + setFlyoutAlertIndex(pagination.pageSize - 1); + onChangePageIndex(pagination.pageIndex === 0 ? lastPage : pagination.pageIndex - 1); + return; + } + + if (newFlyoutAlertIndex >= pagination.pageSize) { + setFlyoutAlertIndex(0); + onChangePageIndex( + pagination.pageIndex === lastPage ? 0 : Math.min(pagination.pageIndex + 1, lastPage) + ); + return; + } + + setFlyoutAlertIndex(newFlyoutAlertIndex); + }, + [pagination, alertsCount, onChangePageIndex] + ); + const onPaginateFlyoutNext = useCallback(() => { + paginateFlyout(flyoutAlertIndex + 1); + }, [paginateFlyout, flyoutAlertIndex]); + const onPaginateFlyoutPrevious = useCallback(() => { + paginateFlyout(flyoutAlertIndex - 1); + }, [paginateFlyout, flyoutAlertIndex]); + + return { + pagination, + onChangePageSize, + onChangePageIndex, + onPaginateFlyoutNext, + onPaginateFlyoutPrevious, + flyoutAlertIndex, + setFlyoutAlertIndex, + }; } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/translations.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/translations.ts index 5bd6b09db427a..b1e916840bfce 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/translations.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/translations.ts @@ -20,3 +20,17 @@ export const ALERTS_TABLE_CONF_ERROR_MESSAGE = i18n.translate( 'There was an error loading the alerts table. This table is missing the necessary configuration. Please contact your administrator for help', } ); + +export const ALERTS_TABLE_CONTROL_COLUMNS_ACTIONS_LABEL = i18n.translate( + 'xpack.triggersActionsUI.sections.alertsTable.column.actions', + { + defaultMessage: 'Actions', + } +); + +export const ALERTS_TABLE_CONTROL_COLUMNS_VIEW_DETAILS_LABEL = i18n.translate( + 'xpack.triggersActionsUI.sections.alertsTable.leadingControl.viewDetails', + { + defaultMessage: 'View details', + } +); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/execution_duration_chart.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/execution_duration_chart.tsx index 08fabc3fba2fd..140dae9dc14a5 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/execution_duration_chart.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/execution_duration_chart.tsx @@ -38,7 +38,7 @@ const NUM_EXECUTIONS_OPTIONS = [120, 60, 30, 15].map((value) => ({ text: i18n.translate( 'xpack.triggersActionsUI.sections.executionDurationChart.numberOfExecutionsOption', { - defaultMessage: '{value} executions', + defaultMessage: '{value} runs', values: { value, }, @@ -70,7 +70,7 @@ export const ExecutionDurationChart: React.FunctionComponent = ({

@@ -84,7 +84,7 @@ export const ExecutionDurationChart: React.FunctionComponent = ({ aria-label={i18n.translate( 'xpack.triggersActionsUI.sections.executionDurationChart.selectNumberOfExecutionDurationsLabel', { - defaultMessage: 'Select number of executions', + defaultMessage: 'Select number of runs', } )} onChange={onChange} @@ -161,7 +161,7 @@ export const ExecutionDurationChart: React.FunctionComponent = ({

diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/index.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/index.tsx index 0aaa3195b7c52..e41c2a73a5124 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/index.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/index.tsx @@ -32,3 +32,9 @@ export const ActionForm = suspendedComponentWithProps( export const RuleStatusDropdown = suspendedComponentWithProps( lazy(() => import('./rules_list/components/rule_status_dropdown')) ); +export const RuleStatusFilter = suspendedComponentWithProps( + lazy(() => import('./rules_list/components/rule_status_filter')) +); +export const RuleTagBadge = suspendedComponentWithProps( + lazy(() => import('./rules_list/components/rule_tag_badge')) +); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule.tsx index b70eaf20a051d..9d62fc2f8e37a 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule.tsx @@ -33,7 +33,7 @@ import { withBulkRuleOperations, } from '../../common/components/with_bulk_rule_api_operations'; import './rule.scss'; -import { getHealthColor } from '../../rules_list/components/rule_status_filter'; +import { getHealthColor } from '../../rules_list/components/rule_execution_status_filter'; import { rulesStatusesTranslationsMapping, ALERT_STATUS_LICENSE_ERROR, @@ -122,7 +122,7 @@ export function RuleComponent({ { id: EVENT_LOG_LIST_TAB, name: i18n.translate('xpack.triggersActionsUI.sections.ruleDetails.rule.eventLogTabText', { - defaultMessage: 'Execution history', + defaultMessage: 'Run history', }), 'data-test-subj': 'eventLogListTab', content: suspendedComponentWithProps( diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_details.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_details.test.tsx index b41af16ccab47..fe17dde8c1282 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_details.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_details.test.tsx @@ -685,6 +685,7 @@ describe('broken connector indicator', () => { name: 'Test connector', config: {}, isPreconfigured: false, + isDeprecated: false, }, { secrets: {}, @@ -694,6 +695,7 @@ describe('broken connector indicator', () => { name: 'Test connector 2', config: {}, isPreconfigured: false, + isDeprecated: false, }, ]); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.test.tsx index f64a3c011187a..cf6a1350d389d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.test.tsx @@ -11,10 +11,12 @@ import { ReactWrapper } from 'enzyme'; import { act } from 'react-dom/test-utils'; import { actionTypeRegistryMock } from '../../action_type_registry.mock'; import { ruleTypeRegistryMock } from '../../rule_type_registry.mock'; +import { ActionForm } from '../action_connector_form'; import { ValidationResult, Rule, RuleType, + RuleTypeModel, ConnectorValidationResult, GenericValidationResult, } from '../../../types'; @@ -30,6 +32,12 @@ jest.mock('../../hooks/use_load_rule_types', () => ({ useLoadRuleTypes: jest.fn(), })); jest.mock('../../../common/lib/kibana'); +jest.mock('../../lib/capabilities', () => ({ + hasAllPrivilege: jest.fn(() => true), + hasSaveRulesCapability: jest.fn(() => true), + hasShowActionsCapability: jest.fn(() => true), + hasExecuteActionsCapability: jest.fn(() => true), +})); describe('rule_form', () => { const ruleType = { @@ -91,6 +99,144 @@ describe('rule_form', () => { const useKibanaMock = useKibana as jest.Mocked; + describe('rule recovery message', () => { + let wrapper: ReactWrapper; + const defaultRecoveryMessage = 'Sample default recovery message'; + + async function setup(enforceMinimum = false, schedule = '1m') { + const mocks = coreMock.createSetup(); + const { useLoadRuleTypes } = jest.requireMock('../../hooks/use_load_rule_types'); + const myRuleModel = { + id: 'my-rule-type', + description: 'Sample rule type model', + iconClass: 'sampleIconClass', + defaultActionMessage: 'Sample default action message', + defaultRecoveryMessage, + requiresAppContext: false, + }; + const myRule = { + id: 'my-rule-type', + name: 'Test', + actionGroups: [ + { + id: 'testActionGroup', + name: 'Test Action Group', + }, + { + id: 'recovered', + name: 'Recovered', + }, + ], + defaultActionGroupId: 'testActionGroup', + minimumLicenseRequired: 'basic', + recoveryActionGroup: RecoveredActionGroup, + producer: ALERTS_FEATURE_ID, + authorizedConsumers: { + [ALERTS_FEATURE_ID]: { read: true, all: true }, + test: { read: true, all: true }, + }, + actionVariables: { + params: [], + state: [], + }, + enabledInLicense: true, + }; + const disabledByLicenseRule = { + id: 'disabled-by-license', + name: 'Test', + actionGroups: [ + { + id: 'testActionGroup', + name: 'Test Action Group', + }, + ], + defaultActionGroupId: 'testActionGroup', + minimumLicenseRequired: 'gold', + recoveryActionGroup: RecoveredActionGroup, + producer: ALERTS_FEATURE_ID, + authorizedConsumers: { + [ALERTS_FEATURE_ID]: { read: true, all: true }, + test: { read: true, all: true }, + }, + actionVariables: { + params: [], + state: [], + }, + enabledInLicense: false, + }; + useLoadRuleTypes.mockReturnValue({ + ruleTypes: [myRule, disabledByLicenseRule], + ruleTypeIndex: new Map([ + [myRule.id, myRule], + [disabledByLicenseRule.id, disabledByLicenseRule], + ]), + }); + const [ + { + application: { capabilities }, + }, + ] = await mocks.getStartServices(); + // eslint-disable-next-line react-hooks/rules-of-hooks + useKibanaMock().services.application.capabilities = { + ...capabilities, + rules: { + show: true, + save: true, + delete: true, + }, + }; + ruleTypeRegistry.list.mockReturnValue([ + ruleType, + ruleTypeNonEditable, + disabledByLicenseRuleType, + ]); + ruleTypeRegistry.has.mockReturnValue(true); + ruleTypeRegistry.get.mockReturnValue(myRuleModel as RuleTypeModel); + actionTypeRegistry.list.mockReturnValue([actionType]); + actionTypeRegistry.has.mockReturnValue(true); + actionTypeRegistry.get.mockReturnValue(actionType); + const initialRule = { + name: 'test', + params: {}, + consumer: ALERTS_FEATURE_ID, + schedule: { + interval: schedule, + }, + actions: [], + tags: [], + muteAll: false, + enabled: false, + mutedInstanceIds: [], + ruleTypeId: 'my-rule-type', + } as unknown as Rule; + + wrapper = mountWithIntl( + {}} + errors={{ name: [], 'schedule.interval': [], ruleTypeId: [], actionConnectors: [] }} + operation="create" + actionTypeRegistry={actionTypeRegistry} + ruleTypeRegistry={ruleTypeRegistry} + /> + ); + + await act(async () => { + await nextTick(); + wrapper.update(); + }); + } + + it('renders defaultRecoveryMessage for recovery action when specified', async () => { + await setup(); + const actionForm = wrapper.find(ActionForm); + expect(actionForm.first().prop('actionGroups')?.[1]).toEqual( + expect.objectContaining({ defaultActionMessage: defaultRecoveryMessage }) + ); + }); + }); + describe('rule_form create rule', () => { let wrapper: ReactWrapper; @@ -282,7 +428,6 @@ describe('rule_form', () => { async function setup() { const { useLoadRuleTypes } = jest.requireMock('../../hooks/use_load_rule_types'); - useLoadRuleTypes.mockReturnValue({ ruleTypes: [ { @@ -384,7 +529,7 @@ describe('rule_form', () => { rule={initialRule} config={{ minimumScheduleInterval: { value: '1m', enforce: false } }} dispatch={() => {}} - errors={{ name: [], 'schedule.interval': [], ruleTypeId: [] }} + errors={{ name: [], 'schedule.interval': [], ruleTypeId: [], actionConnectors: [] }} operation="create" actionTypeRegistry={actionTypeRegistry} ruleTypeRegistry={ruleTypeRegistry} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx index 80923617da064..1bca80a08c936 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx @@ -488,7 +488,7 @@ export const RuleForm = ({ > )} @@ -560,7 +560,8 @@ export const RuleForm = ({ omitMessageVariables: selectedRuleType.doesSetRecoveryContext ? 'keepContext' : 'all', - defaultActionMessage: recoveredActionGroupMessage, + defaultActionMessage: + ruleTypeModel?.defaultRecoveryMessage || recoveredActionGroupMessage, } : { ...actionGroup, defaultActionMessage: ruleTypeModel?.defaultActionMessage } )} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_execution_status_filter.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_execution_status_filter.tsx new file mode 100644 index 0000000000000..9acb8489fa09a --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_execution_status_filter.tsx @@ -0,0 +1,107 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useEffect, useState } from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { + EuiFilterGroup, + EuiPopover, + EuiFilterButton, + EuiFilterSelectItem, + EuiHealth, +} from '@elastic/eui'; +import { RuleExecutionStatuses, RuleExecutionStatusValues } from '@kbn/alerting-plugin/common'; +import { rulesStatusesTranslationsMapping } from '../translations'; + +interface RuleExecutionStatusFilterProps { + selectedStatuses: string[]; + onChange?: (selectedRuleStatusesIds: string[]) => void; +} + +export const RuleExecutionStatusFilter: React.FunctionComponent = ({ + selectedStatuses, + onChange, +}: RuleExecutionStatusFilterProps) => { + const [selectedValues, setSelectedValues] = useState(selectedStatuses); + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + + useEffect(() => { + if (onChange) { + onChange(selectedValues); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [selectedValues]); + + useEffect(() => { + setSelectedValues(selectedStatuses); + }, [selectedStatuses]); + + return ( + + setIsPopoverOpen(false)} + button={ + 0} + numActiveFilters={selectedValues.length} + numFilters={selectedValues.length} + onClick={() => setIsPopoverOpen(!isPopoverOpen)} + data-test-subj="ruleExecutionStatusFilterButton" + > + + + } + > +
+ {[...RuleExecutionStatusValues].sort().map((item: RuleExecutionStatuses) => { + const healthColor = getHealthColor(item); + return ( + { + const isPreviouslyChecked = selectedValues.includes(item); + if (isPreviouslyChecked) { + setSelectedValues(selectedValues.filter((val) => val !== item)); + } else { + setSelectedValues(selectedValues.concat(item)); + } + }} + checked={selectedValues.includes(item) ? 'on' : undefined} + data-test-subj={`ruleExecutionStatus${item}FilterOption`} + > + {rulesStatusesTranslationsMapping[item]} + + ); + })} +
+
+
+ ); +}; + +export function getHealthColor(status: RuleExecutionStatuses) { + switch (status) { + case 'active': + return 'success'; + case 'error': + return 'danger'; + case 'ok': + return 'primary'; + case 'pending': + return 'accent'; + case 'warning': + return 'warning'; + default: + return 'subdued'; + } +} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_status_filter.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_status_filter.test.tsx new file mode 100644 index 0000000000000..f1f2957f9cada --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_status_filter.test.tsx @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { mountWithIntl } from '@kbn/test-jest-helpers'; +import { EuiFilterButton, EuiFilterSelectItem } from '@elastic/eui'; +import { RuleStatusFilter } from './rule_status_filter'; + +const onChangeMock = jest.fn(); + +describe('rule_state_filter', () => { + beforeEach(() => { + onChangeMock.mockReset(); + }); + + it('renders correctly', () => { + const wrapper = mountWithIntl( + + ); + + expect(wrapper.find(EuiFilterSelectItem).exists()).toBeFalsy(); + expect(wrapper.find(EuiFilterButton).exists()).toBeTruthy(); + + expect(wrapper.find('.euiNotificationBadge').text()).toEqual('0'); + }); + + it('can open the popover correctly', () => { + const wrapper = mountWithIntl( + + ); + + expect(wrapper.find('[data-test-subj="ruleStateFilterSelect"]').exists()).toBeFalsy(); + + wrapper.find(EuiFilterButton).simulate('click'); + + const statusItems = wrapper.find(EuiFilterSelectItem); + expect(statusItems.length).toEqual(3); + }); + + it('can select statuses', () => { + const wrapper = mountWithIntl( + + ); + + wrapper.find(EuiFilterButton).simulate('click'); + + wrapper.find(EuiFilterSelectItem).at(0).simulate('click'); + expect(onChangeMock).toHaveBeenCalledWith(['enabled']); + + wrapper.setProps({ + selectedStatuses: ['enabled'], + }); + + wrapper.find(EuiFilterSelectItem).at(0).simulate('click'); + expect(onChangeMock).toHaveBeenCalledWith([]); + + wrapper.find(EuiFilterSelectItem).at(1).simulate('click'); + expect(onChangeMock).toHaveBeenCalledWith(['enabled', 'disabled']); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_status_filter.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_status_filter.tsx index cbb1a7f5455da..6d286ec6d09d7 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_status_filter.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_status_filter.tsx @@ -4,82 +4,87 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - -import React, { useEffect, useState } from 'react'; +import React, { useState, useCallback } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; -import { - EuiFilterGroup, - EuiPopover, - EuiFilterButton, - EuiFilterSelectItem, - EuiHealth, -} from '@elastic/eui'; -import { RuleExecutionStatuses, RuleExecutionStatusValues } from '@kbn/alerting-plugin/common'; -import { rulesStatusesTranslationsMapping } from '../translations'; +import { EuiFilterButton, EuiPopover, EuiFilterGroup, EuiFilterSelectItem } from '@elastic/eui'; +import { RuleStatus } from '../../../../types'; + +const statuses: RuleStatus[] = ['enabled', 'disabled', 'snoozed']; + +const optionStyles = { + textTransform: 'capitalize' as const, +}; -interface RuleStatusFilterProps { - selectedStatuses: string[]; - onChange?: (selectedRuleStatusesIds: string[]) => void; +const getOptionDataTestSubj = (status: RuleStatus) => `ruleStatusFilterOption-${status}`; + +export interface RuleStatusFilterProps { + selectedStatuses: RuleStatus[]; + dataTestSubj?: string; + selectDataTestSubj?: string; + buttonDataTestSubj?: string; + optionDataTestSubj?: (status: RuleStatus) => string; + onChange: (selectedStatuses: RuleStatus[]) => void; } -export const RuleStatusFilter: React.FunctionComponent = ({ - selectedStatuses, - onChange, -}: RuleStatusFilterProps) => { - const [selectedValues, setSelectedValues] = useState(selectedStatuses); +export const RuleStatusFilter = (props: RuleStatusFilterProps) => { + const { + selectedStatuses = [], + dataTestSubj = 'ruleStatusFilter', + selectDataTestSubj = 'ruleStatusFilterSelect', + buttonDataTestSubj = 'ruleStatusFilterButton', + optionDataTestSubj = getOptionDataTestSubj, + onChange = () => {}, + } = props; + const [isPopoverOpen, setIsPopoverOpen] = useState(false); - useEffect(() => { - if (onChange) { - onChange(selectedValues); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [selectedValues]); + const onFilterItemClick = useCallback( + (newOption: RuleStatus) => () => { + if (selectedStatuses.includes(newOption)) { + onChange(selectedStatuses.filter((option) => option !== newOption)); + return; + } + onChange([...selectedStatuses, newOption]); + }, + [selectedStatuses, onChange] + ); - useEffect(() => { - setSelectedValues(selectedStatuses); - }, [selectedStatuses]); + const onClick = useCallback(() => { + setIsPopoverOpen((prevIsOpen) => !prevIsOpen); + }, [setIsPopoverOpen]); return ( - + setIsPopoverOpen(false)} button={ 0} - numActiveFilters={selectedValues.length} - numFilters={selectedValues.length} - onClick={() => setIsPopoverOpen(!isPopoverOpen)} - data-test-subj="ruleStatusFilterButton" + hasActiveFilters={selectedStatuses.length > 0} + numActiveFilters={selectedStatuses.length} + numFilters={selectedStatuses.length} + onClick={onClick} > } > -
- {[...RuleExecutionStatusValues].sort().map((item: RuleExecutionStatuses) => { - const healthColor = getHealthColor(item); +
+ {statuses.map((status) => { return ( { - const isPreviouslyChecked = selectedValues.includes(item); - if (isPreviouslyChecked) { - setSelectedValues(selectedValues.filter((val) => val !== item)); - } else { - setSelectedValues(selectedValues.concat(item)); - } - }} - checked={selectedValues.includes(item) ? 'on' : undefined} - data-test-subj={`ruleStatus${item}FilerOption`} + key={status} + style={optionStyles} + data-test-subj={optionDataTestSubj(status)} + onClick={onFilterItemClick(status)} + checked={selectedStatuses.includes(status) ? 'on' : undefined} > - {rulesStatusesTranslationsMapping[item]} + {status} ); })} @@ -89,19 +94,5 @@ export const RuleStatusFilter: React.FunctionComponent = ); }; -export function getHealthColor(status: RuleExecutionStatuses) { - switch (status) { - case 'active': - return 'success'; - case 'error': - return 'danger'; - case 'ok': - return 'primary'; - case 'pending': - return 'accent'; - case 'warning': - return 'warning'; - default: - return 'subdued'; - } -} +// eslint-disable-next-line import/no-default-export +export { RuleStatusFilter as default }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_tag_badge.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_tag_badge.test.tsx new file mode 100644 index 0000000000000..606d60ff6bfeb --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_tag_badge.test.tsx @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { mountWithIntl } from '@kbn/test-jest-helpers'; +import { RuleTagBadge } from './rule_tag_badge'; + +const onClickMock = jest.fn(); +const onCloseMock = jest.fn(); + +const tags = ['a', 'b', 'c']; + +describe('RuleTagBadge', () => { + beforeEach(() => { + onClickMock.mockReset(); + onCloseMock.mockReset(); + }); + + it('renders the initial badge count correctly', () => { + const wrapper = mountWithIntl( + + ); + + expect(wrapper.find('[data-test-subj="ruleTagBadge"]').exists()).toBeTruthy(); + expect(wrapper.find('[data-test-subj="ruleTagBadge"]').first().text()).toEqual( + `${tags.length}` + ); + }); + + it('can open and close the popover', () => { + const wrapper = mountWithIntl( + + ); + + expect(wrapper.find('[data-test-subj="ruleTagBadgeItem-a"]').exists()).toBeFalsy(); + expect(wrapper.find('[data-test-subj="ruleTagBadgeItem-b"]').exists()).toBeFalsy(); + expect(wrapper.find('[data-test-subj="ruleTagBadgeItem-c"]').exists()).toBeFalsy(); + + wrapper.find('[data-test-subj="ruleTagBadge"]').at(1).simulate('click'); + + expect(onClickMock).toHaveBeenCalledTimes(1); + + wrapper.setProps({ + isOpen: true, + }); + + expect(wrapper.find('[data-test-subj="ruleTagBadgeItem-a"]').exists()).toBeTruthy(); + expect(wrapper.find('[data-test-subj="ruleTagBadgeItem-b"]').exists()).toBeTruthy(); + expect(wrapper.find('[data-test-subj="ruleTagBadgeItem-c"]').exists()).toBeTruthy(); + + wrapper.find('[data-test-subj="ruleTagBadge"]').at(1).simulate('click'); + + expect(onClickMock).toHaveBeenCalledTimes(2); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_tag_badge.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_tag_badge.tsx new file mode 100644 index 0000000000000..c7da398d14403 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_tag_badge.tsx @@ -0,0 +1,89 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useMemo } from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiPopover, EuiBadge, EuiPopoverTitle } from '@elastic/eui'; + +const tagTitle = i18n.translate( + 'xpack.triggersActionsUI.sections.rules_list.rules_tag_badge.tagTitle', + { + defaultMessage: 'Tag', + } +); + +export interface RuleTagBadgeProps { + isOpen: boolean; + tags: string[]; + onClick: React.MouseEventHandler; + onClose: () => void; + badgeDataTestSubj?: string; + titleDataTestSubj?: string; + tagItemDataTestSubj?: (tag: string) => string; +} + +const containerStyle = { + width: '300px', +}; + +const getTagItemDataTestSubj = (tag: string) => `ruleTagBadgeItem-${tag}`; + +export const RuleTagBadge = (props: RuleTagBadgeProps) => { + const { + isOpen = false, + tags = [], + onClick, + onClose, + badgeDataTestSubj = 'ruleTagBadge', + titleDataTestSubj = 'ruleTagPopoverTitle', + tagItemDataTestSubj = getTagItemDataTestSubj, + } = props; + + const badge = useMemo(() => { + return ( + + {tags.length} + + ); + }, [tags, badgeDataTestSubj, onClick]); + + const tagBadges = useMemo( + () => + tags.map((tag, index) => ( + + {tag} + + )), + [tags, tagItemDataTestSubj] + ); + + return ( + + {tagTitle} +
{tagBadges}
+
+ ); +}; + +// eslint-disable-next-line import/no-default-export +export { RuleTagBadge as default }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.test.tsx index f87cee4c6547f..52c6e2d3ed149 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.test.tsx @@ -20,6 +20,7 @@ import { parseDuration, } from '@kbn/alerting-plugin/common'; import { getFormattedDuration, getFormattedMilliseconds } from '../../../lib/monitoring_utils'; +import { getIsExperimentalFeatureEnabled } from '../../../../common/get_experimental_features'; import { useKibana } from '../../../../common/lib/kibana'; jest.mock('../../../../common/lib/kibana'); @@ -59,6 +60,9 @@ jest.mock('../../../lib/capabilities', () => ({ hasShowActionsCapability: jest.fn(() => true), hasExecuteActionsCapability: jest.fn(() => true), })); +jest.mock('../../../../common/get_experimental_features', () => ({ + getIsExperimentalFeatureEnabled: jest.fn(), +})); const { loadRules, loadRuleTypes, loadRuleAggregations } = jest.requireMock('../../../lib/rule_api'); const { loadActionTypes, loadAllActions } = jest.requireMock('../../../lib/action_connector_api'); @@ -95,6 +99,10 @@ ruleTypeRegistry.list.mockReturnValue([ruleType]); actionTypeRegistry.list.mockReturnValue([]); const useKibanaMock = useKibana as jest.Mocked; +beforeEach(() => { + (getIsExperimentalFeatureEnabled as jest.Mock).mockImplementation(() => false); +}); + describe('rules_list component empty', () => { let wrapper: ReactWrapper; async function setup() { @@ -439,7 +447,7 @@ describe('rules_list component with items', () => { wrapper.find('EuiTableRowCell[data-test-subj="rulesTableCell-tagsPopover"]').length ).toEqual(mockedRulesData.length); // only show tags popover if tags exist on rule - const tagsBadges = wrapper.find('EuiBadge[data-test-subj="ruleTagsBadge"]'); + const tagsBadges = wrapper.find('EuiBadge[data-test-subj="ruleTagBadge"]'); expect(tagsBadges.length).toEqual( mockedRulesData.filter((data) => data.tags.length > 0).length ); @@ -459,7 +467,7 @@ describe('rules_list component with items', () => { jest.runAllTimers(); wrapper.update(); - expect(wrapper.find('.euiToolTipPopover').text()).toBe('Start time of the last execution.'); + expect(wrapper.find('.euiToolTipPopover').text()).toBe('Start time of the last run.'); wrapper .find('[data-test-subj="rulesTableCell-lastExecutionDateTooltip"]') @@ -801,6 +809,39 @@ describe('rules_list component with items', () => { 'Warning: 6' ); }); + + it('does not render the status filter if the feature flag is off', async () => { + await setup(); + expect(wrapper.find('[data-test-subj="ruleStatusFilter"]').exists()).toBeFalsy(); + }); + + it('renders the status filter if the experiment is on', async () => { + (getIsExperimentalFeatureEnabled as jest.Mock).mockImplementation(() => true); + await setup(); + expect(wrapper.find('[data-test-subj="ruleStatusFilter"]').exists()).toBeTruthy(); + }); + + it('can filter by rule states', async () => { + (getIsExperimentalFeatureEnabled as jest.Mock).mockImplementation(() => true); + loadRules.mockReset(); + await setup(); + + expect(loadRules.mock.calls[0][0].ruleStatusesFilter).toEqual([]); + + wrapper.find('[data-test-subj="ruleStatusFilterButton"] button').simulate('click'); + + wrapper.find('[data-test-subj="ruleStatusFilterOption-enabled"]').first().simulate('click'); + + expect(loadRules.mock.calls[1][0].ruleStatusesFilter).toEqual(['enabled']); + + wrapper.find('[data-test-subj="ruleStatusFilterOption-snoozed"]').first().simulate('click'); + + expect(loadRules.mock.calls[2][0].ruleStatusesFilter).toEqual(['enabled', 'snoozed']); + + wrapper.find('[data-test-subj="ruleStatusFilterOption-snoozed"]').first().simulate('click'); + + expect(loadRules.mock.calls[3][0].ruleStatusesFilter).toEqual(['enabled']); + }); }); describe('rules_list component empty with show only capability', () => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx index 59515ca3c3622..b1255600b68de 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx @@ -14,7 +14,6 @@ import { FormattedMessage } from '@kbn/i18n-react'; import React, { useEffect, useState, useMemo, ReactNode, useCallback } from 'react'; import { EuiBasicTable, - EuiBadge, EuiButton, EuiFieldSearch, EuiFlexGroup, @@ -30,8 +29,6 @@ import { EuiTableSortingType, EuiButtonIcon, EuiHorizontalRule, - EuiPopover, - EuiPopoverTitle, EuiSelectableOption, EuiIcon, EuiScreenReaderOnly, @@ -61,6 +58,7 @@ import { RuleTableItem, RuleType, RuleTypeIndex, + RuleStatus, Pagination, Percentiles, TriggersActionsUiConfig, @@ -71,7 +69,7 @@ import { RuleQuickEditButtonsWithApi as RuleQuickEditButtons } from '../../commo import { CollapsedItemActionsWithApi as CollapsedItemActions } from './collapsed_item_actions'; import { TypeFilter } from './type_filter'; import { ActionTypeFilter } from './action_type_filter'; -import { RuleStatusFilter, getHealthColor } from './rule_status_filter'; +import { RuleExecutionStatusFilter, getHealthColor } from './rule_execution_status_filter'; import { loadRules, loadRuleAggregations, @@ -95,11 +93,14 @@ import { CenterJustifiedSpinner } from '../../../components/center_justified_spi import { ManageLicenseModal } from './manage_license_modal'; import { checkRuleTypeEnabled } from '../../../lib/check_rule_type_enabled'; import { RuleStatusDropdown } from './rule_status_dropdown'; +import { RuleTagBadge } from './rule_tag_badge'; import { PercentileSelectablePopover } from './percentile_selectable_popover'; import { RuleDurationFormat } from './rule_duration_format'; import { shouldShowDurationWarning } from '../../../lib/execution_duration_utils'; import { getFormattedSuccessRatio } from '../../../lib/monitoring_utils'; import { triggersActionsUiConfig } from '../../../../common/lib/config_api'; +import { RuleStatusFilter } from './rule_status_filter'; +import { getIsExperimentalFeatureEnabled } from '../../../../common/get_experimental_features'; const ENTER_KEY = 13; @@ -155,7 +156,8 @@ export const RulesList: React.FunctionComponent = () => { const [inputText, setInputText] = useState(); const [typesFilter, setTypesFilter] = useState([]); const [actionTypesFilter, setActionTypesFilter] = useState([]); - const [ruleStatusesFilter, setRuleStatusesFilter] = useState([]); + const [ruleExecutionStatusesFilter, setRuleExecutionStatusesFilter] = useState([]); + const [ruleStatusesFilter, setRuleStatusesFilter] = useState([]); const [ruleFlyoutVisible, setRuleFlyoutVisibility] = useState(false); const [editFlyoutVisible, setEditFlyoutVisibility] = useState(false); const [currentRuleToEdit, setCurrentRuleToEdit] = useState(null); @@ -165,6 +167,8 @@ export const RulesList: React.FunctionComponent = () => { ); const [showErrors, setShowErrors] = useState(false); + const isRuleStatusFilterEnabled = getIsExperimentalFeatureEnabled('ruleStatusFilter'); + useEffect(() => { (async () => { setConfig(await triggersActionsUiConfig({ http })); @@ -227,6 +231,7 @@ export const RulesList: React.FunctionComponent = () => { percentileOptions, JSON.stringify(typesFilter), JSON.stringify(actionTypesFilter), + JSON.stringify(ruleExecutionStatusesFilter), JSON.stringify(ruleStatusesFilter), ]); @@ -286,6 +291,7 @@ export const RulesList: React.FunctionComponent = () => { searchText, typesFilter, actionTypesFilter, + ruleExecutionStatusesFilter, ruleStatusesFilter, sort, }); @@ -304,6 +310,7 @@ export const RulesList: React.FunctionComponent = () => { isEmpty(searchText) && isEmpty(typesFilter) && isEmpty(actionTypesFilter) && + isEmpty(ruleExecutionStatusesFilter) && isEmpty(ruleStatusesFilter) ); @@ -330,6 +337,7 @@ export const RulesList: React.FunctionComponent = () => { searchText, typesFilter, actionTypesFilter, + ruleExecutionStatusesFilter, ruleStatusesFilter, }); if (rulesAggs?.ruleExecutionStatus) { @@ -420,7 +428,7 @@ export const RulesList: React.FunctionComponent = () => { content={i18n.translate( 'xpack.triggersActionsUI.sections.rulesList.rulesListTable.columns.ruleExecutionPercentileTooltip', { - defaultMessage: `{percentileOrdinal} percentile of this rule's past {sampleLimit} execution durations (mm:ss).`, + defaultMessage: `{percentileOrdinal} percentile of this rule's past {sampleLimit} run durations (mm:ss).`, values: { percentileOrdinal: percentileOrdinals[selectedPercentile!], sampleLimit: MONITORING_HISTORY_LIMIT, @@ -590,40 +598,12 @@ export const RulesList: React.FunctionComponent = () => { 'data-test-subj': 'rulesTableCell-tagsPopover', render: (tags: string[], item: RuleTableItem) => { return tags.length > 0 ? ( - setTagPopoverOpenIndex(item.index)} - onClickAriaLabel="Tags" - iconOnClick={() => setTagPopoverOpenIndex(item.index)} - iconOnClickAriaLabel="Tags" - > - {tags.length} - - } - anchorPosition="upCenter" + setTagPopoverOpenIndex(-1)} - > - Tags -
- {tags.map((tag: string, index: number) => ( - - {tag} - - ))} - + tags={tags} + onClick={() => setTagPopoverOpenIndex(item.index)} + onClose={() => setTagPopoverOpenIndex(-1)} + /> ) : null; }, }, @@ -635,7 +615,7 @@ export const RulesList: React.FunctionComponent = () => { content={i18n.translate( 'xpack.triggersActionsUI.sections.rulesList.rulesListTable.columns.lastExecutionDateTitle', { - defaultMessage: 'Start time of the last execution.', + defaultMessage: 'Start time of the last run.', } )} > @@ -791,7 +771,7 @@ export const RulesList: React.FunctionComponent = () => { content={i18n.translate( 'xpack.triggersActionsUI.sections.rulesList.rulesListTable.columns.successRatioTitle', { - defaultMessage: 'How often this rule executes successfully.', + defaultMessage: 'How often this rule runs successfully.', } )} > @@ -960,6 +940,15 @@ export const RulesList: React.FunctionComponent = () => { ); }; + const getRuleStatusFilter = () => { + if (isRuleStatusFilterEnabled) { + return [ + , + ]; + } + return []; + }; + const toolsRight = [ { }) )} />, + ...getRuleStatusFilter(), setActionTypesFilter(ids)} />, - setRuleStatusesFilter(ids)} + selectedStatuses={ruleExecutionStatusesFilter} + onChange={(ids: string[]) => setRuleExecutionStatusesFilter(ids)} />, { }} />   - setRuleStatusesFilter(['error'])}> + setRuleExecutionStatusesFilter(['error'])}> { - describe('checkConnectorIsDeprecated', () => { - const connector = { - id: 'test', - actionTypeId: '.webhook', - name: 'Test', - config: { apiUrl: 'http://example.com', usesTableApi: false }, - secrets: { username: 'test', password: 'test' }, - isPreconfigured: false as const, - }; - - it('returns false if the connector is not defined', () => { - expect(checkConnectorIsDeprecated()).toBe(false); - }); - - it('returns false if the connector is not ITSM or SecOps', () => { - expect(checkConnectorIsDeprecated(connector)).toBe(false); - }); - - it('returns false if the connector is .servicenow and the usesTableApi=false', () => { - expect(checkConnectorIsDeprecated({ ...connector, actionTypeId: '.servicenow' })).toBe(false); - }); - - it('returns false if the connector is .servicenow-sir and the usesTableApi=false', () => { - expect(checkConnectorIsDeprecated({ ...connector, actionTypeId: '.servicenow-sir' })).toBe( - false - ); - }); - - it('returns true if the connector is .servicenow and the usesTableApi=true', () => { - expect( - checkConnectorIsDeprecated({ - ...connector, - actionTypeId: '.servicenow', - config: { ...connector.config, usesTableApi: true }, - }) - ).toBe(true); - }); - - it('returns true if the connector is .servicenow-sir and the usesTableApi=true', () => { - expect( - checkConnectorIsDeprecated({ - ...connector, - actionTypeId: '.servicenow-sir', - config: { ...connector.config, usesTableApi: true }, - }) - ).toBe(true); - }); - }); -}); diff --git a/x-pack/plugins/triggers_actions_ui/public/common/connectors_selection.tsx b/x-pack/plugins/triggers_actions_ui/public/common/connectors_selection.tsx index 334a10c95e112..555b2d4c6b71d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/connectors_selection.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/common/connectors_selection.tsx @@ -6,8 +6,6 @@ */ import { i18n } from '@kbn/i18n'; -import { ServiceNowActionConnector } from '../application/components/builtin_action_types/servicenow/types'; -import { ActionConnector, UserConfiguredActionConnector } from '../types'; export const preconfiguredMessage = i18n.translate( 'xpack.triggersActionsUI.sections.actionForm.preconfiguredTitleMessage', @@ -27,44 +25,3 @@ export const connectorDeprecatedMessage = i18n.translate( 'xpack.triggersActionsUI.sections.isDeprecatedDescription', { defaultMessage: 'This connector is deprecated. Update it, or create a new one.' } ); - -export const checkConnectorIsDeprecated = ( - connector?: ActionConnector | ServiceNowActionConnector -): boolean => { - if (connector == null) { - return false; - } - - if ( - isConnectorWithConfig(connector) && - (connector.actionTypeId === '.servicenow' || connector.actionTypeId === '.servicenow-sir') - ) { - /** - * Connectors after the Elastic ServiceNow application use the - * Import Set API (https://developer.servicenow.com/dev.do#!/reference/api/rome/rest/c_ImportSetAPI) - * A ServiceNow connector is considered deprecated if it uses the Table API. - * - * All other connectors do not have the usesTableApi config property - * so the function will always return false for them. - */ - return !!connector.config.usesTableApi; - } - - return false; -}; - -type ConnectorWithUnknownConfig = UserConfiguredActionConnector< - Record, - Record ->; - -const isConnectorWithConfig = ( - connector: ActionConnector | ServiceNowActionConnector -): connector is ConnectorWithUnknownConfig => { - const unsafeConnector = connector as UserConfiguredActionConnector< - Record, - Record - >; - - return unsafeConnector.config != null; -}; diff --git a/x-pack/plugins/triggers_actions_ui/public/common/get_experimental_features.test.tsx b/x-pack/plugins/triggers_actions_ui/public/common/get_experimental_features.test.tsx index 237eccb0b4434..acb409d675dde 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/get_experimental_features.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/common/get_experimental_features.test.tsx @@ -18,6 +18,7 @@ describe('getIsExperimentalFeatureEnabled', () => { rulesListDatagrid: true, internalAlertsTable: true, rulesDetailLogs: true, + ruleStatusFilter: true, internalShareableComponentsSandbox: true, }, }); @@ -38,6 +39,10 @@ describe('getIsExperimentalFeatureEnabled', () => { expect(result).toEqual(true); + result = getIsExperimentalFeatureEnabled('ruleStatusFilter'); + + expect(result).toEqual(true); + expect(() => getIsExperimentalFeatureEnabled('doesNotExist' as any)).toThrowError( `Invalid enable value doesNotExist. Allowed values are: ${allowedExperimentalValueKeys.join( ', ' diff --git a/x-pack/plugins/triggers_actions_ui/public/common/get_rule_status_filter.tsx b/x-pack/plugins/triggers_actions_ui/public/common/get_rule_status_filter.tsx new file mode 100644 index 0000000000000..77ac3fc51d703 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/common/get_rule_status_filter.tsx @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { RuleStatusFilter } from '../application/sections'; +import type { RuleStatusFilterProps } from '../application/sections/rules_list/components/rule_status_filter'; + +export const getRuleStatusFilterLazy = (props: RuleStatusFilterProps) => { + return ; +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/common/get_rule_tag_badge.tsx b/x-pack/plugins/triggers_actions_ui/public/common/get_rule_tag_badge.tsx new file mode 100644 index 0000000000000..dc889402ab3c5 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/common/get_rule_tag_badge.tsx @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { RuleTagBadge } from '../application/sections'; +import type { RuleTagBadgeProps } from '../application/sections/rules_list/components/rule_tag_badge'; + +export const getRuleTagBadgeLazy = (props: RuleTagBadgeProps) => { + return ; +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/common/types.ts b/x-pack/plugins/triggers_actions_ui/public/common/types.ts index 4aca07ad5482e..610962706661a 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/common/types.ts @@ -24,3 +24,5 @@ export interface GroupByType { value: string; validNormalizedTypes: string[]; } + +export type { RuleStatus } from '../types'; diff --git a/x-pack/plugins/triggers_actions_ui/public/index.ts b/x-pack/plugins/triggers_actions_ui/public/index.ts index 94fe718363e2b..1e109b96ae5c9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/index.ts @@ -30,6 +30,7 @@ export type { RuleTypeParams, AsApiContract, RuleTableItem, + AlertsTableConfigurationRegistryContract, } from './types'; export { diff --git a/x-pack/plugins/triggers_actions_ui/public/mocks.ts b/x-pack/plugins/triggers_actions_ui/public/mocks.ts index 79edc1f08ac97..cb79a1509a6c1 100644 --- a/x-pack/plugins/triggers_actions_ui/public/mocks.ts +++ b/x-pack/plugins/triggers_actions_ui/public/mocks.ts @@ -5,13 +5,14 @@ * 2.0. */ +import type { ValidatedEmail } from '@kbn/actions-plugin/common'; import type { TriggersAndActionsUIPublicPluginStart } from './plugin'; import { getAddConnectorFlyoutLazy } from './common/get_add_connector_flyout'; import { getEditConnectorFlyoutLazy } from './common/get_edit_connector_flyout'; import { getAddAlertFlyoutLazy } from './common/get_add_alert_flyout'; import { getEditAlertFlyoutLazy } from './common/get_edit_alert_flyout'; - +import { RegistrationServices } from './application/components/builtin_action_types'; import { TypeRegistry } from './application/type_registry'; import { ActionTypeModel, @@ -25,6 +26,8 @@ import { } from './types'; import { getAlertsTableLazy } from './common/get_alerts_table'; import { getRuleStatusDropdownLazy } from './common/get_rule_status_dropdown'; +import { getRuleStatusFilterLazy } from './common/get_rule_status_filter'; +import { getRuleTagBadgeLazy } from './common/get_rule_tag_badge'; function createStartMock(): TriggersAndActionsUIPublicPluginStart { const actionTypeRegistry = new TypeRegistry(); @@ -63,9 +66,21 @@ function createStartMock(): TriggersAndActionsUIPublicPluginStart { getRuleStatusDropdown: (props) => { return getRuleStatusDropdownLazy(props); }, + getRuleStatusFilter: (props) => { + return getRuleStatusFilterLazy(props); + }, + getRuleTagBadge: (props) => { + return getRuleTagBadgeLazy(props); + }, }; } export const triggersActionsUiMock = { createStart: createStartMock, }; + +function validateEmailAddresses(addresses: string[]): ValidatedEmail[] { + return addresses.map((address) => ({ address, valid: true })); +} + +export const registrationServicesMock: RegistrationServices = { validateEmailAddresses }; diff --git a/x-pack/plugins/triggers_actions_ui/public/plugin.ts b/x-pack/plugins/triggers_actions_ui/public/plugin.ts index ba2e869c82e0f..1d9c3c07e44ca 100644 --- a/x-pack/plugins/triggers_actions_ui/public/plugin.ts +++ b/x-pack/plugins/triggers_actions_ui/public/plugin.ts @@ -16,6 +16,7 @@ import { ManagementAppMountParams, ManagementSetup } from '@kbn/management-plugi import type { HomePublicPluginSetup } from '@kbn/home-plugin/public'; import { ChartsPluginStart } from '@kbn/charts-plugin/public'; import { PluginStartContract as AlertingStart } from '@kbn/alerting-plugin/public'; +import { ActionsPublicPluginSetup } from '@kbn/actions-plugin/public'; import { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import { Storage } from '@kbn/kibana-utils-plugin/public'; @@ -30,6 +31,8 @@ import { getAddAlertFlyoutLazy } from './common/get_add_alert_flyout'; import { getEditAlertFlyoutLazy } from './common/get_edit_alert_flyout'; import { getAlertsTableLazy } from './common/get_alerts_table'; import { getRuleStatusDropdownLazy } from './common/get_rule_status_dropdown'; +import { getRuleStatusFilterLazy } from './common/get_rule_status_filter'; +import { getRuleTagBadgeLazy } from './common/get_rule_tag_badge'; import { ExperimentalFeaturesService } from './common/experimental_features_service'; import { ExperimentalFeatures, @@ -45,6 +48,8 @@ import type { ConnectorEditFlyoutProps, AlertsTableProps, RuleStatusDropdownProps, + RuleStatusFilterProps, + RuleTagBadgeProps, AlertsTableConfigurationRegistry, } from './types'; import { TriggersActionsUiConfigType } from '../common/types'; @@ -75,12 +80,15 @@ export interface TriggersAndActionsUIPublicPluginStart { ) => ReactElement; getAlertsTable: (props: AlertsTableProps) => ReactElement; getRuleStatusDropdown: (props: RuleStatusDropdownProps) => ReactElement; + getRuleStatusFilter: (props: RuleStatusFilterProps) => ReactElement; + getRuleTagBadge: (props: RuleTagBadgeProps) => ReactElement; } interface PluginsSetup { management: ManagementSetup; home?: HomePublicPluginSetup; cloud?: { isCloudEnabled: boolean }; + actions: ActionsPublicPluginSetup; } interface PluginsStart { @@ -193,6 +201,9 @@ export class Plugin registerBuiltInActionTypes({ actionTypeRegistry: this.actionTypeRegistry, + services: { + validateEmailAddresses: plugins.actions.validateEmailAddresses, + }, }); if (this.experimentalFeatures.internalAlertsTable) { @@ -244,6 +255,12 @@ export class Plugin getRuleStatusDropdown: (props: RuleStatusDropdownProps) => { return getRuleStatusDropdownLazy(props); }, + getRuleStatusFilter: (props: RuleStatusFilterProps) => { + return getRuleStatusFilterLazy(props); + }, + getRuleTagBadge: (props: RuleTagBadgeProps) => { + return getRuleTagBadgeLazy(props); + }, }; } diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index 2d4268252a353..25efbfb6ecc38 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -48,6 +48,8 @@ import { import { RuleRegistrySearchRequestPagination } from '@kbn/rule-registry-plugin/common'; import { TypeRegistry } from './application/type_registry'; import type { ComponentOpts as RuleStatusDropdownProps } from './application/sections/rules_list/components/rule_status_dropdown'; +import type { RuleStatusFilterProps } from './application/sections/rules_list/components/rule_status_filter'; +import type { RuleTagBadgeProps } from './application/sections/rules_list/components/rule_tag_badge'; // In Triggers and Actions we treat all `Alert`s as `SanitizedRule` // so the `Params` is a black-box of Record @@ -80,6 +82,8 @@ export type { ResolvedRule, SanitizedRule, RuleStatusDropdownProps, + RuleStatusFilterProps, + RuleTagBadgeProps, }; export type { ActionType, AsApiContract }; export { @@ -195,6 +199,7 @@ export interface ActionConnectorProps { referencedByCount?: number; config: Config; isPreconfigured: boolean; + isDeprecated: boolean; isMissingSecrets?: boolean; } @@ -303,6 +308,7 @@ export interface RuleTypeModel { | React.LazyExoticComponent>>; requiresAppContext: boolean; defaultActionMessage?: string; + defaultRecoveryMessage?: string; } export interface IErrorObject { @@ -372,7 +378,12 @@ export interface TriggersActionsUiConfig { }; } -export type AlertsData = Record; +export enum AlertsField { + name = 'kibana.alert.rule.name', + reason = 'kibana.alert.reason', +} + +export type AlertsData = Record; export interface FetchAlertData { activePage: number; @@ -403,14 +414,22 @@ export interface AlertsTableProps { pageSize: number; pageSizeOptions: number[]; leadingControlColumns: EuiDataGridControlColumn[]; - renderCellValue: (props: EuiDataGridCellValueElementProps) => React.ReactNode; + renderCellValue: (props: RenderCellValueProps) => React.ReactNode; showCheckboxes: boolean; trailingControlColumns: EuiDataGridControlColumn[]; useFetchAlertsData: () => FetchAlertData; + alerts: AlertsData[]; 'data-test-subj': string; } +export type RenderCellValueProps = EuiDataGridCellValueElementProps & { + alert: AlertsData; + field: AlertsField; +}; + export interface AlertsTableConfigurationRegistry { id: string; columns: EuiDataGridColumn[]; } + +export type RuleStatus = 'enabled' | 'disabled' | 'snoozed'; diff --git a/x-pack/plugins/triggers_actions_ui/server/data/routes/fields.ts b/x-pack/plugins/triggers_actions_ui/server/data/routes/fields.ts index 3cd8d8e81e252..e2e9b5967305d 100644 --- a/x-pack/plugins/triggers_actions_ui/server/data/routes/fields.ts +++ b/x-pack/plugins/triggers_actions_ui/server/data/routes/fields.ts @@ -34,6 +34,7 @@ export function createFieldsRoute(logger: Logger, router: IRouter, baseRoute: st }, handler ); + async function handler( ctx: RequestHandlerContext, req: KibanaRequest, @@ -49,10 +50,8 @@ export function createFieldsRoute(logger: Logger, router: IRouter, baseRoute: st } try { - rawFields = await getRawFields( - ctx.core.elasticsearch.client.asCurrentUser, - req.body.indexPatterns - ); + const esClient = (await ctx.core).elasticsearch.client.asCurrentUser; + rawFields = await getRawFields(esClient, req.body.indexPatterns); } catch (err) { const indexPatterns = req.body.indexPatterns.join(','); logger.warn( diff --git a/x-pack/plugins/triggers_actions_ui/server/data/routes/indices.ts b/x-pack/plugins/triggers_actions_ui/server/data/routes/indices.ts index b32c80aa6f0b4..3fdee6f23b39b 100644 --- a/x-pack/plugins/triggers_actions_ui/server/data/routes/indices.ts +++ b/x-pack/plugins/triggers_actions_ui/server/data/routes/indices.ts @@ -45,6 +45,7 @@ export function createIndicesRoute(logger: Logger, router: IRouter, baseRoute: s res: KibanaResponseFactory ): Promise { const pattern = req.body.pattern; + const esClient = (await ctx.core).elasticsearch.client.asCurrentUser; logger.debug(`route ${path} request: ${JSON.stringify(req.body)}`); if (pattern.trim() === '') { @@ -53,14 +54,14 @@ export function createIndicesRoute(logger: Logger, router: IRouter, baseRoute: s let aliases: string[] = []; try { - aliases = await getAliasesFromPattern(ctx.core.elasticsearch.client.asCurrentUser, pattern); + aliases = await getAliasesFromPattern(esClient, pattern); } catch (err) { logger.warn(`route ${path} error getting aliases from pattern "${pattern}": ${err.message}`); } let indices: string[] = []; try { - indices = await getIndicesFromPattern(ctx.core.elasticsearch.client.asCurrentUser, pattern); + indices = await getIndicesFromPattern(esClient, pattern); } catch (err) { logger.warn(`route ${path} error getting indices from pattern "${pattern}": ${err.message}`); } diff --git a/x-pack/plugins/triggers_actions_ui/server/data/routes/time_series_query.ts b/x-pack/plugins/triggers_actions_ui/server/data/routes/time_series_query.ts index 1273351795f87..1fb7f2217d11b 100644 --- a/x-pack/plugins/triggers_actions_ui/server/data/routes/time_series_query.ts +++ b/x-pack/plugins/triggers_actions_ui/server/data/routes/time_series_query.ts @@ -41,9 +41,10 @@ export function createTimeSeriesQueryRoute( ): Promise { logger.debug(`route ${path} request: ${JSON.stringify(req.body)}`); + const esClient = (await ctx.core).elasticsearch.client.asCurrentUser; const result = await timeSeriesQuery({ logger, - esClient: ctx.core.elasticsearch.client.asCurrentUser, + esClient, query: req.body, }); diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.test.ts index 72c71a8a21c8e..d1df5f8e31170 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.test.ts @@ -104,7 +104,10 @@ describe('EsVersionPrecheck', () => { ctx.core.elasticsearch.client.asInternalUser.nodes.info.mockRejectedValue({ statusCode: 403 }); - const result = await esVersionCheck(ctx, kibanaResponseFactory); + const result = await esVersionCheck( + coreMock.createCustomRequestHandlerContext(ctx), + kibanaResponseFactory + ); expect(result).toHaveProperty('status', 403); }); @@ -120,7 +123,10 @@ describe('EsVersionPrecheck', () => { }, }); - const result = await esVersionCheck(ctx, kibanaResponseFactory); + const result = await esVersionCheck( + coreMock.createCustomRequestHandlerContext(ctx), + kibanaResponseFactory + ); expect(result).toHaveProperty('status', 426); expect(result).toHaveProperty('payload.attributes.allNodesUpgraded', false); }); @@ -137,7 +143,10 @@ describe('EsVersionPrecheck', () => { }, }); - const result = await esVersionCheck(ctx, kibanaResponseFactory); + const result = await esVersionCheck( + coreMock.createCustomRequestHandlerContext(ctx), + kibanaResponseFactory + ); expect(result).toHaveProperty('status', 426); expect(result).toHaveProperty('payload.attributes.allNodesUpgraded', true); }); @@ -154,6 +163,8 @@ describe('EsVersionPrecheck', () => { }, }); - await expect(esVersionCheck(ctx, kibanaResponseFactory)).resolves.toBe(undefined); + await expect( + esVersionCheck(coreMock.createCustomRequestHandlerContext(ctx), kibanaResponseFactory) + ).resolves.toBe(undefined); }); }); diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.ts index 699f40a65bae1..2e85cbaf73a94 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.ts @@ -65,7 +65,7 @@ export const esVersionCheck = async ( ctx: RequestHandlerContext, response: KibanaResponseFactory ) => { - const { client } = ctx.core.elasticsearch; + const { client } = (await ctx.core).elasticsearch; let allNodeVersions: SemVer[]; try { diff --git a/x-pack/plugins/upgrade_assistant/server/routes/__mocks__/routes.mock.ts b/x-pack/plugins/upgrade_assistant/server/routes/__mocks__/routes.mock.ts index 9fb35b838d81d..172b1d53474d4 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/__mocks__/routes.mock.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/__mocks__/routes.mock.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { AwaitedProperties } from '@kbn/utility-types'; import { RequestHandler, RequestHandlerContext } from '@kbn/core/server'; import { elasticsearchServiceMock, @@ -20,7 +21,7 @@ export const routeHandlerContextMock = { savedObjects: { client: savedObjectsClientMock.create() }, deprecations: { client: deprecationsServiceMock.createClient() }, }, -} as unknown as RequestHandlerContext; +} as unknown as AwaitedProperties; /** * Creates a very crude mock of the new platform router implementation. This enables use to test diff --git a/x-pack/plugins/upgrade_assistant/server/routes/app.ts b/x-pack/plugins/upgrade_assistant/server/routes/app.ts index b976811a87e5b..2193d69cca255 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/app.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/app.ts @@ -30,50 +30,43 @@ export function registerAppRoutes({ path: `${API_BASE_PATH}/privileges`, validate: false, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, + versionCheckHandlerWrapper(async ({ core }, request, response) => { + const { + elasticsearch: { client }, + } = await core; + const privilegesResult: Privileges = { + hasAllPrivileges: true, + missingPrivileges: { + index: [], }, - request, - response - ) => { - const privilegesResult: Privileges = { - hasAllPrivileges: true, - missingPrivileges: { - index: [], - }, - }; + }; - if (!isSecurityEnabled()) { - return response.ok({ body: privilegesResult }); - } - - try { - const { has_all_requested: hasAllPrivileges, index } = - await client.asCurrentUser.security.hasPrivileges({ - body: { - index: [ - { - names: [DEPRECATION_LOGS_INDEX], - privileges: ['read'], - }, - ], - }, - }); + if (!isSecurityEnabled()) { + return response.ok({ body: privilegesResult }); + } - if (!hasAllPrivileges) { - privilegesResult.missingPrivileges.index = extractMissingPrivileges(index); - } + try { + const { has_all_requested: hasAllPrivileges, index } = + await client.asCurrentUser.security.hasPrivileges({ + body: { + index: [ + { + names: [DEPRECATION_LOGS_INDEX], + privileges: ['read'], + }, + ], + }, + }); - privilegesResult.hasAllPrivileges = hasAllPrivileges; - return response.ok({ body: privilegesResult }); - } catch (error) { - return handleEsError({ error, response }); + if (!hasAllPrivileges) { + privilegesResult.missingPrivileges.index = extractMissingPrivileges(index); } + + privilegesResult.hasAllPrivileges = hasAllPrivileges; + return response.ok({ body: privilegesResult }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/cloud_backup_status.ts b/x-pack/plugins/upgrade_assistant/server/routes/cloud_backup_status.ts index 6dffead8ec91f..17b80f6a685b3 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/cloud_backup_status.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/cloud_backup_status.ts @@ -17,7 +17,7 @@ export function registerCloudBackupStatusRoutes({ router.get( { path: `${API_BASE_PATH}/cloud_backup_status`, validate: false }, versionCheckHandlerWrapper(async (context, request, response) => { - const { client: clusterClient } = context.core.elasticsearch; + const { client: clusterClient } = (await context.core).elasticsearch; try { const { snapshots } = await clusterClient.asCurrentUser.snapshot.get({ diff --git a/x-pack/plugins/upgrade_assistant/server/routes/cluster_settings.ts b/x-pack/plugins/upgrade_assistant/server/routes/cluster_settings.ts index f64c3a383781f..d85123ab3e7d6 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/cluster_settings.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/cluster_settings.ts @@ -23,59 +23,52 @@ export function registerClusterSettingsRoute({ }), }, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - const { settings } = request.body; - - // We need to fetch the current cluster settings in order to determine - // if the settings to delete were set as transient or persistent settings - const currentClusterSettings = await client.asCurrentUser.cluster.getSettings({ - flat_settings: true, - }); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client }, + } = await core; + const { settings } = request.body; - const settingsToDelete = settings.reduce( - (settingsBody, currentSetting) => { - if ( - Object.keys(currentClusterSettings.persistent).find((key) => key === currentSetting) - ) { - settingsBody.persistent[currentSetting] = null; - } + // We need to fetch the current cluster settings in order to determine + // if the settings to delete were set as transient or persistent settings + const currentClusterSettings = await client.asCurrentUser.cluster.getSettings({ + flat_settings: true, + }); - if ( - Object.keys(currentClusterSettings.transient).find((key) => key === currentSetting) - ) { - settingsBody.transient[currentSetting] = null; - } + const settingsToDelete = settings.reduce( + (settingsBody, currentSetting) => { + if ( + Object.keys(currentClusterSettings.persistent).find((key) => key === currentSetting) + ) { + settingsBody.persistent[currentSetting] = null; + } - return settingsBody; - }, - { persistent: {}, transient: {} } as { - persistent: { [key: string]: null }; - transient: { [key: string]: null }; + if ( + Object.keys(currentClusterSettings.transient).find((key) => key === currentSetting) + ) { + settingsBody.transient[currentSetting] = null; } - ); - const settingsResponse = await client.asCurrentUser.cluster.putSettings({ - body: settingsToDelete, - flat_settings: true, - }); + return settingsBody; + }, + { persistent: {}, transient: {} } as { + persistent: { [key: string]: null }; + transient: { [key: string]: null }; + } + ); + + const settingsResponse = await client.asCurrentUser.cluster.putSettings({ + body: settingsToDelete, + flat_settings: true, + }); - return response.ok({ - body: settingsResponse, - }); - } catch (error) { - return handleEsError({ error, response }); - } + return response.ok({ + body: settingsResponse, + }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.ts b/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.ts index 70fd5d035ad52..6770869233ab8 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.ts @@ -30,24 +30,17 @@ export function registerDeprecationLoggingRoutes({ path: `${API_BASE_PATH}/deprecation_logging`, validate: false, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - const result = await getDeprecationLoggingStatus(client); - return response.ok({ body: result }); - } catch (error) { - return handleEsError({ error, response }); - } + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client }, + } = await core; + const result = await getDeprecationLoggingStatus(client); + return response.ok({ body: result }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); router.put( @@ -59,26 +52,19 @@ export function registerDeprecationLoggingRoutes({ }), }, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - const { isEnabled } = request.body as { isEnabled: boolean }; - return response.ok({ - body: await setDeprecationLogging(client, isEnabled), - }); - } catch (error) { - return handleEsError({ error, response }); - } + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client }, + } = await core; + const { isEnabled } = request.body as { isEnabled: boolean }; + return response.ok({ + body: await setDeprecationLogging(client, isEnabled), + }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); router.get( @@ -90,56 +76,49 @@ export function registerDeprecationLoggingRoutes({ }), }, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - const indexExists = await client.asCurrentUser.indices.exists({ - index: DEPRECATION_LOGS_INDEX, - }); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client }, + } = await core; + const indexExists = await client.asCurrentUser.indices.exists({ + index: DEPRECATION_LOGS_INDEX, + }); - if (!indexExists) { - return response.ok({ body: { count: 0 } }); - } + if (!indexExists) { + return response.ok({ body: { count: 0 } }); + } - const now = moment().toISOString(); + const now = moment().toISOString(); - const body = await client.asCurrentUser.count({ - index: DEPRECATION_LOGS_INDEX, - body: { - query: { - bool: { - must: { - range: { - '@timestamp': { - gte: request.query.from, - lte: now, - }, + const body = await client.asCurrentUser.count({ + index: DEPRECATION_LOGS_INDEX, + body: { + query: { + bool: { + must: { + range: { + '@timestamp': { + gte: request.query.from, + lte: now, }, }, - must_not: { - terms: { - [DEPRECATION_LOGS_ORIGIN_FIELD]: [...APPS_WITH_DEPRECATION_LOGS], - }, + }, + must_not: { + terms: { + [DEPRECATION_LOGS_ORIGIN_FIELD]: [...APPS_WITH_DEPRECATION_LOGS], }, }, }, }, - }); + }, + }); - return response.ok({ body: { count: body.count } }); - } catch (error) { - return handleEsError({ error, response }); - } + return response.ok({ body: { count: body.count } }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); router.delete( @@ -147,27 +126,20 @@ export function registerDeprecationLoggingRoutes({ path: `${API_BASE_PATH}/deprecation_logging/cache`, validate: false, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - await client.asCurrentUser.transport.request({ - method: 'DELETE', - path: '/_logging/deprecation_cache', - }); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client }, + } = await core; + await client.asCurrentUser.transport.request({ + method: 'DELETE', + path: '/_logging/deprecation_cache', + }); - return response.ok({ body: 'ok' }); - } catch (error) { - return handleEsError({ error, response }); - } + return response.ok({ body: 'ok' }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/es_deprecations.ts b/x-pack/plugins/upgrade_assistant/server/routes/es_deprecations.ts index 98089e34bdca1..ff04fd694335d 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/es_deprecations.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/es_deprecations.ts @@ -23,41 +23,29 @@ export function registerESDeprecationRoutes({ path: `${API_BASE_PATH}/es_deprecations`, validate: false, }, - versionCheckHandlerWrapper( - async ( - { - core: { - savedObjects: { client: savedObjectsClient }, - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - const status = await getESUpgradeStatus(client); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + savedObjects: { client: savedObjectsClient }, + elasticsearch: { client }, + } = await core; + const status = await getESUpgradeStatus(client); - const asCurrentUser = client.asCurrentUser; - const reindexActions = reindexActionsFactory(savedObjectsClient, asCurrentUser); - const reindexService = reindexServiceFactory( - asCurrentUser, - reindexActions, - log, - licensing - ); - const indexNames = status.deprecations - .filter(({ index }) => typeof index !== 'undefined') - .map(({ index }) => index as string); + const asCurrentUser = client.asCurrentUser; + const reindexActions = reindexActionsFactory(savedObjectsClient, asCurrentUser); + const reindexService = reindexServiceFactory(asCurrentUser, reindexActions, log, licensing); + const indexNames = status.deprecations + .filter(({ index }) => typeof index !== 'undefined') + .map(({ index }) => index as string); - await reindexService.cleanupReindexOperations(indexNames); + await reindexService.cleanupReindexOperations(indexNames); - return response.ok({ - body: status, - }); - } catch (error) { - return handleEsError({ error, response }); - } + return response.ok({ + body: status, + }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/ml_snapshots.ts b/x-pack/plugins/upgrade_assistant/server/routes/ml_snapshots.ts index 45455eee01e10..1698934e0d8a4 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/ml_snapshots.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/ml_snapshots.ts @@ -151,47 +151,40 @@ export function registerMlSnapshotRoutes({ }), }, }, - versionCheckHandlerWrapper( - async ( - { - core: { - savedObjects: { client: savedObjectsClient }, - elasticsearch: { client: esClient }, - }, - }, - request, - response - ) => { - try { - const { snapshotId, jobId } = request.body; - - const body = await esClient.asCurrentUser.ml.upgradeJobSnapshot({ - job_id: jobId, - snapshot_id: snapshotId, - }); - - const snapshotInfo: MlOperation = { - nodeId: body.node, - snapshotId, - jobId, - }; - - // Store snapshot in saved object if upgrade not complete - if (body.completed !== true) { - await createMlOperation(savedObjectsClient, snapshotInfo); - } - - return response.ok({ - body: { - ...snapshotInfo, - status: body.completed === true ? 'complete' : 'in_progress', - }, - }); - } catch (error) { - return handleEsError({ error, response }); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + savedObjects: { client: savedObjectsClient }, + elasticsearch: { client: esClient }, + } = await core; + const { snapshotId, jobId } = request.body; + + const body = await esClient.asCurrentUser.ml.upgradeJobSnapshot({ + job_id: jobId, + snapshot_id: snapshotId, + }); + + const snapshotInfo: MlOperation = { + nodeId: body.node, + snapshotId, + jobId, + }; + + // Store snapshot in saved object if upgrade not complete + if (body.completed !== true) { + await createMlOperation(savedObjectsClient, snapshotInfo); } + + return response.ok({ + body: { + ...snapshotInfo, + status: body.completed === true ? 'complete' : 'in_progress', + }, + }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); // Get the status of the upgrade snapshot task @@ -205,102 +198,67 @@ export function registerMlSnapshotRoutes({ }), }, }, - versionCheckHandlerWrapper( - async ( - { - core: { - savedObjects: { client: savedObjectsClient }, - elasticsearch: { client: esClient }, - }, - }, - request, - response - ) => { - try { - const { snapshotId, jobId } = request.params; - - // Verify snapshot exists - await esClient.asCurrentUser.ml.getModelSnapshots({ - job_id: jobId, - snapshot_id: snapshotId, + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + savedObjects: { client: savedObjectsClient }, + elasticsearch: { client: esClient }, + } = await core; + const { snapshotId, jobId } = request.params; + + // Verify snapshot exists + await esClient.asCurrentUser.ml.getModelSnapshots({ + job_id: jobId, + snapshot_id: snapshotId, + }); + + const foundSnapshots = await findMlOperation(savedObjectsClient, snapshotId); + + // If snapshot is *not* found in SO, assume there has not been an upgrade operation started + if (typeof foundSnapshots === 'undefined' || foundSnapshots.total === 0) { + return response.ok({ + body: { + snapshotId, + jobId, + nodeId: undefined, + status: 'idle', + }, }); + } - const foundSnapshots = await findMlOperation(savedObjectsClient, snapshotId); - - // If snapshot is *not* found in SO, assume there has not been an upgrade operation started - if (typeof foundSnapshots === 'undefined' || foundSnapshots.total === 0) { + const upgradeStatus = await getModelSnapshotUpgradeStatus(esClient, jobId, snapshotId); + // Create snapshotInfo payload to send back in the response + const snapshotOp = foundSnapshots.saved_objects[0]; + const snapshotInfo: MlOperation = { + ...snapshotOp.attributes, + }; + + if (upgradeStatus) { + if ( + upgradeStatus.state === 'loading_old_state' || + upgradeStatus.state === 'saving_new_state' + ) { return response.ok({ body: { - snapshotId, - jobId, - nodeId: undefined, - status: 'idle', + ...snapshotInfo, + status: 'in_progress', + }, + }); + } else if (upgradeStatus.state === 'failed') { + return response.customError({ + statusCode: 500, + body: { + message: i18n.translate( + 'xpack.upgradeAssistant.ml_snapshots.modelSnapshotUpgradeFailed', + { + defaultMessage: + 'The upgrade process for this model snapshot failed. Check the Elasticsearch logs for more details.', + } + ), }, }); - } - - const upgradeStatus = await getModelSnapshotUpgradeStatus(esClient, jobId, snapshotId); - // Create snapshotInfo payload to send back in the response - const snapshotOp = foundSnapshots.saved_objects[0]; - const snapshotInfo: MlOperation = { - ...snapshotOp.attributes, - }; - - if (upgradeStatus) { - if ( - upgradeStatus.state === 'loading_old_state' || - upgradeStatus.state === 'saving_new_state' - ) { - return response.ok({ - body: { - ...snapshotInfo, - status: 'in_progress', - }, - }); - } else if (upgradeStatus.state === 'failed') { - return response.customError({ - statusCode: 500, - body: { - message: i18n.translate( - 'xpack.upgradeAssistant.ml_snapshots.modelSnapshotUpgradeFailed', - { - defaultMessage: - 'The upgrade process for this model snapshot failed. Check the Elasticsearch logs for more details.', - } - ), - }, - }); - } else { - // The task ID was not found; verify the deprecation was resolved - const { isSuccessful: isSnapshotDeprecationResolved, error: upgradeSnapshotError } = - await verifySnapshotUpgrade(esClient, { - snapshotId, - jobId, - }); - - // Delete the SO; if it's complete, no need to store it anymore. If there's an error, this will give the user a chance to retry - await deleteMlOperation(savedObjectsClient, snapshotOp.id); - - if (isSnapshotDeprecationResolved) { - return response.ok({ - body: { - ...snapshotInfo, - status: 'complete', - }, - }); - } - - return response.customError({ - statusCode: upgradeSnapshotError ? upgradeSnapshotError.statusCode! : 500, - body: { - message: - upgradeSnapshotError?.body?.error?.reason || - 'The upgrade process for this model snapshot stopped yet the snapshot is not upgraded. Check the Elasticsearch logs for more details.', - }, - }); - } } else { - // No tasks found; verify the deprecation was resolved + // The task ID was not found; verify the deprecation was resolved const { isSuccessful: isSnapshotDeprecationResolved, error: upgradeSnapshotError } = await verifySnapshotUpgrade(esClient, { snapshotId, @@ -319,23 +277,51 @@ export function registerMlSnapshotRoutes({ }); } - log.error( - `Failed to determine status of the ML model upgrade, upgradeStatus is not defined and snapshot upgrade is not completed. snapshotId=${snapshotId} and jobId=${jobId}` - ); return response.customError({ statusCode: upgradeSnapshotError ? upgradeSnapshotError.statusCode! : 500, body: { message: upgradeSnapshotError?.body?.error?.reason || - 'The upgrade process for this model snapshot completed yet the snapshot is not upgraded. Check the Elasticsearch logs for more details.', + 'The upgrade process for this model snapshot stopped yet the snapshot is not upgraded. Check the Elasticsearch logs for more details.', + }, + }); + } + } else { + // No tasks found; verify the deprecation was resolved + const { isSuccessful: isSnapshotDeprecationResolved, error: upgradeSnapshotError } = + await verifySnapshotUpgrade(esClient, { + snapshotId, + jobId, + }); + + // Delete the SO; if it's complete, no need to store it anymore. If there's an error, this will give the user a chance to retry + await deleteMlOperation(savedObjectsClient, snapshotOp.id); + + if (isSnapshotDeprecationResolved) { + return response.ok({ + body: { + ...snapshotInfo, + status: 'complete', }, }); } - } catch (e) { - return handleEsError({ error: e, response }); + + log.error( + `Failed to determine status of the ML model upgrade, upgradeStatus is not defined and snapshot upgrade is not completed. snapshotId=${snapshotId} and jobId=${jobId}` + ); + return response.customError({ + statusCode: upgradeSnapshotError ? upgradeSnapshotError.statusCode! : 500, + body: { + message: + upgradeSnapshotError?.body?.error?.reason || + 'The upgrade process for this model snapshot completed yet the snapshot is not upgraded. Check the Elasticsearch logs for more details.', + }, + }); } + } catch (e) { + return handleEsError({ error: e, response }); } - ) + }) ); // Get the ml upgrade mode @@ -344,29 +330,22 @@ export function registerMlSnapshotRoutes({ path: `${API_BASE_PATH}/ml_upgrade_mode`, validate: false, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client: esClient }, + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client: esClient }, + } = await core; + const mlInfo = await esClient.asCurrentUser.ml.info(); + + return response.ok({ + body: { + mlUpgradeModeEnabled: mlInfo.upgrade_mode, }, - }, - request, - response - ) => { - try { - const mlInfo = await esClient.asCurrentUser.ml.info(); - - return response.ok({ - body: { - mlUpgradeModeEnabled: mlInfo.upgrade_mode, - }, - }); - } catch (e) { - return handleEsError({ error: e, response }); - } + }); + } catch (e) { + return handleEsError({ error: e, response }); } - ) + }) ); // Delete ML model snapshot @@ -380,31 +359,24 @@ export function registerMlSnapshotRoutes({ }), }, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - const { snapshotId, jobId } = request.params; - - const deleteSnapshotResponse = await client.asCurrentUser.ml.deleteModelSnapshot({ - job_id: jobId, - snapshot_id: snapshotId, - }); - - return response.ok({ - body: deleteSnapshotResponse, - }); - } catch (e) { - return handleEsError({ error: e, response }); - } + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client }, + } = await core; + const { snapshotId, jobId } = request.params; + + const deleteSnapshotResponse = await client.asCurrentUser.ml.deleteModelSnapshot({ + job_id: jobId, + snapshot_id: snapshotId, + }); + + return response.ok({ + body: deleteSnapshotResponse, + }); + } catch (e) { + return handleEsError({ error: e, response }); } - ) + }) ); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/node_disk_space.ts b/x-pack/plugins/upgrade_assistant/server/routes/node_disk_space.ts index 9bd6b39cd6f5e..3707bee0f1395 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/node_disk_space.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/node_disk_space.ts @@ -49,91 +49,84 @@ export function registerNodeDiskSpaceRoute({ router, lib: { handleEsError } }: R path: `${API_BASE_PATH}/node_disk_space`, validate: false, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - const clusterSettings = await client.asCurrentUser.cluster.getSettings({ - flat_settings: true, - include_defaults: true, + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client }, + } = await core; + const clusterSettings = await client.asCurrentUser.cluster.getSettings({ + flat_settings: true, + include_defaults: true, + }); + + const lowDiskWatermarkSetting = getLowDiskWatermarkSetting(clusterSettings); + + if (lowDiskWatermarkSetting) { + const nodeStats = await client.asCurrentUser.nodes.stats({ + metric: 'fs', }); - const lowDiskWatermarkSetting = getLowDiskWatermarkSetting(clusterSettings); + const nodeIds = Object.keys(nodeStats.nodes); - if (lowDiskWatermarkSetting) { - const nodeStats = await client.asCurrentUser.nodes.stats({ - metric: 'fs', - }); + const nodesWithLowDiskSpace: NodeWithLowDiskSpace[] = []; - const nodeIds = Object.keys(nodeStats.nodes); + nodeIds.forEach((nodeId) => { + const node = nodeStats.nodes[nodeId]; + const byteStats = node?.fs?.total; + // @ts-expect-error @elastic/elasticsearch not supported + const { total_in_bytes: totalInBytes, available_in_bytes: availableInBytes } = + byteStats; - const nodesWithLowDiskSpace: NodeWithLowDiskSpace[] = []; + // Regex to determine if the low disk watermark setting is configured as a percentage value + // Elasticsearch accepts a percentage or bytes value + const isLowDiskWatermarkPercentage = /^(\d+|(\.\d+))(\.\d+)?%$/.test( + lowDiskWatermarkSetting! + ); - nodeIds.forEach((nodeId) => { - const node = nodeStats.nodes[nodeId]; - const byteStats = node?.fs?.total; - // @ts-expect-error @elastic/elasticsearch not supported - const { total_in_bytes: totalInBytes, available_in_bytes: availableInBytes } = - byteStats; - - // Regex to determine if the low disk watermark setting is configured as a percentage value - // Elasticsearch accepts a percentage or bytes value - const isLowDiskWatermarkPercentage = /^(\d+|(\.\d+))(\.\d+)?%$/.test( - lowDiskWatermarkSetting! + if (isLowDiskWatermarkPercentage) { + const percentageAvailable = (availableInBytes / totalInBytes) * 100; + const rawLowDiskWatermarkPercentageValue = Number( + lowDiskWatermarkSetting!.replace('%', '') ); - if (isLowDiskWatermarkPercentage) { - const percentageAvailable = (availableInBytes / totalInBytes) * 100; - const rawLowDiskWatermarkPercentageValue = Number( - lowDiskWatermarkSetting!.replace('%', '') - ); - - // If the percentage available is < the low disk watermark setting, mark node as having low disk space - if (percentageAvailable < rawLowDiskWatermarkPercentageValue) { - nodesWithLowDiskSpace.push({ - nodeId, - nodeName: node.name || nodeId, - available: `${Math.round(percentageAvailable)}%`, - lowDiskWatermarkSetting: lowDiskWatermarkSetting!, - }); - } - } else { - // If not a percentage value, assume user configured low disk watermark setting in bytes - const rawLowDiskWatermarkBytesValue = ByteSizeValue.parse( - lowDiskWatermarkSetting! - ).getValueInBytes(); - - const percentageAvailable = (availableInBytes / totalInBytes) * 100; - - // If bytes available < the low disk watermarket setting, mark node as having low disk space - if (availableInBytes < rawLowDiskWatermarkBytesValue) { - nodesWithLowDiskSpace.push({ - nodeId, - nodeName: node.name || nodeId, - available: `${Math.round(percentageAvailable)}%`, - lowDiskWatermarkSetting: lowDiskWatermarkSetting!, - }); - } + // If the percentage available is < the low disk watermark setting, mark node as having low disk space + if (percentageAvailable < rawLowDiskWatermarkPercentageValue) { + nodesWithLowDiskSpace.push({ + nodeId, + nodeName: node.name || nodeId, + available: `${Math.round(percentageAvailable)}%`, + lowDiskWatermarkSetting: lowDiskWatermarkSetting!, + }); } - }); - - return response.ok({ body: nodesWithLowDiskSpace }); - } + } else { + // If not a percentage value, assume user configured low disk watermark setting in bytes + const rawLowDiskWatermarkBytesValue = ByteSizeValue.parse( + lowDiskWatermarkSetting! + ).getValueInBytes(); + + const percentageAvailable = (availableInBytes / totalInBytes) * 100; + + // If bytes available < the low disk watermarket setting, mark node as having low disk space + if (availableInBytes < rawLowDiskWatermarkBytesValue) { + nodesWithLowDiskSpace.push({ + nodeId, + nodeName: node.name || nodeId, + available: `${Math.round(percentageAvailable)}%`, + lowDiskWatermarkSetting: lowDiskWatermarkSetting!, + }); + } + } + }); - // If the low disk watermark setting is undefined, send empty array - // This could occur if the setting is configured in elasticsearch.yml - return response.ok({ body: [] }); - } catch (error) { - return handleEsError({ error, response }); + return response.ok({ body: nodesWithLowDiskSpace }); } + + // If the low disk watermark setting is undefined, send empty array + // This could occur if the setting is configured in elasticsearch.yml + return response.ok({ body: [] }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/batch_reindex_indices.ts b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/batch_reindex_indices.ts index 62be9a1807aad..c6ea9b4a8fb96 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/batch_reindex_indices.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/batch_reindex_indices.ts @@ -38,37 +38,30 @@ export function registerBatchReindexIndicesRoutes( path: `${BASE_PATH}/batch/queue`, validate: {}, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client: esClient }, - savedObjects, - }, - }, - request, - response - ) => { - const { client } = savedObjects; - const callAsCurrentUser = esClient.asCurrentUser; - const reindexActions = reindexActionsFactory(client, callAsCurrentUser); - try { - const inProgressOps = await reindexActions.findAllByStatus(ReindexStatus.inProgress); - const { queue } = sortAndOrderReindexOperations(inProgressOps); - const result: GetBatchQueueResponse = { - queue: queue.map((savedObject) => savedObject.attributes), - }; - return response.ok({ - body: result, - }); - } catch (error) { - if (error instanceof errors.ResponseError) { - return handleEsError({ error, response }); - } - return mapAnyErrorToKibanaHttpResponse(error); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + const { + elasticsearch: { client: esClient }, + savedObjects, + } = await core; + const { client } = savedObjects; + const callAsCurrentUser = esClient.asCurrentUser; + const reindexActions = reindexActionsFactory(client, callAsCurrentUser); + try { + const inProgressOps = await reindexActions.findAllByStatus(ReindexStatus.inProgress); + const { queue } = sortAndOrderReindexOperations(inProgressOps); + const result: GetBatchQueueResponse = { + queue: queue.map((savedObject) => savedObject.attributes), + }; + return response.ok({ + body: result, + }); + } catch (error) { + if (error instanceof errors.ResponseError) { + return handleEsError({ error, response }); } + return mapAnyErrorToKibanaHttpResponse(error); } - ) + }) ); // Add indices for reindexing to the worker's batch @@ -81,53 +74,46 @@ export function registerBatchReindexIndicesRoutes( }), }, }, - versionCheckHandlerWrapper( - async ( - { - core: { - savedObjects: { client: savedObjectsClient }, - elasticsearch: { client: esClient }, - }, - }, - request, - response - ) => { - const { indexNames } = request.body; - const results: PostBatchResponse = { - enqueued: [], - errors: [], - }; - for (const indexName of indexNames) { - try { - const result = await reindexHandler({ - savedObjects: savedObjectsClient, - dataClient: esClient, - indexName, - log, - licensing, - request, - credentialStore, - reindexOptions: { - enqueue: true, - }, - security: getSecurityPlugin(), - }); - results.enqueued.push(result); - } catch (e) { - results.errors.push({ - indexName, - message: e.message, - }); - } - } - - if (results.errors.length < indexNames.length) { - // Kick the worker on this node to immediately pickup the batch. - getWorker().forceRefresh(); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + const { + savedObjects: { client: savedObjectsClient }, + elasticsearch: { client: esClient }, + } = await core; + const { indexNames } = request.body; + const results: PostBatchResponse = { + enqueued: [], + errors: [], + }; + for (const indexName of indexNames) { + try { + const result = await reindexHandler({ + savedObjects: savedObjectsClient, + dataClient: esClient, + indexName, + log, + licensing, + request, + credentialStore, + reindexOptions: { + enqueue: true, + }, + security: getSecurityPlugin(), + }); + results.enqueued.push(result); + } catch (e) { + results.errors.push({ + indexName, + message: e.message, + }); } + } - return response.ok({ body: results }); + if (results.errors.length < indexNames.length) { + // Kick the worker on this node to immediately pickup the batch. + getWorker().forceRefresh(); } - ) + + return response.ok({ body: results }); + }) ); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.ts b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.ts index d5776cb161b4d..11ebb6d5f4a98 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.ts @@ -40,44 +40,37 @@ export function registerReindexIndicesRoutes( }), }, }, - versionCheckHandlerWrapper( - async ( - { - core: { - savedObjects: { client: savedObjectsClient }, - elasticsearch: { client: esClient }, - }, - }, - request, - response - ) => { - const { indexName } = request.params; - try { - const result = await reindexHandler({ - savedObjects: savedObjectsClient, - dataClient: esClient, - indexName, - log, - licensing, - request, - credentialStore, - security: getSecurityPlugin(), - }); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + const { + savedObjects: { client: savedObjectsClient }, + elasticsearch: { client: esClient }, + } = await core; + const { indexName } = request.params; + try { + const result = await reindexHandler({ + savedObjects: savedObjectsClient, + dataClient: esClient, + indexName, + log, + licensing, + request, + credentialStore, + security: getSecurityPlugin(), + }); - // Kick the worker on this node to immediately pickup the new reindex operation. - getWorker().forceRefresh(); + // Kick the worker on this node to immediately pickup the new reindex operation. + getWorker().forceRefresh(); - return response.ok({ - body: result, - }); - } catch (error) { - if (error instanceof errors.ResponseError) { - return handleEsError({ error, response }); - } - return mapAnyErrorToKibanaHttpResponse(error); + return response.ok({ + body: result, + }); + } catch (error) { + if (error instanceof errors.ResponseError) { + return handleEsError({ error, response }); } + return mapAnyErrorToKibanaHttpResponse(error); } - ) + }) ); // Get status @@ -90,55 +83,48 @@ export function registerReindexIndicesRoutes( }), }, }, - versionCheckHandlerWrapper( - async ( - { - core: { - savedObjects, - elasticsearch: { client: esClient }, - }, - }, - request, - response - ) => { - const { client } = savedObjects; - const { indexName } = request.params; - const asCurrentUser = esClient.asCurrentUser; - const reindexActions = reindexActionsFactory(client, asCurrentUser); - const reindexService = reindexServiceFactory(asCurrentUser, reindexActions, log, licensing); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + const { + savedObjects, + elasticsearch: { client: esClient }, + } = await core; + const { client } = savedObjects; + const { indexName } = request.params; + const asCurrentUser = esClient.asCurrentUser; + const reindexActions = reindexActionsFactory(client, asCurrentUser); + const reindexService = reindexServiceFactory(asCurrentUser, reindexActions, log, licensing); - try { - const hasRequiredPrivileges = await reindexService.hasRequiredPrivileges(indexName); - const reindexOp = await reindexService.findReindexOperation(indexName); - // If the user doesn't have privileges than querying for warnings is going to fail. - const warnings = hasRequiredPrivileges - ? await reindexService.detectReindexWarnings(indexName) - : []; + try { + const hasRequiredPrivileges = await reindexService.hasRequiredPrivileges(indexName); + const reindexOp = await reindexService.findReindexOperation(indexName); + // If the user doesn't have privileges than querying for warnings is going to fail. + const warnings = hasRequiredPrivileges + ? await reindexService.detectReindexWarnings(indexName) + : []; - const indexAliases = await reindexService.getIndexAliases(indexName); + const indexAliases = await reindexService.getIndexAliases(indexName); - const body: ReindexStatusResponse = { - reindexOp: reindexOp ? reindexOp.attributes : undefined, - warnings, - hasRequiredPrivileges, - meta: { - indexName, - reindexName: generateNewIndexName(indexName), - aliases: Object.keys(indexAliases), - }, - }; + const body: ReindexStatusResponse = { + reindexOp: reindexOp ? reindexOp.attributes : undefined, + warnings, + hasRequiredPrivileges, + meta: { + indexName, + reindexName: generateNewIndexName(indexName), + aliases: Object.keys(indexAliases), + }, + }; - return response.ok({ - body, - }); - } catch (error) { - if (error instanceof errors.ResponseError) { - return handleEsError({ error, response }); - } - return mapAnyErrorToKibanaHttpResponse(error); + return response.ok({ + body, + }); + } catch (error) { + if (error instanceof errors.ResponseError) { + return handleEsError({ error, response }); } + return mapAnyErrorToKibanaHttpResponse(error); } - ) + }) ); // Cancel reindex @@ -151,40 +137,33 @@ export function registerReindexIndicesRoutes( }), }, }, - versionCheckHandlerWrapper( - async ( - { - core: { - savedObjects, - elasticsearch: { client: esClient }, - }, - }, - request, - response - ) => { - const { indexName } = request.params; - const { client } = savedObjects; - const callAsCurrentUser = esClient.asCurrentUser; - const reindexActions = reindexActionsFactory(client, callAsCurrentUser); - const reindexService = reindexServiceFactory( - callAsCurrentUser, - reindexActions, - log, - licensing - ); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + const { + savedObjects, + elasticsearch: { client: esClient }, + } = await core; + const { indexName } = request.params; + const { client } = savedObjects; + const callAsCurrentUser = esClient.asCurrentUser; + const reindexActions = reindexActionsFactory(client, callAsCurrentUser); + const reindexService = reindexServiceFactory( + callAsCurrentUser, + reindexActions, + log, + licensing + ); - try { - await reindexService.cancelReindexing(indexName); + try { + await reindexService.cancelReindexing(indexName); - return response.ok({ body: { acknowledged: true } }); - } catch (error) { - if (error instanceof errors.ResponseError) { - return handleEsError({ error, response }); - } - - return mapAnyErrorToKibanaHttpResponse(error); + return response.ok({ body: { acknowledged: true } }); + } catch (error) { + if (error instanceof errors.ResponseError) { + return handleEsError({ error, response }); } + + return mapAnyErrorToKibanaHttpResponse(error); } - ) + }) ); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/remote_clusters.ts b/x-pack/plugins/upgrade_assistant/server/routes/remote_clusters.ts index 0d7268e1be5be..6598051e3c7f6 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/remote_clusters.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/remote_clusters.ts @@ -15,26 +15,19 @@ export function registerRemoteClustersRoute({ router, lib: { handleEsError } }: path: `${API_BASE_PATH}/remote_clusters`, validate: false, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - const clustersByName = await client.asCurrentUser.cluster.remoteInfo(); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client }, + } = await core; + const clustersByName = await client.asCurrentUser.cluster.remoteInfo(); - const remoteClusters = Object.keys(clustersByName); + const remoteClusters = Object.keys(clustersByName); - return response.ok({ body: remoteClusters }); - } catch (error) { - return handleEsError({ error, response }); - } + return response.ok({ body: remoteClusters }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/status.ts b/x-pack/plugins/upgrade_assistant/server/routes/status.ts index 9e8d3f9b2734b..691debfe776cd 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/status.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/status.ts @@ -22,98 +22,89 @@ export function registerUpgradeStatusRoute({ router, lib: { handleEsError } }: R path: `${API_BASE_PATH}/status`, validate: false, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client: esClient }, - deprecations: { client: deprecationsClient }, - }, - }, - request, - response - ) => { - try { - // Fetch ES upgrade status - const { totalCriticalDeprecations: esTotalCriticalDeps } = await getESUpgradeStatus( - esClient - ); - // Fetch system indices migration status - const { migration_status: systemIndicesMigrationStatus, features } = - await getESSystemIndicesMigrationStatus(esClient.asCurrentUser); - const notMigratedSystemIndices = features.filter( - (feature) => feature.migration_status !== 'NO_MIGRATION_NEEDED' - ).length; - - // Fetch Kibana upgrade status - const { totalCriticalDeprecations: kibanaTotalCriticalDeps } = - await getKibanaUpgradeStatus(deprecationsClient); - const readyForUpgrade = - esTotalCriticalDeps === 0 && - kibanaTotalCriticalDeps === 0 && - systemIndicesMigrationStatus === 'NO_MIGRATION_NEEDED'; + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client: esClient }, + deprecations: { client: deprecationsClient }, + } = await core; + // Fetch ES upgrade status + const { totalCriticalDeprecations: esTotalCriticalDeps } = await getESUpgradeStatus( + esClient + ); + // Fetch system indices migration status + const { migration_status: systemIndicesMigrationStatus, features } = + await getESSystemIndicesMigrationStatus(esClient.asCurrentUser); + const notMigratedSystemIndices = features.filter( + (feature) => feature.migration_status !== 'NO_MIGRATION_NEEDED' + ).length; - const getStatusMessage = () => { - if (readyForUpgrade) { - return i18n.translate( - 'xpack.upgradeAssistant.status.allDeprecationsResolvedMessage', - { - defaultMessage: 'All deprecation warnings have been resolved.', - } - ); - } + // Fetch Kibana upgrade status + const { totalCriticalDeprecations: kibanaTotalCriticalDeps } = await getKibanaUpgradeStatus( + deprecationsClient + ); + const readyForUpgrade = + esTotalCriticalDeps === 0 && + kibanaTotalCriticalDeps === 0 && + systemIndicesMigrationStatus === 'NO_MIGRATION_NEEDED'; - const upgradeIssues: string[] = []; + const getStatusMessage = () => { + if (readyForUpgrade) { + return i18n.translate('xpack.upgradeAssistant.status.allDeprecationsResolvedMessage', { + defaultMessage: 'All deprecation warnings have been resolved.', + }); + } - if (notMigratedSystemIndices) { - upgradeIssues.push( - i18n.translate('xpack.upgradeAssistant.status.systemIndicesMessage', { - defaultMessage: - '{notMigratedSystemIndices} unmigrated system {notMigratedSystemIndices, plural, one {index} other {indices}}', - values: { notMigratedSystemIndices }, - }) - ); - } + const upgradeIssues: string[] = []; - if (esTotalCriticalDeps) { - upgradeIssues.push( - i18n.translate('xpack.upgradeAssistant.status.esTotalCriticalDepsMessage', { - defaultMessage: - '{esTotalCriticalDeps} Elasticsearch deprecation {esTotalCriticalDeps, plural, one {issue} other {issues}}', - values: { esTotalCriticalDeps }, - }) - ); - } + if (notMigratedSystemIndices) { + upgradeIssues.push( + i18n.translate('xpack.upgradeAssistant.status.systemIndicesMessage', { + defaultMessage: + '{notMigratedSystemIndices} unmigrated system {notMigratedSystemIndices, plural, one {index} other {indices}}', + values: { notMigratedSystemIndices }, + }) + ); + } - if (kibanaTotalCriticalDeps) { - upgradeIssues.push( - i18n.translate('xpack.upgradeAssistant.status.kibanaTotalCriticalDepsMessage', { - defaultMessage: - '{kibanaTotalCriticalDeps} Kibana deprecation {kibanaTotalCriticalDeps, plural, one {issue} other {issues}}', - values: { kibanaTotalCriticalDeps }, - }) - ); - } + if (esTotalCriticalDeps) { + upgradeIssues.push( + i18n.translate('xpack.upgradeAssistant.status.esTotalCriticalDepsMessage', { + defaultMessage: + '{esTotalCriticalDeps} Elasticsearch deprecation {esTotalCriticalDeps, plural, one {issue} other {issues}}', + values: { esTotalCriticalDeps }, + }) + ); + } - return i18n.translate('xpack.upgradeAssistant.status.deprecationsUnresolvedMessage', { - defaultMessage: - 'The following issues must be resolved before upgrading: {upgradeIssues}.', - values: { - upgradeIssues: upgradeIssues.join(', '), - }, - }); - }; + if (kibanaTotalCriticalDeps) { + upgradeIssues.push( + i18n.translate('xpack.upgradeAssistant.status.kibanaTotalCriticalDepsMessage', { + defaultMessage: + '{kibanaTotalCriticalDeps} Kibana deprecation {kibanaTotalCriticalDeps, plural, one {issue} other {issues}}', + values: { kibanaTotalCriticalDeps }, + }) + ); + } - return response.ok({ - body: { - readyForUpgrade, - details: getStatusMessage(), + return i18n.translate('xpack.upgradeAssistant.status.deprecationsUnresolvedMessage', { + defaultMessage: + 'The following issues must be resolved before upgrading: {upgradeIssues}.', + values: { + upgradeIssues: upgradeIssues.join(', '), }, }); - } catch (error) { - return handleEsError({ error, response }); - } + }; + + return response.ok({ + body: { + readyForUpgrade, + details: getStatusMessage(), + }, + }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/system_indices_migration.ts b/x-pack/plugins/upgrade_assistant/server/routes/system_indices_migration.ts index 67f91aa08a076..aae7df2f43f15 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/system_indices_migration.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/system_indices_migration.ts @@ -20,57 +20,43 @@ export function registerSystemIndicesMigrationRoutes({ // GET status of the system indices migration router.get( { path: `${API_BASE_PATH}/system_indices_migration`, validate: false }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - const status = await getESSystemIndicesMigrationStatus(client.asCurrentUser); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client }, + } = await core; + const status = await getESSystemIndicesMigrationStatus(client.asCurrentUser); - return response.ok({ - body: { - ...status, - features: status.features.filter( - (feature) => feature.migration_status !== 'NO_MIGRATION_NEEDED' - ), - }, - }); - } catch (error) { - return handleEsError({ error, response }); - } + return response.ok({ + body: { + ...status, + features: status.features.filter( + (feature) => feature.migration_status !== 'NO_MIGRATION_NEEDED' + ), + }, + }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); // POST starts the system indices migration router.post( { path: `${API_BASE_PATH}/system_indices_migration`, validate: false }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - const status = await startESSystemIndicesMigration(client.asCurrentUser); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client }, + } = await core; + const status = await startESSystemIndicesMigration(client.asCurrentUser); - return response.ok({ - body: status, - }); - } catch (error) { - return handleEsError({ error, response }); - } + return response.ok({ + body: status, + }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/update_index_settings.ts b/x-pack/plugins/upgrade_assistant/server/routes/update_index_settings.ts index c0d7134ffee5f..382ac77721616 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/update_index_settings.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/update_index_settings.ts @@ -23,42 +23,35 @@ export function registerUpdateSettingsRoute({ router }: RouteDependencies) { }), }, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - const { indexName } = request.params; - const { settings } = request.body; + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client }, + } = await core; + const { indexName } = request.params; + const { settings } = request.body; - const settingsToDelete = settings.reduce((settingsBody, currentSetting) => { - settingsBody[currentSetting] = null; - return settingsBody; - }, {} as { [key: string]: null }); + const settingsToDelete = settings.reduce((settingsBody, currentSetting) => { + settingsBody[currentSetting] = null; + return settingsBody; + }, {} as { [key: string]: null }); - const settingsResponse = await client.asCurrentUser.indices.putSettings({ - index: indexName, - body: settingsToDelete, - }); + const settingsResponse = await client.asCurrentUser.indices.putSettings({ + index: indexName, + body: settingsToDelete, + }); - return response.ok({ - body: settingsResponse, - }); - } catch (e) { - const status = e.status || e.statusCode; - if (status === 403) { - return response.forbidden({ body: e }); - } - - throw e; + return response.ok({ + body: settingsResponse, + }); + } catch (e) { + const status = e.status || e.statusCode; + if (status === 403) { + return response.forbidden({ body: e }); } + + throw e; } - ) + }) ); } diff --git a/x-pack/plugins/ux/kibana.json b/x-pack/plugins/ux/kibana.json index bc57b115b7299..5b403e8d3a331 100644 --- a/x-pack/plugins/ux/kibana.json +++ b/x-pack/plugins/ux/kibana.json @@ -5,6 +5,7 @@ "requiredPlugins": [ "features", "data", + "dataViews", "licensing", "triggersActionsUi", "embeddable", diff --git a/x-pack/plugins/ux/public/application/ux_app.tsx b/x-pack/plugins/ux/public/application/ux_app.tsx index d2879d4fa2797..0ea4f9ce83893 100644 --- a/x-pack/plugins/ux/public/application/ux_app.tsx +++ b/x-pack/plugins/ux/public/application/ux_app.tsx @@ -106,7 +106,7 @@ export function UXAppRoot({ appMountParameters, core, deps, - corePlugins: { embeddable, inspector, maps, observability, data }, + corePlugins: { embeddable, inspector, maps, observability, data, dataViews }, }: { appMountParameters: AppMountParameters; core: CoreStart; @@ -130,6 +130,7 @@ export function UXAppRoot({ observability, embeddable, data, + dataViews, }} > diff --git a/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/use_data_view.ts b/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/use_data_view.ts index bb80fd68ff283..f5c446908a801 100644 --- a/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/use_data_view.ts +++ b/x-pack/plugins/ux/public/components/app/rum_dashboard/local_uifilters/use_data_view.ts @@ -5,9 +5,9 @@ * 2.0. */ -import { DataView } from '@kbn/data-plugin/common'; +import { DataView } from '@kbn/data-views-plugin/common'; import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import { useFetcher } from '../../../../hooks/use_fetcher'; import { useDynamicDataViewFetcher } from '../../../../hooks/use_dynamic_data_view'; @@ -15,10 +15,8 @@ export function useDataView() { const { dataView } = useDynamicDataViewFetcher(); const { - services: { - data: { dataViews }, - }, - } = useKibana<{ data: DataPublicPluginStart }>(); + services: { dataViews }, + } = useKibana<{ dataViews: DataViewsPublicPluginStart }>(); const { data } = useFetcher>(async () => { if (dataView?.title) { diff --git a/x-pack/plugins/ux/public/plugin.ts b/x-pack/plugins/ux/public/plugin.ts index f56c7a140ade5..fe98a490b5b80 100644 --- a/x-pack/plugins/ux/public/plugin.ts +++ b/x-pack/plugins/ux/public/plugin.ts @@ -32,6 +32,7 @@ import { LicensingPluginSetup } from '@kbn/licensing-plugin/public'; import { EmbeddableStart } from '@kbn/embeddable-plugin/public'; import { MapsStartApi } from '@kbn/maps-plugin/public'; import { Start as InspectorPluginStart } from '@kbn/inspector-plugin/public'; +import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; export type UxPluginSetup = void; export type UxPluginStart = void; @@ -52,6 +53,7 @@ export interface ApmPluginStartDeps { maps?: MapsStartApi; inspector: InspectorPluginStart; observability: ObservabilityPublicStart; + dataViews: DataViewsPublicPluginStart; } export class UxPlugin implements Plugin { diff --git a/x-pack/plugins/watcher/server/routes/api/indices/register_get_index_patterns_route.ts b/x-pack/plugins/watcher/server/routes/api/indices/register_get_index_patterns_route.ts index 26ecb5de4761e..0c49e5ea894dd 100644 --- a/x-pack/plugins/watcher/server/routes/api/indices/register_get_index_patterns_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/indices/register_get_index_patterns_route.ts @@ -18,8 +18,9 @@ export function registerGetIndexPatternsRoute({ path: '/api/watcher/indices/index_patterns', validate: false, }, - license.guardApiRoute(async ({ core: { savedObjects } }, request, response) => { + license.guardApiRoute(async ({ core }, request, response) => { try { + const { savedObjects } = await core; const finder = savedObjects.client.createPointInTimeFinder({ type: 'index-pattern', fields: ['title'], diff --git a/x-pack/plugins/watcher/server/routes/api/indices/register_get_route.ts b/x-pack/plugins/watcher/server/routes/api/indices/register_get_route.ts index 8cf7d0a61d5d8..da78238ebd5cd 100644 --- a/x-pack/plugins/watcher/server/routes/api/indices/register_get_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/indices/register_get_route.ts @@ -87,7 +87,8 @@ export function registerGetRoute({ router, license, lib: { handleEsError } }: Ro const { pattern } = request.body; try { - const indices = await getIndices(ctx.core.elasticsearch.client, pattern); + const esClient = (await ctx.core).elasticsearch.client; + const indices = await getIndices(esClient, pattern); return response.ok({ body: { indices } }); } catch (e) { return handleEsError({ error: e, response }); diff --git a/x-pack/plugins/watcher/server/routes/api/register_list_fields_route.ts b/x-pack/plugins/watcher/server/routes/api/register_list_fields_route.ts index 458fdb1d56fee..915695eaf50fa 100644 --- a/x-pack/plugins/watcher/server/routes/api/register_list_fields_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/register_list_fields_route.ts @@ -43,7 +43,8 @@ export function registerListFieldsRoute({ const { indexes } = request.body; try { - const fieldsResponse = await fetchFields(ctx.core.elasticsearch.client, indexes); + const esClient = (await ctx.core).elasticsearch.client; + const fieldsResponse = await fetchFields(esClient, indexes); const json = fieldsResponse.statusCode === 404 ? { fields: [] } : fieldsResponse.body; const fields = Fields.fromUpstreamJson(json); return response.ok({ body: fields.downstreamJson }); diff --git a/x-pack/plugins/watcher/server/routes/api/register_load_history_route.ts b/x-pack/plugins/watcher/server/routes/api/register_load_history_route.ts index c24ddc2d74655..d3a3f07e41b9a 100644 --- a/x-pack/plugins/watcher/server/routes/api/register_load_history_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/register_load_history_route.ts @@ -46,7 +46,8 @@ export function registerLoadHistoryRoute({ const id = request.params.id; try { - const responseFromES = await fetchHistoryItem(ctx.core.elasticsearch.client, id); + const esClient = (await ctx.core).elasticsearch.client; + const responseFromES = await fetchHistoryItem(esClient, id); const hit = get(responseFromES, 'hits.hits[0]'); if (!hit) { return response.notFound({ body: `Watch History Item with id = ${id} not found` }); diff --git a/x-pack/plugins/watcher/server/routes/api/settings/register_load_route.ts b/x-pack/plugins/watcher/server/routes/api/settings/register_load_route.ts index 6733da355c862..6fdbbe1de96ac 100644 --- a/x-pack/plugins/watcher/server/routes/api/settings/register_load_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/settings/register_load_route.ts @@ -25,7 +25,8 @@ export function registerLoadRoute({ router, license, lib: { handleEsError } }: R }, license.guardApiRoute(async (ctx, request, response) => { try { - const settings = await fetchClusterSettings(ctx.core.elasticsearch.client); + const esClient = (await ctx.core).elasticsearch.client; + const settings = await fetchClusterSettings(esClient); return response.ok({ body: Settings.fromUpstreamJson(settings).downstreamJson }); } catch (e) { return handleEsError({ error: e, response }); diff --git a/x-pack/plugins/watcher/server/routes/api/watch/action/register_acknowledge_route.ts b/x-pack/plugins/watcher/server/routes/api/watch/action/register_acknowledge_route.ts index 9f0e17cfe4ef5..31b6d9ec15995 100644 --- a/x-pack/plugins/watcher/server/routes/api/watch/action/register_acknowledge_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/watch/action/register_acknowledge_route.ts @@ -40,7 +40,8 @@ export function registerAcknowledgeRoute({ const { watchId, actionId } = request.params; try { - const hit = await acknowledgeAction(ctx.core.elasticsearch.client, watchId, actionId); + const esClient = (await ctx.core).elasticsearch.client; + const hit = await acknowledgeAction(esClient, watchId, actionId); const watchStatusJson = get(hit, 'status'); const json = { id: watchId, diff --git a/x-pack/plugins/watcher/server/routes/api/watch/register_activate_route.ts b/x-pack/plugins/watcher/server/routes/api/watch/register_activate_route.ts index 5b59a35e8ffcd..213567aef26a3 100644 --- a/x-pack/plugins/watcher/server/routes/api/watch/register_activate_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/watch/register_activate_route.ts @@ -38,7 +38,8 @@ export function registerActivateRoute({ const { watchId } = request.params; try { - const hit = await activateWatch(ctx.core.elasticsearch.client, watchId); + const esClient = (await ctx.core).elasticsearch.client; + const hit = await activateWatch(esClient, watchId); const watchStatusJson = get(hit, 'status'); const json = { id: watchId, diff --git a/x-pack/plugins/watcher/server/routes/api/watch/register_deactivate_route.ts b/x-pack/plugins/watcher/server/routes/api/watch/register_deactivate_route.ts index a22fcee62e588..2d929965468b1 100644 --- a/x-pack/plugins/watcher/server/routes/api/watch/register_deactivate_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/watch/register_deactivate_route.ts @@ -38,7 +38,8 @@ export function registerDeactivateRoute({ const { watchId } = request.params; try { - const hit = await deactivateWatch(ctx.core.elasticsearch.client, watchId); + const esClient = (await ctx.core).elasticsearch.client; + const hit = await deactivateWatch(esClient, watchId); const watchStatusJson = get(hit, 'status'); const json = { id: watchId, diff --git a/x-pack/plugins/watcher/server/routes/api/watch/register_delete_route.ts b/x-pack/plugins/watcher/server/routes/api/watch/register_delete_route.ts index 809500dad205e..c35efbd4bb320 100644 --- a/x-pack/plugins/watcher/server/routes/api/watch/register_delete_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/watch/register_delete_route.ts @@ -35,8 +35,9 @@ export function registerDeleteRoute({ const { watchId } = request.params; try { + const esClient = (await ctx.core).elasticsearch.client; return response.ok({ - body: await deleteWatch(ctx.core.elasticsearch.client, watchId), + body: await deleteWatch(esClient, watchId), }); } catch (e) { if (e?.statusCode === 404 && e.meta?.body?.error) { diff --git a/x-pack/plugins/watcher/server/routes/api/watch/register_execute_route.ts b/x-pack/plugins/watcher/server/routes/api/watch/register_execute_route.ts index 106447879198f..c7a082f640c6a 100644 --- a/x-pack/plugins/watcher/server/routes/api/watch/register_execute_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/watch/register_execute_route.ts @@ -50,11 +50,8 @@ export function registerExecuteRoute({ const watch = Watch.fromDownstreamJson(request.body.watch); try { - const hit = await executeWatch( - ctx.core.elasticsearch.client, - executeDetails.upstreamJson, - watch.watchJson - ); + const esClient = (await ctx.core).elasticsearch.client; + const hit = await executeWatch(esClient, executeDetails.upstreamJson, watch.watchJson); const id = get(hit, '_id'); const watchHistoryItemJson = get(hit, 'watch_record'); const watchId = get(hit, 'watch_record.watch_id'); diff --git a/x-pack/plugins/watcher/server/routes/api/watch/register_history_route.ts b/x-pack/plugins/watcher/server/routes/api/watch/register_history_route.ts index af820c20fc01a..f3d810424d9a6 100644 --- a/x-pack/plugins/watcher/server/routes/api/watch/register_history_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/watch/register_history_route.ts @@ -66,7 +66,8 @@ export function registerHistoryRoute({ const { startTime } = request.query; try { - const hits = await fetchHistoryItems(ctx.core.elasticsearch.client, watchId, startTime); + const esClient = (await ctx.core).elasticsearch.client; + const hits = await fetchHistoryItems(esClient, watchId, startTime); const watchHistoryItems = hits.map((hit: any) => { const id = get(hit, '_id'); const watchHistoryItemJson = get(hit, '_source'); diff --git a/x-pack/plugins/watcher/server/routes/api/watch/register_load_route.ts b/x-pack/plugins/watcher/server/routes/api/watch/register_load_route.ts index 76dea16c96981..a2fea1d5b73d4 100644 --- a/x-pack/plugins/watcher/server/routes/api/watch/register_load_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/watch/register_load_route.ts @@ -34,7 +34,8 @@ export function registerLoadRoute({ router, license, lib: { handleEsError } }: R const id = request.params.id; try { - const hit = await fetchWatch(ctx.core.elasticsearch.client, id); + const esClient = (await ctx.core).elasticsearch.client; + const hit = await fetchWatch(esClient, id); const watchJson = get(hit, 'watch'); const watchStatusJson = get(hit, 'status'); const json = { diff --git a/x-pack/plugins/watcher/server/routes/api/watch/register_save_route.ts b/x-pack/plugins/watcher/server/routes/api/watch/register_save_route.ts index 6aebd4968f066..86e3c2d1da102 100644 --- a/x-pack/plugins/watcher/server/routes/api/watch/register_save_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/watch/register_save_route.ts @@ -37,7 +37,7 @@ export function registerSaveRoute({ router, license, lib: { handleEsError } }: R const { id } = request.params; const { type, isNew, isActive, ...watchConfig } = request.body; - const dataClient = ctx.core.elasticsearch.client; + const dataClient = (await ctx.core).elasticsearch.client; // For new watches, verify watch with the same ID doesn't already exist if (isNew) { diff --git a/x-pack/plugins/watcher/server/routes/api/watch/register_visualize_route.ts b/x-pack/plugins/watcher/server/routes/api/watch/register_visualize_route.ts index 40672b3d8f5a4..defc1b3451e6b 100644 --- a/x-pack/plugins/watcher/server/routes/api/watch/register_visualize_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/watch/register_visualize_route.ts @@ -52,7 +52,8 @@ export function registerVisualizeRoute({ const body = watch.getVisualizeQuery(options, kibanaVersion); try { - const hits = await fetchVisualizeData(ctx.core.elasticsearch.client, watch.index, body); + const esClient = (await ctx.core).elasticsearch.client; + const hits = await fetchVisualizeData(esClient, watch.index, body); const visualizeData = watch.formatVisualizeData(hits); return response.ok({ diff --git a/x-pack/plugins/watcher/server/routes/api/watches/register_delete_route.ts b/x-pack/plugins/watcher/server/routes/api/watches/register_delete_route.ts index 9f481fec3f4db..5458f850b33e6 100644 --- a/x-pack/plugins/watcher/server/routes/api/watches/register_delete_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/watches/register_delete_route.ts @@ -56,7 +56,8 @@ export function registerDeleteRoute({ router, license }: RouteDependencies) { }, }, license.guardApiRoute(async (ctx, request, response) => { - const results = await deleteWatches(ctx.core.elasticsearch.client, request.body.watchIds); + const esClient = (await ctx.core).elasticsearch.client; + const results = await deleteWatches(esClient, request.body.watchIds); return response.ok({ body: { results } }); }) ); diff --git a/x-pack/plugins/watcher/server/routes/api/watches/register_list_route.ts b/x-pack/plugins/watcher/server/routes/api/watches/register_list_route.ts index 9ccfddbaf3923..9951da819e9e0 100644 --- a/x-pack/plugins/watcher/server/routes/api/watches/register_list_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/watches/register_list_route.ts @@ -36,7 +36,8 @@ export function registerListRoute({ router, license, lib: { handleEsError } }: R }, license.guardApiRoute(async (ctx, request, response) => { try { - const hits = await fetchWatches(ctx.core.elasticsearch.client); + const esClient = (await ctx.core).elasticsearch.client; + const hits = await fetchWatches(esClient); const watches = hits.map((hit: any) => { const id = get(hit, '_id'); const watchJson = get(hit, '_source'); diff --git a/x-pack/test/accessibility/apps/lens.ts b/x-pack/test/accessibility/apps/lens.ts index f99ff08f86bb8..8a46d662a61cf 100644 --- a/x-pack/test/accessibility/apps/lens.ts +++ b/x-pack/test/accessibility/apps/lens.ts @@ -119,8 +119,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('change chart type', async () => { - await PageObjects.lens.switchToVisualization('line'); + await PageObjects.lens.openChartSwitchPopover(); + await PageObjects.lens.waitForSearchInputValue('line'); await a11y.testAppSnapshot(); + await testSubjects.click('lnsChartSwitchPopover_line'); }); it('change chart type via suggestions', async () => { diff --git a/x-pack/test/alerting_api_integration/common/config.ts b/x-pack/test/alerting_api_integration/common/config.ts index 8c103ef8ce52c..14039ad3360a0 100644 --- a/x-pack/test/alerting_api_integration/common/config.ts +++ b/x-pack/test/alerting_api_integration/common/config.ts @@ -24,6 +24,7 @@ interface CreateTestConfigOptions { preconfiguredAlertHistoryEsIndex?: boolean; customizeLocalHostSsl?: boolean; rejectUnauthorized?: boolean; // legacy + emailDomainsAllowed?: string[]; } // test.not-enabled is specifically not enabled @@ -50,6 +51,7 @@ const enabledActionTypes = [ 'test.no-attempts-rate-limit', 'test.throw', 'test.excluded', + 'test.capped', ]; export function createTestConfig(name: string, options: CreateTestConfigOptions) { @@ -61,6 +63,7 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) preconfiguredAlertHistoryEsIndex = false, customizeLocalHostSsl = false, rejectUnauthorized = true, // legacy + emailDomainsAllowed = undefined, } = options; return async ({ readConfigFile }: FtrConfigProviderContext) => { @@ -131,6 +134,10 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) ? [`--xpack.actions.customHostSettings=${JSON.stringify(customHostSettingsValue)}`] : []; + const emailSettings = emailDomainsAllowed + ? [`--xpack.actions.email.domain_allowlist=${JSON.stringify(emailDomainsAllowed)}`] + : []; + return { testFiles: [require.resolve(`../${name}/tests/`)], servers, @@ -163,12 +170,16 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) '--xpack.alerting.invalidateApiKeysTask.interval="15s"', '--xpack.alerting.healthCheck.interval="1s"', '--xpack.alerting.rules.minimumScheduleInterval.value="1s"', + `--xpack.alerting.rules.run.actions.connectorTypeOverrides=${JSON.stringify([ + { id: 'test.capped', max: '1' }, + ])}`, `--xpack.actions.enabledActionTypes=${JSON.stringify(enabledActionTypes)}`, `--xpack.actions.rejectUnauthorized=${rejectUnauthorized}`, `--xpack.actions.microsoftGraphApiUrl=${servers.kibana.protocol}://${servers.kibana.hostname}:${servers.kibana.port}/api/_actions-FTS-external-service-simulators/exchange/users/test@/sendMail`, `--xpack.actions.ssl.verificationMode=${verificationMode}`, ...actionsProxyUrl, ...customHostSettings, + ...emailSettings, '--xpack.eventLog.logEntries=true', '--xpack.task_manager.ephemeral_tasks.enabled=false', `--xpack.task_manager.unsafe.exclude_task_types=${JSON.stringify([ @@ -183,6 +194,18 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) webhookUrl: 'https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz', }, }, + 'my-deprecated-servicenow': { + actionTypeId: '.servicenow', + name: 'ServiceNow#xyz', + config: { + apiUrl: 'https://ven04334.service-now.com', + usesTableApi: true, + }, + secrets: { + username: 'elastic_integration', + password: 'somepassword', + }, + }, 'custom-system-abc-connector': { actionTypeId: 'system-abc-action-type', name: 'SystemABC', diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/action_types.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/action_types.ts index 357458cc38e41..c83a1c543b5a7 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/action_types.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/action_types.ts @@ -31,8 +31,17 @@ export function defineActionTypes( throw new Error('this action is intended to fail'); }, }; + const cappedActionType: ActionType = { + id: 'test.capped', + name: 'Test: Capped', + minimumLicenseRequired: 'gold', + async executor() { + return { status: 'ok', actionId: '' }; + }, + }; actions.registerType(noopActionType); actions.registerType(throwActionType); + actions.registerType(cappedActionType); actions.registerType(getIndexRecordActionType()); actions.registerType(getDelayedActionType()); actions.registerType(getFailingActionType()); diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/task_manager_fixture/server/plugin.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/task_manager_fixture/server/plugin.ts index 10fedc3151270..6e4eba065ec70 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/task_manager_fixture/server/plugin.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/task_manager_fixture/server/plugin.ts @@ -88,7 +88,8 @@ export class SampleTaskManagerFixturePlugin req: KibanaRequest, res: KibanaResponseFactory ): Promise> { - await context.core.elasticsearch.client.asInternalUser.indices.refresh({ + const coreCtx = await context.core; + await coreCtx.elasticsearch.client.asInternalUser.indices.refresh({ index: '.kibana_task_manager', }); return res.ok({ body: {} }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/email.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/email.ts index d7716c5f30f66..6fb2315956b69 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/email.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/email.ts @@ -45,6 +45,7 @@ export default function emailTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdActionId, is_preconfigured: false, + is_deprecated: false, name: 'An email action', connector_type_id: '.email', is_missing_secrets: false, @@ -70,6 +71,7 @@ export default function emailTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_deprecated: false, name: 'An email action', connector_type_id: '.email', is_missing_secrets: false, @@ -354,6 +356,7 @@ export default function emailTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_deprecated: false, name: 'An email action', connector_type_id: '.email', is_missing_secrets: false, @@ -379,6 +382,7 @@ export default function emailTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_deprecated: false, name: 'An email action', connector_type_id: '.email', is_missing_secrets: false, @@ -418,6 +422,7 @@ export default function emailTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_deprecated: false, name: 'An email action', connector_type_id: '.email', is_missing_secrets: false, @@ -443,6 +448,7 @@ export default function emailTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_deprecated: false, name: 'An email action', connector_type_id: '.email', is_missing_secrets: false, @@ -487,6 +493,7 @@ export default function emailTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdMSExchangeActionId, is_preconfigured: false, + is_deprecated: false, name: 'An email action', connector_type_id: '.email', is_missing_secrets: false, @@ -514,6 +521,7 @@ export default function emailTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_deprecated: false, name: 'An email action', connector_type_id: '.email', is_missing_secrets: false, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts index fc40d036f925a..edf352936e979 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts @@ -41,6 +41,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_deprecated: false, name: 'An index action', connector_type_id: '.index', is_missing_secrets: false, @@ -60,6 +61,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_deprecated: false, is_missing_secrets: false, name: 'An index action', connector_type_id: '.index', @@ -84,6 +86,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(createdActionWithIndex).to.eql({ id: createdActionWithIndex.id, is_preconfigured: false, + is_deprecated: false, name: 'An index action with index config', connector_type_id: '.index', is_missing_secrets: false, @@ -103,6 +106,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(fetchedActionWithIndex).to.eql({ id: fetchedActionWithIndex.id, is_preconfigured: false, + is_deprecated: false, name: 'An index action with index config', connector_type_id: '.index', is_missing_secrets: false, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts index 41a0d65b624b7..33185a20c9249 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts @@ -76,6 +76,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_deprecated: false, name: 'A jira action', connector_type_id: '.jira', is_missing_secrets: false, @@ -92,6 +93,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_deprecated: false, name: 'A jira action', connector_type_id: '.jira', is_missing_secrets: false, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts index 26b59d93e0073..05dba49236197 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts @@ -62,6 +62,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_deprecated: false, name: 'A pagerduty action', connector_type_id: '.pagerduty', is_missing_secrets: false, @@ -79,6 +80,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_deprecated: false, name: 'A pagerduty action', connector_type_id: '.pagerduty', is_missing_secrets: false, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/resilient.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/resilient.ts index 8e2036ce688ea..e2a92701b62cb 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/resilient.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/resilient.ts @@ -79,6 +79,7 @@ export default function resilientTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_deprecated: false, name: 'An IBM Resilient action', connector_type_id: '.resilient', is_missing_secrets: false, @@ -95,6 +96,7 @@ export default function resilientTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_deprecated: false, name: 'An IBM Resilient action', connector_type_id: '.resilient', is_missing_secrets: false, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/server_log.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/server_log.ts index 6dacd19460295..fb7bac7d81e9c 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/server_log.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/server_log.ts @@ -30,6 +30,7 @@ export default function serverLogTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_deprecated: false, is_missing_secrets: false, name: 'A server.log action', connector_type_id: '.server-log', @@ -45,6 +46,7 @@ export default function serverLogTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_deprecated: false, name: 'A server.log action', connector_type_id: '.server-log', is_missing_secrets: false, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_itom.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_itom.ts index 6f1ddc6ee2748..c685fff8abfc6 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_itom.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_itom.ts @@ -7,6 +7,7 @@ import httpProxy from 'http-proxy'; import expect from '@kbn/expect'; +import { asyncForEach } from '@kbn/std'; import getPort from 'get-port'; import http from 'http'; @@ -19,14 +20,7 @@ export default function serviceNowITOMTest({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const configService = getService('config'); - const mockServiceNow = { - config: { - apiUrl: 'www.servicenowisinkibanaactions.com', - }, - secrets: { - password: 'elastic', - username: 'changeme', - }, + const mockServiceNowCommon = { params: { subAction: 'addEvent', subActionParams: { @@ -44,6 +38,30 @@ export default function serviceNowITOMTest({ getService }: FtrProviderContext) { }, }, }; + const mockServiceNowBasic = { + ...mockServiceNowCommon, + config: { + apiUrl: 'www.servicenowisinkibanaactions.com', + }, + secrets: { + password: 'elastic', + username: 'changeme', + }, + }; + const mockServiceNowOAuth = { + ...mockServiceNowCommon, + config: { + apiUrl: 'www.servicenowisinkibanaactions.com', + isOAuth: true, + clientId: 'abc', + userIdentifierValue: 'elastic', + jwtKeyId: 'def', + }, + secrets: { + clientSecret: 'xyz', + privateKey: '-----BEGIN RSA PRIVATE KEY-----\nddddddd\n-----END RSA PRIVATE KEY-----', + }, + }; describe('ServiceNow ITOM', () => { let simulatedActionId = ''; @@ -76,7 +94,7 @@ export default function serviceNowITOMTest({ getService }: FtrProviderContext) { }); describe('ServiceNow ITOM - Action Creation', () => { - it('should return 200 when creating a servicenow action successfully', async () => { + it('should return 200 when creating a servicenow Basic Auth connector successfully', async () => { const { body: createdAction } = await supertest .post('/api/actions/connector') .set('kbn-xsrf', 'foo') @@ -86,18 +104,23 @@ export default function serviceNowITOMTest({ getService }: FtrProviderContext) { config: { apiUrl: serviceNowSimulatorURL, }, - secrets: mockServiceNow.secrets, + secrets: mockServiceNowBasic.secrets, }) .expect(200); expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_deprecated: false, name: 'A servicenow action', connector_type_id: '.servicenow-itom', is_missing_secrets: false, config: { apiUrl: serviceNowSimulatorURL, + isOAuth: false, + clientId: null, + jwtKeyId: null, + userIdentifierValue: null, }, }); @@ -108,16 +131,73 @@ export default function serviceNowITOMTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_deprecated: false, + name: 'A servicenow action', + connector_type_id: '.servicenow-itom', + is_missing_secrets: false, + config: { + apiUrl: serviceNowSimulatorURL, + isOAuth: false, + clientId: null, + jwtKeyId: null, + userIdentifierValue: null, + }, + }); + }); + + it('should return 200 when creating a servicenow OAuth connector successfully', async () => { + const { body: createdConnector } = await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow action', + connector_type_id: '.servicenow-itom', + config: { + ...mockServiceNowOAuth.config, + apiUrl: serviceNowSimulatorURL, + }, + secrets: mockServiceNowOAuth.secrets, + }) + .expect(200); + + expect(createdConnector).to.eql({ + id: createdConnector.id, + is_preconfigured: false, + is_deprecated: false, + name: 'A servicenow action', + connector_type_id: '.servicenow-itom', + is_missing_secrets: false, + config: { + apiUrl: serviceNowSimulatorURL, + isOAuth: true, + clientId: mockServiceNowOAuth.config.clientId, + jwtKeyId: mockServiceNowOAuth.config.jwtKeyId, + userIdentifierValue: mockServiceNowOAuth.config.userIdentifierValue, + }, + }); + + const { body: fetchedConnector } = await supertest + .get(`/api/actions/connector/${createdConnector.id}`) + .expect(200); + + expect(fetchedConnector).to.eql({ + id: fetchedConnector.id, + is_preconfigured: false, + is_deprecated: false, name: 'A servicenow action', connector_type_id: '.servicenow-itom', is_missing_secrets: false, config: { apiUrl: serviceNowSimulatorURL, + isOAuth: true, + clientId: mockServiceNowOAuth.config.clientId, + jwtKeyId: mockServiceNowOAuth.config.jwtKeyId, + userIdentifierValue: mockServiceNowOAuth.config.userIdentifierValue, }, }); }); - it('should respond with a 400 Bad Request when creating a servicenow action with no apiUrl', async () => { + it('should respond with a 400 Bad Request when creating a servicenow Basic Auth connector with no apiUrl', async () => { await supertest .post('/api/actions/connector') .set('kbn-xsrf', 'foo') @@ -137,7 +217,30 @@ export default function serviceNowITOMTest({ getService }: FtrProviderContext) { }); }); - it('should respond with a 400 Bad Request when creating a servicenow action with a not present in allowedHosts apiUrl', async () => { + it('should respond with a 400 Bad Request when creating a servicenow OAuth connector with no apiUrl', async () => { + await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow action', + connector_type_id: '.servicenow-itom', + config: { + isOAuth: true, + }, + secrets: mockServiceNowOAuth.secrets, + }) + .expect(400) + .then((resp: any) => { + expect(resp.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: + 'error validating action type config: [apiUrl]: expected value of type [string] but got [undefined]', + }); + }); + }); + + it('should respond with a 400 Bad Request when creating a servicenow connector with a not present in allowedHosts apiUrl', async () => { await supertest .post('/api/actions/connector') .set('kbn-xsrf', 'foo') @@ -147,7 +250,7 @@ export default function serviceNowITOMTest({ getService }: FtrProviderContext) { config: { apiUrl: 'http://servicenow.mynonexistent.com', }, - secrets: mockServiceNow.secrets, + secrets: mockServiceNowBasic.secrets, }) .expect(400) .then((resp: any) => { @@ -160,7 +263,29 @@ export default function serviceNowITOMTest({ getService }: FtrProviderContext) { }); }); - it('should respond with a 400 Bad Request when creating a servicenow action without secrets', async () => { + it('should respond with a 400 Bad Request when creating a servicenow Basic Auth connector without secrets', async () => { + await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow action', + connector_type_id: '.servicenow-itom', + config: { + apiUrl: serviceNowSimulatorURL, + }, + }) + .expect(400) + .then((resp: any) => { + expect(resp.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: + 'error validating action type secrets: Either basic auth or OAuth credentials must be specified', + }); + }); + }); + + it('should respond with a 400 Bad Request when creating a servicenow OAuth connector without secrets', async () => { await supertest .post('/api/actions/connector') .set('kbn-xsrf', 'foo') @@ -168,6 +293,7 @@ export default function serviceNowITOMTest({ getService }: FtrProviderContext) { name: 'A servicenow action', connector_type_id: '.servicenow-itom', config: { + ...mockServiceNowOAuth.config, apiUrl: serviceNowSimulatorURL, }, }) @@ -177,10 +303,84 @@ export default function serviceNowITOMTest({ getService }: FtrProviderContext) { statusCode: 400, error: 'Bad Request', message: - 'error validating action type secrets: [password]: expected value of type [string] but got [undefined]', + 'error validating action type secrets: Either basic auth or OAuth credentials must be specified', }); }); }); + + it('should respond with a 400 Bad Request when creating a servicenow OAuth connector with missing fields', async () => { + const badConfigs = [ + { + config: { + ...mockServiceNowOAuth.config, + apiUrl: serviceNowSimulatorURL, + clientId: null, + }, + secrets: mockServiceNowOAuth.secrets, + errorMessage: `error validating action type config: clientId must be provided when isOAuth = true`, + }, + { + config: { + ...mockServiceNowOAuth.config, + apiUrl: serviceNowSimulatorURL, + userIdentifierValue: null, + }, + secrets: mockServiceNowOAuth.secrets, + errorMessage: `error validating action type config: userIdentifierValue must be provided when isOAuth = true`, + }, + { + config: { + ...mockServiceNowOAuth.config, + apiUrl: serviceNowSimulatorURL, + jwtKeyId: null, + }, + secrets: mockServiceNowOAuth.secrets, + errorMessage: `error validating action type config: jwtKeyId must be provided when isOAuth = true`, + }, + { + config: { + ...mockServiceNowOAuth.config, + apiUrl: serviceNowSimulatorURL, + }, + secrets: { + ...mockServiceNowOAuth.secrets, + clientSecret: null, + }, + errorMessage: `error validating action type secrets: clientSecret and privateKey must both be specified`, + }, + { + config: { + ...mockServiceNowOAuth.config, + apiUrl: serviceNowSimulatorURL, + }, + secrets: { + ...mockServiceNowOAuth.secrets, + privateKey: null, + }, + errorMessage: `error validating action type secrets: clientSecret and privateKey must both be specified`, + }, + ]; + + await asyncForEach(badConfigs, async (badConfig) => { + await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow action', + connector_type_id: '.servicenow-itom', + config: badConfig.config, + secrets: badConfig.secrets, + }) + .expect(400) + .then((resp: any) => { + expect(resp.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: badConfig.errorMessage, + }); + }); + }); + }); }); describe('ServiceNow ITOM - Executor', () => { @@ -194,7 +394,7 @@ export default function serviceNowITOMTest({ getService }: FtrProviderContext) { config: { apiUrl: serviceNowSimulatorURL, }, - secrets: mockServiceNow.secrets, + secrets: mockServiceNowBasic.secrets, }); simulatedActionId = body.id; }); @@ -282,7 +482,7 @@ export default function serviceNowITOMTest({ getService }: FtrProviderContext) { .post(`/api/actions/connector/${simulatedActionId}/_execute`) .set('kbn-xsrf', 'foo') .send({ - params: mockServiceNow.params, + params: mockServiceNowBasic.params, }) .expect(200); expect(result.status).to.eql('ok'); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_itsm.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_itsm.ts index 1308959ebbacf..0f81753bbc731 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_itsm.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_itsm.ts @@ -7,6 +7,7 @@ import httpProxy from 'http-proxy'; import expect from '@kbn/expect'; +import { asyncForEach } from '@kbn/std'; import getPort from 'get-port'; import http from 'http'; @@ -19,15 +20,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const configService = getService('config'); - const mockServiceNow = { - config: { - apiUrl: 'www.servicenowisinkibanaactions.com', - usesTableApi: false, - }, - secrets: { - password: 'elastic', - username: 'changeme', - }, + const mockServiceNowCommon = { params: { subAction: 'pushToService', subActionParams: { @@ -51,6 +44,33 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { }, }; + const mockServiceNowBasic = { + ...mockServiceNowCommon, + config: { + apiUrl: 'www.servicenowisinkibanaactions.com', + usesTableApi: false, + }, + secrets: { + password: 'elastic', + username: 'changeme', + }, + }; + const mockServiceNowOAuth = { + ...mockServiceNowCommon, + config: { + apiUrl: 'www.servicenowisinkibanaactions.com', + usesTableApi: false, + isOAuth: true, + clientId: 'abc', + userIdentifierValue: 'elastic', + jwtKeyId: 'def', + }, + secrets: { + clientSecret: 'xyz', + privateKey: '-----BEGIN RSA PRIVATE KEY-----\nddddddd\n-----END RSA PRIVATE KEY-----', + }, + }; + describe('ServiceNow ITSM', () => { let simulatedActionId = ''; let serviceNowSimulatorURL: string = ''; @@ -82,7 +102,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { }); describe('ServiceNow ITSM - Action Creation', () => { - it('should return 200 when creating a servicenow action successfully', async () => { + it('should return 200 when creating a servicenow Basic Auth connector successfully', async () => { const { body: createdAction } = await supertest .post('/api/actions/connector') .set('kbn-xsrf', 'foo') @@ -93,19 +113,24 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { apiUrl: serviceNowSimulatorURL, usesTableApi: false, }, - secrets: mockServiceNow.secrets, + secrets: mockServiceNowBasic.secrets, }) .expect(200); expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_deprecated: false, name: 'A servicenow action', connector_type_id: '.servicenow', is_missing_secrets: false, config: { apiUrl: serviceNowSimulatorURL, usesTableApi: false, + isOAuth: false, + clientId: null, + jwtKeyId: null, + userIdentifierValue: null, }, }); @@ -116,12 +141,71 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_deprecated: false, name: 'A servicenow action', connector_type_id: '.servicenow', is_missing_secrets: false, config: { apiUrl: serviceNowSimulatorURL, usesTableApi: false, + isOAuth: false, + clientId: null, + jwtKeyId: null, + userIdentifierValue: null, + }, + }); + }); + + it('should return 200 when creating a servicenow OAuth connector successfully', async () => { + const { body: createdConnector } = await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow action', + connector_type_id: '.servicenow', + config: { + ...mockServiceNowOAuth.config, + apiUrl: serviceNowSimulatorURL, + }, + secrets: mockServiceNowOAuth.secrets, + }) + .expect(200); + + expect(createdConnector).to.eql({ + id: createdConnector.id, + is_preconfigured: false, + is_deprecated: false, + name: 'A servicenow action', + connector_type_id: '.servicenow', + is_missing_secrets: false, + config: { + apiUrl: serviceNowSimulatorURL, + usesTableApi: false, + isOAuth: true, + clientId: mockServiceNowOAuth.config.clientId, + jwtKeyId: mockServiceNowOAuth.config.jwtKeyId, + userIdentifierValue: mockServiceNowOAuth.config.userIdentifierValue, + }, + }); + + const { body: fetchedConnector } = await supertest + .get(`/api/actions/connector/${createdConnector.id}`) + .expect(200); + + expect(fetchedConnector).to.eql({ + id: fetchedConnector.id, + is_preconfigured: false, + is_deprecated: false, + name: 'A servicenow action', + connector_type_id: '.servicenow', + is_missing_secrets: false, + config: { + apiUrl: serviceNowSimulatorURL, + usesTableApi: false, + isOAuth: true, + clientId: mockServiceNowOAuth.config.clientId, + jwtKeyId: mockServiceNowOAuth.config.jwtKeyId, + userIdentifierValue: mockServiceNowOAuth.config.userIdentifierValue, }, }); }); @@ -136,7 +220,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { config: { apiUrl: serviceNowSimulatorURL, }, - secrets: mockServiceNow.secrets, + secrets: mockServiceNowBasic.secrets, }) .expect(200); @@ -147,7 +231,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { expect(fetchedAction.config.usesTableApi).to.be(true); }); - it('should respond with a 400 Bad Request when creating a servicenow action with no apiUrl', async () => { + it('should respond with a 400 Bad Request when creating a servicenow Basic Auth connector with no apiUrl', async () => { await supertest .post('/api/actions/connector') .set('kbn-xsrf', 'foo') @@ -167,7 +251,30 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { }); }); - it('should respond with a 400 Bad Request when creating a servicenow action with a not present in allowedHosts apiUrl', async () => { + it('should respond with a 400 Bad Request when creating a servicenow OAuth connector with no apiUrl', async () => { + await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow action', + connector_type_id: '.servicenow', + config: { + isOAuth: true, + }, + secrets: mockServiceNowOAuth.secrets, + }) + .expect(400) + .then((resp: any) => { + expect(resp.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: + 'error validating action type config: [apiUrl]: expected value of type [string] but got [undefined]', + }); + }); + }); + + it('should respond with a 400 Bad Request when creating a servicenow connector with a not present in allowedHosts apiUrl', async () => { await supertest .post('/api/actions/connector') .set('kbn-xsrf', 'foo') @@ -177,7 +284,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { config: { apiUrl: 'http://servicenow.mynonexistent.com', }, - secrets: mockServiceNow.secrets, + secrets: mockServiceNowBasic.secrets, }) .expect(400) .then((resp: any) => { @@ -190,7 +297,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { }); }); - it('should respond with a 400 Bad Request when creating a servicenow action without secrets', async () => { + it('should respond with a 400 Bad Request when creating a servicenow Basic Auth connector without secrets', async () => { await supertest .post('/api/actions/connector') .set('kbn-xsrf', 'foo') @@ -207,10 +314,107 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { statusCode: 400, error: 'Bad Request', message: - 'error validating action type secrets: [password]: expected value of type [string] but got [undefined]', + 'error validating action type secrets: Either basic auth or OAuth credentials must be specified', }); }); }); + + it('should respond with a 400 Bad Request when creating a servicenow OAuth connector without secrets', async () => { + await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow action', + connector_type_id: '.servicenow', + config: { + ...mockServiceNowOAuth.config, + apiUrl: serviceNowSimulatorURL, + }, + }) + .expect(400) + .then((resp: any) => { + expect(resp.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: + 'error validating action type secrets: Either basic auth or OAuth credentials must be specified', + }); + }); + }); + + it('should respond with a 400 Bad Request when creating a servicenow OAuth connector with missing fields', async () => { + const badConfigs = [ + { + config: { + ...mockServiceNowOAuth.config, + apiUrl: serviceNowSimulatorURL, + clientId: null, + }, + secrets: mockServiceNowOAuth.secrets, + errorMessage: `error validating action type config: clientId must be provided when isOAuth = true`, + }, + { + config: { + ...mockServiceNowOAuth.config, + apiUrl: serviceNowSimulatorURL, + userIdentifierValue: null, + }, + secrets: mockServiceNowOAuth.secrets, + errorMessage: `error validating action type config: userIdentifierValue must be provided when isOAuth = true`, + }, + { + config: { + ...mockServiceNowOAuth.config, + apiUrl: serviceNowSimulatorURL, + jwtKeyId: null, + }, + secrets: mockServiceNowOAuth.secrets, + errorMessage: `error validating action type config: jwtKeyId must be provided when isOAuth = true`, + }, + { + config: { + ...mockServiceNowOAuth.config, + apiUrl: serviceNowSimulatorURL, + }, + secrets: { + ...mockServiceNowOAuth.secrets, + clientSecret: null, + }, + errorMessage: `error validating action type secrets: clientSecret and privateKey must both be specified`, + }, + { + config: { + ...mockServiceNowOAuth.config, + apiUrl: serviceNowSimulatorURL, + }, + secrets: { + ...mockServiceNowOAuth.secrets, + privateKey: null, + }, + errorMessage: `error validating action type secrets: clientSecret and privateKey must both be specified`, + }, + ]; + + await asyncForEach(badConfigs, async (badConfig) => { + await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow action', + connector_type_id: '.servicenow', + config: badConfig.config, + secrets: badConfig.secrets, + }) + .expect(400) + .then((resp: any) => { + expect(resp.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: badConfig.errorMessage, + }); + }); + }); + }); }); describe('ServiceNow ITSM - Executor', () => { @@ -225,7 +429,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { apiUrl: serviceNowSimulatorURL, usesTableApi: false, }, - secrets: mockServiceNow.secrets, + secrets: mockServiceNowBasic.secrets, }); simulatedActionId = body.id; }); @@ -287,7 +491,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'foo') .send({ params: { - ...mockServiceNow.params, + ...mockServiceNowBasic.params, subActionParams: { savedObjectId: 'success', }, @@ -310,10 +514,10 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'foo') .send({ params: { - ...mockServiceNow.params, + ...mockServiceNowBasic.params, subActionParams: { incident: { - ...mockServiceNow.params.subActionParams.incident, + ...mockServiceNowBasic.params.subActionParams.incident, short_description: 'success', }, comments: [{ comment: 'boo' }], @@ -337,10 +541,10 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'foo') .send({ params: { - ...mockServiceNow.params, + ...mockServiceNowBasic.params, subActionParams: { incident: { - ...mockServiceNow.params.subActionParams.incident, + ...mockServiceNowBasic.params.subActionParams.incident, short_description: 'success', }, comments: [{ commentId: 'success' }], @@ -391,9 +595,9 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'foo') .send({ params: { - ...mockServiceNow.params, + ...mockServiceNowBasic.params, subActionParams: { - incident: mockServiceNow.params.subActionParams.incident, + incident: mockServiceNowBasic.params.subActionParams.incident, comments: [], }, }, @@ -427,7 +631,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { apiUrl: serviceNowSimulatorURL, usesTableApi: true, }, - secrets: mockServiceNow.secrets, + secrets: mockServiceNowBasic.secrets, }); simulatedActionId = body.id; }); @@ -438,9 +642,9 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'foo') .send({ params: { - ...mockServiceNow.params, + ...mockServiceNowBasic.params, subActionParams: { - incident: mockServiceNow.params.subActionParams.incident, + incident: mockServiceNowBasic.params.subActionParams.incident, comments: [], }, }, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_sir.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_sir.ts index c27634ecf6aca..0f5640f7edd3e 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_sir.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_sir.ts @@ -7,6 +7,7 @@ import httpProxy from 'http-proxy'; import expect from '@kbn/expect'; +import { asyncForEach } from '@kbn/std'; import getPort from 'get-port'; import http from 'http'; @@ -19,7 +20,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const configService = getService('config'); - const mockServiceNow = { + const mockServiceNowCommon = { config: { apiUrl: 'www.servicenowisinkibanaactions.com', usesTableApi: false, @@ -55,6 +56,33 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { }, }; + const mockServiceNowBasic = { + ...mockServiceNowCommon, + config: { + apiUrl: 'www.servicenowisinkibanaactions.com', + usesTableApi: false, + }, + secrets: { + password: 'elastic', + username: 'changeme', + }, + }; + const mockServiceNowOAuth = { + ...mockServiceNowCommon, + config: { + apiUrl: 'www.servicenowisinkibanaactions.com', + usesTableApi: false, + isOAuth: true, + clientId: 'abc', + userIdentifierValue: 'elastic', + jwtKeyId: 'def', + }, + secrets: { + clientSecret: 'xyz', + privateKey: '-----BEGIN RSA PRIVATE KEY-----\nddddddd\n-----END RSA PRIVATE KEY-----', + }, + }; + describe('ServiceNow SIR', () => { let simulatedActionId = ''; let serviceNowSimulatorURL: string = ''; @@ -86,7 +114,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { }); describe('ServiceNow SIR - Action Creation', () => { - it('should return 200 when creating a servicenow action successfully', async () => { + it('should return 200 when creating a servicenow Basic Auth connector successfully', async () => { const { body: createdAction } = await supertest .post('/api/actions/connector') .set('kbn-xsrf', 'foo') @@ -97,19 +125,24 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { apiUrl: serviceNowSimulatorURL, usesTableApi: false, }, - secrets: mockServiceNow.secrets, + secrets: mockServiceNowBasic.secrets, }) .expect(200); expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_deprecated: false, name: 'A servicenow action', connector_type_id: '.servicenow-sir', is_missing_secrets: false, config: { apiUrl: serviceNowSimulatorURL, usesTableApi: false, + isOAuth: false, + clientId: null, + jwtKeyId: null, + userIdentifierValue: null, }, }); @@ -120,12 +153,71 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_deprecated: false, name: 'A servicenow action', connector_type_id: '.servicenow-sir', is_missing_secrets: false, config: { apiUrl: serviceNowSimulatorURL, usesTableApi: false, + isOAuth: false, + clientId: null, + jwtKeyId: null, + userIdentifierValue: null, + }, + }); + }); + + it('should return 200 when creating a servicenow OAuth connector successfully', async () => { + const { body: createdConnector } = await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow action', + connector_type_id: '.servicenow-sir', + config: { + ...mockServiceNowOAuth.config, + apiUrl: serviceNowSimulatorURL, + }, + secrets: mockServiceNowOAuth.secrets, + }) + .expect(200); + + expect(createdConnector).to.eql({ + id: createdConnector.id, + is_preconfigured: false, + is_deprecated: false, + name: 'A servicenow action', + connector_type_id: '.servicenow-sir', + is_missing_secrets: false, + config: { + apiUrl: serviceNowSimulatorURL, + usesTableApi: false, + isOAuth: true, + clientId: mockServiceNowOAuth.config.clientId, + jwtKeyId: mockServiceNowOAuth.config.jwtKeyId, + userIdentifierValue: mockServiceNowOAuth.config.userIdentifierValue, + }, + }); + + const { body: fetchedConnector } = await supertest + .get(`/api/actions/connector/${createdConnector.id}`) + .expect(200); + + expect(fetchedConnector).to.eql({ + id: fetchedConnector.id, + is_preconfigured: false, + is_deprecated: false, + name: 'A servicenow action', + connector_type_id: '.servicenow-sir', + is_missing_secrets: false, + config: { + apiUrl: serviceNowSimulatorURL, + usesTableApi: false, + isOAuth: true, + clientId: mockServiceNowOAuth.config.clientId, + jwtKeyId: mockServiceNowOAuth.config.jwtKeyId, + userIdentifierValue: mockServiceNowOAuth.config.userIdentifierValue, }, }); }); @@ -140,7 +232,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { config: { apiUrl: serviceNowSimulatorURL, }, - secrets: mockServiceNow.secrets, + secrets: mockServiceNowBasic.secrets, }) .expect(200); @@ -151,7 +243,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { expect(fetchedAction.config.usesTableApi).to.be(true); }); - it('should respond with a 400 Bad Request when creating a servicenow action with no apiUrl', async () => { + it('should respond with a 400 Bad Request when creating a servicenow Basic Auth connector with no apiUrl', async () => { await supertest .post('/api/actions/connector') .set('kbn-xsrf', 'foo') @@ -171,7 +263,30 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { }); }); - it('should respond with a 400 Bad Request when creating a servicenow action with a not present in allowedHosts apiUrl', async () => { + it('should respond with a 400 Bad Request when creating a servicenow OAuth connector with no apiUrl', async () => { + await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow action', + connector_type_id: '.servicenow-sir', + config: { + isOAuth: true, + }, + secrets: mockServiceNowOAuth.secrets, + }) + .expect(400) + .then((resp: any) => { + expect(resp.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: + 'error validating action type config: [apiUrl]: expected value of type [string] but got [undefined]', + }); + }); + }); + + it('should respond with a 400 Bad Request when creating a servicenow connector with a not present in allowedHosts apiUrl', async () => { await supertest .post('/api/actions/connector') .set('kbn-xsrf', 'foo') @@ -181,7 +296,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { config: { apiUrl: 'http://servicenow.mynonexistent.com', }, - secrets: mockServiceNow.secrets, + secrets: mockServiceNowBasic.secrets, }) .expect(400) .then((resp: any) => { @@ -194,7 +309,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { }); }); - it('should respond with a 400 Bad Request when creating a servicenow action without secrets', async () => { + it('should respond with a 400 Bad Request when creating a servicenow Basic Auth connector without secrets', async () => { await supertest .post('/api/actions/connector') .set('kbn-xsrf', 'foo') @@ -211,10 +326,107 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { statusCode: 400, error: 'Bad Request', message: - 'error validating action type secrets: [password]: expected value of type [string] but got [undefined]', + 'error validating action type secrets: Either basic auth or OAuth credentials must be specified', }); }); }); + + it('should respond with a 400 Bad Request when creating a servicenow OAuth connector without secrets', async () => { + await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow action', + connector_type_id: '.servicenow-sir', + config: { + ...mockServiceNowOAuth.config, + apiUrl: serviceNowSimulatorURL, + }, + }) + .expect(400) + .then((resp: any) => { + expect(resp.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: + 'error validating action type secrets: Either basic auth or OAuth credentials must be specified', + }); + }); + }); + + it('should respond with a 400 Bad Request when creating a servicenow OAuth connector with missing fields', async () => { + const badConfigs = [ + { + config: { + ...mockServiceNowOAuth.config, + apiUrl: serviceNowSimulatorURL, + clientId: null, + }, + secrets: mockServiceNowOAuth.secrets, + errorMessage: `error validating action type config: clientId must be provided when isOAuth = true`, + }, + { + config: { + ...mockServiceNowOAuth.config, + apiUrl: serviceNowSimulatorURL, + userIdentifierValue: null, + }, + secrets: mockServiceNowOAuth.secrets, + errorMessage: `error validating action type config: userIdentifierValue must be provided when isOAuth = true`, + }, + { + config: { + ...mockServiceNowOAuth.config, + apiUrl: serviceNowSimulatorURL, + jwtKeyId: null, + }, + secrets: mockServiceNowOAuth.secrets, + errorMessage: `error validating action type config: jwtKeyId must be provided when isOAuth = true`, + }, + { + config: { + ...mockServiceNowOAuth.config, + apiUrl: serviceNowSimulatorURL, + }, + secrets: { + ...mockServiceNowOAuth.secrets, + clientSecret: null, + }, + errorMessage: `error validating action type secrets: clientSecret and privateKey must both be specified`, + }, + { + config: { + ...mockServiceNowOAuth.config, + apiUrl: serviceNowSimulatorURL, + }, + secrets: { + ...mockServiceNowOAuth.secrets, + privateKey: null, + }, + errorMessage: `error validating action type secrets: clientSecret and privateKey must both be specified`, + }, + ]; + + await asyncForEach(badConfigs, async (badConfig) => { + await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow action', + connector_type_id: '.servicenow-sir', + config: badConfig.config, + secrets: badConfig.secrets, + }) + .expect(400) + .then((resp: any) => { + expect(resp.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: badConfig.errorMessage, + }); + }); + }); + }); }); describe('ServiceNow SIR - Executor', () => { @@ -228,8 +440,9 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { config: { apiUrl: serviceNowSimulatorURL, usesTableApi: false, + isOAuth: false, }, - secrets: mockServiceNow.secrets, + secrets: mockServiceNowBasic.secrets, }); simulatedActionId = body.id; }); @@ -291,7 +504,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'foo') .send({ params: { - ...mockServiceNow.params, + ...mockServiceNowBasic.params, subActionParams: { savedObjectId: 'success', }, @@ -314,10 +527,10 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'foo') .send({ params: { - ...mockServiceNow.params, + ...mockServiceNowBasic.params, subActionParams: { incident: { - ...mockServiceNow.params.subActionParams.incident, + ...mockServiceNowBasic.params.subActionParams.incident, short_description: 'success', }, comments: [{ comment: 'boo' }], @@ -341,10 +554,10 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'foo') .send({ params: { - ...mockServiceNow.params, + ...mockServiceNowBasic.params, subActionParams: { incident: { - ...mockServiceNow.params.subActionParams.incident, + ...mockServiceNowBasic.params.subActionParams.incident, short_description: 'success', }, comments: [{ commentId: 'success' }], @@ -395,9 +608,9 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'foo') .send({ params: { - ...mockServiceNow.params, + ...mockServiceNowBasic.params, subActionParams: { - incident: mockServiceNow.params.subActionParams.incident, + incident: mockServiceNowBasic.params.subActionParams.incident, comments: [], }, }, @@ -431,7 +644,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { apiUrl: serviceNowSimulatorURL, usesTableApi: true, }, - secrets: mockServiceNow.secrets, + secrets: mockServiceNowBasic.secrets, }); simulatedActionId = body.id; }); @@ -442,9 +655,9 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'foo') .send({ params: { - ...mockServiceNow.params, + ...mockServiceNowBasic.params, subActionParams: { - incident: mockServiceNow.params.subActionParams.incident, + incident: mockServiceNowBasic.params.subActionParams.incident, comments: [], }, }, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts index 8945c54c843b9..66b988fb9b4eb 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts @@ -59,6 +59,7 @@ export default function slackTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_deprecated: false, is_missing_secrets: false, name: 'A slack action', connector_type_id: '.slack', @@ -74,6 +75,7 @@ export default function slackTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_deprecated: false, is_missing_secrets: false, name: 'A slack action', connector_type_id: '.slack', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/swimlane.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/swimlane.ts index 9647d083460fd..a55e8e30d419a 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/swimlane.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/swimlane.ts @@ -151,6 +151,7 @@ export default function swimlaneTest({ getService }: FtrProviderContext) { id: createdAction.id, is_missing_secrets: false, is_preconfigured: false, + is_deprecated: false, name: 'A swimlane action', }); @@ -163,6 +164,7 @@ export default function swimlaneTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_deprecated: false, is_missing_secrets: false, name: 'A swimlane action', connector_type_id: '.swimlane', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts index 8d879633be2ec..44a74a7a31571 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts @@ -117,6 +117,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_deprecated: false, name: 'A generic Webhook action', connector_type_id: '.webhook', is_missing_secrets: false, @@ -135,6 +136,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_deprecated: false, name: 'A generic Webhook action', connector_type_id: '.webhook', is_missing_secrets: false, @@ -168,6 +170,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_deprecated: false, name: 'A generic Webhook action', connector_type_id: '.webhook', is_missing_secrets: false, @@ -205,6 +208,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_deprecated: false, name: 'A generic Webhook action', connector_type_id: '.webhook', is_missing_secrets: false, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/xmatters.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/xmatters.ts index 83edc6f5a2984..7ce357bc62e36 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/xmatters.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/xmatters.ts @@ -62,6 +62,7 @@ export default function xmattersTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_deprecated: false, name: 'An xmatters action', connector_type_id: '.xmatters', is_missing_secrets: false, @@ -95,6 +96,7 @@ export default function xmattersTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_deprecated: false, name: 'An xmatters action', connector_type_id: '.xmatters', is_missing_secrets: false, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/create.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/create.ts index 87804395fc2b7..06e8017177138 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/create.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/create.ts @@ -59,6 +59,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { expect(response.body).to.eql({ id: response.body.id, is_preconfigured: false, + is_deprecated: false, is_missing_secrets: false, name: 'My action', connector_type_id: 'test.index-record', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/execute.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/execute.ts index 321d14683ee2f..c8433ac60575f 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/execute.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/execute.ts @@ -6,7 +6,7 @@ */ import expect from '@kbn/expect'; -import { IValidatedEvent } from '@kbn/event-log-plugin/server'; +import { IValidatedEvent, nanosToMillis } from '@kbn/event-log-plugin/server'; import { UserAtSpaceScenarios } from '../../scenarios'; import { ESTestIndexTool, @@ -17,8 +17,6 @@ import { } from '../../../common/lib'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; -const NANOS_IN_MILLIS = 1000 * 1000; - // eslint-disable-next-line import/no-default-export export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); @@ -538,14 +536,12 @@ export default function ({ getService }: FtrProviderContext) { const executeEventEnd = Date.parse(executeEvent?.event?.end || 'undefined'); const dateNow = Date.now(); - expect(typeof duration).to.be('number'); + expect(typeof duration).to.be('string'); expect(executeEventStart).to.be.ok(); expect(startExecuteEventStart).to.equal(executeEventStart); expect(executeEventEnd).to.be.ok(); - const durationDiff = Math.abs( - Math.round(duration! / NANOS_IN_MILLIS) - (executeEventEnd - executeEventStart) - ); + const durationDiff = Math.abs(nanosToMillis(duration!) - (executeEventEnd - executeEventStart)); // account for rounding errors expect(durationDiff < 1).to.equal(true); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts index 5a445a4f5f112..9842b13a9745d 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts @@ -64,6 +64,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { id: createdAction.id, is_preconfigured: false, connector_type_id: 'test.index-record', + is_deprecated: false, is_missing_secrets: false, name: 'My action', config: { @@ -150,6 +151,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { connector_type_id: '.slack', name: 'Slack#xyz', is_preconfigured: true, + is_deprecated: false, }); break; default: diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get_all.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get_all.ts index 8ae50b9158487..ab6181369755f 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get_all.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get_all.ts @@ -70,6 +70,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: createdAction.id, is_preconfigured: false, + is_deprecated: false, name: 'My action', connector_type_id: 'test.index-record', is_missing_secrets: false, @@ -81,13 +82,23 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'preconfigured-es-index-action', is_preconfigured: true, + is_deprecated: false, connector_type_id: '.index', name: 'preconfigured_es_index_action', referenced_by_count: 0, }, + { + connector_type_id: '.servicenow', + id: 'my-deprecated-servicenow', + is_preconfigured: true, + is_deprecated: true, + name: 'ServiceNow#xyz', + referenced_by_count: 0, + }, { id: 'my-slack1', is_preconfigured: true, + is_deprecated: false, connector_type_id: '.slack', name: 'Slack#xyz', referenced_by_count: 0, @@ -95,6 +106,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'custom-system-abc-connector', is_preconfigured: true, + is_deprecated: false, connector_type_id: 'system-abc-action-type', name: 'SystemABC', referenced_by_count: 0, @@ -102,6 +114,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'preconfigured.test.index-record', is_preconfigured: true, + is_deprecated: false, connector_type_id: 'test.index-record', name: 'Test:_Preconfigured_Index_Record', referenced_by_count: 0, @@ -184,6 +197,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: createdAction.id, is_preconfigured: false, + is_deprecated: false, name: 'My action', connector_type_id: 'test.index-record', is_missing_secrets: false, @@ -195,13 +209,23 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'preconfigured-es-index-action', is_preconfigured: true, + is_deprecated: false, connector_type_id: '.index', name: 'preconfigured_es_index_action', referenced_by_count: 0, }, + { + connector_type_id: '.servicenow', + id: 'my-deprecated-servicenow', + is_deprecated: true, + is_preconfigured: true, + name: 'ServiceNow#xyz', + referenced_by_count: 0, + }, { id: 'my-slack1', is_preconfigured: true, + is_deprecated: false, connector_type_id: '.slack', name: 'Slack#xyz', referenced_by_count: 0, @@ -209,6 +233,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'custom-system-abc-connector', is_preconfigured: true, + is_deprecated: false, connector_type_id: 'system-abc-action-type', name: 'SystemABC', referenced_by_count: 0, @@ -216,6 +241,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'preconfigured.test.index-record', is_preconfigured: true, + is_deprecated: false, connector_type_id: 'test.index-record', name: 'Test:_Preconfigured_Index_Record', referenced_by_count: 0, @@ -274,13 +300,23 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'preconfigured-es-index-action', is_preconfigured: true, + is_deprecated: false, connector_type_id: '.index', name: 'preconfigured_es_index_action', referenced_by_count: 0, }, + { + connector_type_id: '.servicenow', + id: 'my-deprecated-servicenow', + is_preconfigured: true, + is_deprecated: true, + name: 'ServiceNow#xyz', + referenced_by_count: 0, + }, { id: 'my-slack1', is_preconfigured: true, + is_deprecated: false, connector_type_id: '.slack', name: 'Slack#xyz', referenced_by_count: 0, @@ -288,6 +324,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'custom-system-abc-connector', is_preconfigured: true, + is_deprecated: false, connector_type_id: 'system-abc-action-type', name: 'SystemABC', referenced_by_count: 0, @@ -295,6 +332,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'preconfigured.test.index-record', is_preconfigured: true, + is_deprecated: false, connector_type_id: 'test.index-record', name: 'Test:_Preconfigured_Index_Record', referenced_by_count: 0, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/update.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/update.ts index 31cb9ac03b91b..92bb7084ec534 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/update.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/update.ts @@ -73,6 +73,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { expect(response.body).to.eql({ id: createdAction.id, is_preconfigured: false, + is_deprecated: false, connector_type_id: 'test.index-record', is_missing_secrets: false, name: 'My action updated', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/alerts.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/alerts.ts index 15e648bb2166c..407d6467296e4 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/alerts.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/alerts.ts @@ -8,7 +8,7 @@ import expect from '@kbn/expect'; import { omit } from 'lodash'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { IValidatedEvent } from '@kbn/event-log-plugin/server'; +import { IValidatedEvent, nanosToMillis } from '@kbn/event-log-plugin/server'; import { TaskRunning, TaskRunningStage } from '@kbn/task-manager-plugin/server/task_running'; import { ConcreteTaskInstance } from '@kbn/task-manager-plugin/server'; import { UserAtSpaceScenarios, Superuser } from '../../scenarios'; @@ -25,8 +25,6 @@ import { getEventLog, } from '../../../common/lib'; -const NANOS_IN_MILLIS = 1000 * 1000; - // eslint-disable-next-line import/no-default-export export default function alertTests({ getService }: FtrProviderContext) { const supertest = getService('supertest'); @@ -1303,13 +1301,11 @@ instanceStateValue: true const eventEnd = Date.parse(event?.event?.end || 'undefined'); const dateNow = Date.now(); - expect(typeof duration).to.be('number'); + expect(typeof duration).to.be('string'); expect(eventStart).to.be.ok(); expect(eventEnd).to.be.ok(); - const durationDiff = Math.abs( - Math.round(duration! / NANOS_IN_MILLIS) - (eventEnd - eventStart) - ); + const durationDiff = Math.abs(nanosToMillis(duration!) - (eventEnd - eventStart)); // account for rounding errors expect(durationDiff < 1).to.equal(true); @@ -1332,6 +1328,10 @@ instanceStateValue: true expect(event?.kibana?.alert?.rule?.execution?.metrics?.number_of_searches).to.be(0); expect(event?.kibana?.alert?.rule?.execution?.metrics?.es_search_duration_ms).to.be(0); expect(event?.kibana?.alert?.rule?.execution?.metrics?.total_search_duration_ms).to.be(0); + expect(event?.kibana?.alert?.rule?.execution?.metrics?.number_of_active_alerts).to.be(1); + expect(event?.kibana?.alert?.rule?.execution?.metrics?.number_of_new_alerts).to.be(1); + expect(event?.kibana?.alert?.rule?.execution?.metrics?.number_of_recovered_alerts).to.be(0); + expect(event?.kibana?.alert?.rule?.execution?.metrics?.total_number_of_alerts).to.be(1); expect(event?.rule).to.eql({ id: alertId, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/index.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/index.ts index a1e23db7944f1..9dd7326aa4663 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/index.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/index.ts @@ -11,7 +11,9 @@ import { setupSpacesAndUsers, tearDown } from '..'; // eslint-disable-next-line import/no-default-export export default function alertingTests({ loadTestFile, getService }: FtrProviderContext) { describe('Alerts', () => { - describe('legacy alerts', () => { + describe('legacy alerts', function () { + this.tags('ciGroup17'); + before(async () => { await setupSpacesAndUsers(getService); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/telemetry/actions_telemetry.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/telemetry/actions_telemetry.ts index 350f0019641b8..1d8d0091b67de 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/telemetry/actions_telemetry.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/telemetry/actions_telemetry.ts @@ -188,7 +188,7 @@ export default function createActionsTelemetryTests({ getService }: FtrProviderC const telemetry = JSON.parse(taskState!); // total number of connectors - expect(telemetry.count_total).to.equal(17); + expect(telemetry.count_total).to.equal(18); // total number of active connectors (used by a rule) expect(telemetry.count_active_total).to.equal(7); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/telemetry/alerting_telemetry.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/telemetry/alerting_telemetry.ts index 4a5395b76c694..afc39bf1c6b74 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/telemetry/alerting_telemetry.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/telemetry/alerting_telemetry.ts @@ -382,8 +382,8 @@ export default function createAlertingTelemetryTests({ getService }: FtrProvider // percentile calculations for number of scheduled actions expect(telemetry.percentile_num_generated_actions_per_day.p50 >= 0).to.be(true); - expect(telemetry.percentile_num_generated_actions_per_day.p90 > 0).to.be(true); - expect(telemetry.percentile_num_generated_actions_per_day.p99 > 0).to.be(true); + expect(telemetry.percentile_num_generated_actions_per_day.p90).to.be.greaterThan(0); + expect(telemetry.percentile_num_generated_actions_per_day.p99).to.be.greaterThan(0); // percentile calculations by rule type. most of these rule types don't schedule actions so they should all be 0 expect( @@ -432,17 +432,69 @@ export default function createAlertingTelemetryTests({ getService }: FtrProvider // this rule type does schedule actions so should be least 1 action scheduled expect( - telemetry.percentile_num_generated_actions_by_type_per_day.p50['test__cumulative-firing'] >= - 1 - ).to.be(true); + telemetry.percentile_num_generated_actions_by_type_per_day.p50['test__cumulative-firing'] + ).to.be.greaterThan(0); expect( - telemetry.percentile_num_generated_actions_by_type_per_day.p90['test__cumulative-firing'] >= - 1 - ).to.be(true); + telemetry.percentile_num_generated_actions_by_type_per_day.p90['test__cumulative-firing'] + ).to.be.greaterThan(0); expect( - telemetry.percentile_num_generated_actions_by_type_per_day.p99['test__cumulative-firing'] >= - 1 - ).to.be(true); + telemetry.percentile_num_generated_actions_by_type_per_day.p99['test__cumulative-firing'] + ).to.be.greaterThan(0); + + // percentile calculations for number of alerts + expect(telemetry.percentile_num_alerts_per_day.p50 >= 0).to.be(true); + expect(telemetry.percentile_num_alerts_per_day.p90).to.be.greaterThan(0); + expect(telemetry.percentile_num_alerts_per_day.p99).to.be.greaterThan(0); + + // percentile calculations by rule type. most of these rule types don't generate alerts so they should all be 0 + expect( + telemetry.percentile_num_alerts_by_type_per_day.p50['example__always-firing'] + ).to.equal(0); + expect( + telemetry.percentile_num_alerts_by_type_per_day.p90['example__always-firing'] + ).to.equal(0); + expect( + telemetry.percentile_num_alerts_by_type_per_day.p99['example__always-firing'] + ).to.equal(0); + + expect( + telemetry.percentile_num_alerts_by_type_per_day.p50.test__onlyContextVariables + ).to.equal(0); + expect( + telemetry.percentile_num_alerts_by_type_per_day.p90.test__onlyContextVariables + ).to.equal(0); + expect( + telemetry.percentile_num_alerts_by_type_per_day.p99.test__onlyContextVariables + ).to.equal(0); + + expect(telemetry.percentile_num_alerts_by_type_per_day.p50.test__noop).to.equal(0); + expect(telemetry.percentile_num_alerts_by_type_per_day.p90.test__noop).to.equal(0); + expect(telemetry.percentile_num_alerts_by_type_per_day.p99.test__noop).to.equal(0); + + expect(telemetry.percentile_num_alerts_by_type_per_day.p50.test__throw).to.equal(0); + expect(telemetry.percentile_num_alerts_by_type_per_day.p90.test__throw).to.equal(0); + expect(telemetry.percentile_num_alerts_by_type_per_day.p99.test__throw).to.equal(0); + + expect(telemetry.percentile_num_alerts_by_type_per_day.p50.test__multipleSearches).to.equal( + 0 + ); + expect(telemetry.percentile_num_alerts_by_type_per_day.p90.test__multipleSearches).to.equal( + 0 + ); + expect(telemetry.percentile_num_alerts_by_type_per_day.p99.test__multipleSearches).to.equal( + 0 + ); + + // this rule type does generate alerts so should be least 1 alert + expect( + telemetry.percentile_num_alerts_by_type_per_day.p50['test__cumulative-firing'] + ).to.be.greaterThan(0); + expect( + telemetry.percentile_num_alerts_by_type_per_day.p90['test__cumulative-firing'] + ).to.be.greaterThan(0); + expect( + telemetry.percentile_num_alerts_by_type_per_day.p99['test__cumulative-firing'] + ).to.be.greaterThan(0); }); }); } diff --git a/x-pack/test/alerting_api_integration/spaces_only/config.ts b/x-pack/test/alerting_api_integration/spaces_only/config.ts index 204f5b27da9d5..dcf1c70cf8dca 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/config.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/config.ts @@ -7,6 +7,8 @@ import { createTestConfig } from '../common/config'; +export const EmailDomainsAllowed = ['example.org', 'test.com']; + // eslint-disable-next-line import/no-default-export export default createTestConfig('spaces_only', { disabledPlugins: ['security'], @@ -15,4 +17,5 @@ export default createTestConfig('spaces_only', { verificationMode: 'none', customizeLocalHostSsl: true, preconfiguredAlertHistoryEsIndex: true, + emailDomainsAllowed: EmailDomainsAllowed, }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/email.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/email.ts new file mode 100644 index 0000000000000..22d46b3918932 --- /dev/null +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/email.ts @@ -0,0 +1,175 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import expect from '@kbn/expect'; + +import { FtrProviderContext } from '../../../../common/ftr_provider_context'; +import { ObjectRemover } from '../../../../common/lib'; +import { EmailDomainsAllowed } from '../../../config'; + +const EmailDomainAllowed = EmailDomainsAllowed[EmailDomainsAllowed.length - 1]; + +// eslint-disable-next-line import/no-default-export +export default function emailTest({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + const objectRemover = new ObjectRemover(supertest); + + describe('email connector', () => { + afterEach(() => objectRemover.removeAll()); + + it('succeeds with allowed email domains', async () => { + const from = `bob@${EmailDomainAllowed}`; + const conn = await createConnector(from); + expect(conn.status).to.be(200); + + const { id } = conn.body; + expect(id).to.be.a('string'); + + const to = EmailDomainsAllowed.map((domain) => `jeb@${domain}`).sort(); + const cc = EmailDomainsAllowed.map((domain) => `jim@${domain}`).sort(); + const bcc = EmailDomainsAllowed.map((domain) => `joe@${domain}`).sort(); + + const ccNames = cc.map((email) => `Jimmy Jack <${email}>`); + + const run = await runConnector(id, to, ccNames, bcc); + expect(run.status).to.be(200); + + const { status, data } = run.body || {}; + expect(status).to.be('ok'); + + const { message } = data || {}; + const { from: fromMsg } = message || {}; + + expect(fromMsg?.address).to.be(from); + expect(addressesFromMessage(message, 'to')).to.eql(to); + expect(addressesFromMessage(message, 'cc')).to.eql(cc); + expect(addressesFromMessage(message, 'bcc')).to.eql(bcc); + + const ccNamesMsg = namesFromMessage(message, 'cc'); + for (const ccName of ccNamesMsg) { + expect(ccName).to.be('Jimmy Jack'); + } + }); + + describe('fails for invalid email domains', () => { + it('in create when invalid "from" used', async () => { + const from = `bob@not.allowed`; + const { status, body } = await createConnector(from); + expect(status).to.be(400); + + const { message = 'no message returned' } = body || {}; + expect(message).to.match(/not allowed emails: bob@not.allowed/); + }); + + it('in execute when invalid "to", "cc" or "bcc" used', async () => { + const from = `bob@${EmailDomainAllowed}`; + const conn = await createConnector(from); + expect(conn.status).to.be(200); + + const { id } = conn.body || {}; + expect(id).to.be.a('string'); + + const to = EmailDomainsAllowed.map((domain) => `jeb@${domain}`).sort(); + const cc = EmailDomainsAllowed.map((domain) => `jim@${domain}`).sort(); + const bcc = EmailDomainsAllowed.map((domain) => `joe@${domain}`).sort(); + + to.push('jeb1@not.allowed'); + cc.push('jeb2@not.allowed'); + bcc.push('jeb3@not.allowed'); + + const { status, body } = await runConnector(id, to, cc, bcc); + expect(status).to.be(200); + + expect(body?.status).to.be('error'); + expect(body?.message).to.match( + /not allowed emails: jeb1@not.allowed, jeb2@not.allowed, jeb3@not.allowed/ + ); + }); + }); + }); + + /* returns the following `body`, for the special email __json service: + { + "status": "ok", + "data": { + "envelope": { + "from": "bob@example.org", + "to": [ "jeb@example.com", ...] + }, + "messageId": "", + "message": { + "from": { "address": "bob@example.org", "name": "" }, + "to": [ { "address": "jeb@example.com", "name": "" }, ...], + "cc": [ ... ], + "bcc": [ ... ], + ... + } + }, + ... + } + */ + async function createConnector(from: string): Promise<{ status: number; body: any }> { + const { status, body } = await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'foo') + .send({ + name: `An email connector from ${__filename}`, + connector_type_id: '.email', + config: { + service: '__json', + from, + hasAuth: true, + }, + secrets: { + user: 'bob', + password: 'changeme', + }, + }); + + if (status === 200) { + objectRemover.add('default', body.id, 'connector', 'actions'); + } + + return { status, body }; + } + + async function runConnector( + id: string, + to: string[], + cc: string[], + bcc: string[] + ): Promise<{ status: number; body: any }> { + const subject = 'email-subject'; + const message = 'email-message'; + const { status, body } = await supertest + .post(`/api/actions/connector/${id}/_execute`) + .set('kbn-xsrf', 'foo') + .send({ params: { to, cc, bcc, subject, message } }); + + return { status, body }; + } +} + +function addressesFromMessage(message: any, which: 'to' | 'cc' | 'bcc'): string[] { + return addressFieldFromMessage(message, which, 'address'); +} + +function namesFromMessage(message: any, which: 'to' | 'cc' | 'bcc'): string[] { + return addressFieldFromMessage(message, which, 'name'); +} + +function addressFieldFromMessage( + message: any, + which1: 'to' | 'cc' | 'bcc', + which2: 'name' | 'address' +): string[] { + const result: string[] = []; + + const list = message?.[which1]; + if (!Array.isArray(list)) return result; + + return list.map((entry) => `${entry?.[which2]}`).sort(); +} diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts index 3bc8cec9bf163..5424b18599f64 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts @@ -39,6 +39,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, isPreconfigured: false, + isDeprecated: false, name: 'An index action', actionTypeId: '.index', isMissingSecrets: false, @@ -58,6 +59,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, isPreconfigured: false, + isDeprecated: false, isMissingSecrets: false, name: 'An index action', actionTypeId: '.index', @@ -82,6 +84,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(createdActionWithIndex).to.eql({ id: createdActionWithIndex.id, isPreconfigured: false, + isDeprecated: false, name: 'An index action with index config', actionTypeId: '.index', isMissingSecrets: false, @@ -101,6 +104,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(fetchedActionWithIndex).to.eql({ id: fetchedActionWithIndex.id, isPreconfigured: false, + isDeprecated: false, name: 'An index action with index config', actionTypeId: '.index', isMissingSecrets: false, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts index 95b465e08647f..9312ad8a90335 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts @@ -39,6 +39,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { expect(response.body).to.eql({ id: response.body.id, is_preconfigured: false, + is_deprecated: false, name: 'My action', connector_type_id: 'test.index-record', is_missing_secrets: false, @@ -78,6 +79,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { expect(response.body).to.eql({ id: response.body.id, isPreconfigured: false, + isDeprecated: false, name: 'My action', actionTypeId: 'test.index-record', isMissingSecrets: false, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts index 06e077f4b9de4..24c6427fdf2f6 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts @@ -6,7 +6,7 @@ */ import type { Client } from '@elastic/elasticsearch'; import expect from '@kbn/expect'; -import { IValidatedEvent } from '@kbn/event-log-plugin/server'; +import { IValidatedEvent, nanosToMillis } from '@kbn/event-log-plugin/server'; import { Spaces } from '../../scenarios'; import { ESTestIndexTool, @@ -17,8 +17,6 @@ import { } from '../../../common/lib'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; -const NANOS_IN_MILLIS = 1000 * 1000; - // eslint-disable-next-line import/no-default-export export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); @@ -372,14 +370,12 @@ export default function ({ getService }: FtrProviderContext) { const executeEventEnd = Date.parse(executeEvent?.event?.end || 'undefined'); const dateNow = Date.now(); - expect(typeof duration).to.be('number'); + expect(typeof duration).to.be('string'); expect(executeEventStart).to.be.ok(); expect(startExecuteEventStart).to.equal(executeEventStart); expect(executeEventEnd).to.be.ok(); - const durationDiff = Math.abs( - Math.round(duration! / NANOS_IN_MILLIS) - (executeEventEnd - executeEventStart) - ); + const durationDiff = Math.abs(nanosToMillis(duration!) - (executeEventEnd - executeEventStart)); // account for rounding errors expect(durationDiff < 1).to.equal(true); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts index e08d99a694399..d5d5109b6e738 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts @@ -40,6 +40,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { .expect(200, { id: createdAction.id, is_preconfigured: false, + is_deprecated: false, is_missing_secrets: false, connector_type_id: 'test.index-record', name: 'My action', @@ -81,11 +82,24 @@ export default function getActionTests({ getService }: FtrProviderContext) { .expect(200, { id: 'my-slack1', is_preconfigured: true, + is_deprecated: false, connector_type_id: '.slack', name: 'Slack#xyz', }); }); + it('should handle get action request for deprecated connectors from preconfigured list', async () => { + await supertest + .get(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector/my-deprecated-servicenow`) + .expect(200, { + id: 'my-deprecated-servicenow', + is_preconfigured: true, + is_deprecated: true, + connector_type_id: '.servicenow', + name: 'ServiceNow#xyz', + }); + }); + describe('legacy', () => { it('should handle get action request appropriately', async () => { const { body: createdAction } = await supertest @@ -109,6 +123,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { .expect(200, { id: createdAction.id, isPreconfigured: false, + isDeprecated: false, actionTypeId: 'test.index-record', isMissingSecrets: false, name: 'My action', @@ -150,6 +165,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { .expect(200, { id: 'my-slack1', isPreconfigured: true, + isDeprecated: false, actionTypeId: '.slack', name: 'Slack#xyz', }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts index a965b1716a671..54a0e6e10a198 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts @@ -52,11 +52,13 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { name: 'Alert history Elasticsearch index', connector_type_id: '.index', is_preconfigured: true, + is_deprecated: false, referenced_by_count: 0, }, { id: createdAction.id, is_preconfigured: false, + is_deprecated: false, name: 'My action', connector_type_id: 'test.index-record', is_missing_secrets: false, @@ -68,13 +70,23 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'preconfigured-es-index-action', is_preconfigured: true, + is_deprecated: false, connector_type_id: '.index', name: 'preconfigured_es_index_action', referenced_by_count: 0, }, + { + connector_type_id: '.servicenow', + id: 'my-deprecated-servicenow', + is_deprecated: true, + is_preconfigured: true, + name: 'ServiceNow#xyz', + referenced_by_count: 0, + }, { id: 'my-slack1', is_preconfigured: true, + is_deprecated: false, connector_type_id: '.slack', name: 'Slack#xyz', referenced_by_count: 0, @@ -82,6 +94,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'custom-system-abc-connector', is_preconfigured: true, + is_deprecated: false, connector_type_id: 'system-abc-action-type', name: 'SystemABC', referenced_by_count: 0, @@ -89,6 +102,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'preconfigured.test.index-record', is_preconfigured: true, + is_deprecated: false, connector_type_id: 'test.index-record', name: 'Test:_Preconfigured_Index_Record', referenced_by_count: 0, @@ -129,18 +143,29 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { name: 'Alert history Elasticsearch index', connector_type_id: '.index', is_preconfigured: true, + is_deprecated: false, referenced_by_count: 0, }, { id: 'preconfigured-es-index-action', is_preconfigured: true, + is_deprecated: false, connector_type_id: '.index', name: 'preconfigured_es_index_action', referenced_by_count: 0, }, + { + connector_type_id: '.servicenow', + id: 'my-deprecated-servicenow', + is_deprecated: true, + is_preconfigured: true, + name: 'ServiceNow#xyz', + referenced_by_count: 0, + }, { id: 'my-slack1', is_preconfigured: true, + is_deprecated: false, connector_type_id: '.slack', name: 'Slack#xyz', referenced_by_count: 0, @@ -148,6 +173,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'custom-system-abc-connector', is_preconfigured: true, + is_deprecated: false, connector_type_id: 'system-abc-action-type', name: 'SystemABC', referenced_by_count: 0, @@ -155,6 +181,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'preconfigured.test.index-record', is_preconfigured: true, + is_deprecated: false, connector_type_id: 'test.index-record', name: 'Test:_Preconfigured_Index_Record', referenced_by_count: 0, @@ -196,11 +223,13 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { name: 'Alert history Elasticsearch index', actionTypeId: '.index', isPreconfigured: true, + isDeprecated: false, referencedByCount: 0, }, { id: createdAction.id, isPreconfigured: false, + isDeprecated: false, name: 'My action', actionTypeId: 'test.index-record', isMissingSecrets: false, @@ -212,13 +241,23 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'preconfigured-es-index-action', isPreconfigured: true, + isDeprecated: false, actionTypeId: '.index', name: 'preconfigured_es_index_action', referencedByCount: 0, }, + { + actionTypeId: '.servicenow', + id: 'my-deprecated-servicenow', + isDeprecated: true, + isPreconfigured: true, + name: 'ServiceNow#xyz', + referencedByCount: 0, + }, { id: 'my-slack1', isPreconfigured: true, + isDeprecated: false, actionTypeId: '.slack', name: 'Slack#xyz', referencedByCount: 0, @@ -226,6 +265,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'custom-system-abc-connector', isPreconfigured: true, + isDeprecated: false, actionTypeId: 'system-abc-action-type', name: 'SystemABC', referencedByCount: 0, @@ -233,6 +273,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'preconfigured.test.index-record', isPreconfigured: true, + isDeprecated: false, actionTypeId: 'test.index-record', name: 'Test:_Preconfigured_Index_Record', referencedByCount: 0, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/index.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/index.ts index fc0b23290a865..20498981ac2eb 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/index.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/index.ts @@ -22,6 +22,7 @@ export default function actionsTests({ loadTestFile, getService }: FtrProviderCo loadTestFile(require.resolve('./update')); loadTestFile(require.resolve('./execute')); loadTestFile(require.resolve('./enqueue')); + loadTestFile(require.resolve('./builtin_action_types/email')); loadTestFile(require.resolve('./builtin_action_types/es_index')); loadTestFile(require.resolve('./builtin_action_types/webhook')); loadTestFile(require.resolve('./builtin_action_types/preconfigured_alert_history_connector')); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/migrations.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/migrations.ts index 7b28161c18238..4f23a5ff3a727 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/migrations.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/migrations.ts @@ -6,6 +6,7 @@ */ import expect from '@kbn/expect'; +import { asyncForEach } from '@kbn/std'; import { getUrlPrefix } from '../../../common/lib'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; @@ -83,6 +84,23 @@ export default function createGetTests({ getService }: FtrProviderContext) { expect(connectorWithoutService.body.config.service).to.eql('other'); }); + it('8.3.0 migrates service now connectors to have `isOAuth` property', async () => { + const serviceNowConnectorIds = [ + '7d04bc30-c4c0-11ec-ae29-917aa31a5b75', + '8a9331b0-c4c0-11ec-ae29-917aa31a5b75', + '6d3a1250-c4c0-11ec-ae29-917aa31a5b75', + ]; + + await asyncForEach(serviceNowConnectorIds, async (serviceNowConnectorId) => { + const connectorResponse = await supertest.get( + `${getUrlPrefix(``)}/api/actions/action/${serviceNowConnectorId}` + ); + + expect(connectorResponse.status).to.eql(200); + expect(connectorResponse.body.config.isOAuth).to.eql(false); + }); + }); + it('decryption error during migration', async () => { const badEmailConnector = await supertest.get( `${getUrlPrefix(``)}/api/actions/connector/0f8f2810-0a59-11ec-9a7c-fd0c2b83ff7d` diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/type_not_enabled.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/type_not_enabled.ts index eafe4f487773f..0ab9baad0b554 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/type_not_enabled.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/type_not_enabled.ts @@ -62,6 +62,7 @@ export default function typeNotEnabledTests({ getService }: FtrProviderContext) config: {}, id: 'uuid-actionId', isPreconfigured: false, + isDeprecated: false, isMissingSecrets: false, name: 'an action created before test.not-enabled was disabled', }); @@ -90,6 +91,7 @@ export default function typeNotEnabledTests({ getService }: FtrProviderContext) config: {}, id: 'uuid-actionId', isPreconfigured: false, + isDeprecated: false, isMissingSecrets: false, name: 'an action created before test.not-enabled was disabled', }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts index f779a97eafe2e..fad31d0bd3a12 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts @@ -51,6 +51,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .expect(200, { id: createdAction.id, is_preconfigured: false, + is_deprecated: false, connector_type_id: 'test.index-record', is_missing_secrets: false, name: 'My action updated', @@ -193,6 +194,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .expect(200, { id: createdAction.id, isPreconfigured: false, + isDeprecated: false, actionTypeId: 'test.index-record', isMissingSecrets: false, name: 'My action updated', diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/alert.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/alert.ts index 0c27868e3fbb6..e7e750a92b12c 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/alert.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/alert.ts @@ -35,8 +35,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { const esTestIndexTool = new ESTestIndexTool(es, retry); const esTestIndexToolOutput = new ESTestIndexTool(es, retry, ES_TEST_OUTPUT_INDEX_NAME); - // Failing: See https://github.com/elastic/kibana/issues/126949 - describe.skip('rule', async () => { + describe('rule', async () => { let endDate: string; let connectorId: string; const objectRemover = new ObjectRemover(supertest); @@ -55,7 +54,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { endDate = new Date(endDateMillis).toISOString(); // write documents from now to the future end date in 3 groups - createEsDocumentsInGroups(3); + await createEsDocumentsInGroups(3); }); afterEach(async () => { @@ -102,9 +101,6 @@ export default function ruleTests({ getService }: FtrProviderContext) { }); it('runs correctly: count grouped <= =>', async () => { - // create some more documents in the first group - createEsDocumentsInGroups(1); - await createRule({ name: 'never fire', aggType: 'count', @@ -125,6 +121,9 @@ export default function ruleTests({ getService }: FtrProviderContext) { threshold: [0], }); + // create some more documents in the first group + await createEsDocumentsInGroups(1); + const docs = await waitForDocs(4); let inGroup0 = 0; @@ -146,9 +145,6 @@ export default function ruleTests({ getService }: FtrProviderContext) { }); it('runs correctly: sum all between', async () => { - // create some more documents in the first group - createEsDocumentsInGroups(1); - await createRule({ name: 'never fire', aggType: 'sum', @@ -167,6 +163,9 @@ export default function ruleTests({ getService }: FtrProviderContext) { threshold: [0, 1000000], }); + // create some more documents in the first group + await createEsDocumentsInGroups(1); + const docs = await waitForDocs(2); for (const doc of docs) { const { name, message } = doc._source.params; @@ -180,9 +179,6 @@ export default function ruleTests({ getService }: FtrProviderContext) { }); it('runs correctly: avg all', async () => { - // create some more documents in the first group - createEsDocumentsInGroups(1); - // this never fires because of bad fields error await createRule({ name: 'never fire', @@ -203,6 +199,9 @@ export default function ruleTests({ getService }: FtrProviderContext) { threshold: [0], }); + // create some more documents in the first group + await createEsDocumentsInGroups(1); + const docs = await waitForDocs(4); for (const doc of docs) { const { name, message } = doc._source.params; @@ -216,9 +215,6 @@ export default function ruleTests({ getService }: FtrProviderContext) { }); it('runs correctly: max grouped', async () => { - // create some more documents in the first group - createEsDocumentsInGroups(1); - await createRule({ name: 'never fire', aggType: 'max', @@ -241,6 +237,9 @@ export default function ruleTests({ getService }: FtrProviderContext) { threshold: [0], }); + // create some more documents in the first group + await createEsDocumentsInGroups(1); + const docs = await waitForDocs(4); let inGroup2 = 0; @@ -262,9 +261,6 @@ export default function ruleTests({ getService }: FtrProviderContext) { }); it('runs correctly: min grouped', async () => { - // create some more documents in the first group - createEsDocumentsInGroups(1); - await createRule({ name: 'never fire', aggType: 'min', @@ -287,6 +283,9 @@ export default function ruleTests({ getService }: FtrProviderContext) { threshold: [0], }); + // create some more documents in the first group + await createEsDocumentsInGroups(1); + const docs = await waitForDocs(4); let inGroup0 = 0; @@ -316,9 +315,11 @@ export default function ruleTests({ getService }: FtrProviderContext) { groupBy: 'all', thresholdComparator: '<', threshold: [10], - timeWindowSize: 60, + notifyWhen: 'onActionGroupChange', }); + await waitForDocs(1); + await createEsDocumentsInGroups(1); const docs = await waitForDocs(2); @@ -334,7 +335,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { expect(activeGroup).to.be('all documents'); expect(activeTitle).to.be('alert fire then recovers group all documents met threshold'); expect(activeMessage).to.match( - /alert 'fire then recovers' is active for group \'all documents\':\n\n- Value: \d+\n- Conditions Met: count is less than 10 over 60s\n- Timestamp: \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/ + /alert 'fire then recovers' is active for group \'all documents\':\n\n- Value: \d+\n- Conditions Met: count is less than 10 over 15s\n- Timestamp: \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/ ); const recoveredDoc = docs[1]; @@ -349,7 +350,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { expect(recoveredGroup).to.be('all documents'); expect(recoveredTitle).to.be('alert fire then recovers group all documents recovered'); expect(recoveredMessage).to.match( - /alert 'fire then recovers' is recovered for group \'all documents\':\n\n- Value: \d+\n- Conditions Met: count is NOT less than 10 over 60s\n- Timestamp: \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/ + /alert 'fire then recovers' is recovered for group \'all documents\':\n\n- Value: \d+\n- Conditions Met: count is NOT less than 10 over 15s\n- Timestamp: \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/ ); }); @@ -383,6 +384,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { termSize?: number; thresholdComparator: string; threshold: number[]; + notifyWhen?: string; } async function createRule(params: CreateRuleParams): Promise { @@ -441,7 +443,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { rule_type_id: RULE_TYPE_ID, schedule: { interval: `${RULE_INTERVAL_SECONDS}s` }, actions: [action, recoveryAction], - notify_when: 'onActiveAlert', + notify_when: params.notifyWhen || 'onActiveAlert', params: { index: ES_TEST_INDEX_NAME, timeField: params.timeField || 'date', diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/create_test_data.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/create_test_data.ts index ba063044d9233..943682d185cd6 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/create_test_data.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/create_test_data.ts @@ -33,6 +33,7 @@ export async function createEsDocuments( ) { const endDateMillis = Date.parse(endDate) - intervalMillis / 2; + const promises: Array> = []; times(intervals, (interval) => { const date = endDateMillis - interval * intervalMillis; @@ -41,9 +42,10 @@ export async function createEsDocuments( // don't need await on these, wait at the end of the function times(groups, (group) => { - createEsDocument(es, date, testedValue + group, `group-${group}`); + promises.push(createEsDocument(es, date, testedValue + group, `group-${group}`)); }); }); + await Promise.all(promises); const totalDocuments = intervals * groups; await esTestIndexTool.waitForDocs(DOCUMENT_SOURCE, DOCUMENT_REFERENCE, totalDocuments); @@ -67,6 +69,7 @@ async function createEsDocument( const response = await es.index({ id: uuid(), index: ES_TEST_INDEX_NAME, + refresh: 'wait_for', body: document, }); // console.log(`writing document to ${ES_TEST_INDEX_NAME}:`, JSON.stringify(document, null, 4)); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/capped_action_type.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/capped_action_type.ts new file mode 100644 index 0000000000000..374dbddfc17b4 --- /dev/null +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/capped_action_type.ts @@ -0,0 +1,127 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { Spaces } from '../../scenarios'; +import { FtrProviderContext } from '../../../common/ftr_provider_context'; +import { getEventLog, getTestRuleData, getUrlPrefix, ObjectRemover } from '../../../common/lib'; + +// eslint-disable-next-line import/no-default-export +export default function createCappedActionsTests({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + const retry = getService('retry'); + + describe('Capped action type', () => { + const objectRemover = new ObjectRemover(supertest); + + after(() => objectRemover.removeAll()); + + it('should not trigger actions more than connector types limit', async () => { + const { body: createdAction01 } = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`) + .set('kbn-xsrf', 'foo') + .send({ + name: 'MY action', + connector_type_id: 'test.capped', + config: {}, + secrets: {}, + }) + .expect(200); + const { body: createdAction02 } = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`) + .set('kbn-xsrf', 'foo') + .send({ + name: 'MY action', + connector_type_id: 'test.capped', + config: {}, + secrets: {}, + }) + .expect(200); + const { body: createdAction03 } = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`) + .set('kbn-xsrf', 'foo') + .send({ + name: 'MY action', + connector_type_id: 'test.capped', + config: {}, + secrets: {}, + }) + .expect(200); + + objectRemover.add(Spaces.space1.id, createdAction01.id, 'action', 'actions'); + objectRemover.add(Spaces.space1.id, createdAction02.id, 'action', 'actions'); + objectRemover.add(Spaces.space1.id, createdAction03.id, 'action', 'actions'); + + const { body: createdRule } = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send( + getTestRuleData({ + name: 'should not trigger actions when connector type limit is reached', + rule_type_id: 'test.patternFiring', + schedule: { interval: '1s' }, + throttle: null, + notify_when: 'onActiveAlert', + params: { + pattern: { instance: arrayOfTrues(100) }, + }, + actions: [ + { + id: createdAction01.id, + group: 'default', + params: {}, + }, + { + id: createdAction02.id, + group: 'default', + params: {}, + }, + { + id: createdAction03.id, + group: 'default', + params: {}, + }, + ], + }) + ) + .expect(200); + + objectRemover.add(Spaces.space1.id, createdRule.id, 'rule', 'alerting'); + + await getRuleEvents(createdRule.id); + const [executionEvent] = await getRuleEvents(createdRule.id, 1); + + expect( + executionEvent?.kibana?.alert?.rule?.execution?.metrics?.number_of_generated_actions + ).to.be.eql(3, 'all the generated actions'); + expect( + executionEvent?.kibana?.alert?.rule?.execution?.metrics?.number_of_triggered_actions + ).to.be.eql(1, 'only 1 action was triggered'); + }); + }); + + async function getRuleEvents(id: string, minActions: number = 1) { + return await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: Spaces.space1.id, + type: 'alert', + id, + provider: 'alerting', + actions: new Map([['execute', { gte: minActions }]]), + }); + }); + } +} + +function arrayOfTrues(length: number) { + const result = []; + for (let i = 0; i < length; i++) { + result.push(true); + } + return result; +} diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/event_log.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/event_log.ts index 909b3315600c2..bc382e5d733dd 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/event_log.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/event_log.ts @@ -7,7 +7,7 @@ import expect from '@kbn/expect'; import uuid from 'uuid'; -import { IValidatedEvent } from '@kbn/event-log-plugin/server'; +import { IValidatedEvent, nanosToMillis } from '@kbn/event-log-plugin/server'; import { Spaces } from '../../scenarios'; import { getUrlPrefix, @@ -18,8 +18,6 @@ import { } from '../../../common/lib'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; -const NANOS_IN_MILLIS = 1000 * 1000; - // eslint-disable-next-line import/no-default-export export default function eventLogTests({ getService }: FtrProviderContext) { const supertest = getService('supertest'); @@ -139,6 +137,9 @@ export default function eventLogTests({ getService }: FtrProviderContext) { // validate each event let executeCount = 0; + let numActiveAlerts = 0; + let numNewAlerts = 0; + let numRecoveredAlerts = 0; let currentExecutionId; const executionIds = []; const executeStatuses = ['ok', 'active', 'active']; @@ -165,28 +166,6 @@ export default function eventLogTests({ getService }: FtrProviderContext) { consumer: 'alertsFixture', }); break; - case 'execute': - validateEvent(event, { - spaceId: space.id, - savedObjects: [ - { type: 'alert', id: alertId, rel: 'primary', type_id: 'test.patternFiring' }, - ], - outcome: 'success', - message: `rule executed: test.patternFiring:${alertId}: 'abc'`, - status: executeStatuses[executeCount++], - shouldHaveTask: true, - executionId: currentExecutionId, - ruleTypeId: response.body.rule_type_id, - rule: { - id: alertId, - category: response.body.rule_type_id, - license: 'basic', - ruleset: 'alertsFixture', - name: response.body.name, - }, - consumer: 'alertsFixture', - }); - break; case 'execute-action': validateEvent(event, { spaceId: space.id, @@ -210,6 +189,7 @@ export default function eventLogTests({ getService }: FtrProviderContext) { }); break; case 'new-instance': + numNewAlerts++; validateInstanceEvent( event, `created new alert: 'instance'`, @@ -218,6 +198,7 @@ export default function eventLogTests({ getService }: FtrProviderContext) { ); break; case 'recovered-instance': + numRecoveredAlerts++; validateInstanceEvent( event, `alert 'instance' has recovered`, @@ -226,6 +207,7 @@ export default function eventLogTests({ getService }: FtrProviderContext) { ); break; case 'active-instance': + numActiveAlerts++; validateInstanceEvent( event, `active alert: 'instance' in actionGroup: 'default'`, @@ -233,6 +215,34 @@ export default function eventLogTests({ getService }: FtrProviderContext) { currentExecutionId ); break; + case 'execute': + validateEvent(event, { + spaceId: space.id, + savedObjects: [ + { type: 'alert', id: alertId, rel: 'primary', type_id: 'test.patternFiring' }, + ], + outcome: 'success', + message: `rule executed: test.patternFiring:${alertId}: 'abc'`, + status: executeStatuses[executeCount++], + shouldHaveTask: true, + executionId: currentExecutionId, + ruleTypeId: response.body.rule_type_id, + rule: { + id: alertId, + category: response.body.rule_type_id, + license: 'basic', + ruleset: 'alertsFixture', + name: response.body.name, + }, + consumer: 'alertsFixture', + numActiveAlerts, + numNewAlerts, + numRecoveredAlerts, + }); + numActiveAlerts = 0; + numNewAlerts = 0; + numRecoveredAlerts = 0; + break; // this will get triggered as we add new event actions default: throw new Error(`unexpected event action "${event?.event?.action}"`); @@ -343,11 +353,23 @@ export default function eventLogTests({ getService }: FtrProviderContext) { // validate each event let currentExecutionId; + let numActiveAlerts = 0; + let numNewAlerts = 0; + let numRecoveredAlerts = 0; for (const event of events) { switch (event?.event?.action) { case 'execute-start': currentExecutionId = event?.kibana?.alert?.rule?.execution?.uuid; break; + case 'new-instance': + numNewAlerts++; + break; + case 'recovered-instance': + numRecoveredAlerts++; + break; + case 'active-instance': + numActiveAlerts++; + break; case 'execute': validateEvent(event, { spaceId: space.id, @@ -369,14 +391,22 @@ export default function eventLogTests({ getService }: FtrProviderContext) { name: response.body.name, }, consumer: 'alertsFixture', + numActiveAlerts, + numNewAlerts, + numRecoveredAlerts, }); + numActiveAlerts = 0; + numNewAlerts = 0; + numRecoveredAlerts = 0; expect(event?.kibana?.alert?.rule?.execution?.metrics?.number_of_searches).to.be( numSearches ); - const esSearchDuration = - event?.kibana?.alert?.rule?.execution?.metrics?.es_search_duration_ms; - const totalSearchDuration = - event?.kibana?.alert?.rule?.execution?.metrics?.total_search_duration_ms; + const esSearchDuration = Number( + event?.kibana?.alert?.rule?.execution?.metrics?.es_search_duration_ms + ); + const totalSearchDuration = Number( + event?.kibana?.alert?.rule?.execution?.metrics?.total_search_duration_ms + ); expect(esSearchDuration).not.to.be(undefined); expect(totalSearchDuration).not.to.be(undefined); @@ -477,6 +507,9 @@ export default function eventLogTests({ getService }: FtrProviderContext) { // validate each event let executeCount = 0; + let numActiveAlerts = 0; + let numNewAlerts = 0; + let numRecoveredAlerts = 0; let currentExecutionId; const executeStatuses = ['ok', 'active', 'active']; for (const event of events) { @@ -501,28 +534,6 @@ export default function eventLogTests({ getService }: FtrProviderContext) { consumer: 'alertsFixture', }); break; - case 'execute': - validateEvent(event, { - spaceId: space.id, - savedObjects: [ - { type: 'alert', id: alertId, rel: 'primary', type_id: 'test.patternFiring' }, - ], - outcome: 'success', - message: `rule executed: test.patternFiring:${alertId}: 'abc'`, - status: executeStatuses[executeCount++], - shouldHaveTask: true, - executionId: currentExecutionId, - ruleTypeId: response.body.rule_type_id, - rule: { - id: alertId, - category: response.body.rule_type_id, - license: 'basic', - ruleset: 'alertsFixture', - name: response.body.name, - }, - consumer: 'alertsFixture', - }); - break; case 'execute-action': expect( [firstSubgroup, secondSubgroup].includes( @@ -551,6 +562,7 @@ export default function eventLogTests({ getService }: FtrProviderContext) { }); break; case 'new-instance': + numNewAlerts++; validateInstanceEvent( event, `created new alert: 'instance'`, @@ -559,6 +571,7 @@ export default function eventLogTests({ getService }: FtrProviderContext) { ); break; case 'recovered-instance': + numRecoveredAlerts++; validateInstanceEvent( event, `alert 'instance' has recovered`, @@ -567,6 +580,7 @@ export default function eventLogTests({ getService }: FtrProviderContext) { ); break; case 'active-instance': + numActiveAlerts++; expect( [firstSubgroup, secondSubgroup].includes( event?.kibana?.alerting?.action_subgroup! @@ -579,6 +593,34 @@ export default function eventLogTests({ getService }: FtrProviderContext) { currentExecutionId ); break; + case 'execute': + validateEvent(event, { + spaceId: space.id, + savedObjects: [ + { type: 'alert', id: alertId, rel: 'primary', type_id: 'test.patternFiring' }, + ], + outcome: 'success', + message: `rule executed: test.patternFiring:${alertId}: 'abc'`, + status: executeStatuses[executeCount++], + shouldHaveTask: true, + executionId: currentExecutionId, + ruleTypeId: response.body.rule_type_id, + rule: { + id: alertId, + category: response.body.rule_type_id, + license: 'basic', + ruleset: 'alertsFixture', + name: response.body.name, + }, + consumer: 'alertsFixture', + numActiveAlerts, + numNewAlerts, + numRecoveredAlerts, + }); + numActiveAlerts = 0; + numNewAlerts = 0; + numRecoveredAlerts = 0; + break; // this will get triggered as we add new event actions default: throw new Error(`unexpected event action "${event?.event?.action}"`); @@ -687,6 +729,9 @@ export default function eventLogTests({ getService }: FtrProviderContext) { ruleset: 'alertsFixture', }, consumer: 'alertsFixture', + numActiveAlerts: 0, + numNewAlerts: 0, + numRecoveredAlerts: 0, }); }); }); @@ -715,6 +760,9 @@ interface ValidateEventLogParams { reason?: string; executionId?: string; numTriggeredActions?: number; + numActiveAlerts?: number; + numRecoveredAlerts?: number; + numNewAlerts?: number; consumer?: string; ruleTypeId: string; rule?: { @@ -741,6 +789,9 @@ export function validateEvent(event: IValidatedEvent, params: ValidateEventLogPa shouldHaveTask, executionId, numTriggeredActions = 1, + numActiveAlerts, + numNewAlerts, + numRecoveredAlerts, consumer, ruleTypeId, } = params; @@ -776,6 +827,30 @@ export function validateEvent(event: IValidatedEvent, params: ValidateEventLogPa expect(event?.kibana?.alert?.rule?.consumer).to.be(consumer); } + if (numActiveAlerts) { + expect(event?.kibana?.alert?.rule?.execution?.metrics?.number_of_active_alerts).to.be( + numActiveAlerts + ); + } + + if (numRecoveredAlerts) { + expect(event?.kibana?.alert?.rule?.execution?.metrics?.number_of_recovered_alerts).to.be( + numRecoveredAlerts + ); + } + + if (numNewAlerts) { + expect(event?.kibana?.alert?.rule?.execution?.metrics?.number_of_new_alerts).to.be( + numNewAlerts + ); + } + + if (numActiveAlerts && numRecoveredAlerts) { + expect(event?.kibana?.alert?.rule?.execution?.metrics?.total_number_of_alerts).to.be( + numActiveAlerts + numRecoveredAlerts + ); + } + expect(event?.kibana?.alert?.rule?.rule_type_id).to.be(ruleTypeId); expect(event?.kibana?.space_ids?.[0]).to.equal(spaceId); @@ -786,15 +861,13 @@ export function validateEvent(event: IValidatedEvent, params: ValidateEventLogPa const dateNow = Date.now(); if (duration !== undefined) { - expect(typeof duration).to.be('number'); + expect(typeof duration).to.be('string'); expect(eventStart).to.be.ok(); if (shouldHaveEventEnd !== false) { expect(eventEnd).to.be.ok(); - const durationDiff = Math.abs( - Math.round(duration! / NANOS_IN_MILLIS) - (eventEnd - eventStart) - ); + const durationDiff = Math.abs(nanosToMillis(duration!) - (eventEnd - eventStart)); // account for rounding errors expect(durationDiff < 1).to.equal(true); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/event_log_alerts.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/event_log_alerts.ts index c65ffb1bef5ac..46da0e597e66a 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/event_log_alerts.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/event_log_alerts.ts @@ -6,7 +6,7 @@ */ import expect from '@kbn/expect'; -import { IValidatedEvent } from '@kbn/event-log-plugin/server'; +import { IValidatedEvent, nanosToMillis } from '@kbn/event-log-plugin/server'; import { Spaces } from '../../scenarios'; import { getUrlPrefix, getTestRuleData, ObjectRemover, getEventLog } from '../../../common/lib'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; @@ -91,7 +91,7 @@ export default function eventLogAlertTests({ getService }: FtrProviderContext) { const currentAlertSpan: { alertId?: string; start?: string; - durationToDate?: number; + durationToDate?: string; } = {}; for (let i = 0; i < instanceEvents.length; ++i) { switch (instanceEvents[i]?.event?.action) { @@ -102,7 +102,7 @@ export default function eventLogAlertTests({ getService }: FtrProviderContext) { currentAlertSpan.alertId = instanceEvents[i]?.kibana?.alerting?.instance_id; currentAlertSpan.start = instanceEvents[i]?.event?.start; - currentAlertSpan.durationToDate = instanceEvents[i]?.event?.duration; + currentAlertSpan.durationToDate = `${instanceEvents[i]?.event?.duration}`; break; case 'active-instance': @@ -110,12 +110,13 @@ export default function eventLogAlertTests({ getService }: FtrProviderContext) { expect(instanceEvents[i]?.event?.start).to.equal(currentAlertSpan.start); expect(instanceEvents[i]?.event?.end).to.be(undefined); - if (instanceEvents[i]?.event?.duration! !== 0) { - expect(instanceEvents[i]?.event?.duration! > currentAlertSpan.durationToDate!).to.be( - true - ); + if (instanceEvents[i]?.event?.duration! !== '0') { + expect( + BigInt(instanceEvents[i]?.event?.duration!) > + BigInt(currentAlertSpan.durationToDate!) + ).to.be(true); } - currentAlertSpan.durationToDate = instanceEvents[i]?.event?.duration; + currentAlertSpan.durationToDate = `${instanceEvents[i]?.event?.duration}`; break; case 'recovered-instance': @@ -125,7 +126,7 @@ export default function eventLogAlertTests({ getService }: FtrProviderContext) { expect( new Date(instanceEvents[i]?.event?.end!).valueOf() - new Date(instanceEvents[i]?.event?.start!).valueOf() - ).to.equal(instanceEvents[i]?.event?.duration! / 1000 / 1000); + ).to.equal(nanosToMillis(instanceEvents[i]?.event?.duration!)); break; } } diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/index.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/index.ts index bdc5a6c5ef646..4975207c02391 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/index.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/index.ts @@ -45,6 +45,7 @@ export default function alertingTests({ loadTestFile, getService }: FtrProviderC loadTestFile(require.resolve('./ephemeral')); loadTestFile(require.resolve('./event_log_alerts')); loadTestFile(require.resolve('./snooze')); + loadTestFile(require.resolve('./capped_action_type')); loadTestFile(require.resolve('./scheduled_task_id')); // Do not place test files here, due to https://github.com/elastic/kibana/issues/123059 diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/migrations.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/migrations.ts index 33cb64dcdbed1..4622e84081506 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/migrations.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/migrations.ts @@ -398,14 +398,9 @@ export default function createGetTests({ getService }: FtrProviderContext) { // Only the rule that was enabled should be tagged expect(responseEnabledBeforeMigration.body._source?.alert?.tags).to.eql([ - '__internal_rule_id:064e3fed-6328-416b-bb85-c08265088f41', - '__internal_immutable:false', 'auto_disabled_8.0', ]); - expect(responseDisabledBeforeMigration.body._source?.alert?.tags).to.eql([ - '__internal_rule_id:364e3fed-6328-416b-bb85-c08265088f41', - '__internal_immutable:false', - ]); + expect(responseDisabledBeforeMigration.body._source?.alert?.tags).to.eql([]); }); it('8.2.0 migrates params to mapped_params for specific params properties', async () => { @@ -423,5 +418,18 @@ export default function createGetTests({ getService }: FtrProviderContext) { severity: '80-critical', }); }); + + it('8.3.0 removes internal tags in Security Solution rule', async () => { + const response = await es.get<{ alert: RawRule }>( + { + index: '.kibana', + id: 'alert:8990af61-c09a-11ec-9164-4bfd6fc32c43', + }, + { meta: true } + ); + + expect(response.statusCode).to.equal(200); + expect(response.body._source?.alert?.tags).to.eql(['test-tag-1', 'foo-tag']); + }); }); } diff --git a/x-pack/test/api_integration/config.ts b/x-pack/test/api_integration/config.ts index 203b0b4d53dbf..4e47947aa29dc 100644 --- a/x-pack/test/api_integration/config.ts +++ b/x-pack/test/api_integration/config.ts @@ -37,7 +37,6 @@ export async function getApiIntegrationConfig({ readConfigFile }: FtrConfigProvi '--xpack.ruleRegistry.write.cache.enabled=false', '--xpack.uptime.service.password=test', '--xpack.uptime.service.username=localKibanaIntegrationTestsUser', - `--xpack.securitySolution.enableExperimental=${JSON.stringify(['ruleRegistryEnabled'])}`, ], }, esTestCluster: { diff --git a/x-pack/test/apm_api_integration/tests/suggestions/suggestions.spec.ts b/x-pack/test/apm_api_integration/tests/suggestions/suggestions.spec.ts index 74bdc860bfba3..692cd1c0cf7f1 100644 --- a/x-pack/test/apm_api_integration/tests/suggestions/suggestions.spec.ts +++ b/x-pack/test/apm_api_integration/tests/suggestions/suggestions.spec.ts @@ -9,12 +9,14 @@ import { SERVICE_NAME, TRANSACTION_TYPE, } from '@kbn/apm-plugin/common/elasticsearch_fieldnames'; +import archives_metadata from '../../common/fixtures/es_archiver/archives_metadata'; import { FtrProviderContext } from '../../common/ftr_provider_context'; export default function suggestionsTests({ getService }: FtrProviderContext) { const registry = getService('registry'); const apmApiClient = getService('apmApiClient'); const archiveName = 'apm_8.0.0'; + const { start, end } = archives_metadata[archiveName]; registry.when( 'suggestions when data is loaded', @@ -25,7 +27,7 @@ export default function suggestionsTests({ getService }: FtrProviderContext) { it('returns all environments', async () => { const { body } = await apmApiClient.readUser({ endpoint: 'GET /internal/apm/suggestions', - params: { query: { field: SERVICE_ENVIRONMENT, string: '' } }, + params: { query: { fieldName: SERVICE_ENVIRONMENT, fieldValue: '', start, end } }, }); expectSnapshot(body).toMatchInline(` @@ -43,7 +45,7 @@ export default function suggestionsTests({ getService }: FtrProviderContext) { it('returns items matching the string parameter', async () => { const { body } = await apmApiClient.readUser({ endpoint: 'GET /internal/apm/suggestions', - params: { query: { field: SERVICE_ENVIRONMENT, string: 'pr' } }, + params: { query: { fieldName: SERVICE_ENVIRONMENT, fieldValue: 'pr', start, end } }, }); expectSnapshot(body).toMatchInline(` @@ -62,7 +64,7 @@ export default function suggestionsTests({ getService }: FtrProviderContext) { it('returns all services', async () => { const { body } = await apmApiClient.readUser({ endpoint: 'GET /internal/apm/suggestions', - params: { query: { field: SERVICE_NAME, string: '' } }, + params: { query: { fieldName: SERVICE_NAME, fieldValue: '', start, end } }, }); expectSnapshot(body).toMatchInline(` @@ -86,7 +88,7 @@ export default function suggestionsTests({ getService }: FtrProviderContext) { it('returns items matching the string parameter', async () => { const { body } = await apmApiClient.readUser({ endpoint: 'GET /internal/apm/suggestions', - params: { query: { field: SERVICE_NAME, string: 'aud' } }, + params: { query: { fieldName: SERVICE_NAME, fieldValue: 'aud', start, end } }, }); expectSnapshot(body).toMatchInline(` @@ -105,7 +107,7 @@ export default function suggestionsTests({ getService }: FtrProviderContext) { it('returns all transaction types', async () => { const { body } = await apmApiClient.readUser({ endpoint: 'GET /internal/apm/suggestions', - params: { query: { field: TRANSACTION_TYPE, string: '' } }, + params: { query: { fieldName: TRANSACTION_TYPE, fieldValue: '', start, end } }, }); expectSnapshot(body).toMatchInline(` @@ -125,7 +127,7 @@ export default function suggestionsTests({ getService }: FtrProviderContext) { it('returns items matching the string parameter', async () => { const { body } = await apmApiClient.readUser({ endpoint: 'GET /internal/apm/suggestions', - params: { query: { field: TRANSACTION_TYPE, string: 'w' } }, + params: { query: { fieldName: TRANSACTION_TYPE, fieldValue: 'w', start, end } }, }); expectSnapshot(body).toMatchInline(` diff --git a/x-pack/test/cases_api_integration/common/config.ts b/x-pack/test/cases_api_integration/common/config.ts index 803327cd037d3..89dd19ae74897 100644 --- a/x-pack/test/cases_api_integration/common/config.ts +++ b/x-pack/test/cases_api_integration/common/config.ts @@ -20,7 +20,6 @@ interface CreateTestConfigOptions { testFiles?: string[]; } -// test.not-enabled is specifically not enabled const enabledActionTypes = [ '.email', '.index', @@ -139,6 +138,19 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) (pluginDir) => `--plugin-path=${path.resolve(__dirname, 'fixtures', 'plugins', pluginDir)}` ), + `--xpack.actions.preconfigured=${JSON.stringify({ + 'preconfigured-servicenow': { + name: 'preconfigured-servicenow', + actionTypeId: '.servicenow', + config: { + apiUrl: 'https://example.com', + }, + secrets: { + username: 'elastic', + password: 'elastic', + }, + }, + })}`, `--server.xsrf.allowlist=${JSON.stringify(getAllExternalServiceSimulatorPaths())}`, ...(ssl ? [ @@ -148,7 +160,6 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) : []), '--xpack.ruleRegistry.write.enabled=true', '--xpack.ruleRegistry.write.cache.enabled=false', - `--xpack.securitySolution.enableExperimental=${JSON.stringify(['ruleRegistryEnabled'])}`, ], }, }; diff --git a/x-pack/test/cases_api_integration/common/lib/mock.ts b/x-pack/test/cases_api_integration/common/lib/mock.ts index ce025a5681b4f..34f1d4a9273d2 100644 --- a/x-pack/test/cases_api_integration/common/lib/mock.ts +++ b/x-pack/test/cases_api_integration/common/lib/mock.ts @@ -85,6 +85,7 @@ export const postCaseResp = ( ...req, ...(id != null ? { id } : {}), comments: [], + duration: null, totalAlerts: 0, totalComment: 0, closed_by: null, diff --git a/x-pack/test/cases_api_integration/common/lib/utils.ts b/x-pack/test/cases_api_integration/common/lib/utils.ts index a433f5da1d74a..bb8f31abefd47 100644 --- a/x-pack/test/cases_api_integration/common/lib/utils.ts +++ b/x-pack/test/cases_api_integration/common/lib/utils.ts @@ -48,9 +48,10 @@ import { ConnectorMappings, CasesByAlertId, CaseResolveResponse, - CaseMetricsResponse, + SingleCaseMetricsResponse, BulkCreateCommentRequest, CommentType, + CasesMetricsResponse, } from '@kbn/cases-plugin/common/api'; import { getCaseUserActionUrl } from '@kbn/cases-plugin/common/api/helpers'; import { SignalHit } from '@kbn/security-solution-plugin/server/lib/detection_engine/signals/types'; @@ -217,6 +218,23 @@ export const getServiceNowConnector = () => ({ }, }); +export const getServiceNowOAuthConnector = () => ({ + name: 'ServiceNow OAuth Connector', + connector_type_id: '.servicenow', + secrets: { + clientSecret: 'xyz', + privateKey: '-----BEGIN RSA PRIVATE KEY-----\nddddddd\n-----END RSA PRIVATE KEY-----', + }, + config: { + apiUrl: 'http://some.non.existent.com', + usesTableApi: false, + isOAuth: true, + clientId: 'abc', + userIdentifierValue: 'elastic', + jwtKeyId: 'def', + }, +}); + export const getJiraConnector = () => ({ name: 'Jira Connector', connector_type_id: '.jira', @@ -262,7 +280,7 @@ export const getResilientConnector = () => ({ }); export const getServiceNowSIRConnector = () => ({ - name: 'ServiceNow Connector', + name: 'ServiceNow SIR Connector', connector_type_id: '.servicenow-sir', secrets: { username: 'admin', @@ -289,6 +307,19 @@ export const getWebhookConnector = () => ({ }, }); +export const getEmailConnector = () => ({ + name: 'An email action', + connector_type_id: '.email', + config: { + service: '__json', + from: 'bob@example.com', + }, + secrets: { + user: 'bob', + password: 'supersecret', + }, +}); + interface CommonSavedObjectAttributes { id?: string | null; created_at?: string | null; @@ -982,7 +1013,7 @@ export const getCaseMetrics = async ({ features: string[]; expectedHttpCode?: number; auth?: { user: User; space: string | null }; -}): Promise => { +}): Promise => { const { body: metricsResponse } = await supertest .get(`${getSpaceUrlPrefix(auth?.space)}${CASES_URL}/metrics/${caseId}`) .query({ features: JSON.stringify(features) }) @@ -1216,3 +1247,46 @@ export const createCaseAndBulkCreateAttachments = async ({ return { theCase: patchedCase, attachments }; }; + +export const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); + +export const calculateDuration = (closedAt: string | null, createdAt: string | null): number => { + if (closedAt == null || createdAt == null) { + throw new Error('Dates are null'); + } + + const createdAtMillis = new Date(createdAt).getTime(); + const closedAtMillis = new Date(closedAt).getTime(); + + if (isNaN(createdAtMillis) || isNaN(closedAtMillis)) { + throw new Error('Dates are invalid'); + } + + if (closedAtMillis < createdAtMillis) { + throw new Error('Closed date is earlier than created date'); + } + + return Math.floor(Math.abs((closedAtMillis - createdAtMillis) / 1000)); +}; + +export const getCasesMetrics = async ({ + supertest, + features, + query = {}, + expectedHttpCode = 200, + auth = { user: superUser, space: null }, +}: { + supertest: SuperTest.SuperTest; + features: string[]; + query?: Record; + expectedHttpCode?: number; + auth?: { user: User; space: string | null }; +}): Promise => { + const { body: metricsResponse } = await supertest + .get(`${getSpaceUrlPrefix(auth?.space)}${CASES_URL}/metrics`) + .query({ features: JSON.stringify(features), ...query }) + .auth(auth.user.username, auth.user.password) + .expect(expectedHttpCode); + + return metricsResponse; +}; diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/configure/create_connector.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/configure/create_connector.ts deleted file mode 100644 index fe8e311b5e4f6..0000000000000 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/configure/create_connector.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { createConnector, getServiceNowConnector } from '../../../../common/lib/utils'; -import { FtrProviderContext } from '../../../../common/ftr_provider_context'; - -// eslint-disable-next-line import/no-default-export -export default function serviceNow({ getService }: FtrProviderContext) { - const supertest = getService('supertest'); - - describe('create service now action', () => { - it('should return 403 when creating a service now action', async () => { - await createConnector({ supertest, req: getServiceNowConnector(), expectedHttpCode: 403 }); - }); - }); -} diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/configure/get_connectors.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/configure/get_connectors.ts new file mode 100644 index 0000000000000..57854075c20fb --- /dev/null +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/configure/get_connectors.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; + +import { getCaseConnectors } from '../../../../common/lib/utils'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext): void => { + const supertest = getService('supertest'); + + describe('get_connectors', () => { + /** + * A ServiceNow preconfigured connector is registered here + * x-pack/test/cases_api_integration/common/config.ts + * + * The license for this test is set to basic. ServiceNow connectors + * needs license >= platinum. The test below ensures + * that connectors without valid license are being filtered correctly + */ + it('should return an empty list of connectors', async () => { + const connectors = await getCaseConnectors({ supertest }); + + expect(connectors).to.eql([]); + }); + }); +}; diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/index.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/index.ts index ce2f59a115e69..b618cf5b4df68 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/index.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/basic/index.ts @@ -24,6 +24,7 @@ export default ({ loadTestFile, getService }: FtrProviderContext): void => { // Basic loadTestFile(require.resolve('./cases/push_case')); + loadTestFile(require.resolve('./configure/get_connectors')); // Common loadTestFile(require.resolve('../common')); diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/find_cases.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/find_cases.ts index 657424e644be5..ddf0425fb5386 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/find_cases.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/find_cases.ts @@ -517,8 +517,15 @@ export default ({ getService }: FtrProviderContext): void => { } }); - it('returns a bad request on malformed parameter', async () => { - await findCases({ supertest, query: { from: '<' }, expectedHttpCode: 400 }); + it('escapes correctly', async () => { + const cases = await findCases({ + supertest, + query: { from: '2022-03-15T10:16:56.252Z', to: '2022-03-20T10:16:56.252' }, + }); + + expect(cases.total).to.be(2); + expect(cases.count_open_cases).to.be(2); + expect(cases.cases.length).to.be(2); }); }); diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/migrations.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/migrations.ts index d844cbae1d79e..3c43ac1932986 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/migrations.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/migrations.ts @@ -368,5 +368,50 @@ export default function createGetTests({ getService }: FtrProviderContext) { expect(caseInfo).not.to.have.property('type'); }); }); + + describe('8.3.0 adding duration', () => { + before(async () => { + await kibanaServer.importExport.load( + 'x-pack/test/functional/fixtures/kbn_archiver/cases/8.2.0/cases_duration.json' + ); + }); + + after(async () => { + await kibanaServer.importExport.unload( + 'x-pack/test/functional/fixtures/kbn_archiver/cases/8.2.0/cases_duration.json' + ); + await deleteAllCaseItems(es); + }); + + it('calculates the correct duration for closed cases', async () => { + const caseInfo = await getCase({ + supertest, + caseId: '4537b380-a512-11ec-b92f-859b9e89e434', + }); + + expect(caseInfo).to.have.property('duration'); + expect(caseInfo.duration).to.be(120); + }); + + it('sets the duration to null to open cases', async () => { + const caseInfo = await getCase({ + supertest, + caseId: '7537b580-a512-11ec-b94f-85979e89e434', + }); + + expect(caseInfo).to.have.property('duration'); + expect(caseInfo.duration).to.be(null); + }); + + it('sets the duration to null to in-progress cases', async () => { + const caseInfo = await getCase({ + supertest, + caseId: '1537b580-a512-11ec-b94f-85979e89e434', + }); + + expect(caseInfo).to.have.property('duration'); + expect(caseInfo.duration).to.be(null); + }); + }); }); } diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/patch_cases.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/patch_cases.ts index 8e25ee9225493..9ef1c3d5655e4 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/patch_cases.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/patch_cases.ts @@ -34,6 +34,8 @@ import { removeServerGeneratedPropertiesFromUserAction, findCases, superUserSpace1Auth, + delay, + calculateDuration, } from '../../../../common/lib/utils'; import { createSignalsIndex, @@ -111,9 +113,11 @@ export default ({ getService }: FtrProviderContext): void => { const userActions = await getCaseUserActions({ supertest, caseID: postedCase.id }); const statusUserAction = removeServerGeneratedPropertiesFromUserAction(userActions[1]); const data = removeServerGeneratedPropertiesFromCase(patchedCases[0]); + const { duration, ...dataWithoutDuration } = data; + const { duration: resDuration, ...resWithoutDuration } = postCaseResp(); - expect(data).to.eql({ - ...postCaseResp(), + expect(dataWithoutDuration).to.eql({ + ...resWithoutDuration, status: CaseStatuses.closed, closed_by: defaultUser, updated_by: defaultUser, @@ -198,6 +202,65 @@ export default ({ getService }: FtrProviderContext): void => { updated_by: defaultUser, }); }); + + describe('duration', () => { + it('updates the duration correctly when the case closes', async () => { + const postedCase = await createCase(supertest, postCaseReq); + await delay(1000); + + const patchedCases = await updateCase({ + supertest, + params: { + cases: [ + { + id: postedCase.id, + version: postedCase.version, + status: CaseStatuses.closed, + }, + ], + }, + }); + + const duration = calculateDuration(patchedCases[0].closed_at, postedCase.created_at); + expect(duration).to.be(patchedCases[0].duration); + }); + + for (const status of [CaseStatuses.open, CaseStatuses['in-progress']]) { + it(`sets the duration to null when the case status changes to ${status}`, async () => { + const postedCase = await createCase(supertest, postCaseReq); + + const closedCases = await updateCase({ + supertest, + params: { + cases: [ + { + id: postedCase.id, + version: postedCase.version, + status: CaseStatuses.closed, + }, + ], + }, + }); + + expect(closedCases[0].duration).to.not.be(null); + + const openCases = await updateCase({ + supertest, + params: { + cases: [ + { + id: postedCase.id, + version: closedCases[0].version, + status, + }, + ], + }, + }); + + expect(openCases[0].duration).to.be(null); + }); + } + }); }); describe('unhappy path', () => { diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/status/get_status.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/status/get_status.ts index 1a9671385a36c..4b7a11166ed16 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/status/get_status.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/status/get_status.ts @@ -113,8 +113,17 @@ export default ({ getService }: FtrProviderContext): void => { } }); - it('returns a bad request on malformed parameter', async () => { - await getAllCasesStatuses({ supertest, query: { from: '<' }, expectedHttpCode: 400 }); + it('escapes correctly', async () => { + const statuses = await getAllCasesStatuses({ + supertest, + query: { from: '2022-03-15T10:16:56.252Z', to: '2022-03-20T10:16:56.252' }, + }); + + expect(statuses).to.eql({ + count_open_cases: 2, + count_closed_cases: 0, + count_in_progress_cases: 0, + }); }); }); diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/configure/get_connectors.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/configure/get_connectors.ts deleted file mode 100644 index 46f712ff84aa3..0000000000000 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/configure/get_connectors.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import expect from '@kbn/expect'; -import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; - -import { getCaseConnectors } from '../../../../common/lib/utils'; - -// eslint-disable-next-line import/no-default-export -export default ({ getService }: FtrProviderContext): void => { - const supertest = getService('supertest'); - - describe('get_connectors', () => { - it('should return an empty find body correctly if no connectors are loaded', async () => { - const connectors = await getCaseConnectors({ supertest }); - expect(connectors).to.eql([]); - }); - - it.skip('filters out connectors that are not enabled in license', async () => { - // TODO: Should find a way to downgrade license to gold and upgrade back to trial - }); - }); -}; diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/index.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/index.ts index f70c8593d3c94..93bb948265ba0 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/index.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/index.ts @@ -31,13 +31,13 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./cases/tags/get_tags')); loadTestFile(require.resolve('./user_actions/get_all_user_actions')); loadTestFile(require.resolve('./configure/get_configure')); - loadTestFile(require.resolve('./configure/get_connectors')); loadTestFile(require.resolve('./configure/patch_configure')); loadTestFile(require.resolve('./configure/post_configure')); loadTestFile(require.resolve('./metrics/get_case_metrics')); loadTestFile(require.resolve('./metrics/get_case_metrics_alerts')); loadTestFile(require.resolve('./metrics/get_case_metrics_actions')); loadTestFile(require.resolve('./metrics/get_case_metrics_connectors')); + loadTestFile(require.resolve('./metrics/get_cases_metrics')); /** * Internal routes diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/metrics/get_cases_metrics.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/metrics/get_cases_metrics.ts new file mode 100644 index 0000000000000..c1abfada39dd2 --- /dev/null +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/metrics/get_cases_metrics.ts @@ -0,0 +1,233 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { CaseStatuses } from '@kbn/cases-plugin/common/api'; +import { + secOnly, + obsOnlyRead, + secOnlyRead, + noKibanaPrivileges, + superUser, + globalRead, + obsSecRead, + obsSec, +} from '../../../../common/lib/authentication/users'; +import { FtrProviderContext } from '../../../../common/ftr_provider_context'; +import { + createCase, + deleteAllCaseItems, + getCasesMetrics, + updateCase, +} from '../../../../common/lib/utils'; +import { getPostCaseRequest } from '../../../../common/lib/mock'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext): void => { + const es = getService('es'); + const supertest = getService('supertest'); + const supertestWithoutAuth = getService('supertestWithoutAuth'); + const kibanaServer = getService('kibanaServer'); + + describe('all cases metrics', () => { + describe('MTTR', () => { + it('responses with zero if there are no cases', async () => { + const metrics = await getCasesMetrics({ + supertest, + features: ['mttr'], + }); + + expect(metrics).to.eql({ mttr: 0 }); + }); + + it('responses with zero if there are only open case and in-progress cases', async () => { + await createCase(supertest, getPostCaseRequest()); + const theCase = await createCase(supertest, getPostCaseRequest()); + + await updateCase({ + supertest, + params: { + cases: [ + { + id: theCase.id, + version: theCase.version, + status: CaseStatuses['in-progress'], + }, + ], + }, + }); + + const metrics = await getCasesMetrics({ + supertest, + features: ['mttr'], + }); + + expect(metrics).to.eql({ mttr: 0 }); + }); + + describe('closed and open cases from kbn archive', () => { + before(async () => { + await kibanaServer.importExport.load( + 'x-pack/test/functional/fixtures/kbn_archiver/cases/8.3.0/all_cases_metrics.json' + ); + }); + + after(async () => { + await kibanaServer.importExport.unload( + 'x-pack/test/functional/fixtures/kbn_archiver/cases/8.3.0/all_cases_metrics.json' + ); + await deleteAllCaseItems(es); + }); + + it('should calculate the mttr correctly across all cases', async () => { + const metrics = await getCasesMetrics({ + supertest, + features: ['mttr'], + }); + + expect(metrics).to.eql({ mttr: 220 }); + }); + + it('should respects the range parameters', async () => { + const metrics = await getCasesMetrics({ + supertest, + features: ['mttr'], + query: { + from: '2022-04-28', + to: '2022-04-29', + }, + }); + + expect(metrics).to.eql({ mttr: 90 }); + }); + }); + }); + + describe('rbac', () => { + before(async () => { + await kibanaServer.importExport.load( + 'x-pack/test/functional/fixtures/kbn_archiver/cases/8.3.0/all_cases_metrics.json', + { space: 'space1' } + ); + }); + + after(async () => { + await kibanaServer.importExport.unload( + 'x-pack/test/functional/fixtures/kbn_archiver/cases/8.3.0/all_cases_metrics.json', + { space: 'space1' } + ); + await deleteAllCaseItems(es); + }); + + it('should calculate the mttr correctly only for the cases the user has access to', async () => { + for (const scenario of [ + { + user: globalRead, + expectedMetrics: { mttr: 220 }, + owners: ['securitySolutionFixture', 'observabilityFixture'], + }, + { + user: superUser, + expectedMetrics: { mttr: 220 }, + owners: ['securitySolutionFixture', 'observabilityFixture'], + }, + { + user: secOnlyRead, + expectedMetrics: { mttr: 250 }, + owners: ['securitySolutionFixture'], + }, + { user: obsOnlyRead, expectedMetrics: { mttr: 160 }, owners: ['observabilityFixture'] }, + { + user: obsSecRead, + expectedMetrics: { mttr: 220 }, + owners: ['securitySolutionFixture', 'observabilityFixture'], + }, + ]) { + const metrics = await getCasesMetrics({ + supertest: supertestWithoutAuth, + features: ['mttr'], + auth: { + user: scenario.user, + space: 'space1', + }, + }); + + expect(metrics).to.eql(scenario.expectedMetrics); + } + }); + + for (const scenario of [ + { user: noKibanaPrivileges, space: 'space1' }, + { user: secOnly, space: 'space2' }, + ]) { + it(`User ${scenario.user.username} with role(s) ${scenario.user.roles.join()} and space ${ + scenario.space + } - should NOT read a case`, async () => { + // user should not be able to read cases at the appropriate space + await getCasesMetrics({ + supertest: supertestWithoutAuth, + features: ['mttr'], + auth: { + user: scenario.user, + space: scenario.space, + }, + expectedHttpCode: 403, + }); + }); + } + + it('should respect the owner filter when having permissions', async () => { + const metrics = await getCasesMetrics({ + supertest: supertestWithoutAuth, + features: ['mttr'], + query: { + owner: 'securitySolutionFixture', + }, + auth: { + user: obsSec, + space: 'space1', + }, + }); + + expect(metrics).to.eql({ mttr: 250 }); + }); + + it('should return the correct cases when trying to exploit RBAC through the owner query parameter', async () => { + const metrics = await getCasesMetrics({ + supertest: supertestWithoutAuth, + features: ['mttr'], + query: { + owner: ['securitySolutionFixture', 'observabilityFixture'], + }, + auth: { + user: secOnly, + space: 'space1', + }, + }); + + expect(metrics).to.eql({ mttr: 250 }); + }); + + it('should respect the owner filter when using range queries', async () => { + const metrics = await getCasesMetrics({ + supertest: supertestWithoutAuth, + features: ['mttr'], + query: { + from: '2022-04-20', + to: '2022-04-30', + }, + auth: { + user: secOnly, + space: 'space1', + }, + }); + + expect(metrics).to.eql({ mttr: 250 }); + }); + }); + }); +}; diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts index b5a58d3af5086..de72e0f343026 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts @@ -6,16 +6,18 @@ */ import expect from '@kbn/expect'; -import { CASE_CONFIGURE_CONNECTORS_URL } from '@kbn/cases-plugin/common/constants'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; import { getServiceNowConnector, + getServiceNowOAuthConnector, getJiraConnector, getResilientConnector, createConnector, getServiceNowSIRConnector, + getEmailConnector, + getCaseConnectors, } from '../../../../common/lib/utils'; // eslint-disable-next-line import/no-default-export @@ -29,56 +31,27 @@ export default ({ getService }: FtrProviderContext): void => { }); it('should return the correct connectors', async () => { - const { body: snConnector } = await supertest - .post('/api/actions/connector') - .set('kbn-xsrf', 'true') - .send(getServiceNowConnector()) - .expect(200); - - const { body: emailConnector } = await supertest - .post('/api/actions/connector') - .set('kbn-xsrf', 'true') - .send({ - name: 'An email action', - connector_type_id: '.email', - config: { - service: '__json', - from: 'bob@example.com', - }, - secrets: { - user: 'bob', - password: 'supersecret', - }, - }) - .expect(200); - - const { body: jiraConnector } = await supertest - .post('/api/actions/connector') - .set('kbn-xsrf', 'true') - .send(getJiraConnector()) - .expect(200); - - const { body: resilientConnector } = await supertest - .post('/api/actions/connector') - .set('kbn-xsrf', 'true') - .send(getResilientConnector()) - .expect(200); - + const snConnector = await createConnector({ supertest, req: getServiceNowConnector() }); + const snOAuthConnector = await createConnector({ + supertest, + req: getServiceNowOAuthConnector(), + }); + const emailConnector = await createConnector({ supertest, req: getEmailConnector() }); + const jiraConnector = await createConnector({ supertest, req: getJiraConnector() }); + const resilientConnector = await createConnector({ supertest, req: getResilientConnector() }); const sir = await createConnector({ supertest, req: getServiceNowSIRConnector() }); actionsRemover.add('default', sir.id, 'action', 'actions'); actionsRemover.add('default', snConnector.id, 'action', 'actions'); + actionsRemover.add('default', snOAuthConnector.id, 'action', 'actions'); actionsRemover.add('default', emailConnector.id, 'action', 'actions'); actionsRemover.add('default', jiraConnector.id, 'action', 'actions'); actionsRemover.add('default', resilientConnector.id, 'action', 'actions'); - const { body: connectors } = await supertest - .get(`${CASE_CONFIGURE_CONNECTORS_URL}/_find`) - .set('kbn-xsrf', 'true') - .send() - .expect(200); + const connectors = await getCaseConnectors({ supertest }); + const sortedConnectors = connectors.sort((a, b) => a.name.localeCompare(b.name)); - expect(connectors).to.eql([ + expect(sortedConnectors).to.eql([ { id: jiraConnector.id, actionTypeId: '.jira', @@ -88,9 +61,22 @@ export default ({ getService }: FtrProviderContext): void => { projectKey: 'pkey', }, isPreconfigured: false, + isDeprecated: false, isMissingSecrets: false, referencedByCount: 0, }, + /** + * Preconfigured connectors are being registered here: + * x-pack/test/cases_api_integration/common/config.ts + */ + { + actionTypeId: '.servicenow', + id: 'preconfigured-servicenow', + isPreconfigured: true, + isDeprecated: false, + name: 'preconfigured-servicenow', + referencedByCount: 0, + }, { id: resilientConnector.id, actionTypeId: '.resilient', @@ -100,6 +86,7 @@ export default ({ getService }: FtrProviderContext): void => { orgId: 'pkey', }, isPreconfigured: false, + isDeprecated: false, isMissingSecrets: false, referencedByCount: 0, }, @@ -110,20 +97,47 @@ export default ({ getService }: FtrProviderContext): void => { config: { apiUrl: 'http://some.non.existent.com', usesTableApi: false, + isOAuth: false, + clientId: null, + jwtKeyId: null, + userIdentifierValue: null, }, isPreconfigured: false, + isDeprecated: false, + isMissingSecrets: false, + referencedByCount: 0, + }, + { + id: snOAuthConnector.id, + actionTypeId: '.servicenow', + name: 'ServiceNow OAuth Connector', + config: { + apiUrl: 'http://some.non.existent.com', + usesTableApi: false, + isOAuth: true, + clientId: 'abc', + userIdentifierValue: 'elastic', + jwtKeyId: 'def', + }, + isPreconfigured: false, + isDeprecated: false, isMissingSecrets: false, referencedByCount: 0, }, { id: sir.id, actionTypeId: '.servicenow-sir', - name: 'ServiceNow Connector', + name: 'ServiceNow SIR Connector', config: { apiUrl: 'http://some.non.existent.com', usesTableApi: false, + isOAuth: false, + clientId: null, + jwtKeyId: null, + userIdentifierValue: null, }, isPreconfigured: false, + isDeprecated: false, isMissingSecrets: false, referencedByCount: 0, }, diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/index.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/index.ts index 985393eafe719..3c1ee84296270 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/index.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/index.ts @@ -11,8 +11,6 @@ import { createSpacesAndUsers, deleteSpacesAndUsers } from '../../../common/lib/ // eslint-disable-next-line import/no-default-export export default ({ loadTestFile, getService }: FtrProviderContext): void => { describe('cases security and spaces enabled: trial', function () { - this.tags('ciGroup25'); - before(async () => { await createSpacesAndUsers(getService); }); @@ -21,15 +19,23 @@ export default ({ loadTestFile, getService }: FtrProviderContext): void => { await deleteSpacesAndUsers(getService); }); - // Trial - loadTestFile(require.resolve('./cases/push_case')); - loadTestFile(require.resolve('./cases/user_actions/get_all_user_actions')); - loadTestFile(require.resolve('./configure')); + describe('', function () { + this.tags('ciGroup13'); + + // Trial + loadTestFile(require.resolve('./cases/push_case')); + loadTestFile(require.resolve('./cases/user_actions/get_all_user_actions')); + loadTestFile(require.resolve('./configure')); + }); - // Common - loadTestFile(require.resolve('../common')); + describe('', function () { + this.tags('ciGroup25'); - // NOTE: These need to be at the end because they could delete the .kibana index and inadvertently remove the users and spaces - loadTestFile(require.resolve('../common/migrations')); + // Common + loadTestFile(require.resolve('../common')); + + // NOTE: These need to be at the end because they could delete the .kibana index and inadvertently remove the users and spaces + loadTestFile(require.resolve('../common/migrations')); + }); }); }; diff --git a/x-pack/test/cases_api_integration/spaces_only/tests/common/index.ts b/x-pack/test/cases_api_integration/spaces_only/tests/common/index.ts index 0b18a56bdcd11..a180d46d45edb 100644 --- a/x-pack/test/cases_api_integration/spaces_only/tests/common/index.ts +++ b/x-pack/test/cases_api_integration/spaces_only/tests/common/index.ts @@ -29,6 +29,8 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./configure/get_configure')); loadTestFile(require.resolve('./configure/patch_configure')); loadTestFile(require.resolve('./configure/post_configure')); + loadTestFile(require.resolve('./configure/post_configure')); + loadTestFile(require.resolve('./metrics/get_cases_metrics')); /** * Internal routes diff --git a/x-pack/test/cases_api_integration/spaces_only/tests/common/metrics/get_cases_metrics.ts b/x-pack/test/cases_api_integration/spaces_only/tests/common/metrics/get_cases_metrics.ts new file mode 100644 index 0000000000000..66fb3f4343e58 --- /dev/null +++ b/x-pack/test/cases_api_integration/spaces_only/tests/common/metrics/get_cases_metrics.ts @@ -0,0 +1,73 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; + +import { FtrProviderContext } from '../../../../common/ftr_provider_context'; +import { + deleteAllCaseItems, + getAuthWithSuperUser, + getCasesMetrics, +} from '../../../../common/lib/utils'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext): void => { + const es = getService('es'); + const supertest = getService('supertest'); + const kibanaServer = getService('kibanaServer'); + const authSpace1 = getAuthWithSuperUser(); + + describe('all cases metrics', () => { + before(async () => { + await kibanaServer.importExport.load( + 'x-pack/test/functional/fixtures/kbn_archiver/cases/8.3.0/all_cases_metrics.json', + { space: 'space1' } + ); + + await kibanaServer.importExport.load( + 'x-pack/test/functional/fixtures/kbn_archiver/cases/8.3.0/all_cases_metrics.json', + { space: 'space2' } + ); + }); + + after(async () => { + await kibanaServer.importExport.unload( + 'x-pack/test/functional/fixtures/kbn_archiver/cases/8.3.0/all_cases_metrics.json', + { space: 'space1' } + ); + + await kibanaServer.importExport.unload( + 'x-pack/test/functional/fixtures/kbn_archiver/cases/8.3.0/all_cases_metrics.json', + { space: 'space2' } + ); + await deleteAllCaseItems(es); + }); + + describe('MTTR', () => { + it('should calculate the mttr correctly on space 1', async () => { + const metrics = await getCasesMetrics({ + supertest, + features: ['mttr'], + auth: authSpace1, + }); + + expect(metrics).to.eql({ mttr: 220 }); + }); + + it('should calculate the mttr correctly on space 2', async () => { + const authSpace2 = getAuthWithSuperUser('space2'); + const metrics = await getCasesMetrics({ + supertest, + features: ['mttr'], + auth: authSpace2, + }); + + expect(metrics).to.eql({ mttr: 220 }); + }); + }); + }); +}; diff --git a/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_connectors.ts b/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_connectors.ts index 02b91c9f0b918..0ca47597e7b6b 100644 --- a/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_connectors.ts +++ b/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_connectors.ts @@ -11,6 +11,7 @@ import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib'; import { getServiceNowConnector, + getServiceNowOAuthConnector, getJiraConnector, getResilientConnector, createConnector, @@ -18,6 +19,7 @@ import { getAuthWithSuperUser, getCaseConnectors, getActionsSpace, + getEmailConnector, } from '../../../../common/lib/utils'; // eslint-disable-next-line import/no-default-export @@ -38,32 +40,29 @@ export default ({ getService }: FtrProviderContext): void => { req: getServiceNowConnector(), auth: authSpace1, }); + const snOAuthConnector = await createConnector({ + supertest, + req: getServiceNowOAuthConnector(), + auth: authSpace1, + }); const emailConnector = await createConnector({ supertest, - req: { - name: 'An email action', - connector_type_id: '.email', - config: { - service: '__json', - from: 'bob@example.com', - }, - secrets: { - user: 'bob', - password: 'supersecret', - }, - }, + req: getEmailConnector(), auth: authSpace1, }); + const jiraConnector = await createConnector({ supertest, req: getJiraConnector(), auth: authSpace1, }); + const resilientConnector = await createConnector({ supertest, req: getResilientConnector(), auth: authSpace1, }); + const sir = await createConnector({ supertest, req: getServiceNowSIRConnector(), @@ -72,13 +71,15 @@ export default ({ getService }: FtrProviderContext): void => { actionsRemover.add(space, sir.id, 'action', 'actions'); actionsRemover.add(space, snConnector.id, 'action', 'actions'); + actionsRemover.add(space, snOAuthConnector.id, 'action', 'actions'); actionsRemover.add(space, emailConnector.id, 'action', 'actions'); actionsRemover.add(space, jiraConnector.id, 'action', 'actions'); actionsRemover.add(space, resilientConnector.id, 'action', 'actions'); const connectors = await getCaseConnectors({ supertest, auth: authSpace1 }); + const sortedConnectors = connectors.sort((a, b) => a.name.localeCompare(b.name)); - expect(connectors).to.eql([ + expect(sortedConnectors).to.eql([ { id: jiraConnector.id, actionTypeId: '.jira', @@ -88,9 +89,22 @@ export default ({ getService }: FtrProviderContext): void => { projectKey: 'pkey', }, isPreconfigured: false, + isDeprecated: false, isMissingSecrets: false, referencedByCount: 0, }, + /** + * Preconfigured connectors are being registered here: + * x-pack/test/cases_api_integration/common/config.ts + */ + { + actionTypeId: '.servicenow', + id: 'preconfigured-servicenow', + isPreconfigured: true, + isDeprecated: false, + name: 'preconfigured-servicenow', + referencedByCount: 0, + }, { id: resilientConnector.id, actionTypeId: '.resilient', @@ -100,6 +114,7 @@ export default ({ getService }: FtrProviderContext): void => { orgId: 'pkey', }, isPreconfigured: false, + isDeprecated: false, isMissingSecrets: false, referencedByCount: 0, }, @@ -110,20 +125,47 @@ export default ({ getService }: FtrProviderContext): void => { config: { apiUrl: 'http://some.non.existent.com', usesTableApi: false, + isOAuth: false, + clientId: null, + jwtKeyId: null, + userIdentifierValue: null, + }, + isPreconfigured: false, + isDeprecated: false, + isMissingSecrets: false, + referencedByCount: 0, + }, + { + id: snOAuthConnector.id, + actionTypeId: '.servicenow', + name: 'ServiceNow OAuth Connector', + config: { + apiUrl: 'http://some.non.existent.com', + usesTableApi: false, + isOAuth: true, + clientId: 'abc', + userIdentifierValue: 'elastic', + jwtKeyId: 'def', }, isPreconfigured: false, + isDeprecated: false, isMissingSecrets: false, referencedByCount: 0, }, { id: sir.id, actionTypeId: '.servicenow-sir', - name: 'ServiceNow Connector', + name: 'ServiceNow SIR Connector', config: { apiUrl: 'http://some.non.existent.com', usesTableApi: false, + isOAuth: false, + clientId: null, + jwtKeyId: null, + userIdentifierValue: null, }, isPreconfigured: false, + isDeprecated: false, isMissingSecrets: false, referencedByCount: 0, }, @@ -136,32 +178,31 @@ export default ({ getService }: FtrProviderContext): void => { req: getServiceNowConnector(), auth: authSpace1, }); + + const snOAuthConnector = await createConnector({ + supertest, + req: getServiceNowOAuthConnector(), + auth: authSpace1, + }); + const emailConnector = await createConnector({ supertest, - req: { - name: 'An email action', - connector_type_id: '.email', - config: { - service: '__json', - from: 'bob@example.com', - }, - secrets: { - user: 'bob', - password: 'supersecret', - }, - }, + req: getEmailConnector(), auth: authSpace1, }); + const jiraConnector = await createConnector({ supertest, req: getJiraConnector(), auth: authSpace1, }); + const resilientConnector = await createConnector({ supertest, req: getResilientConnector(), auth: authSpace1, }); + const sir = await createConnector({ supertest, req: getServiceNowSIRConnector(), @@ -170,6 +211,7 @@ export default ({ getService }: FtrProviderContext): void => { actionsRemover.add(space, sir.id, 'action', 'actions'); actionsRemover.add(space, snConnector.id, 'action', 'actions'); + actionsRemover.add(space, snOAuthConnector.id, 'action', 'actions'); actionsRemover.add(space, emailConnector.id, 'action', 'actions'); actionsRemover.add(space, jiraConnector.id, 'action', 'actions'); actionsRemover.add(space, resilientConnector.id, 'action', 'actions'); @@ -179,7 +221,20 @@ export default ({ getService }: FtrProviderContext): void => { auth: getAuthWithSuperUser('space2'), }); - expect(connectors).to.eql([]); + expect(connectors).to.eql([ + /** + * Preconfigured connectors are being registered here: + * x-pack/test/cases_api_integration/common/config.ts + */ + { + actionTypeId: '.servicenow', + id: 'preconfigured-servicenow', + isPreconfigured: true, + isDeprecated: false, + name: 'preconfigured-servicenow', + referencedByCount: 0, + }, + ]); }); }); }; diff --git a/x-pack/test/detection_engine_api_integration/basic/tests/import_rules.ts b/x-pack/test/detection_engine_api_integration/basic/tests/import_rules.ts index 8df19b4fb910d..2fac0f48552e9 100644 --- a/x-pack/test/detection_engine_api_integration/basic/tests/import_rules.ts +++ b/x-pack/test/detection_engine_api_integration/basic/tests/import_rules.ts @@ -88,7 +88,10 @@ export default ({ getService }: FtrProviderContext): void => { .expect(200); const bodyToCompare = removeServerGeneratedProperties(body); - expect(bodyToCompare).to.eql(getSimpleRuleOutput('rule-1', false)); + expect(bodyToCompare).to.eql({ + ...getSimpleRuleOutput('rule-1', false), + output_index: '', + }); }); it('should fail validation when importing a rule with malformed "from" params on the rules', async () => { @@ -317,7 +320,10 @@ export default ({ getService }: FtrProviderContext): void => { .expect(200); const bodyToCompare = removeServerGeneratedProperties(body); - const ruleOutput = getSimpleRuleOutput('rule-1'); + const ruleOutput = { + ...getSimpleRuleOutput('rule-1'), + output_index: '', + }; ruleOutput.name = 'some other name'; ruleOutput.version = 2; expect(bodyToCompare).to.eql(ruleOutput); @@ -393,6 +399,10 @@ export default ({ getService }: FtrProviderContext): void => { }); it('should be able to correctly read back a mixed import of different rules even if some cause conflicts', async () => { + const getRuleOutput = (name: string) => ({ + ...getSimpleRuleOutput(name), + output_index: '', + }); await supertest .post(`${DETECTION_ENGINE_RULES_URL}/_import`) .set('kbn-xsrf', 'true') @@ -425,9 +435,9 @@ export default ({ getService }: FtrProviderContext): void => { const bodyToCompareOfRule3 = removeServerGeneratedProperties(bodyOfRule3); expect([bodyToCompareOfRule1, bodyToCompareOfRule2, bodyToCompareOfRule3]).to.eql([ - getSimpleRuleOutput('rule-1'), - getSimpleRuleOutput('rule-2'), - getSimpleRuleOutput('rule-3'), + getRuleOutput('rule-1'), + getRuleOutput('rule-2'), + getRuleOutput('rule-3'), ]); }); }); diff --git a/x-pack/test/detection_engine_api_integration/common/config.ts b/x-pack/test/detection_engine_api_integration/common/config.ts index 950ba3e8e2ce7..96a83d2c3a427 100644 --- a/x-pack/test/detection_engine_api_integration/common/config.ts +++ b/x-pack/test/detection_engine_api_integration/common/config.ts @@ -75,7 +75,6 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) '--xpack.ruleRegistry.unsafe.indexUpgrade.enabled=true', '--xpack.ruleRegistry.unsafe.legacyMultiTenancy.enabled=true', `--xpack.securitySolution.enableExperimental=${JSON.stringify([ - 'ruleRegistryEnabled', 'previewTelemetryUrlEnabled', ])}`, ...(ssl diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/exception_operators_data_types/index.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/exception_operators_data_types/index.ts index 85cc484146032..ded3df8b6716c 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/exception_operators_data_types/index.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/exception_operators_data_types/index.ts @@ -22,13 +22,23 @@ export default ({ loadTestFile }: FtrProviderContext): void => { describe('', function () { this.tags('ciGroup24'); - loadTestFile(require.resolve('./ip')); - loadTestFile(require.resolve('./ip_array')); loadTestFile(require.resolve('./keyword')); loadTestFile(require.resolve('./keyword_array')); loadTestFile(require.resolve('./long')); loadTestFile(require.resolve('./text')); loadTestFile(require.resolve('./text_array')); }); + + describe('', function () { + this.tags('ciGroup16'); + + loadTestFile(require.resolve('./ip')); + }); + + describe('', function () { + this.tags('ciGroup21'); + + loadTestFile(require.resolve('./ip_array')); + }); }); }; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/import_rules.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/import_rules.ts index 6c332b09483e2..dea25e0147a08 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/import_rules.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/import_rules.ts @@ -46,7 +46,7 @@ const getImportRuleBuffer = (connectorId: string) => { risk_score: 21, severity: 'low', license: '', - output_index: '.siem-signals-devin-hurley-7', + output_index: '', meta: { from: '1m', kibana_siem_app_url: 'http://0.0.0.0:5601/s/7/app/security' }, author: [], false_positives: [], @@ -280,7 +280,10 @@ export default ({ getService }: FtrProviderContext): void => { .expect(200); const bodyToCompare = removeServerGeneratedProperties(body); - expect(bodyToCompare).to.eql(getSimpleRuleOutput('rule-1', false)); + expect(bodyToCompare).to.eql({ + ...getSimpleRuleOutput('rule-1', false), + output_index: '', + }); }); it('should be able to import two rules', async () => { @@ -419,7 +422,10 @@ export default ({ getService }: FtrProviderContext): void => { .expect(200); const bodyToCompare = removeServerGeneratedProperties(body); - const ruleOutput = getSimpleRuleOutput('rule-1'); + const ruleOutput = { + ...getSimpleRuleOutput('rule-1'), + output_index: '', + }; ruleOutput.name = 'some other name'; ruleOutput.version = 2; expect(bodyToCompare).to.eql(ruleOutput); @@ -495,6 +501,11 @@ export default ({ getService }: FtrProviderContext): void => { }); it('should be able to correctly read back a mixed import of different rules even if some cause conflicts', async () => { + const simpleRuleOutput = (ruleName: string) => ({ + ...getSimpleRuleOutput(ruleName), + output_index: '', + }); + await supertest .post(`${DETECTION_ENGINE_RULES_URL}/_import`) .set('kbn-xsrf', 'true') @@ -527,9 +538,9 @@ export default ({ getService }: FtrProviderContext): void => { const bodyToCompareOfRule3 = removeServerGeneratedProperties(bodyOfRule3); expect([bodyToCompareOfRule1, bodyToCompareOfRule2, bodyToCompareOfRule3]).to.eql([ - getSimpleRuleOutput('rule-1'), - getSimpleRuleOutput('rule-2'), - getSimpleRuleOutput('rule-3'), + simpleRuleOutput('rule-1'), + simpleRuleOutput('rule-2'), + simpleRuleOutput('rule-3'), ]); }); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/index.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/index.ts index a6d052a22bee6..a3c4dd8ed3be1 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/index.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/index.ts @@ -14,7 +14,6 @@ export default ({ loadTestFile }: FtrProviderContext): void => { this.tags('ciGroup11'); loadTestFile(require.resolve('./aliases')); - loadTestFile(require.resolve('./create_endpoint_exceptions')); loadTestFile(require.resolve('./add_actions')); loadTestFile(require.resolve('./update_actions')); loadTestFile(require.resolve('./add_prepackaged_rules')); @@ -54,6 +53,12 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./migrations')); }); + describe('', function () { + this.tags('ciGroup26'); + + loadTestFile(require.resolve('./create_endpoint_exceptions')); + }); + describe('', function () { this.tags('ciGroup14'); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/resolve_read_rules.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/resolve_read_rules.ts index 2b4b31bb5510b..5c2bdafbd5c32 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/resolve_read_rules.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/resolve_read_rules.ts @@ -65,10 +65,7 @@ export default ({ getService }: FtrProviderContext) => { body: { alert: { name: 'test 7.14', - tags: [ - '__internal_rule_id:82747bb8-bae0-4b59-8119-7f65ac564e14', - '__internal_immutable:false', - ], + tags: [], alertTypeId: 'siem.queryRule', consumer: 'siem', params: { diff --git a/x-pack/test/detection_engine_api_integration/utils/downgrade_immutable_rule.ts b/x-pack/test/detection_engine_api_integration/utils/downgrade_immutable_rule.ts index 36ebfaee231d9..57f20a1c0e645 100644 --- a/x-pack/test/detection_engine_api_integration/utils/downgrade_immutable_rule.ts +++ b/x-pack/test/detection_engine_api_integration/utils/downgrade_immutable_rule.ts @@ -7,7 +7,6 @@ import type { ToolingLog } from '@kbn/tooling-log'; import type { Client } from '@elastic/elasticsearch'; -import { INTERNAL_RULE_ID_KEY } from '@kbn/security-solution-plugin/common/constants'; import { countDownES } from './count_down_es'; export const downgradeImmutableRule = async ( @@ -29,7 +28,7 @@ export const downgradeImmutableRule = async ( }, query: { term: { - 'alert.tags': `${INTERNAL_RULE_ID_KEY}:${ruleId}`, + 'alert.params.ruleId': ruleId, }, }, }, diff --git a/x-pack/test/detection_engine_api_integration/utils/find_immutable_rule_by_id.ts b/x-pack/test/detection_engine_api_integration/utils/find_immutable_rule_by_id.ts index 2d77cffcdfe41..0e6fe73685c48 100644 --- a/x-pack/test/detection_engine_api_integration/utils/find_immutable_rule_by_id.ts +++ b/x-pack/test/detection_engine_api_integration/utils/find_immutable_rule_by_id.ts @@ -9,11 +9,7 @@ import type { ToolingLog } from '@kbn/tooling-log'; import type SuperTest from 'supertest'; import type { FullResponseSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; -import { - DETECTION_ENGINE_RULES_URL, - INTERNAL_IMMUTABLE_KEY, - INTERNAL_RULE_ID_KEY, -} from '@kbn/security-solution-plugin/common/constants'; +import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants'; /** * Helper to cut down on the noise in some of the tests. This @@ -32,7 +28,7 @@ export const findImmutableRuleById = async ( }> => { const response = await supertest .get( - `${DETECTION_ENGINE_RULES_URL}/_find?filter=alert.attributes.tags: "${INTERNAL_IMMUTABLE_KEY}:true" AND alert.attributes.tags: "${INTERNAL_RULE_ID_KEY}:${ruleId}"` + `${DETECTION_ENGINE_RULES_URL}/_find?filter=alert.attributes.params.immutable: true AND alert.attributes.params.ruleId: "${ruleId}"` ) .set('kbn-xsrf', 'true') .send(); diff --git a/x-pack/test/examples/screenshotting/index.ts b/x-pack/test/examples/screenshotting/index.ts index b59663766389f..e9ecd2ecde346 100644 --- a/x-pack/test/examples/screenshotting/index.ts +++ b/x-pack/test/examples/screenshotting/index.ts @@ -20,9 +20,11 @@ export default function ({ const testSubjects = getService('testSubjects'); const PageObjects = getPageObjects(['common']); - describe('Screenshotting Example', function () { + // FAILING: https://github.com/elastic/kibana/issues/131190 + describe.skip('Screenshotting Example', function () { + this.tags('ciGroup13'); + before(async () => { - this.tags('ciGroup13'); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/visualize.json'); await PageObjects.common.navigateToApp('screenshottingExample'); diff --git a/x-pack/test/fleet_api_integration/apis/epm/get.ts b/x-pack/test/fleet_api_integration/apis/epm/get.ts index 891bf7019eda3..a030a988656b9 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/get.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/get.ts @@ -88,6 +88,26 @@ export default function (providerContext: FtrProviderContext) { await uninstallPackage(testPkgName, testPkgVersion); }); + it('returns correct package info from upload if a uploaded version is not in registry', async function () { + const testPkgArchiveZipV9999 = path.join( + path.dirname(__filename), + '../fixtures/direct_upload_packages/apache_9999.0.0.zip' + ); + const buf = fs.readFileSync(testPkgArchiveZipV9999); + await supertest + .post(`/api/fleet/epm/packages`) + .set('kbn-xsrf', 'xxxx') + .type('application/zip') + .send(buf) + .expect(200); + + const res = await supertest.get(`/api/fleet/epm/packages/apache/9999.0.0`).expect(200); + const packageInfo = res.body.item; + expect(packageInfo.description).to.equal('Apache Uploaded Test Integration'); + expect(packageInfo.download).to.equal(undefined); + await uninstallPackage(testPkgName, '9999.0.0'); + }); + it('returns a 404 for a package that do not exists', async function () { await supertest.get('/api/fleet/epm/packages/notexists/99.99.99').expect(404); }); diff --git a/x-pack/test/fleet_api_integration/apis/epm/index.js b/x-pack/test/fleet_api_integration/apis/epm/index.js index 6364b1de59fc8..ef103592dfb45 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/index.js +++ b/x-pack/test/fleet_api_integration/apis/epm/index.js @@ -27,6 +27,7 @@ export default function loadTests({ loadTestFile }) { loadTestFile(require.resolve('./update_assets')); loadTestFile(require.resolve('./data_stream')); loadTestFile(require.resolve('./package_install_complete')); + loadTestFile(require.resolve('./remove_legacy_templates')); loadTestFile(require.resolve('./install_error_rollback')); loadTestFile(require.resolve('./final_pipeline')); }); diff --git a/x-pack/test/fleet_api_integration/apis/epm/remove_legacy_templates.ts b/x-pack/test/fleet_api_integration/apis/epm/remove_legacy_templates.ts new file mode 100644 index 0000000000000..53022461244b3 --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/epm/remove_legacy_templates.ts @@ -0,0 +1,152 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import path from 'path'; +import fs from 'fs'; +import { promisify } from 'util'; +import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; +import { skipIfNoDockerRegistry } from '../../helpers'; +import { setupFleetAndAgents } from '../agents/services'; +const sleep = promisify(setTimeout); + +export default function (providerContext: FtrProviderContext) { + const { getService } = providerContext; + const supertest = getService('supertest'); + const dockerServers = getService('dockerServers'); + const server = dockerServers.get('registry'); + const esClient = getService('es'); + + const uploadPkgName = 'apache'; + const uploadPkgVersion = '0.1.4'; + + const installUploadPackage = async () => { + const buf = fs.readFileSync(testPkgArchiveZip); + await supertest + .post(`/api/fleet/epm/packages`) + .set('kbn-xsrf', 'xxxx') + .type('application/zip') + .send(buf) + .expect(200); + }; + + const testPkgArchiveZip = path.join( + path.dirname(__filename), + '../fixtures/direct_upload_packages/apache_0.1.4.zip' + ); + + const legacyComponentTemplates = [ + { + name: 'logs-apache.access@settings', + template: { + settings: { + index: { + lifecycle: { + name: 'idontexist', + }, + }, + }, + }, + _meta: { + package: { + name: 'apache', + }, + }, + }, + { + name: 'logs-apache.access@mappings', + template: { + mappings: { + dynamic: false, + }, + }, + _meta: { + package: { + name: 'apache', + }, + }, + }, + ]; + const createLegacyComponentTemplates = async () => + Promise.all( + legacyComponentTemplates.map((tmpl) => esClient.cluster.putComponentTemplate(tmpl)) + ); + + const deleteLegacyComponentTemplates = async () => { + esClient.cluster + .deleteComponentTemplate({ name: legacyComponentTemplates.map((t) => t.name) }) + .catch((e) => {}); + }; + + const waitUntilLegacyComponentTemplatesCreated = async () => { + const legacyTemplateNames = legacyComponentTemplates.map((t) => t.name); + for (let i = 5; i > 0; i--) { + const { component_templates: ctmps } = await esClient.cluster.getComponentTemplate(); + + const createdTemplates = ctmps.filter((tmp) => legacyTemplateNames.includes(tmp.name)); + + if (createdTemplates.length === legacyTemplateNames.length) return; + + await sleep(500); + } + + throw new Error('Legacy component templates not created after 5 attempts'); + }; + const uninstallPackage = async (pkg: string, version: string) => { + await supertest.delete(`/api/fleet/epm/packages/${pkg}/${version}`).set('kbn-xsrf', 'xxxx'); + }; + + describe('legacy component template removal', async () => { + skipIfNoDockerRegistry(providerContext); + setupFleetAndAgents(providerContext); + + afterEach(async () => { + if (!server.enabled) return; + await deleteLegacyComponentTemplates(); + await uninstallPackage(uploadPkgName, uploadPkgVersion); + }); + + after(async () => { + await esClient.indices.deleteIndexTemplate({ name: 'testtemplate' }); + }); + + it('should remove legacy component templates if not in use by index templates', async () => { + await createLegacyComponentTemplates(); + + await waitUntilLegacyComponentTemplatesCreated(); + await installUploadPackage(); + + const { component_templates: allComponentTemplates } = + await esClient.cluster.getComponentTemplate(); + const allComponentTemplateNames = allComponentTemplates.map((t) => t.name); + + expect(allComponentTemplateNames.includes('logs-apache.access@settings')).to.equal(false); + expect(allComponentTemplateNames.includes('logs-apache.access@mappings')).to.equal(false); + }); + + it('should not remove legacy component templates if in use by index templates', async () => { + await createLegacyComponentTemplates(); + + await esClient.indices.putIndexTemplate({ + name: 'testtemplate', + index_patterns: ['nonexistentindices'], + template: {}, + composed_of: ['logs-apache.access@settings', 'logs-apache.access@mappings'], + }); + + await waitUntilLegacyComponentTemplatesCreated(); + await installUploadPackage(); + + const { component_templates: allComponentTemplates } = + await esClient.cluster.getComponentTemplate(); + const allComponentTemplateNames = allComponentTemplates.map((t) => t.name); + + expect(allComponentTemplateNames.includes('logs-apache.access@settings')).to.equal(true); + expect(allComponentTemplateNames.includes('logs-apache.access@mappings')).to.equal(true); + }); + }); +} diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/direct_upload_packages/apache_9999.0.0.zip b/x-pack/test/fleet_api_integration/apis/fixtures/direct_upload_packages/apache_9999.0.0.zip new file mode 100644 index 0000000000000..67a7e09bfec89 Binary files /dev/null and b/x-pack/test/fleet_api_integration/apis/fixtures/direct_upload_packages/apache_9999.0.0.zip differ diff --git a/x-pack/test/functional/apps/apm/correlations/latency_correlations.ts b/x-pack/test/functional/apps/apm/correlations/latency_correlations.ts index 22b553d006303..5cba074eedbec 100644 --- a/x-pack/test/functional/apps/apm/correlations/latency_correlations.ts +++ b/x-pack/test/functional/apps/apm/correlations/latency_correlations.ts @@ -70,7 +70,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await retry.try(async () => { const apmMainContainerText = await testSubjects.getVisibleTextAll('apmMainContainer'); const apmMainContainerTextItems = apmMainContainerText[0].split('\n'); - expect(apmMainContainerTextItems).to.not.contain('No services found'); expect(apmMainContainerTextItems).to.contain('opbeans-go'); diff --git a/x-pack/test/functional/apps/canvas/feature_controls/canvas_security.ts b/x-pack/test/functional/apps/canvas/feature_controls/canvas_security.ts index 1497c85b91bad..d1a500be98ff8 100644 --- a/x-pack/test/functional/apps/canvas/feature_controls/canvas_security.ts +++ b/x-pack/test/functional/apps/canvas/feature_controls/canvas_security.ts @@ -94,7 +94,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it(`allows a workpad to be edited`, async () => { await PageObjects.common.navigateToActualUrl( 'canvas', - 'workpad/workpad-1705f884-6224-47de-ba49-ca224fe6ec31', + '/workpad/workpad-1705f884-6224-47de-ba49-ca224fe6ec31', { ensureCurrentUrl: true, shouldLoginIfPrompted: false, @@ -171,7 +171,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it(`does not allow a workpad to be edited`, async () => { await PageObjects.common.navigateToActualUrl( 'canvas', - 'workpad/workpad-1705f884-6224-47de-ba49-ca224fe6ec31', + '/workpad/workpad-1705f884-6224-47de-ba49-ca224fe6ec31', { ensureCurrentUrl: true, shouldLoginIfPrompted: false, diff --git a/x-pack/test/functional/apps/canvas/feature_controls/canvas_spaces.ts b/x-pack/test/functional/apps/canvas/feature_controls/canvas_spaces.ts index 5060ac60eceae..e030cdbf5f624 100644 --- a/x-pack/test/functional/apps/canvas/feature_controls/canvas_spaces.ts +++ b/x-pack/test/functional/apps/canvas/feature_controls/canvas_spaces.ts @@ -80,7 +80,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it(`allows a workpad to be edited`, async () => { await PageObjects.common.navigateToActualUrl( 'canvas', - 'workpad/workpad-1705f884-6224-47de-ba49-ca224fe6ec31', + '/workpad/workpad-1705f884-6224-47de-ba49-ca224fe6ec31', { ensureCurrentUrl: true, shouldLoginIfPrompted: false, diff --git a/x-pack/test/functional/apps/canvas/index.js b/x-pack/test/functional/apps/canvas/index.js index e4d59a038af74..784aeb6655768 100644 --- a/x-pack/test/functional/apps/canvas/index.js +++ b/x-pack/test/functional/apps/canvas/index.js @@ -27,7 +27,7 @@ export default function canvasApp({ loadTestFile, getService }) { await security.testUser.restoreDefaults(); }); - this.tags('ciGroup2'); // CI requires tags ヽ(゜Q。)ノ? + this.tags('ciGroup2'); loadTestFile(require.resolve('./smoke_test')); loadTestFile(require.resolve('./expression')); loadTestFile(require.resolve('./filters')); diff --git a/x-pack/test/functional/apps/canvas/smoke_test.js b/x-pack/test/functional/apps/canvas/smoke_test.js index 053c58e88cde1..dff3cb7ce30a6 100644 --- a/x-pack/test/functional/apps/canvas/smoke_test.js +++ b/x-pack/test/functional/apps/canvas/smoke_test.js @@ -48,9 +48,9 @@ export default function canvasSmokeTest({ getService, getPageObjects }) { await retry.try(async () => { const url = await browser.getCurrentUrl(); - // remove all the search params, just compare the route - const hashRoute = new URL(url).hash.split('?')[0]; - expect(hashRoute).to.equal(`#/workpad/${testWorkpadId}/page/1`); + const path = new URL(url).pathname; + + expect(path).to.equal(`/app/canvas/workpad/${testWorkpadId}/page/1`); }); }); diff --git a/x-pack/test/functional/apps/graph/feature_controls/graph_security.ts b/x-pack/test/functional/apps/graph/feature_controls/graph_security.ts index 9179373cf610c..a1f0e3db2c187 100644 --- a/x-pack/test/functional/apps/graph/feature_controls/graph_security.ts +++ b/x-pack/test/functional/apps/graph/feature_controls/graph_security.ts @@ -16,8 +16,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const appsMenu = getService('appsMenu'); const globalNav = getService('globalNav'); - // FLAKY https://github.com/elastic/kibana/issues/109564 - describe.skip('security', () => { + describe('security', () => { before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana'); // ensure we're logged out so we can login as the appropriate users diff --git a/x-pack/test/functional/apps/home/feature_controls/home_security.ts b/x-pack/test/functional/apps/home/feature_controls/home_security.ts index f306b9f553d64..96a3ccbe8ea5d 100644 --- a/x-pack/test/functional/apps/home/feature_controls/home_security.ts +++ b/x-pack/test/functional/apps/home/feature_controls/home_security.ts @@ -78,7 +78,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); it('shows the "Manage" action item', async () => { - await testSubjects.existOrFail('homManagementActionItem', { + await testSubjects.existOrFail('homeManage', { timeout: 2000, }); }); @@ -128,7 +128,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); it('does not show the "Manage" action item', async () => { - await testSubjects.missingOrFail('homManagementActionItem', { + await testSubjects.missingOrFail('homeManage', { timeout: 2000, }); }); diff --git a/x-pack/test/functional/apps/lens/chart_data.ts b/x-pack/test/functional/apps/lens/chart_data.ts index ff2f5b339fe53..7ea61c1fa3d81 100644 --- a/x-pack/test/functional/apps/lens/chart_data.ts +++ b/x-pack/test/functional/apps/lens/chart_data.ts @@ -73,37 +73,31 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { } it('should render xy chart', async () => { - await PageObjects.lens.waitForVisualization('xyVisChart'); - - const data = await PageObjects.lens.getCurrentChartDebugState(); + const data = await PageObjects.lens.getCurrentChartDebugState('xyVisChart'); assertMatchesExpectedData(data!); }); it('should render pie chart', async () => { await PageObjects.lens.switchToVisualization('pie'); - await PageObjects.lens.waitForVisualization('partitionVisChart'); - const data = await PageObjects.lens.getCurrentChartDebugState(); + const data = await PageObjects.lens.getCurrentChartDebugState('partitionVisChart'); assertMatchesExpectedPieData(data!); }); it('should render donut chart', async () => { await PageObjects.lens.switchToVisualization('donut'); - await PageObjects.lens.waitForVisualization('partitionVisChart'); - const data = await PageObjects.lens.getCurrentChartDebugState(); + const data = await PageObjects.lens.getCurrentChartDebugState('partitionVisChart'); assertMatchesExpectedPieData(data!); }); it('should render treemap chart', async () => { await PageObjects.lens.switchToVisualization('treemap', 'treemap'); - await PageObjects.lens.waitForVisualization('partitionVisChart'); - const data = await PageObjects.lens.getCurrentChartDebugState(); + const data = await PageObjects.lens.getCurrentChartDebugState('partitionVisChart'); assertMatchesExpectedPieData(data!); }); it('should render heatmap chart', async () => { await PageObjects.lens.switchToVisualization('heatmap', 'heat'); - await PageObjects.lens.waitForVisualization('heatmapChart'); - const debugState = await PageObjects.lens.getCurrentChartDebugState(); + const debugState = await PageObjects.lens.getCurrentChartDebugState('heatmapChart'); if (!debugState) { throw new Error('Debug state is not available'); diff --git a/x-pack/test/functional/apps/lens/heatmap.ts b/x-pack/test/functional/apps/lens/heatmap.ts index 1386e1beea899..ff1378ac82539 100644 --- a/x-pack/test/functional/apps/lens/heatmap.ts +++ b/x-pack/test/functional/apps/lens/heatmap.ts @@ -38,8 +38,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should render heatmap chart with the temperature palette', async () => { await PageObjects.lens.switchToVisualization('heatmap', 'heat'); - await PageObjects.lens.waitForVisualization('heatmapChart'); - const debugState = await PageObjects.lens.getCurrentChartDebugState(); + const debugState = await PageObjects.lens.getCurrentChartDebugState('heatmapChart'); if (!debugState) { throw new Error('Debug state is not available'); @@ -78,9 +77,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { typeCharByChar: true, }); }); - await PageObjects.lens.waitForVisualization('heatmapChart'); - - const debugState = await PageObjects.lens.getCurrentChartDebugState(); + const debugState = await PageObjects.lens.getCurrentChartDebugState('heatmapChart'); if (!debugState) { throw new Error('Debug state is not available'); @@ -98,9 +95,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should not change when passing from percentage to number', async () => { await testSubjects.click('lnsPalettePanel_dynamicColoring_rangeType_groups_number'); - await PageObjects.lens.waitForVisualization('heatmapChart'); - - const debugState = await PageObjects.lens.getCurrentChartDebugState(); + const debugState = await PageObjects.lens.getCurrentChartDebugState('heatmapChart'); if (!debugState) { throw new Error('Debug state is not available'); @@ -124,9 +119,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await testSubjects.setValue('lnsPalettePanel_dynamicColoring_range_value_0', '0', { clearWithKeyboard: true, }); - await PageObjects.lens.waitForVisualization('heatmapChart'); - const debugState = await PageObjects.lens.getCurrentChartDebugState(); + const debugState = await PageObjects.lens.getCurrentChartDebugState('heatmapChart'); if (!debugState) { throw new Error('Debug state is not available'); @@ -144,9 +138,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should reset stop numbers when changing palette', async () => { await PageObjects.lens.changePaletteTo('status'); - await PageObjects.lens.waitForVisualization('heatmapChart'); - const debugState = await PageObjects.lens.getCurrentChartDebugState(); + const debugState = await PageObjects.lens.getCurrentChartDebugState('heatmapChart'); if (!debugState) { throw new Error('Debug state is not available'); @@ -164,9 +157,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should not change when passing from number to percent', async () => { await testSubjects.click('lnsPalettePanel_dynamicColoring_rangeType_groups_percent'); - await PageObjects.lens.waitForVisualization('heatmapChart'); - const debugState = await PageObjects.lens.getCurrentChartDebugState(); + const debugState = await PageObjects.lens.getCurrentChartDebugState('heatmapChart'); if (!debugState) { throw new Error('Debug state is not available'); diff --git a/x-pack/test/functional/apps/lens/multi_terms.ts b/x-pack/test/functional/apps/lens/multi_terms.ts index 18936f09925f5..05283b80a7c81 100644 --- a/x-pack/test/functional/apps/lens/multi_terms.ts +++ b/x-pack/test/functional/apps/lens/multi_terms.ts @@ -50,7 +50,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'Top values of geo.src + 2 others' ); - const data = await PageObjects.lens.getCurrentChartDebugState(); + const data = await PageObjects.lens.getCurrentChartDebugState('xyVisChart'); expect(data!.bars![0].bars[0].x).to.eql('PE › US › 19,986'); }); @@ -75,7 +75,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.lens.closeDimensionEditor(); - const data = await PageObjects.lens.getCurrentChartDebugState(); + const data = await PageObjects.lens.getCurrentChartDebugState('xyVisChart'); expect(data?.bars?.[0]?.name).to.eql('PE › US › 19,986'); }); diff --git a/x-pack/test/functional/apps/lens/smokescreen.ts b/x-pack/test/functional/apps/lens/smokescreen.ts index 721ff1e210326..d817ee912664a 100644 --- a/x-pack/test/functional/apps/lens/smokescreen.ts +++ b/x-pack/test/functional/apps/lens/smokescreen.ts @@ -240,14 +240,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); await PageObjects.lens.changeAxisSide('right'); - await PageObjects.lens.waitForVisualization('xyVisChart'); - let data = await PageObjects.lens.getCurrentChartDebugState(); + let data = await PageObjects.lens.getCurrentChartDebugState('xyVisChart'); expect(data?.axes?.y.length).to.eql(2); expect(data?.axes?.y.some(({ position }) => position === 'right')).to.eql(true); await PageObjects.lens.changeAxisSide('left'); - await PageObjects.lens.waitForVisualization('xyVisChart'); - data = await PageObjects.lens.getCurrentChartDebugState(); + data = await PageObjects.lens.getCurrentChartDebugState('xyVisChart'); expect(data?.axes?.y.length).to.eql(1); expect(data?.axes?.y.some(({ position }) => position === 'right')).to.eql(false); @@ -262,18 +260,15 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.lens.openVisualOptions(); await testSubjects.click('lns_valueLabels_inside'); - await PageObjects.lens.waitForVisualization('xyVisChart'); - // check for value labels - let data = await PageObjects.lens.getCurrentChartDebugState(); + let data = await PageObjects.lens.getCurrentChartDebugState('xyVisChart'); expect(data?.bars?.[0].labels).not.to.eql(0); // switch to stacked bar chart await PageObjects.lens.switchToVisualization('bar_stacked'); - await PageObjects.lens.waitForVisualization('xyVisChart'); // check for value labels - data = await PageObjects.lens.getCurrentChartDebugState(); + data = await PageObjects.lens.getCurrentChartDebugState('xyVisChart'); expect(data?.bars?.[0].labels.length).to.eql(0); }); @@ -283,16 +278,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await testSubjects.setValue('lnsyLeftAxisTitle', axisTitle, { clearWithKeyboard: true, }); - await PageObjects.lens.waitForVisualization('xyVisChart'); - let data = await PageObjects.lens.getCurrentChartDebugState(); + let data = await PageObjects.lens.getCurrentChartDebugState('xyVisChart'); expect(data?.axes?.y?.[0].title).to.eql(axisTitle); // hide the gridlines await testSubjects.click('lnsshowyLeftAxisGridlines'); - await PageObjects.lens.waitForVisualization('xyVisChart'); - data = await PageObjects.lens.getCurrentChartDebugState(); + data = await PageObjects.lens.getCurrentChartDebugState('xyVisChart'); expect(data?.axes?.y?.[0].gridlines.length).to.eql(0); }); diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation_saved_search.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation_saved_search.ts index 75ad646a26ac9..861be18591a11 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation_saved_search.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation_saved_search.ts @@ -163,8 +163,7 @@ export default function ({ getService }: FtrProviderContext) { ]; for (const testData of testDataList) { - // FLAKY: https://github.com/elastic/kibana/issues/126112 - describe.skip(`${testData.suiteTitle}`, function () { + describe(`${testData.suiteTitle}`, function () { after(async () => { await ml.api.deleteIndices(testData.destinationIndex); await ml.testResources.deleteIndexPatternByTitle(testData.destinationIndex); diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/results_view_content.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/results_view_content.ts index 57d3922b043a3..2bddf0a7d9512 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/results_view_content.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/results_view_content.ts @@ -14,8 +14,7 @@ export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const ml = getService('ml'); - // FLAKY: https://github.com/elastic/kibana/issues/126422 - describe.skip('results view content and total feature importance', function () { + describe('results view content and total feature importance', function () { const testDataList: Array<{ suiteTitle: string; archive: string; @@ -284,6 +283,7 @@ export default function ({ getService }: FtrProviderContext) { }); it('should display the total feature importance in the results view', async () => { + await ml.dataFrameAnalyticsResults.expandFeatureImportanceSection(true); await ml.dataFrameAnalyticsResults.assertTotalFeatureImportanceEvaluatePanelExists(); }); diff --git a/x-pack/test/functional/apps/ml/model_management/model_list.ts b/x-pack/test/functional/apps/ml/model_management/model_list.ts index 811ae280e0780..08fb3b7124aec 100644 --- a/x-pack/test/functional/apps/ml/model_management/model_list.ts +++ b/x-pack/test/functional/apps/ml/model_management/model_list.ts @@ -10,8 +10,7 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { const ml = getService('ml'); - // Failing: See https://github.com/elastic/kibana/issues/125455 - describe.skip('trained models', function () { + describe('trained models', function () { before(async () => { await ml.trainedModels.createTestTrainedModels('classification', 15, true); await ml.trainedModels.createTestTrainedModels('regression', 15); diff --git a/x-pack/test/functional/apps/uptime/feature_controls/uptime_security.ts b/x-pack/test/functional/apps/uptime/feature_controls/uptime_security.ts index 4d4acbe6242ba..b90337c3648b2 100644 --- a/x-pack/test/functional/apps/uptime/feature_controls/uptime_security.ts +++ b/x-pack/test/functional/apps/uptime/feature_controls/uptime_security.ts @@ -71,6 +71,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { 'Overview', 'Alerts', 'Uptime', + 'Synthetics', 'Stack Management', ]); }); @@ -123,7 +124,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it('shows uptime navlink', async () => { const navLinks = (await appsMenu.readLinks()).map((link) => link.text); - expect(navLinks).to.eql(['Overview', 'Alerts', 'Uptime', 'Stack Management']); + expect(navLinks).to.eql(['Overview', 'Alerts', 'Uptime', 'Synthetics', 'Stack Management']); }); it('can navigate to Uptime app', async () => { diff --git a/x-pack/test/functional/config.js b/x-pack/test/functional/config.js index 3d1f7d5e3dbd5..8d39f26d4569d 100644 --- a/x-pack/test/functional/config.js +++ b/x-pack/test/functional/config.js @@ -30,6 +30,7 @@ export default async function ({ readConfigFile }) { return { // list paths to the files that contain your plugins tests testFiles: [ + resolve(__dirname, './apps/home'), resolve(__dirname, './apps/advanced_settings'), resolve(__dirname, './apps/canvas'), resolve(__dirname, './apps/graph'), diff --git a/x-pack/test/functional/es_archives/actions/data.json b/x-pack/test/functional/es_archives/actions/data.json index 79e7920872ab0..75206672358db 100644 --- a/x-pack/test/functional/es_archives/actions/data.json +++ b/x-pack/test/functional/es_archives/actions/data.json @@ -205,4 +205,96 @@ "updated_at": "2021-08-31T12:43:37.117Z" } } +} + +{ + "type": "doc", + "value": { + "id": "action:7d04bc30-c4c0-11ec-ae29-917aa31a5b75", + "index": ".kibana_1", + "source": { + "action": { + "actionTypeId" : ".servicenow-sir", + "name" : "test servicenow SecOps", + "isMissingSecrets" : false, + "config" : { + "apiUrl": "https://devtestsecops.service-now.com", + "usesTableApi": false + }, + "secrets" : "kPp4tl4ueQ2ZNWSfATR3dFrbxd+NNBo4MY8izS6GJf358Lmeg/YaYjb2rIymrbPktR6HnPBRaVyXWlRTvBGstRicJc0LJHZbx3wNJlTRIj4UFlVqZLGQWQ/GcSqFLSZ1JQbKwgAvyfLtF6BhjAhGYEovK3/OLUNzGc3gvUOOHBiPWjiAY8A=" + }, + "migrationVersion": { + "action": "8.0.0" + }, + "coreMigrationVersion" : "8.2.0", + "references": [ + ], + "namespaces": [ + "default" + ], + "type": "action", + "updated_at": "2022-04-25T17:52:35.201Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "action:8a9331b0-c4c0-11ec-ae29-917aa31a5b75", + "index": ".kibana_1", + "source": { + "action": { + "actionTypeId" : ".servicenow-itom", + "name" : "test servicenow ITOM", + "isMissingSecrets" : false, + "config" : { + "apiUrl": "https://devtestsecops.service-now.com" + }, + "secrets" : "yYThM4vbrSTIg5IjKWE+eMDrxzL7UO0JQIyh6FvEMgqoNREUxRrIavSo25v+DXQIX1DyfsvjjKg97pNPlZhvS3siCwDZZafSFrwkCKDl+S4KHORgIMX+slilcQeuEnzwit7bFxcY7Y/AcNF8Ks6jO0Gs1UR58ibSPUALXoK2VOlJnHSgtvE=" + }, + "migrationVersion": { + "action": "8.0.0" + }, + "coreMigrationVersion" : "8.2.0", + "references": [ + ], + "namespaces": [ + "default" + ], + "type": "action", + "updated_at": "2022-04-25T17:52:35.201Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "action:6d3a1250-c4c0-11ec-ae29-917aa31a5b75", + "index": ".kibana_1", + "source": { + "action": { + "actionTypeId" : ".servicenow", + "name" : "test servicenow ITSM", + "isMissingSecrets" : false, + "config" : { + "usesTableApi": false, + "apiUrl": "https://devtestsecops.service-now.com" + }, + "secrets" : "zfXUDtG0CyJkJUKnQ8rSqo75hb6ZhbRUWkV1NiFEjApM87b72Rcqz3Fv+sbm8eBDOO1Fdd9CVyK+Bfly4ZwVCgL2lR0qIbPzz34q36r267dnGVsaERyJIVv2WPy+EGdiRZKgfpy4XFbMNT1R3gyIsUkd4TT+McqGfVTont2XTFIpMW2A9y8=" + }, + "migrationVersion": { + "action": "8.0.0" + }, + "coreMigrationVersion" : "8.2.0", + "references": [ + ], + "namespaces": [ + "default" + ], + "type": "action", + "updated_at": "2022-04-25T17:52:35.201Z" + } + } } \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/alerts/data.json b/x-pack/test/functional/es_archives/alerts/data.json index 39ce6248c7ebb..1c096d9df9930 100644 --- a/x-pack/test/functional/es_archives/alerts/data.json +++ b/x-pack/test/functional/es_archives/alerts/data.json @@ -671,10 +671,7 @@ "source":{ "alert":{ "name":"enabled 7.16.1 query rule", - "tags":[ - "__internal_rule_id:064e3fed-6328-416b-bb85-c08265088f41", - "__internal_immutable:false" - ], + "tags":[], "alertTypeId":"siem.signals", "consumer":"siem", "params":{ @@ -767,10 +764,7 @@ "source":{ "alert":{ "name":"disabled 7.16.1 query rule", - "tags":[ - "__internal_rule_id:364e3fed-6328-416b-bb85-c08265088f41", - "__internal_immutable:false" - ], + "tags":[], "alertTypeId":"siem.signals", "consumer":"siem", "params":{ @@ -895,4 +889,104 @@ ] } } +} + +{ + "type":"doc", + "value":{ + "id":"alert:8990af61-c09a-11ec-9164-4bfd6fc32c43", + "index":".kibana_1", + "source":{ + "alert":{ + "name":"Test remove internal tags", + "alertTypeId":"siem.queryRule", + "consumer":"siem", + "params":{ + "immutable":true, + "ruleId":"bf9638eb-7d3c-4f40-83d7-8c40a7c80f2e", + "author":[ + + ], + "description":"remove interns tags mock rule", + "falsePositives":[ + + ], + "from":"now-36000060s", + "license":"", + "outputIndex":".siem-signals-default", + "meta":{ + "from":"10000h" + }, + "maxSignals":100, + "riskScore":21, + "riskScoreMapping":[ + + ], + "severity":"low", + "severityMapping":[ + + ], + "threat":[ + + ], + "to":"now", + "references":[ + + ], + "version":4, + "exceptionsList":[ + ], + "type":"query", + "language":"kuery", + "index":[ + "apm-*-transaction*", + "traces-apm*", + "auditbeat-*", + "endgame-*", + "filebeat-*", + "logs-*", + "packetbeat-*", + "winlogbeat-*", + "test-index-3" + ], + "query":"*:*", + "filters":[ + + ] + }, + "schedule":{ + "interval":"1m" + }, + "enabled":true, + "actions":[ + + ], + "throttle":null, + "apiKeyOwner":null, + "apiKey":null, + "createdBy":"elastic", + "updatedBy":"elastic", + "createdAt":"2021-07-27T20:42:55.896Z", + "muteAll":false, + "mutedInstanceIds":[ + + ], + "scheduledTaskId":null, + "tags":[ + "__internal_rule_id:364e3fed-6328-416b-bb85-c08265088f41", + "__internal_immutable:false", + "test-tag-1", + "foo-tag" + ] + }, + "type":"alert", + "migrationVersion":{ + "alert":"8.2.0" + }, + "updated_at":"2021-08-13T23:00:11.985Z", + "references":[ + + ] + } + } } \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/task_manager_tasks/data.json b/x-pack/test/functional/es_archives/task_manager_tasks/data.json index 916010b56b8e0..974642e98c07f 100644 --- a/x-pack/test/functional/es_archives/task_manager_tasks/data.json +++ b/x-pack/test/functional/es_archives/task_manager_tasks/data.json @@ -213,4 +213,4 @@ "updated_at": "2020-11-30T15:43:08.277Z" } } -} \ No newline at end of file +} diff --git a/x-pack/test/functional/fixtures/kbn_archiver/cases/8.2.0/cases_duration.json b/x-pack/test/functional/fixtures/kbn_archiver/cases/8.2.0/cases_duration.json new file mode 100644 index 0000000000000..ba8bab9227fbb --- /dev/null +++ b/x-pack/test/functional/fixtures/kbn_archiver/cases/8.2.0/cases_duration.json @@ -0,0 +1,129 @@ +{ + "attributes": { + "closed_at": "2022-03-25T10:18:00.000Z", + "closed_by": { + "email": "", + "full_name": "", + "username": "elastic" + }, + "connector": { + "fields": null, + "name": "none", + "type": ".none" + }, + "created_at": "2022-03-25T10:16:00.000Z", + "created_by": { + "email": "", + "full_name": "", + "username": "elastic" + }, + "description": "test 2", + "external_service": null, + "owner": "securitySolutionFixture", + "settings": { + "syncAlerts": false + }, + "status": "closed", + "tags": [], + "title": "stack", + "updated_at": "2022-03-29T10:33:09.754Z", + "updated_by": { + "email": "", + "full_name": "", + "username": "elastic" + } + }, + "coreMigrationVersion": "8.2.0", + "id": "4537b380-a512-11ec-b92f-859b9e89e434", + "migrationVersion": { + "cases": "8.1.0" + }, + "references": [], + "type": "cases", + "updated_at": "2022-03-29T10:33:09.754Z", + "version": "WzE2OTYyNCwxNF0=" +} + +{ + "attributes": { + "closed_at": null, + "closed_by": null, + "connector": { + "fields": null, + "name": "none", + "type": ".none" + }, + "created_at": "2022-03-20T10:16:56.252Z", + "created_by": { + "email": "", + "full_name": "", + "username": "elastic" + }, + "description": "test 2", + "external_service": null, + "owner": "observabilityFixture", + "settings": { + "syncAlerts": false + }, + "status": "open", + "tags": [], + "title": "stack", + "updated_at": "2022-03-29T10:33:09.754Z", + "updated_by": { + "email": "", + "full_name": "", + "username": "elastic" + } + }, + "coreMigrationVersion": "8.2.0", + "id": "7537b580-a512-11ec-b94f-85979e89e434", + "migrationVersion": { + "cases": "8.1.0" + }, + "references": [], + "type": "cases", + "updated_at": "2022-03-29T10:33:09.754Z", + "version": "WzE2OTYyNCwxNF0=" +} + +{ + "attributes": { + "closed_at": null, + "closed_by": null, + "connector": { + "fields": null, + "name": "none", + "type": ".none" + }, + "created_at": "2022-03-20T10:16:56.252Z", + "created_by": { + "email": "", + "full_name": "", + "username": "elastic" + }, + "description": "test 2", + "external_service": null, + "owner": "observabilityFixture", + "settings": { + "syncAlerts": false + }, + "status": "in-progress", + "tags": [], + "title": "stack", + "updated_at": "2022-03-29T10:33:09.754Z", + "updated_by": { + "email": "", + "full_name": "", + "username": "elastic" + } + }, + "coreMigrationVersion": "8.2.0", + "id": "1537b580-a512-11ec-b94f-85979e89e434", + "migrationVersion": { + "cases": "8.1.0" + }, + "references": [], + "type": "cases", + "updated_at": "2022-03-29T10:33:09.754Z", + "version": "WzE2OTYyNCwxNF0=" +} diff --git a/x-pack/test/functional/fixtures/kbn_archiver/cases/8.2.0/cases_various_dates.json b/x-pack/test/functional/fixtures/kbn_archiver/cases/8.2.0/cases_various_dates.json index ffdfef08735fd..cd87b6c44de1b 100644 --- a/x-pack/test/functional/fixtures/kbn_archiver/cases/8.2.0/cases_various_dates.json +++ b/x-pack/test/functional/fixtures/kbn_archiver/cases/8.2.0/cases_various_dates.json @@ -11,7 +11,7 @@ "created_by": { "email": "", "full_name": "", - "username": "cnasikas" + "username": "elastic" }, "description": "test", "external_service": null, @@ -26,7 +26,7 @@ "updated_by": { "email": "", "full_name": "", - "username": "cnasikas" + "username": "elastic" } }, "coreMigrationVersion": "8.2.0", @@ -53,7 +53,7 @@ "created_by": { "email": "", "full_name": "", - "username": "cnasikas" + "username": "elastic" }, "description": "test 2", "external_service": null, @@ -68,7 +68,7 @@ "updated_by": { "email": "", "full_name": "", - "username": "cnasikas" + "username": "elastic" } }, "coreMigrationVersion": "8.2.0", @@ -95,7 +95,7 @@ "created_by": { "email": "", "full_name": "", - "username": "cnasikas" + "username": "elastic" }, "description": "test 2", "external_service": null, @@ -110,7 +110,7 @@ "updated_by": { "email": "", "full_name": "", - "username": "cnasikas" + "username": "elastic" } }, "coreMigrationVersion": "8.2.0", diff --git a/x-pack/test/functional/fixtures/kbn_archiver/cases/8.3.0/all_cases_metrics.json b/x-pack/test/functional/fixtures/kbn_archiver/cases/8.3.0/all_cases_metrics.json new file mode 100644 index 0000000000000..f677d7624692c --- /dev/null +++ b/x-pack/test/functional/fixtures/kbn_archiver/cases/8.3.0/all_cases_metrics.json @@ -0,0 +1,182 @@ +{ + "attributes": { + "closed_at": "2022-04-29T13:24:44.448Z", + "closed_by": { + "email": null, + "full_name": null, + "username": "elastic" + }, + "connector": { + "fields": [], + "name": "none", + "type": ".none" + }, + "created_at": "2022-04-28T13:24:24.011Z", + "created_by": { + "email": null, + "full_name": null, + "username": "elastic" + }, + "description": "test mttr", + "duration": 20, + "external_service": null, + "owner": "securitySolutionFixture", + "settings": { + "syncAlerts": true + }, + "status": "closed", + "tags": [], + "title": "test mttr", + "updated_at": "2022-04-29T13:24:44.448Z", + "updated_by": { + "email": null, + "full_name": null, + "username": "elastic" + } + }, + "coreMigrationVersion": "8.3.0", + "id": "af948570-c7bf-11ec-9771-d5eef9232089", + "migrationVersion": { + "cases": "8.3.0" + }, + "references": [], + "type": "cases", + "updated_at": "2022-04-29T13:24:44.449Z", + "version": "WzE0NjgsMV0=" +} + +{ + "attributes": { + "closed_at": "2022-04-30T13:32:00.448Z", + "closed_by": { + "email": null, + "full_name": null, + "username": "elastic" + }, + "connector": { + "fields": [], + "name": "none", + "type": ".none" + }, + "created_at": "2022-04-30T13:24:00.011Z", + "created_by": { + "email": null, + "full_name": null, + "username": "elastic" + }, + "description": "test mttr", + "duration": 480, + "external_service": null, + "owner": "securitySolutionFixture", + "settings": { + "syncAlerts": true + }, + "status": "closed", + "tags": [], + "title": "test mttr", + "updated_at": "2022-04-29T13:24:44.448Z", + "updated_by": { + "email": null, + "full_name": null, + "username": "elastic" + } + }, + "coreMigrationVersion": "8.3.0", + "id": "bf948570-c7bf-11ec-9771-d5eef9232089", + "migrationVersion": { + "cases": "8.3.0" + }, + "references": [], + "type": "cases", + "updated_at": "2022-04-29T13:24:44.449Z", + "version": "WzE0NjgsMV0=" +} + +{ + "attributes": { + "closed_at": "2022-04-29T13:32:00.448Z", + "closed_by": { + "email": null, + "full_name": null, + "username": "elastic" + }, + "connector": { + "fields": [], + "name": "none", + "type": ".none" + }, + "created_at": "2022-04-29T13:24:00.011Z", + "created_by": { + "email": null, + "full_name": null, + "username": "elastic" + }, + "description": "test mttr", + "duration": 160, + "external_service": null, + "owner": "observabilityFixture", + "settings": { + "syncAlerts": true + }, + "status": "closed", + "tags": [], + "title": "test mttr", + "updated_at": "2022-04-29T13:24:44.448Z", + "updated_by": { + "email": null, + "full_name": null, + "username": "elastic" + } + }, + "coreMigrationVersion": "8.3.0", + "id": "cf948570-c7bf-11ec-9771-d5eef9232089", + "migrationVersion": { + "cases": "8.3.0" + }, + "references": [], + "type": "cases", + "updated_at": "2022-04-29T13:24:44.449Z", + "version": "WzE0NjgsMV0=" +} + +{ + "attributes": { + "closed_at": null, + "closed_by": null, + "connector": { + "fields": null, + "name": "none", + "type": ".none" + }, + "created_at": "2022-03-20T10:16:56.252Z", + "created_by": { + "email": "", + "full_name": "", + "username": "elastic" + }, + "description": "test 2", + "external_service": null, + "owner": "securitySolutionFixture", + "settings": { + "syncAlerts": false + }, + "status": "open", + "tags": [], + "title": "stack", + "updated_at": "2022-03-29T10:33:09.754Z", + "updated_by": { + "email": "", + "full_name": "", + "username": "elastic" + } + }, + "coreMigrationVersion": "8.3.0", + "id": "df948570-c7bf-11ec-9771-d5eef9232089", + "migrationVersion": { + "cases": "8.3.0" + }, + "references": [], + "type": "cases", + "updated_at": "2022-04-29T13:24:44.449Z", + "version": "WzE0NjgsMV0=" +} diff --git a/x-pack/test/functional/page_objects/graph_page.ts b/x-pack/test/functional/page_objects/graph_page.ts index 1203d4077b5b8..aec58d27acbbe 100644 --- a/x-pack/test/functional/page_objects/graph_page.ts +++ b/x-pack/test/functional/page_objects/graph_page.ts @@ -283,4 +283,9 @@ export class GraphPageObject extends FtrService { const el = await this.find.byCssSelector('small.gphLinkSummary__term--2'); return await el.getVisibleText(); } + + async getAllGraphNodes() { + const el = await this.find.allByCssSelector('.gphNode'); + return el.length; + } } diff --git a/x-pack/test/functional/page_objects/lens_page.ts b/x-pack/test/functional/page_objects/lens_page.ts index 5e7922a9b30dc..d38264150cfa5 100644 --- a/x-pack/test/functional/page_objects/lens_page.ts +++ b/x-pack/test/functional/page_objects/lens_page.ts @@ -655,7 +655,7 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont }, async editDimensionLabel(label: string) { - await testSubjects.setValue('indexPattern-label-edit', label, { clearWithKeyboard: true }); + await testSubjects.setValue('column-label-edit', label, { clearWithKeyboard: true }); }, async editDimensionFormat(format: string) { const formatInput = await testSubjects.find('indexPattern-dimension-format'); @@ -720,15 +720,24 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont */ async switchToVisualization(subVisualizationId: string, searchTerm?: string) { await this.openChartSwitchPopover(); - const searchInput = await testSubjects.find('lnsChartSwitchSearch'); - await searchInput.focus(); - await this.searchOnChartSwitch(subVisualizationId, searchTerm); + await this.waitForSearchInputValue(subVisualizationId, searchTerm); await testSubjects.click(`lnsChartSwitchPopover_${subVisualizationId}`); await PageObjects.header.waitUntilLoadingHasFinished(); }, + async waitForSearchInputValue(subVisualizationId: string, searchTerm?: string) { + await retry.try(async () => { + await this.searchOnChartSwitch(subVisualizationId, searchTerm); + await PageObjects.common.sleep(1000); // give time for the value to be typed + const searchInputValue = await testSubjects.getAttribute('lnsChartSwitchSearch', 'value'); + const queryTerm = searchTerm ?? subVisualizationId.substring(subVisualizationId.length - 3); + if (searchInputValue !== queryTerm) { + throw new Error('Search input value is not the expected value'); + } + }); + }, async openChartSwitchPopover() { - if (await testSubjects.exists('lnsChartSwitchList')) { + if (await testSubjects.exists('lnsChartSwitchList', { timeout: 50 })) { return; } await retry.try(async () => { @@ -897,7 +906,8 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont ); }, - async getCurrentChartDebugState() { + async getCurrentChartDebugState(visType: string) { + await this.waitForVisualization(visType); return await elasticChart.getChartDebugData('lnsWorkspace'); }, diff --git a/x-pack/test/functional/page_objects/uptime_page.ts b/x-pack/test/functional/page_objects/uptime_page.ts index 366511f7f43c5..531e0e5980255 100644 --- a/x-pack/test/functional/page_objects/uptime_page.ts +++ b/x-pack/test/functional/page_objects/uptime_page.ts @@ -107,7 +107,7 @@ export class UptimePageObject extends FtrService { public async setAlertKueryBarText(filters: string) { const { setKueryBarText } = this.commonService; - await setKueryBarText('xpack.uptime.alerts.monitorStatus.filterBar', filters); + await setKueryBarText('xpack.synthetics.alerts.monitorStatus.filterBar', filters); } public async setMonitorListPageSize(size: number): Promise { diff --git a/x-pack/test/functional/services/observability/alerts/common.ts b/x-pack/test/functional/services/observability/alerts/common.ts index fc81cce20426d..26312b81b7b3b 100644 --- a/x-pack/test/functional/services/observability/alerts/common.ts +++ b/x-pack/test/functional/services/observability/alerts/common.ts @@ -131,12 +131,14 @@ export function ObservabilityAlertsCommonProvider({ }; // Flyout - const getOpenFlyoutButton = async () => { - return await testSubjects.find('openFlyoutButton'); + const getViewAlertDetailsFlyoutButton = async () => { + await openActionsMenuForRow(0); + + return await testSubjects.find('viewAlertDetails'); }; const openAlertsFlyout = async () => { - await (await getOpenFlyoutButton()).click(); + await (await getViewAlertDetailsFlyoutButton()).click(); await retry.waitFor( 'flyout open', async () => await testSubjects.exists(ALERTS_FLYOUT_SELECTOR, { timeout: 2500 }) diff --git a/x-pack/test/functional/services/uptime/alerts.ts b/x-pack/test/functional/services/uptime/alerts.ts index 76bea59cc4207..356bec6fa104e 100644 --- a/x-pack/test/functional/services/uptime/alerts.ts +++ b/x-pack/test/functional/services/uptime/alerts.ts @@ -13,18 +13,18 @@ export function UptimeAlertsProvider({ getService }: FtrProviderContext) { return { async openFlyout(alertType: 'monitorStatus' | 'tls') { - await testSubjects.click('xpack.uptime.alertsPopover.toggleButton'); - await testSubjects.click('xpack.uptime.openAlertContextPanel'); + await testSubjects.click('xpack.synthetics.alertsPopover.toggleButton'); + await testSubjects.click('xpack.synthetics.openAlertContextPanel'); if (alertType === 'monitorStatus') { - await testSubjects.click('xpack.uptime.toggleAlertFlyout'); + await testSubjects.click('xpack.synthetics.toggleAlertFlyout'); } else if (alertType === 'tls') { - await testSubjects.click('xpack.uptime.toggleTlsAlertFlyout'); + await testSubjects.click('xpack.synthetics.toggleTlsAlertFlyout'); } // ensure the flyout has opened await testSubjects.exists('ruleNameInput'); }, async openMonitorStatusAlertType(alertType: string) { - await testSubjects.click(`xpack.uptime.alerts.${alertType}-SelectOption`); + await testSubjects.click(`xpack.synthetics.alerts.${alertType}-SelectOption`); }, async setAlertTags(tags: string[]) { for (let i = 0; i < tags.length; i += 1) { @@ -55,15 +55,15 @@ export function UptimeAlertsProvider({ getService }: FtrProviderContext) { }, async setAlertStatusNumTimes(value: string) { await this.setAlertExpressionValue( - 'xpack.uptime.alerts.monitorStatus.numTimesExpression', - 'xpack.uptime.alerts.monitorStatus.numTimesField', + 'xpack.synthetics.alerts.monitorStatus.numTimesExpression', + 'xpack.synthetics.alerts.monitorStatus.numTimesField', value ); }, async setAlertTimerangeSelection(value: string) { await this.setAlertExpressionValue( - 'xpack.uptime.alerts.monitorStatus.timerangeValueExpression', - 'xpack.uptime.alerts.monitorStatus.timerangeValueField', + 'xpack.synthetics.alerts.monitorStatus.timerangeValueExpression', + 'xpack.synthetics.alerts.monitorStatus.timerangeValueField', value ); }, @@ -81,9 +81,9 @@ export function UptimeAlertsProvider({ getService }: FtrProviderContext) { }, async setMonitorStatusSelectableToHours() { await this.setAlertExpressionSelectable( - 'xpack.uptime.alerts.monitorStatus.timerangeUnitExpression', - 'xpack.uptime.alerts.monitorStatus.timerangeUnitSelectable', - ['xpack.uptime.alerts.monitorStatus.timerangeUnitSelectable.hoursOption'] + 'xpack.synthetics.alerts.monitorStatus.timerangeUnitExpression', + 'xpack.synthetics.alerts.monitorStatus.timerangeUnitSelectable', + ['xpack.synthetics.alerts.monitorStatus.timerangeUnitSelectable.hoursOption'] ); }, async clickAddFilter() { diff --git a/x-pack/test/functional/services/uptime/common.ts b/x-pack/test/functional/services/uptime/common.ts index adc84aa7b8352..4488c340a2b6b 100644 --- a/x-pack/test/functional/services/uptime/common.ts +++ b/x-pack/test/functional/services/uptime/common.ts @@ -45,26 +45,26 @@ export function UptimeCommonProvider({ getService, getPageObjects }: FtrProvider await this.setKueryBarText('queryInput', filterQuery); }, async goToNextPage() { - await testSubjects.click('xpack.uptime.monitorList.nextButton', 5000); + await testSubjects.click('xpack.synthetics.monitorList.nextButton', 5000); }, async goToPreviousPage() { - await testSubjects.click('xpack.uptime.monitorList.prevButton', 5000); + await testSubjects.click('xpack.synthetics.monitorList.prevButton', 5000); }, async setStatusFilterUp() { - await testSubjects.click('xpack.uptime.filterBar.filterStatusUp'); + await testSubjects.click('xpack.synthetics.filterBar.filterStatusUp'); }, async setStatusFilterDown() { - await testSubjects.click('xpack.uptime.filterBar.filterStatusDown'); + await testSubjects.click('xpack.synthetics.filterBar.filterStatusDown'); }, async resetStatusFilter() { const upFilter = await find.byCssSelector( - '[data-test-subj="xpack.uptime.filterBar.filterStatusUp"]' + '[data-test-subj="xpack.synthetics.filterBar.filterStatusUp"]' ); if (await upFilter.elementHasClass('euiFilterButton-hasActiveFilters')) { await this.setStatusFilterUp(); } const downFilter = await find.byCssSelector( - '[data-test-subj="xpack.uptime.filterBar.filterStatusDown"]' + '[data-test-subj="xpack.synthetics.filterBar.filterStatusDown"]' ); if (await downFilter.elementHasClass('euiFilterButton-hasActiveFilters')) { await this.setStatusFilterDown(); @@ -92,16 +92,16 @@ export function UptimeCommonProvider({ getService, getPageObjects }: FtrProvider }, async getSnapshotCount() { return { - up: await testSubjects.getVisibleText('xpack.uptime.snapshot.donutChart.up'), - down: await testSubjects.getVisibleText('xpack.uptime.snapshot.donutChart.down'), + up: await testSubjects.getVisibleText('xpack.synthetics.snapshot.donutChart.up'), + down: await testSubjects.getVisibleText('xpack.synthetics.snapshot.donutChart.down'), }; }, async openPageSizeSelectPopover(): Promise { - return testSubjects.click('xpack.uptime.monitorList.pageSizeSelect.popoverOpen', 5000); + return testSubjects.click('xpack.synthetics.monitorList.pageSizeSelect.popoverOpen', 5000); }, async clickPageSizeSelectPopoverItem(size: number = 10): Promise { return testSubjects.click( - `xpack.uptime.monitorList.pageSizeSelect.sizeSelectItem${size.toString()}`, + `xpack.synthetics.monitorList.pageSizeSelect.sizeSelectItem${size.toString()}`, 5000 ); }, @@ -116,7 +116,7 @@ export function UptimeCommonProvider({ getService, getPageObjects }: FtrProvider }); }, async hasMappingsError() { - return testSubjects.exists('xpack.uptime.mappingsErrorPage'); + return testSubjects.exists('xpack.synthetics.mappingsErrorPage'); }, }; } diff --git a/x-pack/test/functional/services/uptime/monitor.ts b/x-pack/test/functional/services/uptime/monitor.ts index a8b8d96381747..529cbf6eac2da 100644 --- a/x-pack/test/functional/services/uptime/monitor.ts +++ b/x-pack/test/functional/services/uptime/monitor.ts @@ -23,19 +23,19 @@ export function UptimeMonitorProvider({ getService, getPageObjects }: FtrProvide }); }, async setPingListLocation(location: string) { - await testSubjects.click('xpack.uptime.pingList.locationSelect', 5000); - return testSubjects.click(`xpack.uptime.pingList.locationOptions.${location}`, 5000); + await testSubjects.click('xpack.synthetics.pingList.locationSelect', 5000); + return testSubjects.click(`xpack.synthetics.pingList.locationOptions.${location}`, 5000); }, async setPingListStatus(status: string) { - await testSubjects.click('xpack.uptime.pingList.statusSelect', 5000); - return testSubjects.click(`xpack.uptime.pingList.statusOptions.${status}`, 5000); + await testSubjects.click('xpack.synthetics.pingList.statusSelect', 5000); + return testSubjects.click(`xpack.synthetics.pingList.statusOptions.${status}`, 5000); }, async checkForPingListTimestamps(timestamps: string[]): Promise { return retry.tryForTime(10000, async () => { await Promise.all( timestamps.map( async (timestamp) => - await testSubjects.existOrFail(`xpack.uptime.pingList.ping-${timestamp}`) + await testSubjects.existOrFail(`xpack.synthetics.pingList.ping-${timestamp}`) ) ); }); diff --git a/x-pack/test/functional/services/uptime/overview.ts b/x-pack/test/functional/services/uptime/overview.ts index 8918a0df70ee7..a41884c74cd08 100644 --- a/x-pack/test/functional/services/uptime/overview.ts +++ b/x-pack/test/functional/services/uptime/overview.ts @@ -13,24 +13,24 @@ export function UptimeOverviewProvider({ getService }: FtrProviderContext) { return { async expandMonitorDetail(id: string): Promise { - return testSubjects.click(`xpack.uptime.monitorList.${id}.expandMonitorDetail`); + return testSubjects.click(`xpack.synthetics.monitorList.${id}.expandMonitorDetail`); }, async openIntegrationsPopoverForMonitor(id: string): Promise { - return testSubjects.click(`xpack.uptime.monitorList.actionsPopover.${id}`); + return testSubjects.click(`xpack.synthetics.monitorList.actionsPopover.${id}`); }, async openAlertsPopover(): Promise { - return testSubjects.click('xpack.uptime.alertsPopover.toggleButton'); + return testSubjects.click('xpack.synthetics.alertsPopover.toggleButton'); }, /** * If the popover is already open, click the nested button. * Otherwise, open the popover, then click the nested button. */ async navigateToNestedPopover(): Promise { - if (await testSubjects.exists('xpack.uptime.openAlertContextPanel')) { - return testSubjects.click('xpack.uptime.openAlertContextPanel'); + if (await testSubjects.exists('xpack.synthetics.openAlertContextPanel')) { + return testSubjects.click('xpack.synthetics.openAlertContextPanel'); } - await testSubjects.click('xpack.uptime.alertsPopover.toggleButton'); - return testSubjects.click('xpack.uptime.openAlertContextPanel'); + await testSubjects.click('xpack.synthetics.alertsPopover.toggleButton'); + return testSubjects.click('xpack.synthetics.openAlertContextPanel'); }, async clickDefineSettings() { diff --git a/x-pack/test/functional_basic/apps/ml/permissions/full_ml_access.ts b/x-pack/test/functional_basic/apps/ml/permissions/full_ml_access.ts index 6db82801a5bdd..b44c5f08bdbc6 100644 --- a/x-pack/test/functional_basic/apps/ml/permissions/full_ml_access.ts +++ b/x-pack/test/functional_basic/apps/ml/permissions/full_ml_access.ts @@ -20,9 +20,7 @@ export default function ({ getService }: FtrProviderContext) { { user: USER.ML_POWERUSER_SPACES, discoverAvailable: false }, ]; - // FLAKY: https://github.com/elastic/kibana/issues/124413 - // FLAKY: https://github.com/elastic/kibana/issues/122838 - describe.skip('for user with full ML access', function () { + describe('for user with full ML access', function () { for (const testUser of testUsers) { describe(`(${testUser.user})`, function () { const ecIndexPattern = 'ft_module_sample_ecommerce'; diff --git a/x-pack/test/functional_execution_context/fixtures/plugins/alerts/server/plugin.ts b/x-pack/test/functional_execution_context/fixtures/plugins/alerts/server/plugin.ts index 82e6253ab6d10..e6fc9c5aff6c4 100644 --- a/x-pack/test/functional_execution_context/fixtures/plugins/alerts/server/plugin.ts +++ b/x-pack/test/functional_execution_context/fixtures/plugins/alerts/server/plugin.ts @@ -103,7 +103,8 @@ export class FixturePlugin implements Plugin { const refreshResults = await pageObjects.triggersActionsUI.getAlertsListWithStatus(); expect(refreshResults.map((item: any) => item.status).sort()).to.eql(['Error', 'Ok']); }); - await testSubjects.click('ruleStatusFilterButton'); - await testSubjects.click('ruleStatuserrorFilerOption'); // select Error status filter + await testSubjects.click('ruleExecutionStatusFilterButton'); + await testSubjects.click('ruleExecutionStatuserrorFilterOption'); // select Error status filter await retry.try(async () => { const filterErrorOnlyResults = await pageObjects.triggersActionsUI.getAlertsListWithStatus(); @@ -600,5 +601,63 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await testSubjects.missingOrFail('centerJustifiedSpinner'); }); + + it('should filter alerts by the rule status', async () => { + const assertRulesLength = async (length: number) => { + return await retry.try(async () => { + const rules = await pageObjects.triggersActionsUI.getAlertsList(); + expect(rules.length).to.equal(length); + }); + }; + + // Enabled alert + await createAlert({ + supertest, + objectRemover, + }); + const disabledAlert = await createAlert({ + supertest, + objectRemover, + }); + const snoozedAlert = await createAlert({ + supertest, + objectRemover, + }); + + await disableAlert({ + supertest, + alertId: disabledAlert.id, + }); + await snoozeAlert({ + supertest, + alertId: snoozedAlert.id, + }); + + await refreshAlertsList(); + await assertRulesLength(3); + + // Select enabled + await testSubjects.click('ruleStatusFilterButton'); + await testSubjects.click('ruleStatusFilterOption-enabled'); + await assertRulesLength(1); + + // Select disabled + await testSubjects.click('ruleStatusFilterOption-enabled'); + await testSubjects.click('ruleStatusFilterOption-disabled'); + await assertRulesLength(1); + + // Select snoozed + await testSubjects.click('ruleStatusFilterOption-disabled'); + await testSubjects.click('ruleStatusFilterOption-snoozed'); + await assertRulesLength(1); + + // Select disabled and snoozed + await testSubjects.click('ruleStatusFilterOption-disabled'); + await assertRulesLength(2); + + // Select all 3 + await testSubjects.click('ruleStatusFilterOption-enabled'); + await assertRulesLength(3); + }); }); }; diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alerts_table.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alerts_table.ts index f0797ffd54d91..436770696dbab 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alerts_table.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alerts_table.ts @@ -30,27 +30,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await waitTableIsLoaded(); - const euiDataGridRows = await find.allByCssSelector('.euiDataGridRow'); - const rows = []; - for (const euiDataGridRow of euiDataGridRows) { - const $ = await euiDataGridRow.parseDomContent(); - rows.push({ - status: $.findTestSubjects('dataGridRowCell') - .find('[data-gridcell-column-id="event.action"] .euiDataGridRowCell__truncate') - .text(), - lastUpdated: $.findTestSubjects('dataGridRowCell') - .find('[data-gridcell-column-id="@timestamp"] .euiDataGridRowCell__truncate') - .text(), - duration: $.findTestSubjects('dataGridRowCell') - .find( - '[data-gridcell-column-id="kibana.alert.duration.us"] .euiDataGridRowCell__truncate' - ) - .text(), - reason: $.findTestSubjects('dataGridRowCell') - .find('[data-gridcell-column-id="kibana.alert.reason"] .euiDataGridRowCell__truncate') - .text(), - }); - } + const rows = await getRows(); expect(rows.length).to.be(10); expect(rows[0].status).to.be('active'); expect(rows[0].lastUpdated).to.be('2021-10-19T15:20:38.749Z'); @@ -76,27 +56,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await waitTableIsLoaded(); - const euiDataGridRows = await find.allByCssSelector('.euiDataGridRow'); - const rows = []; - for (const euiDataGridRow of euiDataGridRows) { - const $ = await euiDataGridRow.parseDomContent(); - rows.push({ - status: $.findTestSubjects('dataGridRowCell') - .find('[data-gridcell-column-id="event.action"] .euiDataGridRowCell__truncate') - .text(), - lastUpdated: $.findTestSubjects('dataGridRowCell') - .find('[data-gridcell-column-id="@timestamp"] .euiDataGridRowCell__truncate') - .text(), - duration: $.findTestSubjects('dataGridRowCell') - .find( - '[data-gridcell-column-id="kibana.alert.duration.us"] .euiDataGridRowCell__truncate' - ) - .text(), - reason: $.findTestSubjects('dataGridRowCell') - .find('[data-gridcell-column-id="kibana.alert.reason"] .euiDataGridRowCell__truncate') - .text(), - }); - } + const rows = await getRows(); expect(rows.length).to.be(10); expect(rows[0].status).to.be('open'); expect(rows[0].lastUpdated).to.be('2021-10-19T15:20:26.974Z'); @@ -117,6 +77,67 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await waitTableIsLoaded(); + const rows = await getRows(); + expect(rows.length).to.be(10); + expect(rows[0].status).to.be('active'); + expect(rows[0].lastUpdated).to.be('2021-10-19T15:20:26.974Z'); + expect(rows[0].duration).to.be('63291000'); + expect(rows[0].reason).to.be( + 'CPU usage is greater than a threshold of 40 (current value is 40.8%) for gke-edge-oblt-default-pool-350b44de-3v4p' + ); + }); + + it('should open a flyout and paginate through the flyout', async () => { + await PageObjects.common.navigateToUrlWithBrowserHistory('triggersActions', '/alerts'); + await waitTableIsLoaded(); + await testSubjects.click('expandColumnCellOpenFlyoutButton-0'); + await waitFlyoutOpen(); + + expect(await testSubjects.getVisibleText('alertsFlyoutTitle')).to.be( + 'APM Failed Transaction Rate (one)' + ); + expect(await testSubjects.getVisibleText('alertsFlyoutReason')).to.be( + 'Failed transactions rate is greater than 5.0% (current value is 31%) for elastic-co-frontend' + ); + + await testSubjects.click('alertsFlyoutPaginateNext'); + + expect(await testSubjects.getVisibleText('alertsFlyoutTitle')).to.be( + 'APM Failed Transaction Rate (one)' + ); + expect(await testSubjects.getVisibleText('alertsFlyoutReason')).to.be( + 'Failed transactions rate is greater than 5.0% (current value is 35%) for opbeans-python' + ); + + await testSubjects.click('alertsFlyoutPaginatePrevious'); + await testSubjects.click('alertsFlyoutPaginatePrevious'); + + await waitTableIsLoaded(); + + const rows = await getRows(); + expect(rows[0].status).to.be('close'); + expect(rows[0].lastUpdated).to.be('2021-10-19T14:55:14.503Z'); + expect(rows[0].duration).to.be('252002000'); + expect(rows[0].reason).to.be( + 'CPU usage is greater than a threshold of 40 (current value is 56.7%) for gke-edge-oblt-default-pool-350b44de-c3dd' + ); + }); + + async function waitTableIsLoaded() { + return await retry.try(async () => { + const exists = await testSubjects.exists('internalAlertsPageLoading'); + if (exists) throw new Error('Still loading...'); + }); + } + + async function waitFlyoutOpen() { + return await retry.try(async () => { + const exists = await testSubjects.exists('alertsFlyout'); + if (!exists) throw new Error('Still loading...'); + }); + } + + async function getRows() { const euiDataGridRows = await find.allByCssSelector('.euiDataGridRow'); const rows = []; for (const euiDataGridRow of euiDataGridRows) { @@ -138,20 +159,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { .text(), }); } - expect(rows.length).to.be(10); - expect(rows[0].status).to.be('active'); - expect(rows[0].lastUpdated).to.be('2021-10-19T15:20:26.974Z'); - expect(rows[0].duration).to.be('63291000'); - expect(rows[0].reason).to.be( - 'CPU usage is greater than a threshold of 40 (current value is 40.8%) for gke-edge-oblt-default-pool-350b44de-3v4p' - ); - }); - - async function waitTableIsLoaded() { - return await retry.try(async () => { - const exists = await testSubjects.exists('internalAlertsPageLoading'); - if (exists) throw new Error('Still loading...'); - }); + return rows; } }); }; diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/index.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/index.ts index 179cd0c7ab8e9..9c57f29c6f707 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/index.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/index.ts @@ -17,5 +17,7 @@ export default ({ loadTestFile, getService }: FtrProviderContext) => { loadTestFile(require.resolve('./connectors')); loadTestFile(require.resolve('./alerts_table')); loadTestFile(require.resolve('./rule_status_dropdown')); + loadTestFile(require.resolve('./rule_status_filter')); + loadTestFile(require.resolve('./rule_tag_badge')); }); }; diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/rule_status_filter.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/rule_status_filter.ts new file mode 100644 index 0000000000000..0afdc932b0289 --- /dev/null +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/rule_status_filter.ts @@ -0,0 +1,54 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default ({ getPageObjects, getService }: FtrProviderContext) => { + const testSubjects = getService('testSubjects'); + const PageObjects = getPageObjects(['common', 'triggersActionsUI', 'header']); + const esArchiver = getService('esArchiver'); + + describe('Rule status filter', () => { + before(async () => { + await esArchiver.load('x-pack/test/functional/es_archives/observability/alerts'); + await PageObjects.common.navigateToUrlWithBrowserHistory( + 'triggersActions', + '/__components_sandbox' + ); + }); + after(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/observability/alerts'); + }); + + it('should load from the shareable lazy loader', async () => { + await testSubjects.find('ruleStatusFilter'); + const exists = await testSubjects.exists('ruleStatusFilter'); + expect(exists).to.be(true); + }); + + it('should allow rule statuses to be filtered', async () => { + const ruleStatusFilter = await testSubjects.find('ruleStatusFilter'); + let badge = await ruleStatusFilter.findByCssSelector('.euiFilterButton__notification'); + expect(await badge.getVisibleText()).to.be('0'); + + await testSubjects.click('ruleStatusFilter'); + await testSubjects.click('ruleStatusFilterOption-enabled'); + + badge = await ruleStatusFilter.findByCssSelector('.euiFilterButton__notification'); + expect(await badge.getVisibleText()).to.be('1'); + + await testSubjects.click('ruleStatusFilterOption-disabled'); + + badge = await ruleStatusFilter.findByCssSelector('.euiFilterButton__notification'); + expect(await badge.getVisibleText()).to.be('2'); + + await testSubjects.click('ruleStatusFilterOption-enabled'); + expect(await badge.getVisibleText()).to.be('1'); + }); + }); +}; diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/rule_tag_badge.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/rule_tag_badge.ts new file mode 100644 index 0000000000000..0743896fbcbdb --- /dev/null +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/rule_tag_badge.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default ({ getPageObjects, getService }: FtrProviderContext) => { + const testSubjects = getService('testSubjects'); + const PageObjects = getPageObjects(['common', 'triggersActionsUI', 'header']); + const esArchiver = getService('esArchiver'); + + describe('Rule tag badge', () => { + before(async () => { + await esArchiver.load('x-pack/test/functional/es_archives/observability/alerts'); + await PageObjects.common.navigateToUrlWithBrowserHistory( + 'triggersActions', + '/__components_sandbox' + ); + }); + after(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/observability/alerts'); + }); + + it('should load from the shareable lazy loader', async () => { + await testSubjects.find('ruleTagBadge'); + const exists = await testSubjects.exists('ruleTagBadge'); + expect(exists).to.be(true); + }); + + it('should open and display tags', async () => { + await testSubjects.click('ruleTagBadge'); + expect(await testSubjects.exists('ruleTagBadgeItem-tag1')).to.be(true); + expect(await testSubjects.exists('ruleTagBadgeItem-tag2')).to.be(true); + expect(await testSubjects.exists('ruleTagBadgeItem-tag3')).to.be(true); + expect(await testSubjects.exists('ruleTagBadgeItem-tag4')).to.be(true); + }); + }); +}; diff --git a/x-pack/test/functional_with_es_ssl/apps/uptime/alert_flyout.ts b/x-pack/test/functional_with_es_ssl/apps/uptime/alert_flyout.ts index 8cddb9b08a01b..81e05b65348ee 100644 --- a/x-pack/test/functional_with_es_ssl/apps/uptime/alert_flyout.ts +++ b/x-pack/test/functional_with_es_ssl/apps/uptime/alert_flyout.ts @@ -16,7 +16,8 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { const supertest = getService('supertest'); const retry = getService('retry'); - describe('overview page alert flyout controls', function () { + // FLAKY: https://github.com/elastic/kibana/issues/101984 + describe.skip('overview page alert flyout controls', function () { const DEFAULT_DATE_START = 'Sep 10, 2019 @ 12:40:08.078'; const DEFAULT_DATE_END = 'Sep 11, 2019 @ 19:40:08.078'; let alerts: any; diff --git a/x-pack/test/functional_with_es_ssl/apps/uptime/simple_down_alert.ts b/x-pack/test/functional_with_es_ssl/apps/uptime/simple_down_alert.ts index 597b5eb38379d..425ce5a55524d 100644 --- a/x-pack/test/functional_with_es_ssl/apps/uptime/simple_down_alert.ts +++ b/x-pack/test/functional_with_es_ssl/apps/uptime/simple_down_alert.ts @@ -75,7 +75,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { it('displays relevant alert in list drawer', async () => { await toasts.dismissAllToasts(); - await testSubjects.click(`xpack.uptime.monitorList.${monitorId}.expandMonitorDetail`); + await testSubjects.click(`xpack.synthetics.monitorList.${monitorId}.expandMonitorDetail`); await pageObjects.header.waitUntilLoadingHasFinished(); await testSubjects.existOrFail('uptimeMonitorListDrawerAlert0'); }); diff --git a/x-pack/test/functional_with_es_ssl/config.ts b/x-pack/test/functional_with_es_ssl/config.ts index 5243b97898578..4783ad683c0cf 100644 --- a/x-pack/test/functional_with_es_ssl/config.ts +++ b/x-pack/test/functional_with_es_ssl/config.ts @@ -74,6 +74,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { `--xpack.trigger_actions_ui.enableExperimental=${JSON.stringify([ 'internalAlertsTable', 'internalShareableComponentsSandbox', + 'ruleStatusFilter', ])}`, `--xpack.alerting.rules.minimumScheduleInterval.value="2s"`, `--xpack.actions.enabledActionTypes=${JSON.stringify(enabledActionTypes)}`, diff --git a/x-pack/test/functional_with_es_ssl/lib/alert_api_actions.ts b/x-pack/test/functional_with_es_ssl/lib/alert_api_actions.ts index 40e567c299826..ab15d4b2ec3f4 100644 --- a/x-pack/test/functional_with_es_ssl/lib/alert_api_actions.ts +++ b/x-pack/test/functional_with_es_ssl/lib/alert_api_actions.ts @@ -8,6 +8,8 @@ import type { ObjectRemover } from './object_remover'; import { getTestAlertData, getTestActionData } from './get_test_data'; +const FUTURE_SNOOZE_TIME = '9999-12-31T06:00:00.000Z'; + export async function createAlertManualCleanup({ supertest, overwrites = {}, @@ -85,3 +87,14 @@ export async function disableAlert({ supertest, alertId }: { supertest: any; ale .set('kbn-xsrf', 'foo'); return alert; } + +export async function snoozeAlert({ supertest, alertId }: { supertest: any; alertId: string }) { + const { body: alert } = await supertest + .post(`/internal/alerting/rule/${alertId}/_snooze`) + .set('kbn-xsrf', 'foo') + .set('content-type', 'application/json') + .send({ + snooze_end_time: FUTURE_SNOOZE_TIME, + }); + return alert; +} diff --git a/x-pack/test/observability_functional/apps/observability/index.ts b/x-pack/test/observability_functional/apps/observability/index.ts index 972067b2a6b68..9ec3791aef35f 100644 --- a/x-pack/test/observability_functional/apps/observability/index.ts +++ b/x-pack/test/observability_functional/apps/observability/index.ts @@ -9,7 +9,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ loadTestFile }: FtrProviderContext) { describe('ObservabilityApp', function () { - this.tags('ciGroup6'); + this.tags('ciGroup22'); loadTestFile(require.resolve('./alerts')); loadTestFile(require.resolve('./alerts/add_to_case')); diff --git a/x-pack/test/plugin_api_integration/plugins/elasticsearch_client/server/plugin.ts b/x-pack/test/plugin_api_integration/plugins/elasticsearch_client/server/plugin.ts index 9f227af8a7a64..e8d40e07e10b5 100644 --- a/x-pack/test/plugin_api_integration/plugins/elasticsearch_client/server/plugin.ts +++ b/x-pack/test/plugin_api_integration/plugins/elasticsearch_client/server/plugin.ts @@ -15,7 +15,8 @@ export class ElasticsearchClientXPack implements Plugin { router.get( { path: '/api/elasticsearch_client_xpack/context/user', validate: false }, async (context, req, res) => { - const body = await context.core.elasticsearch.client.asCurrentUser.security.getUser(); + const coreContext = await context.core; + const body = await coreContext.elasticsearch.client.asCurrentUser.security.getUser(); return res.ok({ body }); } ); diff --git a/x-pack/test/plugin_api_integration/plugins/event_log/server/init_routes.ts b/x-pack/test/plugin_api_integration/plugins/event_log/server/init_routes.ts index 031f898c06fc9..f4cbc4ad31ffc 100644 --- a/x-pack/test/plugin_api_integration/plugins/event_log/server/init_routes.ts +++ b/x-pack/test/plugin_api_integration/plugins/event_log/server/init_routes.ts @@ -35,13 +35,14 @@ export const logEventRoute = (router: IRouter, eventLogger: IEventLogger, logger ): Promise> { const { id } = req.params as { id: string }; const event: IValidatedEvent = req.body; + const soClient = (await context.core).savedObjects.client; logger.info(`test fixture: log event: ${id} ${JSON.stringify(event)}`); try { - await context.core.savedObjects.client.get('event_log_test', id); + await soClient.get('event_log_test', id); logger.info(`found existing saved object`); } catch (ex) { logger.info(`log event error: ${ex}`); - await context.core.savedObjects.client.create('event_log_test', {}, { id }); + await soClient.create('event_log_test', {}, { id }); logger.info(`created saved object ${id}`); } // mark now as start and end diff --git a/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/init_routes.ts b/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/init_routes.ts index cea7432cbae08..2d98a58d29d7c 100644 --- a/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/init_routes.ts +++ b/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/init_routes.ts @@ -249,7 +249,7 @@ export function initRoutes( res: KibanaResponseFactory ): Promise> { try { - await ensureIndexIsRefreshed(context.core.elasticsearch.client); + await ensureIndexIsRefreshed((await context.core).elasticsearch.client); const taskManager = await taskManagerStart; return res.ok({ body: await taskManager.get(req.params.taskId) }); } catch ({ isBoom, output, message }) { @@ -268,7 +268,7 @@ export function initRoutes( req: KibanaRequest, res: KibanaResponseFactory ): Promise> { - await ensureIndexIsRefreshed(context.core.elasticsearch.client); + await ensureIndexIsRefreshed((await context.core).elasticsearch.client); return res.ok({ body: {} }); } ); @@ -284,7 +284,7 @@ export function initRoutes( res: KibanaResponseFactory ): Promise> { try { - await ensureIndexIsRefreshed(context.core.elasticsearch.client); + await ensureIndexIsRefreshed((await context.core).elasticsearch.client); let tasksFound = 0; const taskManager = await taskManagerStart; do { diff --git a/x-pack/test/plugin_functional/plugins/timelines_test/kibana.json b/x-pack/test/plugin_functional/plugins/timelines_test/kibana.json index f96e8b2bbcc23..1960c49839566 100644 --- a/x-pack/test/plugin_functional/plugins/timelines_test/kibana.json +++ b/x-pack/test/plugin_functional/plugins/timelines_test/kibana.json @@ -4,7 +4,7 @@ "version": "1.0.0", "kibanaVersion": "kibana", "configPath": ["xpack", "timelinesTest"], - "requiredPlugins": ["timelines", "data", "dataEnhanced"], + "requiredPlugins": ["timelines", "data"], "requiredBundles": ["kibanaReact"], "server": false, "ui": true diff --git a/x-pack/test/reporting_functional/reporting_and_deprecated_security/index.ts b/x-pack/test/reporting_functional/reporting_and_deprecated_security/index.ts index a59939deeae0b..4725cb1eae82e 100644 --- a/x-pack/test/reporting_functional/reporting_and_deprecated_security/index.ts +++ b/x-pack/test/reporting_functional/reporting_and_deprecated_security/index.ts @@ -43,7 +43,7 @@ export default function (context: FtrProviderContext) { }; describe('Reporting Functional Tests with Deprecated Security configuration enabled', function () { - this.tags('ciGroup2'); + this.tags('ciGroup20'); before(async () => { const reportingAPI = context.getService('reportingAPI'); diff --git a/x-pack/test/reporting_functional/reporting_and_security/index.ts b/x-pack/test/reporting_functional/reporting_and_security/index.ts index 22057c9be77dc..4b06eb426389e 100644 --- a/x-pack/test/reporting_functional/reporting_and_security/index.ts +++ b/x-pack/test/reporting_functional/reporting_and_security/index.ts @@ -10,7 +10,7 @@ import { FtrProviderContext } from '../ftr_provider_context'; // eslint-disable-next-line import/no-default-export export default function ({ getService, loadTestFile }: FtrProviderContext) { describe('Reporting Functional Tests with Security enabled', function () { - this.tags('ciGroup2'); + this.tags('ciGroup20'); before(async () => { const reportingFunctional = getService('reportingFunctional'); diff --git a/x-pack/test/rule_registry/common/config.ts b/x-pack/test/rule_registry/common/config.ts index d6fec474a00bf..d6ad262ca2c62 100644 --- a/x-pack/test/rule_registry/common/config.ts +++ b/x-pack/test/rule_registry/common/config.ts @@ -83,8 +83,6 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) ...disabledPlugins .filter((k) => k !== 'security') .map((key) => `--xpack.${key}.enabled=false`), - // TO DO: Remove feature flags once we're good to go - '--xpack.securitySolution.enableExperimental=["ruleRegistryEnabled"]', '--xpack.ruleRegistry.write.enabled=true', `--server.xsrf.allowlist=${JSON.stringify(getAllExternalServiceSimulatorPaths())}`, ...(ssl diff --git a/x-pack/test/security_api_integration/fixtures/audit/audit_log/server/plugin.ts b/x-pack/test/security_api_integration/fixtures/audit/audit_log/server/plugin.ts index 3fe195595d0ff..dcbe7a86bf353 100644 --- a/x-pack/test/security_api_integration/fixtures/audit/audit_log/server/plugin.ts +++ b/x-pack/test/security_api_integration/fixtures/audit/audit_log/server/plugin.ts @@ -11,8 +11,9 @@ export class AuditTrailTestPlugin implements Plugin { public setup(core: CoreSetup) { const router = core.http.createRouter(); router.get({ path: '/audit_log', validate: false }, async (context, request, response) => { - await context.core.savedObjects.client.create('dashboard', {}); - await context.core.savedObjects.client.find({ type: 'dashboard' }); + const soClient = (await context.core).savedObjects.client; + await soClient.create('dashboard', {}); + await soClient.find({ type: 'dashboard' }); return response.noContent(); }); } diff --git a/x-pack/test/security_api_integration/tests/kerberos/index.ts b/x-pack/test/security_api_integration/tests/kerberos/index.ts index 39aac8cc4ca2f..cec92939a5194 100644 --- a/x-pack/test/security_api_integration/tests/kerberos/index.ts +++ b/x-pack/test/security_api_integration/tests/kerberos/index.ts @@ -9,7 +9,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ loadTestFile }: FtrProviderContext) { describe('security APIs - Kerberos', function () { - this.tags('ciGroup16'); + this.tags('ciGroup31'); loadTestFile(require.resolve('./kerberos_login')); }); diff --git a/x-pack/test/security_api_integration/tests/pki/index.ts b/x-pack/test/security_api_integration/tests/pki/index.ts index 4ec858da28dbd..c3b733d0b31f8 100644 --- a/x-pack/test/security_api_integration/tests/pki/index.ts +++ b/x-pack/test/security_api_integration/tests/pki/index.ts @@ -9,7 +9,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ loadTestFile }: FtrProviderContext) { describe('security APIs - PKI', function () { - this.tags('ciGroup6'); + this.tags('ciGroup22'); loadTestFile(require.resolve('./pki_auth')); }); diff --git a/x-pack/test/security_api_integration/tests/saml/index.ts b/x-pack/test/security_api_integration/tests/saml/index.ts index dbabb835ee980..e7ffdbd410de3 100644 --- a/x-pack/test/security_api_integration/tests/saml/index.ts +++ b/x-pack/test/security_api_integration/tests/saml/index.ts @@ -9,7 +9,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ loadTestFile }: FtrProviderContext) { describe('security APIs - SAML', function () { - this.tags('ciGroup18'); + this.tags('ciGroup27'); loadTestFile(require.resolve('./saml_login')); }); diff --git a/x-pack/test/security_functional/fixtures/common/test_endpoints/server/init_routes.ts b/x-pack/test/security_functional/fixtures/common/test_endpoints/server/init_routes.ts index 951ca0b755758..16db5c8242931 100644 --- a/x-pack/test/security_functional/fixtures/common/test_endpoints/server/init_routes.ts +++ b/x-pack/test/security_functional/fixtures/common/test_endpoints/server/init_routes.ts @@ -62,7 +62,7 @@ export function initRoutes(initializerContext: PluginInitializerContext, core: C if (request.body.client === 'start-contract') { scopedClient = (await core.getStartServices())[0].elasticsearch.client.asScoped(request); } else if (request.body.client === 'request-context') { - scopedClient = context.core.elasticsearch.client; + scopedClient = (await context.core).elasticsearch.client; } else { scopedClient = (await core.getStartServices())[0].elasticsearch .createClient('custom') diff --git a/x-pack/test/security_solution_cypress/config.ts b/x-pack/test/security_solution_cypress/config.ts index e32283685f0b2..7f196880e8fca 100644 --- a/x-pack/test/security_solution_cypress/config.ts +++ b/x-pack/test/security_solution_cypress/config.ts @@ -50,9 +50,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { '--xpack.ruleRegistry.unsafe.legacyMultiTenancy.enabled=true', `--xpack.securitySolution.enableExperimental=${JSON.stringify([ 'riskyHostsEnabled', - 'usersEnabled', 'riskyUsersEnabled', - 'ruleRegistryEnabled', ])}`, `--home.disableWelcomeScreen=true`, ], diff --git a/x-pack/test/security_solution_cypress/es_archives/exceptions_2/data.json b/x-pack/test/security_solution_cypress/es_archives/exceptions_2/data.json index ae2e267abc7cf..3ad636b20a9cc 100644 --- a/x-pack/test/security_solution_cypress/es_archives/exceptions_2/data.json +++ b/x-pack/test/security_solution_cypress/es_archives/exceptions_2/data.json @@ -2,7 +2,7 @@ "type": "doc", "value": { "id": "_aZE5nwBOpWiDweSth_E", - "index": "exceptions-0001", + "index": "exceptions-0002", "source": { "@timestamp": "2019-09-02T00:41:06.527Z", "agent": { diff --git a/x-pack/test/security_solution_cypress/es_archives/exceptions_2/mappings.json b/x-pack/test/security_solution_cypress/es_archives/exceptions_2/mappings.json index 3b5cc2dae545c..f5f07c23046aa 100644 --- a/x-pack/test/security_solution_cypress/es_archives/exceptions_2/mappings.json +++ b/x-pack/test/security_solution_cypress/es_archives/exceptions_2/mappings.json @@ -11,7 +11,7 @@ "refresh_interval": "5s" } }, - "index": "exceptions-0001", + "index": "exceptions-0002", "mappings": { "properties": { "@timestamp": { diff --git a/x-pack/test/security_solution_cypress/response_ops_cli_config.ts b/x-pack/test/security_solution_cypress/response_ops_cli_config.ts new file mode 100644 index 0000000000000..d70837bff55e7 --- /dev/null +++ b/x-pack/test/security_solution_cypress/response_ops_cli_config.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrConfigProviderContext } from '@kbn/test'; + +import { SecuritySolutionCypressCliResponseOpsTestRunner } from './runner'; + +export default async function ({ readConfigFile }: FtrConfigProviderContext) { + const securitySolutionCypressConfig = await readConfigFile(require.resolve('./config.ts')); + return { + ...securitySolutionCypressConfig.getAll(), + + testRunner: SecuritySolutionCypressCliResponseOpsTestRunner, + }; +} diff --git a/x-pack/test/security_solution_cypress/runner.ts b/x-pack/test/security_solution_cypress/runner.ts index 21404b8b2e47f..6ae5812c56658 100644 --- a/x-pack/test/security_solution_cypress/runner.ts +++ b/x-pack/test/security_solution_cypress/runner.ts @@ -38,6 +38,33 @@ export async function SecuritySolutionCypressCliTestRunner({ getService }: FtrPr }); } +export async function SecuritySolutionCypressCliResponseOpsTestRunner({ + getService, +}: FtrProviderContext) { + const log = getService('log'); + const config = getService('config'); + const esArchiver = getService('esArchiver'); + + await esArchiver.load('x-pack/test/security_solution_cypress/es_archives/auditbeat'); + + await withProcRunner(log, async (procs) => { + await procs.run('cypress', { + cmd: 'yarn', + args: ['cypress:run:respops'], + cwd: resolve(__dirname, '../../plugins/security_solution'), + env: { + FORCE_COLOR: '1', + CYPRESS_BASE_URL: Url.format(config.get('servers.kibana')), + CYPRESS_ELASTICSEARCH_URL: Url.format(config.get('servers.elasticsearch')), + CYPRESS_ELASTICSEARCH_USERNAME: config.get('servers.elasticsearch.username'), + CYPRESS_ELASTICSEARCH_PASSWORD: config.get('servers.elasticsearch.password'), + ...process.env, + }, + wait: true, + }); + }); +} + export async function SecuritySolutionCypressCliCasesTestRunner({ getService, }: FtrProviderContext) { diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts index 368783b0efd1c..48dc450737229 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts @@ -34,29 +34,29 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { 'Last active', 'Actions', ], - ['Host-9fafsc3tqe', 'x', 'x', 'Warning', 'Windows', '10.231.117.28', '7.17.12', 'x', ''], [ 'Host-ku5jy6j0pw', 'x', 'x', - 'Warning', + 'Unsupported', 'Windows', - '10.246.87.11, 10.145.117.106,10.109.242.136', + '10.12.215.130, 10.130.188.228,10.19.102.141', '7.0.13', 'x', '', ], [ - 'Host-o07wj6uaa5', + 'Host-ntr4rkj24m', 'x', 'x', - 'Failure', + 'Success', 'Windows', - '10.82.134.220, 10.47.25.170', - '7.11.13', + '10.36.46.252, 10.222.152.110', + '7.4.13', 'x', '', ], + ['Host-q9qenwrl9k', 'x', 'x', 'Warning', 'Windows', '10.206.226.90', '7.11.10', 'x', ''], ]; const formattedTableData = async () => { @@ -209,9 +209,9 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { 'Host-ku5jy6j0pw', 'x', 'x', - 'Warning', + 'Unsupported', 'Windows', - '10.246.87.11, 10.145.117.106,10.109.242.136', + '10.12.215.130, 10.130.188.228,10.19.102.141', '7.0.13', 'x', '', diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/fleet_integrations.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/fleet_integrations.ts index 4f9b7ad7c0401..ea5746060dedc 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/fleet_integrations.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/fleet_integrations.ts @@ -48,7 +48,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it('should show the Trusted Apps page when link is clicked', async () => { await (await fleetIntegrations.findIntegrationDetailCustomTab()).click(); await (await testSubjects.find('trustedApps-artifactsLink')).click(); - await trustedApps.ensureIsOnTrustedAppsListPage(); + await trustedApps.ensureIsOnTrustedAppsEmptyPage(); }); }); }); diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/trusted_apps_list.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/trusted_apps_list.ts index 7f2357cebb2c6..4643b91303be0 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/trusted_apps_list.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/trusted_apps_list.ts @@ -37,18 +37,12 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { const SHA256 = 'A4370C0CF81686C0B696FA6261c9d3e0d810ae704ab8301839dffd5d5112f476'; // Add it - await testSubjects.click('trustedAppsListAddButton'); - await testSubjects.setValue( - 'addTrustedAppFlyout-createForm-nameTextField', - 'Windows Defender' - ); - await testSubjects.setValue( - 'addTrustedAppFlyout-createForm-conditionsBuilder-group1-entry0-value', - SHA256 - ); - await testSubjects.click('addTrustedAppFlyout-createButton'); + await testSubjects.click('trustedAppsListPage-emptyState-addButton'); + await testSubjects.setValue('trustedApps-form-nameTextField', 'Windows Defender'); + await testSubjects.setValue('trustedApps-form-conditionsBuilder-group1-entry0-value', SHA256); + await testSubjects.click('trustedAppsListPage-flyout-submitButton'); expect( - await testSubjects.getVisibleText('trustedAppCard-criteriaConditions-condition') + await testSubjects.getVisibleText('trustedAppsListPage-card-criteriaConditions-condition') ).to.equal( 'AND process.hash.*IS a4370c0cf81686c0b696fa6261c9d3e0d810ae704ab8301839dffd5d5112f476' ); @@ -61,11 +55,11 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { // Remove it await pageObjects.trustedApps.clickCardActionMenu(); - await testSubjects.click('deleteTrustedAppAction'); - await testSubjects.click('trustedAppDeletionConfirm'); - await testSubjects.waitForDeleted('trustedAppDeletionConfirm'); + await testSubjects.click('trustedAppsListPage-card-cardDeleteAction'); + await testSubjects.click('trustedAppsListPage-deleteModal-submitButton'); + await testSubjects.waitForDeleted('trustedAppsListPage-deleteModal-submitButton'); // We only expect one trusted app to have been visible - await testSubjects.missingOrFail('trustedAppCard'); + await testSubjects.missingOrFail('trustedAppsListPage-card'); // Header has gone because there is no trusted app await testSubjects.missingOrFail('header-page-title'); }); diff --git a/x-pack/test/security_solution_endpoint/page_objects/trusted_apps_page.ts b/x-pack/test/security_solution_endpoint/page_objects/trusted_apps_page.ts index 1678358acc11e..7dc2e84358f54 100644 --- a/x-pack/test/security_solution_endpoint/page_objects/trusted_apps_page.ts +++ b/x-pack/test/security_solution_endpoint/page_objects/trusted_apps_page.ts @@ -24,7 +24,11 @@ export function TrustedAppsPageProvider({ getService, getPageObjects }: FtrProvi * ensures that the Policy Page is the currently display view */ async ensureIsOnTrustedAppsListPage() { - await testSubjects.existOrFail('trustedAppsListPage'); + await testSubjects.existOrFail('trustedAppsListPage-list'); + }, + + async ensureIsOnTrustedAppsEmptyPage() { + await testSubjects.existOrFail('trustedAppsListPage-emptyState'); }, /** @@ -41,7 +45,7 @@ export function TrustedAppsPageProvider({ getService, getPageObjects }: FtrProvi */ async clickCardActionMenu() { await this.ensureIsOnTrustedAppsListPage(); - await testSubjects.click('trustedAppCard-header-actions-button'); + await testSubjects.click('trustedAppsListPage-card-header-actions-button'); }, }; } diff --git a/x-pack/test/timeline/common/config.ts b/x-pack/test/timeline/common/config.ts index 7b0e02aec7efb..d4349eb7f0dc7 100644 --- a/x-pack/test/timeline/common/config.ts +++ b/x-pack/test/timeline/common/config.ts @@ -84,8 +84,6 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) ...disabledPlugins .filter((k) => k !== 'security') .map((key) => `--xpack.${key}.enabled=false`), - // TO DO: Remove feature flags once we're good to go - '--xpack.securitySolution.enableExperimental=["ruleRegistryEnabled"]', '--xpack.ruleRegistry.write.enabled=true', '--xpack.security.audit.enabled=true', '--xpack.security.audit.appender.type=file', diff --git a/x-pack/test/tsconfig.json b/x-pack/test/tsconfig.json index d6bdf8cfaa6fd..8c6a1cb88c0ba 100644 --- a/x-pack/test/tsconfig.json +++ b/x-pack/test/tsconfig.json @@ -58,7 +58,6 @@ { "path": "../plugins/global_search/tsconfig.json" }, { "path": "../plugins/global_search_providers/tsconfig.json" }, { "path": "../plugins/features/tsconfig.json" }, - { "path": "../plugins/data_enhanced/tsconfig.json" }, { "path": "../plugins/drilldowns/url_drilldown/tsconfig.json" }, { "path": "../plugins/embeddable_enhanced/tsconfig.json" }, { "path": "../plugins/encrypted_saved_objects/tsconfig.json" }, diff --git a/x-pack/test/upgrade/apps/canvas/canvas_smoke_tests.ts b/x-pack/test/upgrade/apps/canvas/canvas_smoke_tests.ts index b12b751e94c07..7de0e1247f01a 100644 --- a/x-pack/test/upgrade/apps/canvas/canvas_smoke_tests.ts +++ b/x-pack/test/upgrade/apps/canvas/canvas_smoke_tests.ts @@ -14,7 +14,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const testSubjects = getService('testSubjects'); const browser = getService('browser'); - describe('canvas smoke tests', function describeIndexTests() { + describe('upgrade canvas smoke tests', function describeIndexTests() { const spaces = [ { space: 'default', basePath: '' }, { space: 'automation', basePath: 's/automation' }, @@ -28,17 +28,17 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { ]; spaces.forEach(({ space, basePath }) => { - describe('space ' + space, () => { - beforeEach(async () => { - await PageObjects.common.navigateToActualUrl('home', '/tutorial_directory/sampleData', { - basePath, - }); - await PageObjects.header.waitUntilLoadingHasFinished(); - }); - canvasTests.forEach(({ name, numElements, page }) => { - it('renders elements on workpad ' + name + ' page ' + page, async () => { + canvasTests.forEach(({ name, numElements, page }) => { + describe('space: ' + space, () => { + before(async () => { + await PageObjects.common.navigateToActualUrl('home', '/tutorial_directory/sampleData', { + basePath, + }); + await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.home.launchSampleCanvas(name); await PageObjects.header.waitUntilLoadingHasFinished(); + }); + it('renders elements on workpad ' + name + ' page ' + page, async () => { const currentUrl = await browser.getCurrentUrl(); const [, hash] = currentUrl.split('#/'); if (hash.length === 0) { diff --git a/x-pack/test/upgrade/apps/canvas/index.js b/x-pack/test/upgrade/apps/canvas/index.js deleted file mode 100644 index 0ecc2e98ea67a..0000000000000 --- a/x-pack/test/upgrade/apps/canvas/index.js +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export default ({ loadTestFile }) => { - describe('upgrade', function () { - loadTestFile(require.resolve('./canvas_smoke_tests')); - }); -}; diff --git a/x-pack/test/upgrade/apps/canvas/index.ts b/x-pack/test/upgrade/apps/canvas/index.ts new file mode 100644 index 0000000000000..f28bff9a1820c --- /dev/null +++ b/x-pack/test/upgrade/apps/canvas/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ loadTestFile }: FtrProviderContext) { + describe('upgrade', function () { + loadTestFile(require.resolve('./canvas_smoke_tests')); + }); +} diff --git a/x-pack/test/upgrade/apps/dashboard/dashboard_smoke_tests.ts b/x-pack/test/upgrade/apps/dashboard/dashboard_smoke_tests.ts index 2f35f0e1e12d3..b87ec4dfe4159 100644 --- a/x-pack/test/upgrade/apps/dashboard/dashboard_smoke_tests.ts +++ b/x-pack/test/upgrade/apps/dashboard/dashboard_smoke_tests.ts @@ -18,7 +18,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const kibanaServer = getService('kibanaServer'); const browser = getService('browser'); - describe('dashboard smoke tests', function describeIndexTests() { + describe('upgrade dashboard smoke tests', function describeIndexTests() { const spaces = [ { space: 'default', basePath: '' }, { space: 'automation', basePath: 's/automation' }, @@ -31,7 +31,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { ]; spaces.forEach(({ space, basePath }) => { - describe('space ' + space, () => { + describe('space: ' + space, () => { beforeEach(async () => { await PageObjects.common.navigateToActualUrl('home', '/tutorial_directory/sampleData', { basePath, diff --git a/x-pack/test/upgrade/apps/dashboard/index.js b/x-pack/test/upgrade/apps/dashboard/index.js deleted file mode 100644 index b12d1270f79f9..0000000000000 --- a/x-pack/test/upgrade/apps/dashboard/index.js +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export default ({ loadTestFile }) => { - describe('upgrade', function () { - loadTestFile(require.resolve('./dashboard_smoke_tests')); - }); -}; diff --git a/x-pack/test/upgrade/apps/dashboard/index.ts b/x-pack/test/upgrade/apps/dashboard/index.ts new file mode 100644 index 0000000000000..1f380a18dfb70 --- /dev/null +++ b/x-pack/test/upgrade/apps/dashboard/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ loadTestFile }: FtrProviderContext) { + describe('upgrade', function () { + loadTestFile(require.resolve('./dashboard_smoke_tests')); + }); +} diff --git a/x-pack/test/upgrade/apps/discover/discover_smoke_tests.ts b/x-pack/test/upgrade/apps/discover/discover_smoke_tests.ts new file mode 100644 index 0000000000000..150458919d41d --- /dev/null +++ b/x-pack/test/upgrade/apps/discover/discover_smoke_tests.ts @@ -0,0 +1,57 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ getPageObjects, getService }: FtrProviderContext) { + const PageObjects = getPageObjects(['common', 'header', 'home', 'discover', 'timePicker']); + + describe('upgrade discover smoke tests', function describeIndexTests() { + const spaces = [ + { space: 'default', basePath: '' }, + { space: 'automation', basePath: 's/automation' }, + ]; + + const discoverTests = [ + { name: 'kibana_sample_data_flights', timefield: true, hits: '' }, + { name: 'kibana_sample_data_logs', timefield: true, hits: '' }, + { name: 'kibana_sample_data_ecommerce', timefield: true, hits: '' }, + ]; + + spaces.forEach(({ space, basePath }) => { + discoverTests.forEach(({ name, timefield, hits }) => { + describe('space: ' + space + ', name: ' + name, () => { + before(async () => { + await PageObjects.common.navigateToApp('discover', { + basePath, + }); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.discover.selectIndexPattern(name); + await PageObjects.discover.waitUntilSearchingHasFinished(); + if (timefield) { + await PageObjects.timePicker.setCommonlyUsedTime('Last_24 hours'); + await PageObjects.discover.waitUntilSearchingHasFinished(); + } + }); + it('shows hit count greater than zero', async () => { + const hitCount = await PageObjects.discover.getHitCount(); + if (hits === '') { + expect(hitCount).to.be.greaterThan(0); + } else { + expect(hitCount).to.be.equal(hits); + } + }); + it('shows table rows not empty', async () => { + const tableRows = await PageObjects.discover.getDocTableRows(); + expect(tableRows.length).to.be.greaterThan(0); + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/upgrade/apps/discover/index.ts b/x-pack/test/upgrade/apps/discover/index.ts new file mode 100644 index 0000000000000..18fdd6992b892 --- /dev/null +++ b/x-pack/test/upgrade/apps/discover/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ loadTestFile }: FtrProviderContext) { + describe('upgrade', function () { + loadTestFile(require.resolve('./discover_smoke_tests')); + }); +} diff --git a/x-pack/test/upgrade/apps/graph/graph_smoke_tests.ts b/x-pack/test/upgrade/apps/graph/graph_smoke_tests.ts new file mode 100644 index 0000000000000..cca4e220c7aa5 --- /dev/null +++ b/x-pack/test/upgrade/apps/graph/graph_smoke_tests.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ getPageObjects, getService }: FtrProviderContext) { + const PageObjects = getPageObjects(['common', 'header', 'home', 'graph']); + + describe('upgrade graph smoke tests', function describeIndexTests() { + const spaces = [ + { space: 'default', basePath: '' }, + { space: 'automation', basePath: 's/automation' }, + ]; + + const graphTests = [ + { name: 'flights', numNodes: 91 }, + { name: 'logs', numNodes: 27 }, + { name: 'ecommerce', numNodes: 12 }, + ]; + + spaces.forEach(({ space, basePath }) => { + graphTests.forEach(({ name, numNodes }) => { + describe('space: ' + space, () => { + before(async () => { + await PageObjects.common.navigateToActualUrl('home', '/tutorial_directory/sampleData', { + basePath, + }); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.home.launchSampleGraph(name); + await PageObjects.header.waitUntilLoadingHasFinished(); + }); + it('renders graph for ' + name, async () => { + const elements = await PageObjects.graph.getAllGraphNodes(); + expect(elements).to.be.equal(numNodes); + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/upgrade/apps/graph/index.ts b/x-pack/test/upgrade/apps/graph/index.ts new file mode 100644 index 0000000000000..649b1a740bb6c --- /dev/null +++ b/x-pack/test/upgrade/apps/graph/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ loadTestFile }: FtrProviderContext) { + describe('upgrade', function () { + loadTestFile(require.resolve('./graph_smoke_tests')); + }); +} diff --git a/x-pack/test/upgrade/apps/logs/index.ts b/x-pack/test/upgrade/apps/logs/index.ts new file mode 100644 index 0000000000000..ed4181f75d76d --- /dev/null +++ b/x-pack/test/upgrade/apps/logs/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ loadTestFile }: FtrProviderContext) { + describe('upgrade', function () { + loadTestFile(require.resolve('./logs_smoke_tests')); + }); +} diff --git a/x-pack/test/upgrade/apps/logs/logs_smoke_tests.ts b/x-pack/test/upgrade/apps/logs/logs_smoke_tests.ts new file mode 100644 index 0000000000000..8d9964f25422e --- /dev/null +++ b/x-pack/test/upgrade/apps/logs/logs_smoke_tests.ts @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ getPageObjects, getService }: FtrProviderContext) { + const PageObjects = getPageObjects(['common', 'header', 'home']); + const logsUi = getService('logsUi'); + + describe('upgrade logs smoke tests', function describeIndexTests() { + const spaces = [ + { space: 'default', basePath: '' }, + { space: 'automation', basePath: 's/automation' }, + ]; + + spaces.forEach(({ space, basePath }) => { + describe('space: ' + space, () => { + before(async () => { + await PageObjects.common.navigateToActualUrl('home', '/tutorial_directory/sampleData', { + basePath, + }); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.home.launchSampleLogs('logs'); + await PageObjects.header.waitUntilLoadingHasFinished(); + }); + + it('should show log streams', async () => { + const logStreamEntries = await logsUi.logStreamPage.getStreamEntries(); + expect(logStreamEntries.length).to.be.greaterThan(100); + }); + }); + }); + }); +} diff --git a/x-pack/test/upgrade/apps/maps/index.js b/x-pack/test/upgrade/apps/maps/index.js deleted file mode 100644 index 57d175a62ceb3..0000000000000 --- a/x-pack/test/upgrade/apps/maps/index.js +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export default ({ loadTestFile }) => { - describe('upgrade', function () { - loadTestFile(require.resolve('./maps_smoke_tests')); - }); -}; diff --git a/x-pack/test/upgrade/apps/maps/index.ts b/x-pack/test/upgrade/apps/maps/index.ts new file mode 100644 index 0000000000000..7fac9ae891128 --- /dev/null +++ b/x-pack/test/upgrade/apps/maps/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ loadTestFile }: FtrProviderContext) { + describe('upgrade', function () { + loadTestFile(require.resolve('./maps_smoke_tests')); + }); +} diff --git a/x-pack/test/upgrade/apps/maps/maps_smoke_tests.ts b/x-pack/test/upgrade/apps/maps/maps_smoke_tests.ts index 98e31129a3ccd..ecb000d691ab0 100644 --- a/x-pack/test/upgrade/apps/maps/maps_smoke_tests.ts +++ b/x-pack/test/upgrade/apps/maps/maps_smoke_tests.ts @@ -82,7 +82,7 @@ export default function ({ // Only update the baseline images from Jenkins session images after comparing them // These tests might fail locally because of scaling factors and resolution. - describe('maps smoke tests', function describeIndexTests() { + describe('upgrade maps smoke tests', function describeIndexTests() { const spaces = [ { space: 'default', basePath: '' }, { space: 'automation', basePath: 's/automation' }, @@ -101,7 +101,7 @@ export default function ({ }); spaces.forEach(({ space, basePath }) => { - describe('space ' + space + ' ecommerce', () => { + describe('space: ' + space + ', name: ecommerce', () => { before(async () => { await PageObjects.common.navigateToActualUrl('home', '/tutorial_directory/sampleData', { basePath, @@ -129,7 +129,7 @@ export default function ({ expect(percentDifference.toFixed(3)).to.be.lessThan(0.031); }); }); - describe('space ' + space + ' flights', () => { + describe('space: ' + space + ', name: flights', () => { before(async () => { await PageObjects.common.navigateToActualUrl('home', '/tutorial_directory/sampleData', { basePath, @@ -153,7 +153,7 @@ export default function ({ expect(percentDifference.toFixed(3)).to.be.lessThan(0.031); }); }); - describe('space ' + space + ' web logs', () => { + describe('space: ' + space + ', name: web logs', () => { before(async () => { await PageObjects.common.navigateToActualUrl('home', '/tutorial_directory/sampleData', { basePath, diff --git a/x-pack/test/upgrade/apps/reporting/index.js b/x-pack/test/upgrade/apps/reporting/index.js deleted file mode 100644 index 5bd5081a3568c..0000000000000 --- a/x-pack/test/upgrade/apps/reporting/index.js +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export default ({ loadTestFile }) => { - describe('upgrade', function () { - loadTestFile(require.resolve('./reporting_smoke_tests')); - }); -}; diff --git a/x-pack/test/upgrade/apps/reporting/index.ts b/x-pack/test/upgrade/apps/reporting/index.ts new file mode 100644 index 0000000000000..c4c70660935ad --- /dev/null +++ b/x-pack/test/upgrade/apps/reporting/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ loadTestFile }: FtrProviderContext) { + describe('upgrade', function () { + loadTestFile(require.resolve('./reporting_smoke_tests')); + }); +} diff --git a/x-pack/test/upgrade/apps/reporting/reporting_smoke_tests.ts b/x-pack/test/upgrade/apps/reporting/reporting_smoke_tests.ts index 14136b23abfd5..f7b0eef003c91 100644 --- a/x-pack/test/upgrade/apps/reporting/reporting_smoke_tests.ts +++ b/x-pack/test/upgrade/apps/reporting/reporting_smoke_tests.ts @@ -8,7 +8,7 @@ import expect from '@kbn/expect'; import { parse } from 'url'; import { FtrProviderContext } from '../../ftr_provider_context'; -import { ReportingUsageStats } from '../../reporting_services'; +import { ReportingUsageStats } from '../../services/reporting_upgrade_services'; interface UsageStats { reporting: ReportingUsageStats; @@ -21,6 +21,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const browser = getService('browser'); const PageObjects = getPageObjects(['common', 'header', 'home', 'dashboard', 'share']); const testSubjects = getService('testSubjects'); + const log = getService('log'); const spaces = [ { space: 'default', basePath: '' }, @@ -39,7 +40,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { { name: 'ecommerce', type: 'png', link: 'PNG Reports' }, ]; - describe('reporting smoke tests', () => { + describe('upgrade reporting smoke tests', () => { let completedReportCount: number; let usage: UsageStats; describe('initial state', () => { @@ -53,7 +54,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); }); spaces.forEach(({ space, basePath }) => { - describe('generate report space ' + space, () => { + describe('generate report for space ' + space, () => { beforeEach(async () => { await PageObjects.common.navigateToActualUrl('home', '/tutorial_directory/sampleData', { basePath, @@ -63,7 +64,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { completedReportCount = reportingAPI.getCompletedReportCount(usage); }); reportingTests.forEach(({ name, type, link }) => { - it('name ' + name + ' type ' + type, async () => { + it('name: ' + name + ' type: ' + type, async () => { await PageObjects.home.launchSampleDashboard(name); await PageObjects.share.openShareMenuItem(link); if (type === 'pdf_optimize') { @@ -89,9 +90,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const postUrl = await find.byXPath(`//button[descendant::*[text()='Copy POST URL']]`); await postUrl.click(); const url = await browser.getClipboardValue(); - await reportingAPI.expectAllJobsToFinishSuccessfully([ - await reportingAPI.postJob(parse(url).pathname + '?' + parse(url).query), - ]); + // Add try/catch for https://github.com/elastic/elastic-stack-testing/issues/1199 + // Waiting for job to finish sometimes gets socket hang up error, from what I + // observed during debug testing the command does complete. + // Checking expected report count will still fail if the job did not finish. + try { + await reportingAPI.expectAllJobsToFinishSuccessfully([ + await reportingAPI.postJob(parse(url).pathname + '?' + parse(url).query), + ]); + } catch (e) { + log.debug(`Error waiting for job to finish: ${e}`); + } usage = (await usageAPI.getUsageStats()) as UsageStats; reportingAPI.expectCompletedReportCount(usage, completedReportCount + 1); }); diff --git a/x-pack/test/upgrade/config.ts b/x-pack/test/upgrade/config.ts index 7722c244223cf..78d61d5239556 100644 --- a/x-pack/test/upgrade/config.ts +++ b/x-pack/test/upgrade/config.ts @@ -6,9 +6,9 @@ */ import { FtrConfigProviderContext } from '@kbn/test'; -import { pageObjects } from './page_objects'; -import { ReportingAPIProvider } from './reporting_services'; -import { MapsHelper } from './maps_upgrade_services'; +import { pageObjects } from '../functional/page_objects'; +import { ReportingAPIProvider } from './services/reporting_upgrade_services'; +import { MapsHelper } from './services/maps_upgrade_services'; export default async function ({ readConfigFile }: FtrConfigProviderContext) { const apiConfig = await readConfigFile(require.resolve('../api_integration/config')); @@ -20,6 +20,9 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { testFiles: [ require.resolve('./apps/canvas'), require.resolve('./apps/dashboard'), + require.resolve('./apps/discover'), + require.resolve('./apps/graph'), + require.resolve('./apps/logs'), require.resolve('./apps/maps'), require.resolve('./apps/reporting'), ], diff --git a/x-pack/test/upgrade/ftr_provider_context.d.ts b/x-pack/test/upgrade/ftr_provider_context.d.ts index 24f5087ef7fe2..2cd67b6698a70 100644 --- a/x-pack/test/upgrade/ftr_provider_context.d.ts +++ b/x-pack/test/upgrade/ftr_provider_context.d.ts @@ -7,7 +7,7 @@ import { GenericFtrProviderContext } from '@kbn/test'; -import { pageObjects } from './page_objects'; +import { pageObjects } from '../functional/page_objects'; import { services } from './services'; export type FtrProviderContext = GenericFtrProviderContext; diff --git a/x-pack/test/upgrade/page_objects.ts b/x-pack/test/upgrade/page_objects.ts deleted file mode 100644 index c8b0c9050dbb9..0000000000000 --- a/x-pack/test/upgrade/page_objects.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { pageObjects } from '../functional/page_objects'; - -export { pageObjects }; diff --git a/x-pack/test/upgrade/reporting_services.ts b/x-pack/test/upgrade/reporting_services.ts deleted file mode 100644 index 2467cee0ad822..0000000000000 --- a/x-pack/test/upgrade/reporting_services.ts +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import expect from '@kbn/expect'; -import { indexTimestamp } from '@kbn/reporting-plugin/server/lib/store/index_timestamp'; -import { services as xpackServices } from '../functional/services'; -import { services as apiIntegrationServices } from '../api_integration/services'; -import { FtrProviderContext } from './ftr_provider_context'; - -interface PDFAppCounts { - app: { - [appName: string]: number; - }; - layout: { - [layoutType: string]: number; - }; -} - -export interface ReportingUsageStats { - available: boolean; - enabled: boolean; - total: number; - last_7_days: { - total: number; - printable_pdf: PDFAppCounts; - [jobType: string]: any; - }; - printable_pdf: PDFAppCounts; - status: any; - [jobType: string]: any; -} - -interface UsageStats { - reporting: ReportingUsageStats; -} - -function removeWhitespace(str: string) { - return str.replace(/\s/g, ''); -} - -export function ReportingAPIProvider({ getService }: FtrProviderContext) { - const log = getService('log'); - const supertest = getService('supertest'); - const esSupertest = getService('esSupertest'); - const retry = getService('retry'); - const config = getService('config'); - - return { - async waitForJobToFinish(downloadReportPath: string, options?: { timeout?: number }) { - await retry.waitForWithTimeout( - `job ${downloadReportPath} finished`, - options?.timeout ?? config.get('timeouts.kibanaReportCompletion'), - async () => { - const response = await supertest - .get(downloadReportPath) - .responseType('blob') - .set('kbn-xsrf', 'xxx'); - - if (response.status === 503) { - log.debug(`Report at path ${downloadReportPath} is pending`); - return false; - } - - log.debug(`Report at path ${downloadReportPath} returned code ${response.status}`); - - if (response.status === 200) { - log.debug(`Report at path ${downloadReportPath} is complete`); - return true; - } - - throw new Error(`unexpected status code ${response.status}`); - } - ); - }, - - async expectAllJobsToFinishSuccessfully(jobPaths: string[]) { - await Promise.all( - jobPaths.map(async (path) => { - await this.waitForJobToFinish(path); - }) - ); - }, - - async postJob(apiPath: string): Promise { - log.debug(`ReportingAPI.postJob(${apiPath})`); - const { body } = await supertest - .post(removeWhitespace(apiPath)) - .set('kbn-xsrf', 'xxx') - .expect(200); - return body.path; - }, - - async postJobJSON(apiPath: string, jobJSON: object = {}): Promise { - log.debug(`ReportingAPI.postJobJSON((${apiPath}): ${JSON.stringify(jobJSON)})`); - const { body } = await supertest.post(apiPath).set('kbn-xsrf', 'xxx').send(jobJSON); - return body.path; - }, - - /** - * - * @return {Promise} A function to call to clean up the index alias that was added. - */ - async coerceReportsIntoExistingIndex(indexName: string) { - log.debug(`ReportingAPI.coerceReportsIntoExistingIndex(${indexName})`); - - // Adding an index alias coerces the report to be generated on an existing index which means any new - // index schema won't be applied. This is important if a point release updated the schema. Reports may still - // be inserted into an existing index before the new schema is applied. - const timestampForIndex = indexTimestamp('week', '.'); - await esSupertest - .post('/_aliases') - .send({ - actions: [ - { - add: { index: indexName, alias: `.reporting-${timestampForIndex}` }, - }, - ], - }) - .expect(200); - - return async () => { - await esSupertest - .post('/_aliases') - .send({ - actions: [ - { - remove: { index: indexName, alias: `.reporting-${timestampForIndex}` }, - }, - ], - }) - .expect(200); - }; - }, - - async deleteAllReports() { - log.debug('ReportingAPI.deleteAllReports'); - - // ignores 409 errs and keeps retrying - await retry.tryForTime(5000, async () => { - await esSupertest - .post('/.reporting*/_delete_by_query') - .send({ query: { match_all: {} } }) - .expect(200); - }); - }, - - expectRecentPdfAppStats(stats: UsageStats, app: string, count: number) { - expect(stats.reporting.last_7_days.printable_pdf.app[app]).to.be(count); - }, - - expectAllTimePdfAppStats(stats: UsageStats, app: string, count: number) { - expect(stats.reporting.printable_pdf.app[app]).to.be(count); - }, - - expectRecentPdfLayoutStats(stats: UsageStats, layout: string, count: number) { - expect(stats.reporting.last_7_days.printable_pdf.layout[layout]).to.be(count); - }, - - expectAllTimePdfLayoutStats(stats: UsageStats, layout: string, count: number) { - expect(stats.reporting.printable_pdf.layout[layout]).to.be(count); - }, - - expectRecentJobTypeTotalStats(stats: UsageStats, jobType: string, count: number) { - expect(stats.reporting.last_7_days[jobType].total).to.be(count); - }, - - expectAllTimeJobTypeTotalStats(stats: UsageStats, jobType: string, count: number) { - expect(stats.reporting[jobType].total).to.be(count); - }, - - getCompletedReportCount(stats: UsageStats) { - return stats.reporting.status.completed; - }, - - expectCompletedReportCount(stats: UsageStats, count: number) { - expect(this.getCompletedReportCount(stats)).to.be(count); - }, - - getRecentPdfAppStats(stats: UsageStats, app: string) { - return stats.reporting.last_7_days.printable_pdf.app[app]; - }, - - getAllTimePdfAppStats(stats: UsageStats, app: string) { - return stats.reporting.printable_pdf.app[app]; - }, - - getRecentPdfLayoutStats(stats: UsageStats, layout: string) { - return stats.reporting.last_7_days.printable_pdf.layout[layout]; - }, - - getAllTimePdfLayoutStats(stats: UsageStats, layout: string) { - return stats.reporting.printable_pdf.layout[layout]; - }, - - getRecentJobTypeTotalStats(stats: UsageStats, jobType: string) { - return stats.reporting.last_7_days[jobType].total; - }, - - getAllTimeJobTypeTotalStats(stats: UsageStats, jobType: string) { - return stats.reporting[jobType].total; - }, - }; -} - -export const services = { - ...xpackServices, - supertestWithoutAuth: apiIntegrationServices.supertestWithoutAuth, - usageAPI: apiIntegrationServices.usageAPI, - reportingAPI: ReportingAPIProvider, -}; diff --git a/x-pack/test/upgrade/services.ts b/x-pack/test/upgrade/services.ts deleted file mode 100644 index ca5c23ba335e3..0000000000000 --- a/x-pack/test/upgrade/services.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { services as functionalServices } from '../functional/services'; -import { services as reportingServices } from './reporting_services'; -import { services as mapsUpgradeServices } from './maps_upgrade_services'; - -export const services = { - ...functionalServices, - ...reportingServices, - ...mapsUpgradeServices, -}; diff --git a/x-pack/test/upgrade/services/index.ts b/x-pack/test/upgrade/services/index.ts new file mode 100644 index 0000000000000..cfd227cd86aff --- /dev/null +++ b/x-pack/test/upgrade/services/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { services as functionalServices } from '../../functional/services'; +import { services as reportingServices } from './reporting_upgrade_services'; +import { services as mapsUpgradeServices } from './maps_upgrade_services'; + +export const services = { + ...functionalServices, + ...reportingServices, + ...mapsUpgradeServices, +}; diff --git a/x-pack/test/upgrade/maps_upgrade_services.ts b/x-pack/test/upgrade/services/maps_upgrade_services.ts similarity index 97% rename from x-pack/test/upgrade/maps_upgrade_services.ts rename to x-pack/test/upgrade/services/maps_upgrade_services.ts index b5553eeb9366d..7b80bce7682f0 100644 --- a/x-pack/test/upgrade/maps_upgrade_services.ts +++ b/x-pack/test/upgrade/services/maps_upgrade_services.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { FtrProviderContext } from './ftr_provider_context'; +import { FtrProviderContext } from '../ftr_provider_context'; export function MapsHelper({ getPageObjects, getService }: FtrProviderContext) { const PageObjects = getPageObjects(['maps']); diff --git a/x-pack/test/upgrade/services/reporting_upgrade_services.ts b/x-pack/test/upgrade/services/reporting_upgrade_services.ts new file mode 100644 index 0000000000000..1a1e6113c3735 --- /dev/null +++ b/x-pack/test/upgrade/services/reporting_upgrade_services.ts @@ -0,0 +1,214 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { indexTimestamp } from '@kbn/reporting-plugin/server/lib/store/index_timestamp'; +import { services as xpackServices } from '../../functional/services'; +import { services as apiIntegrationServices } from '../../api_integration/services'; +import { FtrProviderContext } from '../ftr_provider_context'; + +interface PDFAppCounts { + app: { + [appName: string]: number; + }; + layout: { + [layoutType: string]: number; + }; +} + +export interface ReportingUsageStats { + available: boolean; + enabled: boolean; + total: number; + last_7_days: { + total: number; + printable_pdf: PDFAppCounts; + [jobType: string]: any; + }; + printable_pdf: PDFAppCounts; + status: any; + [jobType: string]: any; +} + +interface UsageStats { + reporting: ReportingUsageStats; +} + +function removeWhitespace(str: string) { + return str.replace(/\s/g, ''); +} + +export function ReportingAPIProvider({ getService }: FtrProviderContext) { + const log = getService('log'); + const supertest = getService('supertest'); + const esSupertest = getService('esSupertest'); + const retry = getService('retry'); + const config = getService('config'); + + return { + async waitForJobToFinish(downloadReportPath: string, options?: { timeout?: number }) { + await retry.waitForWithTimeout( + `job ${downloadReportPath} finished`, + options?.timeout ?? config.get('timeouts.kibanaReportCompletion'), + async () => { + const response = await supertest + .get(downloadReportPath) + .responseType('blob') + .set('kbn-xsrf', 'xxx'); + + if (response.status === 503) { + log.debug(`Report at path ${downloadReportPath} is pending`); + return false; + } + + log.debug(`Report at path ${downloadReportPath} returned code ${response.status}`); + + if (response.status === 200) { + log.debug(`Report at path ${downloadReportPath} is complete`); + return true; + } + + throw new Error(`unexpected status code ${response.status}`); + } + ); + }, + + async expectAllJobsToFinishSuccessfully(jobPaths: string[]) { + await Promise.all( + jobPaths.map(async (path) => { + await this.waitForJobToFinish(path); + }) + ); + }, + + async postJob(apiPath: string): Promise { + log.debug(`ReportingAPI.postJob(${apiPath})`); + const { body } = await supertest + .post(removeWhitespace(apiPath)) + .set('kbn-xsrf', 'xxx') + .expect(200); + return body.path; + }, + + async postJobJSON(apiPath: string, jobJSON: object = {}): Promise { + log.debug(`ReportingAPI.postJobJSON((${apiPath}): ${JSON.stringify(jobJSON)})`); + const { body } = await supertest.post(apiPath).set('kbn-xsrf', 'xxx').send(jobJSON); + return body.path; + }, + + /** + * + * @return {Promise} A function to call to clean up the index alias that was added. + */ + async coerceReportsIntoExistingIndex(indexName: string): Promise { + log.debug(`ReportingAPI.coerceReportsIntoExistingIndex(${indexName})`); + + // Adding an index alias coerces the report to be generated on an existing index which means any new + // index schema won't be applied. This is important if a point release updated the schema. Reports may still + // be inserted into an existing index before the new schema is applied. + const timestampForIndex = indexTimestamp('week', '.'); + await esSupertest + .post('/_aliases') + .send({ + actions: [ + { + add: { index: indexName, alias: `.reporting-${timestampForIndex}` }, + }, + ], + }) + .expect(200); + + return async () => { + await esSupertest + .post('/_aliases') + .send({ + actions: [ + { + remove: { index: indexName, alias: `.reporting-${timestampForIndex}` }, + }, + ], + }) + .expect(200); + }; + }, + + async deleteAllReports() { + log.debug('ReportingAPI.deleteAllReports'); + + // ignores 409 errs and keeps retrying + await retry.tryForTime(5000, async () => { + await esSupertest + .post('/.reporting*/_delete_by_query') + .send({ query: { match_all: {} } }) + .expect(200); + }); + }, + + expectRecentPdfAppStats(stats: UsageStats, app: string, count: number) { + expect(stats.reporting.last_7_days.printable_pdf.app[app]).to.be(count); + }, + + expectAllTimePdfAppStats(stats: UsageStats, app: string, count: number) { + expect(stats.reporting.printable_pdf.app[app]).to.be(count); + }, + + expectRecentPdfLayoutStats(stats: UsageStats, layout: string, count: number) { + expect(stats.reporting.last_7_days.printable_pdf.layout[layout]).to.be(count); + }, + + expectAllTimePdfLayoutStats(stats: UsageStats, layout: string, count: number) { + expect(stats.reporting.printable_pdf.layout[layout]).to.be(count); + }, + + expectRecentJobTypeTotalStats(stats: UsageStats, jobType: string, count: number) { + expect(stats.reporting.last_7_days[jobType].total).to.be(count); + }, + + expectAllTimeJobTypeTotalStats(stats: UsageStats, jobType: string, count: number) { + expect(stats.reporting[jobType].total).to.be(count); + }, + + getCompletedReportCount(stats: UsageStats) { + return stats.reporting.status.completed; + }, + + expectCompletedReportCount(stats: UsageStats, count: number) { + expect(this.getCompletedReportCount(stats)).to.be(count); + }, + + getRecentPdfAppStats(stats: UsageStats, app: string) { + return stats.reporting.last_7_days.printable_pdf.app[app]; + }, + + getAllTimePdfAppStats(stats: UsageStats, app: string) { + return stats.reporting.printable_pdf.app[app]; + }, + + getRecentPdfLayoutStats(stats: UsageStats, layout: string) { + return stats.reporting.last_7_days.printable_pdf.layout[layout]; + }, + + getAllTimePdfLayoutStats(stats: UsageStats, layout: string) { + return stats.reporting.printable_pdf.layout[layout]; + }, + + getRecentJobTypeTotalStats(stats: UsageStats, jobType: string) { + return stats.reporting.last_7_days[jobType].total; + }, + + getAllTimeJobTypeTotalStats(stats: UsageStats, jobType: string) { + return stats.reporting[jobType].total; + }, + }; +} + +export const services = { + ...xpackServices, + supertestWithoutAuth: apiIntegrationServices.supertestWithoutAuth, + usageAPI: apiIntegrationServices.usageAPI, + reportingAPI: ReportingAPIProvider, +}; diff --git a/yarn.lock b/yarn.lock index a1c9373e08175..426588b11a9c4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1415,29 +1415,29 @@ dependencies: tslib "^2.0.0" -"@elastic/apm-rum-core@^5.14.1": - version "5.14.1" - resolved "https://registry.yarnpkg.com/@elastic/apm-rum-core/-/apm-rum-core-5.14.1.tgz#8f65060967c8d68498f2c520e4169ec07eb3b5bb" - integrity sha512-RFgTpXUIEIoy44TPnEN7cVcf2YIBOwaNdALrYVc4lOTMH3u0v4gaS0n9/Aee5nTGqWBLKWXXvMk/dAkjQW6qEg== +"@elastic/apm-rum-core@^5.15.0": + version "5.15.0" + resolved "https://registry.yarnpkg.com/@elastic/apm-rum-core/-/apm-rum-core-5.15.0.tgz#f1067078080be1b7167c72ae6d155b0ed5cdf6c6" + integrity sha512-T5/1hZPskmU6N3Xo2CRNi5tX2ht8R5nLmh5t0I1v8RxkwbQms47AR1f0ZVvXN7W2FCDPadyQXC3f9do3k5A6OA== dependencies: error-stack-parser "^1.3.5" opentracing "^0.14.3" promise-polyfill "^8.1.3" -"@elastic/apm-rum-react@^1.3.4": - version "1.3.4" - resolved "https://registry.yarnpkg.com/@elastic/apm-rum-react/-/apm-rum-react-1.3.4.tgz#f60f1ba55696f4e04eba64edb323e43ef9d67acb" - integrity sha512-HPKU/tnTbiSQr6HYxHB9rP4TKBHZ9HKhBPzmCvZj8PNH5tkMFR4nj0PLN9eYL59A7omAmtH2Sg95T47OIG9ZtQ== +"@elastic/apm-rum-react@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@elastic/apm-rum-react/-/apm-rum-react-1.4.0.tgz#f36453e54d2ebdedb0d6d0c4f6cc76e16304b118" + integrity sha512-YIBuEJN6fkiB1M/o84PF4lQheAjrd3PQCm6t8pP4dKuWN1cWZnSsojnuGacx2bJn1kWWZxVDQ7wTjPJutkIy2A== dependencies: - "@elastic/apm-rum" "^5.10.2" + "@elastic/apm-rum" "^5.11.0" hoist-non-react-statics "^3.3.0" -"@elastic/apm-rum@^5.10.2": - version "5.10.2" - resolved "https://registry.yarnpkg.com/@elastic/apm-rum/-/apm-rum-5.10.2.tgz#06d3e9f08adc19e1227073dda7e5c4ab34be48c7" - integrity sha512-NrBQcgautAGwJOrJ20WUUXV1Ynux4dEEU/fgeqfdG7G3JGqMbuIlF8s/nqLgQ9oXz72Z5MirOf68P7m5Zh/5HA== +"@elastic/apm-rum@^5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@elastic/apm-rum/-/apm-rum-5.11.0.tgz#97dbc426d0ec27b46e78a649f73d9e4a198ae258" + integrity sha512-+98NLG4NDa7o1DCtkhXeGmKW5riDPHSpgy2UxzLK4j02ZPBOccOUjIw5F8yZAUsrPUpQmk39x13IJl0mFyzjyA== dependencies: - "@elastic/apm-rum-core" "^5.14.1" + "@elastic/apm-rum-core" "^5.15.0" "@elastic/apm-synthtrace@link:bazel-bin/packages/elastic-apm-synthtrace": version "0.0.0" @@ -1504,10 +1504,10 @@ "@elastic/transport" "^8.0.2" tslib "^2.3.0" -"@elastic/ems-client@8.2.0": - version "8.2.0" - resolved "https://registry.yarnpkg.com/@elastic/ems-client/-/ems-client-8.2.0.tgz#35ca17f07a576c464b15a17ef9b228a51043e329" - integrity sha512-NtU/KjTMGntnrCY6+2jdkugn6pqMJj2EV4/Mff/MGlBLrWSlxYkYa6Q6KFhmT3V68RJUxOsId47mUdoQbRi/yg== +"@elastic/ems-client@8.3.0": + version "8.3.0" + resolved "https://registry.yarnpkg.com/@elastic/ems-client/-/ems-client-8.3.0.tgz#9d40c02e33c407d433b8e509d83c5edec24c4902" + integrity sha512-DlJDyUQzNrxGbS0AWxGiBNfq1hPQUP3Ib/Zyotgv7+VGGklb0mBwppde7WLVvuj0E+CYc6E63TJsoD8KNUO0MQ== dependencies: "@types/geojson" "^7946.0.7" "@types/lru-cache" "^5.1.0" @@ -1527,10 +1527,10 @@ resolved "https://registry.yarnpkg.com/@elastic/eslint-plugin-eui/-/eslint-plugin-eui-0.0.2.tgz#56b9ef03984a05cc213772ae3713ea8ef47b0314" integrity sha512-IoxURM5zraoQ7C8f+mJb9HYSENiZGgRVcG4tLQxE61yHNNRDXtGDWTZh8N1KIHcsqN1CEPETjuzBXkJYF/fDiQ== -"@elastic/eui@54.0.0": - version "54.0.0" - resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-54.0.0.tgz#373a50f0ebbecfbe39b86f1d87f3ba1c6f942a81" - integrity sha512-0qm4SoGYup0Cyb+k50heIdJ9pTIYQwA2knNWZ+UE92SzPUzAwSmhrwkiqzTqGCgB6/Kd2Ck4gzFjI+ct1njkmg== +"@elastic/eui@55.0.1": + version "55.0.1" + resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-55.0.1.tgz#d10978aa01b3e44f54dbfa148bc31af58d64b251" + integrity sha512-k6ES2Sp8bZlYGRFYIoBS2EQ3C9BmEgC4p/A4ViHWNKpb0qriS37A28/QyIR2cPXwiesRq6rt7L+LQSLJlXmGzA== dependencies: "@types/chroma-js" "^2.0.0" "@types/lodash" "^4.14.160" @@ -1564,7 +1564,7 @@ remark-emoji "^2.1.0" remark-parse "^8.0.3" remark-rehype "^8.0.0" - tabbable "^3.0.0" + tabbable "^5.2.1" text-diff "^1.0.1" unified "^9.2.0" unist-util-visit "^2.0.3" @@ -2968,10 +2968,6 @@ version "0.0.0" uid "" -"@kbn/ci-stats-client@link:bazel-bin/packages/kbn-ci-stats-client": - version "0.0.0" - uid "" - "@kbn/ci-stats-core@link:bazel-bin/packages/kbn-ci-stats-core": version "0.0.0" uid "" @@ -3437,10 +3433,13 @@ concat-stream "~2.0.0" minimist "^1.2.5" -"@mapbox/geojson-types@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@mapbox/geojson-types/-/geojson-types-1.0.2.tgz#9aecf642cb00eab1080a57c4f949a65b4a5846d6" - integrity sha512-e9EBqHHv3EORHrSfbR9DqecPNn+AmuAoQxV6aL8Xu30bJMJR1o8PZLZzpk1Wq7/NfCbuhmakHTPYRhoqLsXRnw== +"@mapbox/geojson-rewind@^0.5.1": + version "0.5.1" + resolved "https://registry.yarnpkg.com/@mapbox/geojson-rewind/-/geojson-rewind-0.5.1.tgz#adbe16dc683eb40e90934c51a5e28c7bbf44f4e1" + integrity sha512-eL7fMmfTBKjrb+VFHXCGv9Ot0zc3C0U+CwXo1IrP+EPwDczLoXv34Tgq3y+2mPSFNVUXgU42ILWJTC7145KPTA== + dependencies: + get-stream "^6.0.1" + minimist "^1.2.5" "@mapbox/hast-util-table-cell-style@^0.1.3": version "0.1.3" @@ -3472,25 +3471,25 @@ resolved "https://registry.yarnpkg.com/@mapbox/mapbox-gl-rtl-text/-/mapbox-gl-rtl-text-0.2.3.tgz#a26ecfb3f0061456d93ee8570dd9587d226ea8bd" integrity sha512-RaCYfnxULUUUxNwcUimV9C/o2295ktTyLEUzD/+VWkqXqvaVfFcZ5slytGzb2Sd/Jj4MlbxD0DCZbfa6CzcmMw== -"@mapbox/mapbox-gl-supported@^1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-1.5.0.tgz#f60b6a55a5d8e5ee908347d2ce4250b15103dc8e" - integrity sha512-/PT1P6DNf7vjEEiPkVIRJkvibbqWtqnyGaBz3nfRdcxclNSnSdaLU5tfAgcD7I8Yt5i+L19s406YLl1koLnLbg== +"@mapbox/mapbox-gl-supported@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-2.0.1.tgz#c15367178d8bfe4765e6b47b542fe821ce259c7b" + integrity sha512-HP6XvfNIzfoMVfyGjBckjiAOQK9WfX0ywdLubuPMPv+Vqf5fj0uCbgBQYpiqcWZT6cbyyRnTSXDheT1ugvF6UQ== "@mapbox/point-geometry@0.1.0", "@mapbox/point-geometry@^0.1.0", "@mapbox/point-geometry@~0.1.0": version "0.1.0" resolved "https://registry.yarnpkg.com/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz#8a83f9335c7860effa2eeeca254332aa0aeed8f2" integrity sha1-ioP5M1x4YO/6Lu7KJUMyqgru2PI= -"@mapbox/tiny-sdf@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@mapbox/tiny-sdf/-/tiny-sdf-1.1.1.tgz#16a20c470741bfe9191deb336f46e194da4a91ff" - integrity sha512-Ihn1nZcGIswJ5XGbgFAvVumOgWpvIjBX9jiRlIl46uQG9vJOF51ViBYHF95rEZupuyQbEmhLaDPLQlU7fUTsBg== +"@mapbox/tiny-sdf@^2.0.4": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@mapbox/tiny-sdf/-/tiny-sdf-2.0.5.tgz#cdba698d3d65087643130f9af43a2b622ce0b372" + integrity sha512-OhXt2lS//WpLdkqrzo/KwB7SRD8AiNTFFzuo9n14IBupzIMa67yGItcK7I2W9D8Ghpa4T04Sw9FWsKCJG50Bxw== -"@mapbox/unitbezier@^0.0.0": - version "0.0.0" - resolved "https://registry.yarnpkg.com/@mapbox/unitbezier/-/unitbezier-0.0.0.tgz#15651bd553a67b8581fb398810c98ad86a34524e" - integrity sha1-FWUb1VOme4WB+zmIEMmK2Go0Uk4= +"@mapbox/unitbezier@^0.0.1": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz#d32deb66c7177e9e9dfc3bbd697083e2e657ff01" + integrity sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw== "@mapbox/vector-tile@1.3.1", "@mapbox/vector-tile@^1.3.1": version "1.3.1" @@ -5707,6 +5706,11 @@ resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.7.tgz#c8fa532b60a0042219cdf173ca21a975ef0666ad" integrity sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ== +"@types/geojson@^7946.0.8": + version "7946.0.8" + resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.8.tgz#30744afdb385e2945e22f3b033f897f76b1f12ca" + integrity sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA== + "@types/getos@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/getos/-/getos-3.0.0.tgz#582c758e99e9d634f31f471faf7ce59cf1c39a71" @@ -6056,10 +6060,6 @@ version "0.0.0" uid "" -"@types/kbn__ci-stats-client@link:bazel-bin/packages/kbn-ci-stats-client/npm_module_types": - version "0.0.0" - uid "" - "@types/kbn__ci-stats-core@link:bazel-bin/packages/kbn-ci-stats-core/npm_module_types": version "0.0.0" uid "" @@ -6394,12 +6394,12 @@ resolved "https://registry.yarnpkg.com/@types/lz-string/-/lz-string-1.3.34.tgz#69bfadde419314b4a374bf2c8e58659c035ed0a5" integrity sha512-j6G1e8DULJx3ONf6NdR5JiR2ZY3K3PaaqiEuKYkLQO0Czfi1AzrtjfnfCROyWGeDd5IVMKCwsgSmMip9OWijow== -"@types/mapbox__point-geometry@*": +"@types/mapbox__point-geometry@*", "@types/mapbox__point-geometry@^0.1.2": version "0.1.2" resolved "https://registry.yarnpkg.com/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.2.tgz#488a9b76e8457d6792ea2504cdd4ecdd9860a27e" integrity sha512-D0lgCq+3VWV85ey1MZVkE8ZveyuvW5VAfuahVTQRpXFQTxw03SuIf1/K4UQ87MMIXVKzpFjXFiFMZzLj2kU+iA== -"@types/mapbox__vector-tile@1.3.0": +"@types/mapbox__vector-tile@1.3.0", "@types/mapbox__vector-tile@^1.3.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.0.tgz#8fa1379dbaead1e1b639b8d96cfd174404c379d6" integrity sha512-kDwVreQO5V4c8yAxzZVQLE5tyWF+IPToAanloQaSnwfXmIcJ7cyOrv8z4Ft4y7PsLYmhWXmON8MBV8RX0Rgr8g== @@ -6544,10 +6544,10 @@ "@types/node" "*" form-data "^2.3.3" -"@types/node-forge@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.0.1.tgz#0df103639da9d5ec6a708d462020f0df70679f37" - integrity sha512-96ELNKv9tQJ19afdBUiM5iDw7OYEc53iUc51gAPR2aGaqRsO1DBROjqgZRjZa1tkPj7TnEOR0EnyAX6iryGkzA== +"@types/node-forge@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.0.2.tgz#454299d3eaa846a38f8d88872a895b40a02e86dd" + integrity sha512-J1OkeZGaW0y9Y7xD49Ja8O82B9l5nZDeoYuGWqIOYPAf9LR+xF23k9ILdzv8dH+2H033fx3D5oiA0GlmicI+sg== dependencies: "@types/node" "*" @@ -6638,7 +6638,7 @@ resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== -"@types/pbf@*", "@types/pbf@3.0.2": +"@types/pbf@*", "@types/pbf@3.0.2", "@types/pbf@^3.0.2": version "3.0.2" resolved "https://registry.yarnpkg.com/@types/pbf/-/pbf-3.0.2.tgz#8d291ad68b4b8c533e96c174a2e3e6399a59ed61" integrity sha512-EDrLIPaPXOZqDjrkzxxbX7UlJSeQVgah3i0aA4pOSzmK9zq3BIh7/MZIQxED7slJByvKM4Gc6Hypyu2lJzh3SQ== @@ -6955,10 +6955,10 @@ resolved "https://registry.yarnpkg.com/@types/seedrandom/-/seedrandom-2.4.28.tgz#9ce8fa048c1e8c85cb71d7fe4d704e000226036f" integrity sha512-SMA+fUwULwK7sd/ZJicUztiPs8F1yCPwF3O23Z9uQ32ME5Ha0NmDK9+QTsYE4O2tHXChzXomSWWeIhCnoN1LqA== -"@types/selenium-webdriver@^4.0.18": - version "4.0.18" - resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-4.0.18.tgz#98f6e1ccd2d92f6fddaccfc7c148d2e158da0f92" - integrity sha512-gkrUo3QldGr8V9im/DjgKkX4UVd1rtflfEBuPG9hPSA1keu7A0rF8h/MQjpTMm2EPVhBCd2K8tn5nlC9Vsd5Xw== +"@types/selenium-webdriver@^4.0.19": + version "4.0.19" + resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-4.0.19.tgz#25699713552a63ee70215effdfd2e5d6dda19f8e" + integrity sha512-Irrh+iKc6Cxj6DwTupi4zgWhSBm1nK+JElOklIUiBVE6rcLYDtT1mwm9oFkHie485BQXNmZRoayjwxhowdInnA== "@types/semver@^7": version "7.3.4" @@ -7118,10 +7118,10 @@ dependencies: "@types/geojson" "*" -"@types/tough-cookie@*", "@types/tough-cookie@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.1.tgz#8f80dd965ad81f3e1bc26d6f5c727e132721ff40" - integrity sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg== +"@types/tough-cookie@*", "@types/tough-cookie@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.2.tgz#6286b4c7228d58ab7866d19716f3696e03a09397" + integrity sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw== "@types/type-detect@^4.0.1": version "4.0.1" @@ -7290,14 +7290,14 @@ resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.0.tgz#8b63ab7f1aa5321248aad5ac890a485656dcea4d" integrity sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg== -"@typescript-eslint/eslint-plugin@^5.17.0": - version "5.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.17.0.tgz#704eb4e75039000531255672bf1c85ee85cf1d67" - integrity sha512-qVstvQilEd89HJk3qcbKt/zZrfBZ+9h2ynpAGlWjWiizA7m/MtLT9RoX6gjtpE500vfIg8jogAkDzdCxbsFASQ== +"@typescript-eslint/eslint-plugin@^5.20.0": + version "5.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.20.0.tgz#022531a639640ff3faafaf251d1ce00a2ef000a1" + integrity sha512-fapGzoxilCn3sBtC6NtXZX6+P/Hef7VDbyfGqTTpzYydwhlkevB+0vE0EnmHPVTVSy68GUncyJ/2PcrFBeCo5Q== dependencies: - "@typescript-eslint/scope-manager" "5.17.0" - "@typescript-eslint/type-utils" "5.17.0" - "@typescript-eslint/utils" "5.17.0" + "@typescript-eslint/scope-manager" "5.20.0" + "@typescript-eslint/type-utils" "5.20.0" + "@typescript-eslint/utils" "5.20.0" debug "^4.3.2" functional-red-black-tree "^1.0.1" ignore "^5.1.8" @@ -7317,14 +7317,14 @@ eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/parser@^5.17.0": - version "5.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.17.0.tgz#7def77d5bcd8458d12d52909118cf3f0a45f89d5" - integrity sha512-aRzW9Jg5Rlj2t2/crzhA2f23SIYFlF9mchGudyP0uiD6SenIxzKoLjwzHbafgHn39dNV/TV7xwQkLfFTZlJ4ig== +"@typescript-eslint/parser@^5.20.0": + version "5.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.20.0.tgz#4991c4ee0344315c2afc2a62f156565f689c8d0b" + integrity sha512-UWKibrCZQCYvobmu3/N8TWbEeo/EPQbS41Ux1F9XqPzGuV7pfg6n50ZrFo6hryynD8qOTTfLHtHjjdQtxJ0h/w== dependencies: - "@typescript-eslint/scope-manager" "5.17.0" - "@typescript-eslint/types" "5.17.0" - "@typescript-eslint/typescript-estree" "5.17.0" + "@typescript-eslint/scope-manager" "5.20.0" + "@typescript-eslint/types" "5.20.0" + "@typescript-eslint/typescript-estree" "5.20.0" debug "^4.3.2" "@typescript-eslint/scope-manager@4.31.2": @@ -7335,20 +7335,20 @@ "@typescript-eslint/types" "4.31.2" "@typescript-eslint/visitor-keys" "4.31.2" -"@typescript-eslint/scope-manager@5.17.0": - version "5.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.17.0.tgz#4cea7d0e0bc0e79eb60cad431c89120987c3f952" - integrity sha512-062iCYQF/doQ9T2WWfJohQKKN1zmmXVfAcS3xaiialiw8ZUGy05Em6QVNYJGO34/sU1a7a+90U3dUNfqUDHr3w== +"@typescript-eslint/scope-manager@5.20.0": + version "5.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.20.0.tgz#79c7fb8598d2942e45b3c881ced95319818c7980" + integrity sha512-h9KtuPZ4D/JuX7rpp1iKg3zOH0WNEa+ZIXwpW/KWmEFDxlA/HSfCMhiyF1HS/drTICjIbpA6OqkAhrP/zkCStg== dependencies: - "@typescript-eslint/types" "5.17.0" - "@typescript-eslint/visitor-keys" "5.17.0" + "@typescript-eslint/types" "5.20.0" + "@typescript-eslint/visitor-keys" "5.20.0" -"@typescript-eslint/type-utils@5.17.0": - version "5.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.17.0.tgz#1c4549d68c89877662224aabb29fbbebf5fc9672" - integrity sha512-3hU0RynUIlEuqMJA7dragb0/75gZmwNwFf/QJokWzPehTZousP/MNifVSgjxNcDCkM5HI2K22TjQWUmmHUINSg== +"@typescript-eslint/type-utils@5.20.0": + version "5.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.20.0.tgz#151c21cbe9a378a34685735036e5ddfc00223be3" + integrity sha512-WxNrCwYB3N/m8ceyoGCgbLmuZwupvzN0rE8NBuwnl7APgjv24ZJIjkNzoFBXPRCGzLNkoU/WfanW0exvp/+3Iw== dependencies: - "@typescript-eslint/utils" "5.17.0" + "@typescript-eslint/utils" "5.20.0" debug "^4.3.2" tsutils "^3.21.0" @@ -7357,10 +7357,10 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.31.2.tgz#2aea7177d6d744521a168ed4668eddbd912dfadf" integrity sha512-kWiTTBCTKEdBGrZKwFvOlGNcAsKGJSBc8xLvSjSppFO88AqGxGNYtF36EuEYG6XZ9vT0xX8RNiHbQUKglbSi1w== -"@typescript-eslint/types@5.17.0": - version "5.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.17.0.tgz#861ec9e669ffa2aa9b873dd4d28d9b1ce26d216f" - integrity sha512-AgQ4rWzmCxOZLioFEjlzOI3Ch8giDWx8aUDxyNw9iOeCvD3GEYAB7dxWGQy4T/rPVe8iPmu73jPHuaSqcjKvxw== +"@typescript-eslint/types@5.20.0": + version "5.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.20.0.tgz#fa39c3c2aa786568302318f1cb51fcf64258c20c" + integrity sha512-+d8wprF9GyvPwtoB4CxBAR/s0rpP25XKgnOvMf/gMXYDvlUC3rPFHupdTQ/ow9vn7UDe5rX02ovGYQbv/IUCbg== "@typescript-eslint/typescript-estree@4.31.2": version "4.31.2" @@ -7375,28 +7375,28 @@ semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/typescript-estree@5.17.0", "@typescript-eslint/typescript-estree@^5.17.0": - version "5.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.17.0.tgz#a7cba7dfc8f9cc2ac78c18584e684507df4f2488" - integrity sha512-X1gtjEcmM7Je+qJRhq7ZAAaNXYhTgqMkR10euC4Si6PIjb+kwEQHSxGazXUQXFyqfEXdkGf6JijUu5R0uceQzg== +"@typescript-eslint/typescript-estree@5.20.0", "@typescript-eslint/typescript-estree@^5.20.0": + version "5.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.20.0.tgz#ab73686ab18c8781bbf249c9459a55dc9417d6b0" + integrity sha512-36xLjP/+bXusLMrT9fMMYy1KJAGgHhlER2TqpUVDYUQg4w0q/NW/sg4UGAgVwAqb8V4zYg43KMUpM8vV2lve6w== dependencies: - "@typescript-eslint/types" "5.17.0" - "@typescript-eslint/visitor-keys" "5.17.0" + "@typescript-eslint/types" "5.20.0" + "@typescript-eslint/visitor-keys" "5.20.0" debug "^4.3.2" globby "^11.0.4" is-glob "^4.0.3" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/utils@5.17.0": - version "5.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.17.0.tgz#549a9e1d491c6ccd3624bc3c1b098f5cfb45f306" - integrity sha512-DVvndq1QoxQH+hFv+MUQHrrWZ7gQ5KcJzyjhzcqB1Y2Xes1UQQkTRPUfRpqhS8mhTWsSb2+iyvDW1Lef5DD7vA== +"@typescript-eslint/utils@5.20.0": + version "5.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.20.0.tgz#b8e959ed11eca1b2d5414e12417fd94cae3517a5" + integrity sha512-lHONGJL1LIO12Ujyx8L8xKbwWSkoUKFSO+0wDAqGXiudWB2EO7WEUT+YZLtVbmOmSllAjLb9tpoIPwpRe5Tn6w== dependencies: "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.17.0" - "@typescript-eslint/types" "5.17.0" - "@typescript-eslint/typescript-estree" "5.17.0" + "@typescript-eslint/scope-manager" "5.20.0" + "@typescript-eslint/types" "5.20.0" + "@typescript-eslint/typescript-estree" "5.20.0" eslint-scope "^5.1.1" eslint-utils "^3.0.0" @@ -7408,12 +7408,12 @@ "@typescript-eslint/types" "4.31.2" eslint-visitor-keys "^2.0.0" -"@typescript-eslint/visitor-keys@5.17.0": - version "5.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.17.0.tgz#52daae45c61b0211b4c81b53a71841911e479128" - integrity sha512-6K/zlc4OfCagUu7Am/BD5k8PSWQOgh34Nrv9Rxe2tBzlJ7uOeJ/h7ugCGDCeEZHT6k2CJBhbk9IsbkPI0uvUkA== +"@typescript-eslint/visitor-keys@5.20.0": + version "5.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.20.0.tgz#70236b5c6b67fbaf8b2f58bf3414b76c1e826c2a" + integrity sha512-1flRpNF+0CAQkMNlTJ6L/Z5jiODG/e5+7mk6XwtPOUS3UrTz3UOiAg9jG2VtKsWI6rZQfy4C6a232QNRZTRGlg== dependencies: - "@typescript-eslint/types" "5.17.0" + "@typescript-eslint/types" "5.20.0" eslint-visitor-keys "^3.0.0" "@ungap/promise-all-settled@1.1.2": @@ -9281,20 +9281,7 @@ brfs@^2.0.0, brfs@^2.0.2: static-module "^3.0.2" through2 "^2.0.0" -broadcast-channel@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/broadcast-channel/-/broadcast-channel-3.4.1.tgz#65b63068d0a5216026a19905c9b2d5e9adf0928a" - integrity sha512-VXYivSkuBeQY+pL5hNQQNvBdKKQINBAROm4G8lAbWQfOZ7Yn4TMcgLNlJyEqlkxy5G8JJBsI3VJ1u8FUTOROcg== - dependencies: - "@babel/runtime" "^7.7.2" - detect-node "^2.0.4" - js-sha3 "0.8.0" - microseconds "0.2.0" - nano-time "1.0.0" - rimraf "3.0.2" - unload "2.2.0" - -broadcast-channel@^4.10.0: +broadcast-channel@4.10.0: version "4.10.0" resolved "https://registry.yarnpkg.com/broadcast-channel/-/broadcast-channel-4.10.0.tgz#d19fb902df227df40b1b580351713d30c302d198" integrity sha512-hOUh312XyHk6JTVyX9cyXaH1UYs+2gHVtnW16oQAu9FL7ALcXGXc/YoJWqlkV8vUn14URQPMmRi4A9q4UrwVEQ== @@ -9308,6 +9295,19 @@ broadcast-channel@^4.10.0: rimraf "3.0.2" unload "2.3.1" +broadcast-channel@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/broadcast-channel/-/broadcast-channel-3.4.1.tgz#65b63068d0a5216026a19905c9b2d5e9adf0928a" + integrity sha512-VXYivSkuBeQY+pL5hNQQNvBdKKQINBAROm4G8lAbWQfOZ7Yn4TMcgLNlJyEqlkxy5G8JJBsI3VJ1u8FUTOROcg== + dependencies: + "@babel/runtime" "^7.7.2" + detect-node "^2.0.4" + js-sha3 "0.8.0" + microseconds "0.2.0" + nano-time "1.0.0" + rimraf "3.0.2" + unload "2.2.0" + brorand@^1.0.1, brorand@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" @@ -9884,9 +9884,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001097, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001286: - version "1.0.30001309" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001309.tgz#e0ee78b9bec0704f67304b00ff3c5c0c768a9f62" - integrity sha512-Pl8vfigmBXXq+/yUz1jUwULeq9xhMJznzdc/xwl4WclDAuebcTHVefpz8lE/bMI+UN7TOkSSe7B7RnZd6+dzjA== + version "1.0.30001335" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001335.tgz" + integrity sha512-ddP1Tgm7z2iIxu6QTtbZUv6HJxSaV/PZeSrWFZtbY4JZ69tOeNhBCl3HyRQgeNZKE5AOn1kpV7fhljigy0Ty3w== canvg@^3.0.9: version "3.0.9" @@ -12951,10 +12951,10 @@ each-props@^1.3.0: is-plain-object "^2.0.1" object.defaults "^1.1.0" -earcut@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/earcut/-/earcut-2.2.2.tgz#41b0bc35f63e0fe80da7cddff28511e7e2e80d11" - integrity sha512-eZoZPPJcUHnfRZ0PjLvx2qBordSiO8ofC3vt+qACLM95u+4DovnbYNpQtJh0DNsWj8RnxrQytD4WA8gj5cRIaQ== +earcut@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/earcut/-/earcut-2.2.3.tgz#d44ced2ff5a18859568e327dd9c7d46b16f55cf4" + integrity sha512-iRDI1QeCQIhMCZk48DRDMVgQSSBDmbzzNhnxIo+pwx3swkfjMh6vh0nWLq1NdvGHLKH6wIrAM3vQWeTj6qeoug== ecc-jsbn@~0.1.1: version "0.1.2" @@ -13009,10 +13009,10 @@ elastic-apm-http-client@11.0.1: semver "^6.3.0" stream-chopper "^3.0.1" -elastic-apm-node@^3.31.0: - version "3.31.0" - resolved "https://registry.yarnpkg.com/elastic-apm-node/-/elastic-apm-node-3.31.0.tgz#6e0bf622d922c95ff0127a263babcdeaeea71457" - integrity sha512-0OulazfhkXYbOaGkHncqjwOfxtcvzsDyzUKr6Y1k95HwKrjf1Vi+xPutZv4p/WfDdO+JadphI0U2Uu5ncGB2iA== +elastic-apm-node@^3.32.0: + version "3.32.0" + resolved "https://registry.yarnpkg.com/elastic-apm-node/-/elastic-apm-node-3.32.0.tgz#fdad3c03aabc4e7994b4155b031f68d9774af49a" + integrity sha512-6vOe1FZv5toCouuyfiXZuWNE1+1fim9zvsv7H56BKRYa7xQ3X1fxq7QAP2gLd/Z9zvSDLGNXS4DPE1eqX1A1Jw== dependencies: "@elastic/ecs-pino-format" "^1.2.0" after-all-results "^2.0.0" @@ -13087,6 +13087,11 @@ elliptic@^6.0.0: minimalistic-assert "^1.0.1" minimalistic-crypto-utils "^1.0.1" +email-addresses@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/email-addresses/-/email-addresses-5.0.0.tgz#7ae9e7f58eef7d5e3e2c2c2d3ea49b78dc854fa6" + integrity sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw== + emittery@^0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.7.1.tgz#c02375a927a40948c0345cc903072597f5270451" @@ -14739,7 +14744,7 @@ font-awesome@4.7.0: resolved "https://registry.yarnpkg.com/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133" integrity sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM= -for-each@^0.3.2, for-each@^0.3.3, for-each@~0.3.3: +for-each@^0.3.3, for-each@~0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== @@ -15193,6 +15198,11 @@ get-stream@^5.0.0, get-stream@^5.1.0: dependencies: pump "^3.0.0" +get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + get-symbol-description@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" @@ -15262,7 +15272,12 @@ github-slugger@^1.0.0: dependencies: emoji-regex ">=6.0.0 <=6.1.1" -gl-matrix@^3.2.1, gl-matrix@~3.3.0: +gl-matrix@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/gl-matrix/-/gl-matrix-3.4.3.tgz#fc1191e8320009fd4d20e9339595c6041ddc22c9" + integrity sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA== + +gl-matrix@~3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/gl-matrix/-/gl-matrix-3.3.0.tgz#232eef60b1c8b30a28cbbe75b2caf6c48fd6358b" integrity sha512-COb7LDz+SXaHtl/h4LeaFcNdJdAQSDeVqjiIihSXNrkWObZLhDI4hIkZC11Aeqp7bcE72clzB0BnDXr2SmslRA== @@ -15652,11 +15667,6 @@ graphql@^16.3.0: resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.3.0.tgz#a91e24d10babf9e60c706919bb182b53ccdffc05" integrity sha512-xm+ANmA16BzCT5pLjuXySbQVFwH3oJctUVdy81w1sV0vBU0KgDdBGtxQOUd5zqOBk/JayAFeG8Dlmeq74rjm/A== -grid-index@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/grid-index/-/grid-index-1.1.0.tgz#97f8221edec1026c8377b86446a7c71e79522ea7" - integrity sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA== - growl@1.10.5: version "1.10.5" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" @@ -16123,11 +16133,6 @@ highlight.js@^10.1.1, highlight.js@^10.4.1, highlight.js@~10.4.0: resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.4.1.tgz#d48fbcf4a9971c4361b3f95f302747afe19dbad0" integrity sha512-yR5lWvNz7c85OhVAEAeFhVCc/GV4C30Fjzc/rCP0aCWzc1UUOPUk55dK/qdwTZHBvMZo+eZ2jpk62ndX/xMFlg== -history-extra@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/history-extra/-/history-extra-5.0.1.tgz#95a2e59dda526c4241d0ae1b124a77a5e4675ce8" - integrity sha512-6XV1L1lHgporVWgppa/Kq+Fnz4lhBew7iMxYCTfzVmoEywsAKJnTjdw1zOd+EGLHGYp0/V8jSVMEgqx4QbHLTw== - history@^4.9.0: version "4.9.0" resolved "https://registry.yarnpkg.com/history/-/history-4.9.0.tgz#84587c2068039ead8af769e9d6a6860a14fa1bca" @@ -19713,34 +19718,34 @@ mapcap@^1.0.0: resolved "https://registry.yarnpkg.com/mapcap/-/mapcap-1.0.0.tgz#e8e29d04a160eaf8c92ec4bcbd2c5d07ed037e5a" integrity sha512-KcNlZSlFPx+r1jYZmxEbTVymG+dIctf10WmWkuhrhrblM+KMoF77HelwihL5cxYlORye79KoR4IlOOk99lUJ0g== -maplibre-gl@1.15.2: - version "1.15.2" - resolved "https://registry.yarnpkg.com/maplibre-gl/-/maplibre-gl-1.15.2.tgz#7fb47868b62455af916c090903f2154394450f9c" - integrity sha512-uPeV530apb4JfX3cRFfE+awFnbcJTOnCv2QvY4mw4huiInbybElWYkNzTs324YLSADq0f4bidRoYcR81ho3aLA== +maplibre-gl@2.1.9: + version "2.1.9" + resolved "https://registry.yarnpkg.com/maplibre-gl/-/maplibre-gl-2.1.9.tgz#042f3ef4224fa890ecf7a410145243f1fc943dcd" + integrity sha512-pnWJmILeZpgA5QSI7K7xFK3yrkyYTd9srw3fCi2Ca52Phm78hsznPwUErEQcZLfxXKn/1h9t8IPdj0TH0NBNbg== dependencies: - "@mapbox/geojson-rewind" "^0.5.0" - "@mapbox/geojson-types" "^1.0.2" + "@mapbox/geojson-rewind" "^0.5.1" "@mapbox/jsonlint-lines-primitives" "^2.0.2" - "@mapbox/mapbox-gl-supported" "^1.5.0" + "@mapbox/mapbox-gl-supported" "^2.0.1" "@mapbox/point-geometry" "^0.1.0" - "@mapbox/tiny-sdf" "^1.1.1" - "@mapbox/unitbezier" "^0.0.0" + "@mapbox/tiny-sdf" "^2.0.4" + "@mapbox/unitbezier" "^0.0.1" "@mapbox/vector-tile" "^1.3.1" "@mapbox/whoots-js" "^3.1.0" + "@types/geojson" "^7946.0.8" + "@types/mapbox__point-geometry" "^0.1.2" + "@types/mapbox__vector-tile" "^1.3.0" + "@types/pbf" "^3.0.2" csscolorparser "~1.0.3" - earcut "^2.2.2" + earcut "^2.2.3" geojson-vt "^3.2.1" - gl-matrix "^3.2.1" - grid-index "^1.1.0" - minimist "^1.2.5" + gl-matrix "^3.4.3" murmurhash-js "^1.0.0" pbf "^3.2.1" - potpack "^1.0.1" + potpack "^1.0.2" quickselect "^2.0.0" - rw "^1.3.3" - supercluster "^7.1.0" + supercluster "^7.1.4" tinyqueue "^2.0.3" - vt-pbf "^3.1.1" + vt-pbf "^3.1.3" marge@^1.0.1: version "1.0.1" @@ -20886,10 +20891,10 @@ node-forge@^0.10.0: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== -node-forge@^1.2.1, node-forge@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.0.tgz#37a874ea723855f37db091e6c186e5b67a01d4b2" - integrity sha512-08ARB91bUi6zNKzVmaj3QO7cr397uiDT2nJ63cHjyNtCTWIgvS47j3eT0WfzUwS9+6Z5YshRaoasFkXCKrIYbA== +node-forge@^1.2.1, node-forge@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== node-gyp-build@^4.2.3: version "4.2.3" @@ -21985,12 +21990,9 @@ parse-filepath@^1.0.1: path-root "^0.1.1" parse-headers@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.1.tgz#6ae83a7aa25a9d9b700acc28698cd1f1ed7e9536" - integrity sha1-aug6eqJanZtwCswoaYzR8e1+lTY= - dependencies: - for-each "^0.3.2" - trim "0.0.1" + version "2.0.5" + resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.5.tgz#069793f9356a54008571eb7f9761153e6c770da9" + integrity sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA== parse-json@^2.2.0: version "2.2.0" @@ -22969,10 +22971,10 @@ postcss@^7.0.1, postcss@^7.0.27, postcss@^7.0.35, postcss@^7.0.36: picocolors "^0.2.1" source-map "^0.6.1" -potpack@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/potpack/-/potpack-1.0.1.tgz#d1b1afd89e4c8f7762865ec30bd112ab767e2ebf" - integrity sha512-15vItUAbViaYrmaB/Pbw7z6qX2xENbFSTA7Ii4tgbPtasxm5v6ryKhKtL91tpWovDJzTiZqdwzhcFBCwiMVdVw== +potpack@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/potpack/-/potpack-1.0.2.tgz#23b99e64eb74f5741ffe7656b5b5c4ddce8dfc14" + integrity sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ== preact-render-to-string@^5.1.19: version "5.1.19" @@ -23027,10 +23029,10 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.1.tgz#d472797e0d7461605c1609808e27b80c0f9cfe17" - integrity sha512-8UVbTBYGwN37Bs9LERmxCPjdvPxlEowx2urIL6urHzdb3SDq4B/Z6xLFCblrSnE4iKWcS6ziJ3aOYrc1kz/E2A== +prettier@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.2.tgz#e26d71a18a74c3d0f0597f55f01fb6c06c206032" + integrity sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew== prettier@~2.2.1: version "2.2.1" @@ -25465,7 +25467,7 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" -rw@1, rw@^1.3.2, rw@^1.3.3: +rw@1, rw@^1.3.2: version "1.3.3" resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4" integrity sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q= @@ -26397,11 +26399,9 @@ sourcemap-codec@^1.4.1: integrity sha512-1ZooVLYFxC448piVLBbtOxFcXwnymH9oUF8nRd3CuYDVvkRBxRl6pB4Mtas5a4drtL+E8LDgFkQNcgIw6tc8Hg== space-separated-tokens@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.2.tgz#e95ab9d19ae841e200808cd96bc7bd0adbbb3412" - integrity sha512-G3jprCEw+xFEs0ORweLmblJ3XLymGGr6hxZYTYZjIlvDti9vOBUjRQa1Rzjt012aRrocKstHwdNi+F7HguPsEA== - dependencies: - trim "0.0.1" + version "1.1.5" + resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" + integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== sparkles@^1.0.0: version "1.0.0" @@ -27310,10 +27310,10 @@ superagent@^3.8.2: qs "^6.5.1" readable-stream "^2.3.5" -supercluster@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/supercluster/-/supercluster-7.1.0.tgz#f0a457426ec0ab95d69c5f03b51e049774b94479" - integrity sha512-LDasImUAFMhTqhK+cUXfy9C2KTUqJ3gucLjmNLNFmKWOnDUBxLFLH9oKuXOTCLveecmxh8fbk8kgh6Q0gsfe2w== +supercluster@^7.1.4: + version "7.1.4" + resolved "https://registry.yarnpkg.com/supercluster/-/supercluster-7.1.4.tgz#6762aabfd985d3390b49f13b815567d5116a828a" + integrity sha512-GhKkRM1jMR6WUwGPw05fs66pOFWhf59lXq+Q3J3SxPvhNcmgOtLRV6aVQPMRsmXdpaeFJGivt+t7QXUPL3ff4g== dependencies: kdbush "^3.0.0" @@ -27457,10 +27457,10 @@ tabbable@1.1.3: resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-1.1.3.tgz#0e4ee376f3631e42d7977a074dbd2b3827843081" integrity sha512-nOWwx35/JuDI4ONuF0ZTo6lYvI0fY0tZCH1ErzY2EXfu4az50ZyiUX8X073FLiZtmWUVlkRnuXsehjJgCw9tYg== -tabbable@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-3.1.2.tgz#f2d16cccd01f400e38635c7181adfe0ad965a4a2" - integrity sha512-wjB6puVXTYO0BSFtCmWQubA/KIn7Xvajw0x0l6eJUudMG/EAiJvIUnyNX6xO4NpGrJ16lbD0eUseB9WxW0vlpQ== +tabbable@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-5.2.1.tgz#e3fda7367ddbb172dcda9f871c0fdb36d1c4cd9c" + integrity sha512-40pEZ2mhjaZzK0BnI+QGNjJO8UYx9pP5v7BGe17SORTO0OEuuaAwQTkAp8whcZvqon44wKFOikD+Al11K3JICQ== table@^6.0.3, table@^6.0.9: version "6.7.1" @@ -29716,6 +29716,15 @@ vt-pbf@^3.1.1: "@mapbox/vector-tile" "^1.3.1" pbf "^3.0.5" +vt-pbf@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/vt-pbf/-/vt-pbf-3.1.3.tgz#68fd150756465e2edae1cc5c048e063916dcfaac" + integrity sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA== + dependencies: + "@mapbox/point-geometry" "0.1.0" + "@mapbox/vector-tile" "^1.3.1" + pbf "^3.2.1" + w3c-hr-time@^1.0.1, w3c-hr-time@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"